This commit is contained in:
fmodf 2024-08-18 00:12:23 +02:00
parent 4b092a8831
commit 6a5555a603
5 changed files with 147 additions and 164 deletions

View file

@ -49,17 +49,17 @@ struct Message: DBStorable, Equatable {
static let databaseTableName = "messages" static let databaseTableName = "messages"
let id: String let id: String
let type: MessageType var type: MessageType
let date: Date let date: Date
var contentType: MessageContentType var contentType: MessageContentType
var status: MessageStatus var status: MessageStatus
let from: String var from: String
let to: String? var to: String?
var body: String? var body: String?
let subject: String? var subject: String?
let thread: String? var thread: String?
var oobUrl: String? var oobUrl: String?
} }
@ -77,4 +77,20 @@ extension Message {
try updatedMessage.update(db, columns: ["status"]) try updatedMessage.update(db, columns: ["status"])
} }
} }
static var blank: Message {
Message(
id: UUID().uuidString,
type: .chat,
date: Date(),
contentType: .text,
status: .pending,
from: "",
to: nil,
body: nil,
subject: nil,
thread: nil,
oobUrl: nil
)
}
} }

View file

@ -11,8 +11,6 @@ final class ConversationStore: ObservableObject {
private(set) var roster: Roster private(set) var roster: Roster
private let client: Client private let client: Client
private let blockSize = Const.messagesPageSize
private let messagesMax = Const.messagesMaxSize
private var messagesCancellable: AnyCancellable? private var messagesCancellable: AnyCancellable?
@ -25,28 +23,18 @@ final class ConversationStore: ObservableObject {
extension ConversationStore { extension ConversationStore {
func sendMessage(_ message: String) async { func sendMessage(_ message: String) async {
// prepare message var msg = Message.blank
let message = Message( msg.from = roster.bareJid
id: UUID().uuidString, msg.to = roster.contactBareJid
type: .chat, msg.body = message
date: Date(),
contentType: .text,
status: .pending,
from: roster.bareJid,
to: roster.contactBareJid,
body: message,
subject: nil,
thread: nil,
oobUrl: nil
)
// store as pending on db, and send // store as pending on db, and send
do { do {
try await message.save() try await msg.save()
try await client.sendMessage(message) try await client.sendMessage(msg)
try await message.setStatus(.sent) try await msg.setStatus(.sent)
} catch { } catch {
try? await message.setStatus(.error) try? await msg.setStatus(.error)
} }
} }
} }
@ -67,7 +55,10 @@ extension ConversationStore {
func sendCaptured(_ data: Data, _ type: GalleryMediaType) async { func sendCaptured(_ data: Data, _ type: GalleryMediaType) async {
// save locally and make message // save locally and make message
let messageId = UUID().uuidString var message = Message.blank
message.from = roster.bareJid
message.to = roster.contactBareJid
let localName: String let localName: String
let msgType: AttachmentType let msgType: AttachmentType
do { do {
@ -78,11 +69,11 @@ extension ConversationStore {
let msgType: AttachmentType let msgType: AttachmentType
switch type { switch type {
case .photo: case .photo:
localName = "\(messageId)_\(fileId).jpg" localName = "\(message.id)_\(fileId).jpg"
msgType = .image msgType = .image
case .video: case .video:
localName = "\(messageId)_\(fileId).mov" localName = "\(message.id)_\(fileId).mov"
msgType = .video msgType = .video
} }
@ -97,25 +88,13 @@ extension ConversationStore {
} }
// save message // save message
let message = Message( message.contentType = .attachment(
id: UUID().uuidString, Attachment(
type: .chat, type: msgType,
date: Date(), localName: localName,
contentType: .attachment( thumbnailName: nil,
Attachment( remotePath: nil
type: msgType, )
localName: localName,
thumbnailName: nil,
remotePath: nil
)
),
status: .pending,
from: roster.bareJid,
to: roster.contactBareJid,
body: nil,
subject: nil,
thread: nil,
oobUrl: nil
) )
do { do {
try await message.save() try await message.save()

View file

@ -2,15 +2,6 @@ import Foundation
import UIKit import UIKit
enum Const { enum Const {
// // Network
// #if DEBUG
// static let baseUrl = "staging.some.com/api"
// #else
// static let baseUrl = "prod.some.com/api"
// #endif
// static let requestTimeout = 15.0
// static let networkLogging = true
// App // App
static var appVersion: String { static var appVersion: String {
let info = Bundle.main.infoDictionary let info = Bundle.main.infoDictionary
@ -54,8 +45,4 @@ enum Const {
// Lenght in days for MAM request // Lenght in days for MAM request
static let mamRequestDaysLength = 30 static let mamRequestDaysLength = 30
// Limits for messages pagination
static let messagesPageSize = 20 // size for block requesting
static let messagesMaxSize = 100 // total messages in memory
} }

View file

@ -12,8 +12,8 @@ struct ConversationMessageContainer: View {
EmbededMapView(location: msgText.getLatLon) EmbededMapView(location: msgText.getLatLon)
} else if let msgText = message.body, msgText.isContact { } else if let msgText = message.body, msgText.isContact {
ContactView(message: message) ContactView(message: message)
// } else if message.attachmentType != nil { } else if case .attachment(let attachment) = message.contentType {
// AttachmentView(message: message) AttachmentView(message: message, attachment: attachment)
} else { } else {
Text(message.body ?? "...") Text(message.body ?? "...")
.font(.body2) .font(.body2)
@ -98,107 +98,108 @@ private struct ContactView: View {
} }
} }
// private struct AttachmentView: View { private struct AttachmentView: View {
// let message: Message let message: Message
// let attachment: Attachment
// var body: some View {
// if message.attachmentDownloadFailed || (message.attachmentLocalName != nil && message.sentError) { var body: some View {
// failed if message.status == .error {
// } else { failed
// switch message.attachmentType { } else {
// case .image: switch attachment.type {
// if let thumbnail = thumbnail() { case .image:
// thumbnail if let thumbnail = thumbnail() {
// .resizable() thumbnail
// .aspectRatio(contentMode: .fit) .resizable()
// .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize) .aspectRatio(contentMode: .fit)
// } else { .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize)
// placeholder } else {
// } placeholder
// }
// case .movie:
// if let file = message.attachmentLocalPath { case .video:
// VideoPlayerView(url: file) if let file = attachment.localPath {
// .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize) VideoPlayerView(url: file)
// } else { .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize)
// placeholder } else {
// } placeholder
// }
// case .file:
// if let file = message.attachmentLocalPath { case .file:
// DocumentPreview(url: file) if let file = attachment.localPath {
// .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize) DocumentPreview(url: file)
// } else { .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize)
// placeholder } else {
// } placeholder
// }
// default:
// placeholder default:
// } placeholder
// } }
// } }
// }
// @ViewBuilder private var placeholder: some View {
// Rectangle() @ViewBuilder private var placeholder: some View {
// .foregroundColor(.Material.Background.dark) Rectangle()
// .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize) .foregroundColor(.Material.Background.dark)
// .overlay { .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize)
// ZStack { .overlay {
// ProgressView() ZStack {
// .scaleEffect(1.5) ProgressView()
// .progressViewStyle(CircularProgressViewStyle(tint: .Material.Elements.active)) .scaleEffect(1.5)
// let imageName = progressImageName(message.attachmentType ?? .file) .progressViewStyle(CircularProgressViewStyle(tint: .Material.Elements.active))
// Image(systemName: imageName) let imageName = progressImageName(attachment.type ?? .file)
// .font(.body1) Image(systemName: imageName)
// .foregroundColor(.Material.Elements.active) .font(.body1)
// } .foregroundColor(.Material.Elements.active)
// } }
// } }
// }
// @ViewBuilder private var failed: some View {
// Rectangle() @ViewBuilder private var failed: some View {
// .foregroundColor(.Material.Background.dark) Rectangle()
// .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize) .foregroundColor(.Material.Background.dark)
// .overlay { .frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize)
// ZStack { .overlay {
// VStack { ZStack {
// Text(L10n.Attachment.Downloading.retry) VStack {
// .font(.body3) Text(L10n.Attachment.Downloading.retry)
// .foregroundColor(.Rainbow.red500) .font(.body3)
// Image(systemName: "exclamationmark.arrow.triangle.2.circlepath") .foregroundColor(.Rainbow.red500)
// .font(.body1) Image(systemName: "exclamationmark.arrow.triangle.2.circlepath")
// .foregroundColor(.Rainbow.red500) .font(.body1)
// } .foregroundColor(.Rainbow.red500)
// } }
// } }
// .onTapGesture { }
// if let url = message.attachmentRemotePath { .onTapGesture {
// store.dispatch(.fileAction(.downloadAttachmentFile(messageId: message.id, attachmentRemotePath: url))) // if let url = message.attachmentRemotePath {
// } else if message.attachmentLocalName != nil && message.sentError { // store.dispatch(.fileAction(.downloadAttachmentFile(messageId: message.id, attachmentRemotePath: url)))
// store.dispatch(.sharingAction(.retrySharing(messageId: message.id))) // } else if message.attachmentLocalName != nil && message.sentError {
// } // store.dispatch(.sharingAction(.retrySharing(messageId: message.id)))
// } // }
// } }
// }
// private func progressImageName(_ type: MessageAttachmentType) -> String {
// switch type { private func progressImageName(_ type: AttachmentType) -> String {
// case .image: switch type {
// return "photo" case .image:
// case .audio: return "photo"
// return "music.note" case .audio:
// case .movie: return "music.note"
// return "film" case .video:
// case .file: return "film"
// return "doc" case .file:
// } return "doc"
// } }
// }
// private func thumbnail() -> Image? {
// guard let thumbnailPath = message.attachmentThumbnailPath else { return nil } private func thumbnail() -> Image? {
// guard let uiImage = UIImage(contentsOfFile: thumbnailPath.path()) else { return nil } guard let thumbnailPath = attachment.thumbnailPath else { return nil }
// return Image(uiImage: uiImage) guard let uiImage = UIImage(contentsOfFile: thumbnailPath.path()) else { return nil }
// } return Image(uiImage: uiImage)
// } }
}
// TODO: Make video player better! // TODO: Make video player better!
private struct VideoPlayerView: UIViewControllerRepresentable { private struct VideoPlayerView: UIViewControllerRepresentable {

View file

@ -50,7 +50,7 @@ struct ConversationMessageRow: View {
} }
if value.translation.width <= targetWidth { if value.translation.width <= targetWidth {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) {
// store.dispatch(.conversationAction(.setReplyText(message.body ?? ""))) conversation.replyText = message.body ?? ""
} }
} }
} }