This commit is contained in:
JRoberts committed 2022-04-12 22:35:09 +04:00
1 parent 9d84ddc214
commit 1a869460b8
9 files changed
+238 -26

No files matched your search

+12 -7
View File
@@ -775,13 +775,13 @@ struct CIFile: Decodable {
}
}
enum CIFileStatus: Decodable {
case sndStored
case sndCancelled
case rcvInvitation
case rcvTransfer
case rcvComplete
case rcvCancelled
enum CIFileStatus: String, Decodable {
case sndStored = "snd_stored"
case sndCancelled = "snd_cancelled"
case rcvInvitation = "rcv_invitation"
case rcvTransfer = "rcv_transfer"
case rcvComplete = "rcv_complete"
case rcvCancelled = "rcv_cancelled"
}
enum MsgContent {
@@ -819,6 +819,7 @@ enum MsgContent {
case type
case text
case preview
case image
}
}
@@ -836,6 +837,10 @@ extension MsgContent: Decodable {
let text = try container.decode(String.self, forKey: CodingKeys.text)
let preview = try container.decode(LinkPreview.self, forKey: CodingKeys.preview)
self = .link(text: text, preview: preview)
case "image":
let text = try container.decode(String.self, forKey: CodingKeys.text)
let image = try container.decode(String.self, forKey: CodingKeys.image)
self = .image(text: text, image: image)
default:
let text = try? container.decode(String.self, forKey: CodingKeys.text)
self = .unknown(type: type, text: text ?? "unknown message format")
@@ -51,7 +51,9 @@ struct FramedItemView: View {
.frame(minWidth: msgWidth, alignment: .center)
.padding(.bottom, 2)
} else {
if case let .link(_, preview) = chatItem.content.msgContent {
if case let .image(_, image) = chatItem.content.msgContent {
ChatItemImageView(image: image, file: chatItem.file?.filePath)
} else if case let .link(_, preview) = chatItem.content.msgContent {
ChatItemLinkView(linkPreview: preview)
}
MsgContentView(
+38 -3
View File
@@ -24,6 +24,9 @@ struct ChatView: View {
@State private var showChatInfo = false
@State private var showDeleteMessage = false
@State private var chosenImage: UIImage? = nil
@State private var imagePreview: String? = nil
var body: some View {
let cInfo = chat.chatInfo
@@ -90,7 +93,9 @@ struct ChatView: View {
sendMessage: sendMessage,
resetMessage: { message = "" },
inProgress: inProgress,
keyboardVisible: $keyboardVisible
keyboardVisible: $keyboardVisible,
chosenImage: $chosenImage,
imagePreview: $imagePreview
)
}
.navigationTitle(cInfo.chatViewName)
@@ -221,7 +226,13 @@ struct ChatView: View {
}
} else {
let mc: MsgContent
if let preview = linkPreview {
var file: String? = nil
if let preview = imagePreview,
let uiImage = chosenImage,
let savedFile = saveImage(uiImage) {
mc = .image(text: text, image: preview)
file = savedFile
} else if let preview = linkPreview {
mc = .link(text: text, preview: preview)
} else {
mc = .text(text)
@@ -229,7 +240,7 @@ struct ChatView: View {
let chatItem = try await apiSendMessage(
type: chat.chatInfo.chatType,
id: chat.chatInfo.apiId,
file: nil,
file: file,
quotedItemId: quotedItem?.meta.itemId,
msg: mc
)
@@ -244,6 +255,30 @@ struct ChatView: View {
}
}
}
func saveImage(_ uiImage: UIImage) -> String? {
if let imageResized = resizeImageToDataSize(uiImage, maxDataSize: 160000),
let dataResized = Data(base64Encoded: dropImagePrefix(imageResized)),
let jpegData = UIImage(data: dataResized)?.jpegData(compressionQuality: 1) {
let imgName = "IMG_\(Date().timeIntervalSince1970).jpg"
let filename = getDocumentsDirectory().appendingPathComponent(imgName)
do {
try jpegData.write(to: filename)
return filename.path
} catch {
logger.error("ChatView.saveImage error: \(error.localizedDescription)")
return nil
}
}
return nil
}
func getDocumentsDirectory() -> URL {
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
return path
// let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
// return paths[0]
}
func deleteMessage(_ mode: CIDeleteMode) {
logger.debug("ChatView deleteMessage")
@@ -15,6 +15,24 @@ import SwiftUI
// case editing(editingItem: ChatItem)
//}
//enum ReferencedItem {
// case none
// case quoted(quotedItem: ChatItem)
// case editing(editingItem: ChatItem)
//}
//
//enum Preview {
// case none
// case link(linkPreview: LinkPreview)
// case image(image: UIImage)
//}
//
//struct ComposeState {
// var quotedItem: ChatItem? = nil
// var editingItem: ChatItem? = nil
// var linkPreview: LinkPreview? = nil
//}
struct ComposeView: View {
@Binding var message: String
@Binding var quotedItem: ChatItem?
@@ -31,10 +49,17 @@ struct ComposeView: View {
@State var pendingLinkUrl: URL? = nil
@State var cancelledLinks: Set<String> = []
@State private var showChooseSource = false
@State private var showImagePicker = false
@State private var imageSource: ImageSource = .imageLibrary
@Binding var chosenImage: UIImage?
@Binding var imagePreview: String?
var body: some View {
VStack(spacing: 0) {
if let metadata = linkPreview {
if let metadata = imagePreview {
ComposeImageView(image: metadata, cancelImage: nil)
} else if let metadata = linkPreview {
ComposeLinkView(linkPreview: metadata, cancelPreview: cancelPreview)
}
if (quotedItem != nil) {
@@ -42,17 +67,30 @@ struct ComposeView: View {
} else if (editingItem != nil) {
ContextItemView(contextItem: $editingItem, editing: $editing, resetMessage: resetMessage)
}
SendMessageView(
sendMessage: { text in
sendMessage(text)
resetLinkPreview()
},
inProgress: inProgress,
message: $message,
keyboardVisible: $keyboardVisible,
editing: $editing
)
.background(.background)
HStack{
Button {
showChooseSource = true
} label: {
Image(systemName: "paperclip")
.resizable()
}
.disabled(editingItem != nil)
.frame(width: 25, height: 25)
.padding(.vertical, 4)
.padding(.leading, 12)
SendMessageView(
sendMessage: { text in
sendMessage(text)
resetLinkPreview()
},
inProgress: inProgress,
message: $message,
keyboardVisible: $keyboardVisible,
editing: $editing
)
.padding(.trailing, 12)
.background(.background)
}
}
.onChange(of: message) { _ in
if message.count > 0 {
@@ -64,6 +102,33 @@ struct ComposeView: View {
.onChange(of: editingItem == nil) { _ in
editing = (editingItem != nil)
}
.confirmationDialog("Add image", isPresented: $showChooseSource, titleVisibility: .visible) {
Button("Take picture") {
imageSource = .camera
showImagePicker = true
}
Button("Choose from library") {
imageSource = .imageLibrary
showImagePicker = true
}
}
.sheet(isPresented: $showImagePicker) {
switch imageSource {
case .imageLibrary:
LibraryImagePicker(image: $chosenImage) {
didSelectItem in showImagePicker = false
}
case .camera:
CameraImagePicker(image: $chosenImage)
}
}
.onChange(of: chosenImage) { image in
if let image = image {
imagePreview = resizeImageToDataSize(cropToSquare(image), maxDataSize: 12500)
} else {
imagePreview = nil
}
}
}
private func showLinkPreview(_ s: String) {
@@ -136,6 +201,8 @@ struct ComposeView_Previews: PreviewProvider {
@State var item: ChatItem? = ChatItem.getSample(1, .directSnd, .now, "hello")
@State var nilItem: ChatItem? = nil
@State var linkPreview: LinkPreview? = nil
@State var chosenImage: UIImage? = nil
@State var imagePreview: String? = nil
return Group {
ComposeView(
@@ -145,7 +212,9 @@ struct ComposeView_Previews: PreviewProvider {
linkPreview: $linkPreview,
sendMessage: { print ($0) },
resetMessage: {},
keyboardVisible: $keyboardVisible
keyboardVisible: $keyboardVisible,
chosenImage: $chosenImage,
imagePreview: $imagePreview
)
ComposeView(
message: $message,
@@ -154,7 +223,9 @@ struct ComposeView_Previews: PreviewProvider {
linkPreview: $linkPreview,
sendMessage: { print ($0) },
resetMessage: {},
keyboardVisible: $keyboardVisible
keyboardVisible: $keyboardVisible,
chosenImage: $chosenImage,
imagePreview: $imagePreview
)
}
}
@@ -62,7 +62,6 @@ struct SendMessageView: View {
.strokeBorder(.secondary, lineWidth: 0.3, antialiased: true)
.frame(height: teHeight)
}
.padding(.horizontal, 12)
.padding(.vertical, 8)
}
@@ -0,0 +1,54 @@
//
// ChatItemImageView.swift
// SimpleX
//
// Created by JRoberts on 12/04/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct ChatItemImageView: View {
@Environment(\.colorScheme) var colorScheme
let image: String
let file: String?
var body: some View {
VStack(alignment: .center, spacing: 6) {
if let file = file,
let uiImage = UIImage(contentsOfFile: file) {
Image(uiImage: uiImage)
.resizable()
.scaledToFit()
} else if let data = Data(base64Encoded: dropImagePrefix(image)),
let uiImage = UIImage(data: data) {
Image(uiImage: uiImage)
.resizable()
.scaledToFit()
}
}
}
}
func loadImage(file: String?) -> UIImage? {
if let file = file {
return UIImage(contentsOfFile: file)
} else {
return nil
}
}
//struct ChatItemImageView_Previews: PreviewProvider {
// static var previews: some View {
// let preview = LinkPreview(
// uri: URL(string: "http://DuckDuckGo.com")!,
// title: "Privacy, simplified.",
// description: "",
// image: "data:image/jpg;base64,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 truncated
// )
// ChatItemLinkView(linkPreview: preview)
// .previewLayout(.fixed(width: 360, height: 200))
// }
//}
@@ -0,0 +1,37 @@
//
// ComposeImageView.swift
// SimpleX
//
// Created by JRoberts on 11/04/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct ComposeImageView: View {
@Environment(\.colorScheme) var colorScheme
let image: String
var cancelImage: (() -> Void)? = nil
var body: some View {
HStack(alignment: .center, spacing: 8) {
if let data = Data(base64Encoded: dropImagePrefix(image)),
let uiImage = UIImage(data: data) {
Image(uiImage: uiImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 80, maxHeight: 60)
}
if let cancelImage = cancelImage {
Button { cancelImage() } label: {
Image(systemName: "multiply")
}
}
}
.padding(.vertical, 1)
.padding(.trailing, 12)
.background(colorScheme == .light ? sentColorLight : sentColorDark)
.frame(maxWidth: .infinity)
.padding(.top, 8)
}
}
+1
View File
@@ -69,6 +69,7 @@ struct TerminalView: View {
keyboardVisible: $keyboardVisible,
editing: $editing
)
.padding(.horizontal, 12)
}
}
.navigationViewStyle(.stack)
@@ -113,6 +113,8 @@
649BCD9C280430D100C3A862 /* libHSsimplex-chat-1.5.0-3uBn0HoMpg08OGLfasXsOx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649BCD97280430D100C3A862 /* libHSsimplex-chat-1.5.0-3uBn0HoMpg08OGLfasXsOx.a */; };
649BCD9D280430D100C3A862 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649BCD98280430D100C3A862 /* libgmp.a */; };
649BCD9E280430D100C3A862 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649BCD99280430D100C3A862 /* libgmpxx.a */; };
649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */; };
649BCDA22805D6EF00C3A862 /* ChatItemImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* ChatItemImageView.swift */; };
64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; };
64AA1C6A27EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; };
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; };
@@ -201,6 +203,8 @@
649BCD97280430D100C3A862 /* libHSsimplex-chat-1.5.0-3uBn0HoMpg08OGLfasXsOx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-1.5.0-3uBn0HoMpg08OGLfasXsOx.a"; sourceTree = "<group>"; };
649BCD98280430D100C3A862 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
649BCD99280430D100C3A862 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
649BCD9F280460FD00C3A862 /* ComposeImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeImageView.swift; sourceTree = "<group>"; };
649BCDA12805D6EF00C3A862 /* ChatItemImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemImageView.swift; sourceTree = "<group>"; };
64AA1C6827EE10C800AC7277 /* ContextItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextItemView.swift; sourceTree = "<group>"; };
64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedItemView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -319,6 +323,8 @@
5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */,
3CDBCF4127FAE51000354CDD /* ComposeLinkView.swift */,
3CDBCF4727FF621E00354CDD /* ChatItemLinkView.swift */,
649BCD9F280460FD00C3A862 /* ComposeImageView.swift */,
649BCDA12805D6EF00C3A862 /* ChatItemImageView.swift */,
);
path = Helpers;
sourceTree = "<group>";
@@ -635,6 +641,7 @@
5CC1C99227A6C7F5000D9FF6 /* QRCode.swift in Sources */,
5C116CDC27AABE0400E66D01 /* ContactRequestView.swift in Sources */,
5CB9250D27A9432000ACCCDD /* ChatListNavLink.swift in Sources */,
649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */,
5CA059ED279559F40002BEB4 /* ContentView.swift in Sources */,
5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */,
5C3A88CE27DF50170060F1C2 /* DetermineWidth.swift in Sources */,
@@ -649,6 +656,7 @@
5C577F7D27C83AA10006112D /* MarkdownHelp.swift in Sources */,
5CA059EB279559F40002BEB4 /* SimpleXApp.swift in Sources */,
5CCD403727A5F9A200368C90 /* ConnectContactView.swift in Sources */,
649BCDA22805D6EF00C3A862 /* ChatItemImageView.swift in Sources */,
5CCD403A27A5F9BE00368C90 /* CreateGroupView.swift in Sources */,
5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */,
5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */,