mv-experiment #1

Merged
fmodf merged 88 commits from mv-experiment into develop 2024-09-03 15:13:59 +00:00
5 changed files with 147 additions and 164 deletions
Showing only changes of commit 6a5555a603 - Show all commits

View file

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

View file

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

View file

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