diff --git a/ConversationsClassic/AppData/Client/Client+MartinMAM.swift b/ConversationsClassic/AppData/Client/Client+MartinMAM.swift index b399a18..9eda58a 100644 --- a/ConversationsClassic/AppData/Client/Client+MartinMAM.swift +++ b/ConversationsClassic/AppData/Client/Client+MartinMAM.swift @@ -36,7 +36,7 @@ private actor ArchiveMessageProcessor { func append(_ msg: ArchMsg) async { accumulator.append(msg) - if accumulator.count >= Const.mamRequestLimit { + if accumulator.count >= Const.mamRequestPageSize { await process() } } diff --git a/ConversationsClassic/AppData/Store/AttachmentsStore.swift b/ConversationsClassic/AppData/Store/AttachmentsStore.swift index c991a8d..3004821 100644 --- a/ConversationsClassic/AppData/Store/AttachmentsStore.swift +++ b/ConversationsClassic/AppData/Store/AttachmentsStore.swift @@ -218,19 +218,19 @@ private extension AttachmentsStore { if attachment.localPath != nil, attachment.remotePath == nil { // Uploading self?.processing.insert(message.id) - Task(priority: .background) { + Task { await self?.uploadAttachment(message) } } else if attachment.localPath == nil, attachment.remotePath != nil { // Downloading self?.processing.insert(message.id) - Task(priority: .background) { + Task { await self?.downloadAttachment(message) } } else if attachment.localPath != nil, attachment.remotePath != nil, attachment.thumbnailName == nil, attachment.type == .image { // Generate thumbnail self?.processing.insert(message.id) - Task(priority: .background) { + Task { await self?.generateThumbnail(message) } } diff --git a/ConversationsClassic/AppData/Store/MessagesStore.swift b/ConversationsClassic/AppData/Store/MessagesStore.swift index 586ff3f..37635a2 100644 --- a/ConversationsClassic/AppData/Store/MessagesStore.swift +++ b/ConversationsClassic/AppData/Store/MessagesStore.swift @@ -74,17 +74,17 @@ private extension MessagesStore { } } -// MARK: - Fetch archived messages +// MARK: - Archived messages extension MessagesStore { - func fetchForward() { - Task { - await archiver.fetchForward(roster, client) - } - } - - func fetchBackward() { - Task { - await archiver.fetchBackward(roster, client) + func scrolledMessage(_ messageId: String) { + if messageId == messages.last?.id { + Task { + await archiver.fetchBackward(roster, client) + } + } else if messageId == messages.first?.id { + Task { + await archiver.fetchForward(roster, client) + } } } } @@ -93,142 +93,57 @@ private actor ArchiveMessageFetcher { private var initFetchStarted = false private var forwardRsm: RSM.Query? private var backwardRsm: RSM.Query? + private var fetchInProgress = false func initialFetch(_ messages: [Message], _ roster: Roster, _ client: Client) async { if initFetchStarted { return } initFetchStarted = true + fetchInProgress = true do { if let firstExistId = messages.first?.id { - let result = try await client.fetchArchiveMessages(for: roster, query: .init(before: firstExistId, max: Const.mamRequestLimit)) - result.complete ? forwardRsm = nil : (forwardRsm = .init(after: result.rsm?.last, max: Const.mamRequestLimit)) - result.complete ? backwardRsm = nil : (backwardRsm = .init(before: result.rsm?.first, max: Const.mamRequestLimit)) + let result = try await client.fetchArchiveMessages(for: roster, query: .init(before: firstExistId, max: Const.mamRequestPageSize)) + result.complete ? forwardRsm = nil : (forwardRsm = .init(after: result.rsm?.last, max: Const.mamRequestPageSize)) + result.complete ? backwardRsm = nil : (backwardRsm = .init(before: result.rsm?.first, max: Const.mamRequestPageSize)) } else { - let result = try await client.fetchArchiveMessages(for: roster, query: .init(lastItems: Const.mamRequestLimit)) - result.complete ? backwardRsm = nil : (backwardRsm = .init(before: result.rsm?.first, max: Const.mamRequestLimit)) + let result = try await client.fetchArchiveMessages(for: roster, query: .init(lastItems: Const.mamRequestPageSize)) + result.complete ? backwardRsm = nil : (backwardRsm = .init(before: result.rsm?.first, max: Const.mamRequestPageSize)) } } catch { logIt(.error, "Error requesting archived messages: \(error)") initFetchStarted = false } + + fetchInProgress = false } - func fetchForward(_ roster: Roster, _ client: Client) { + func fetchForward(_ roster: Roster, _ client: Client) async { + while !initFetchStarted { + await Task.yield() + } guard let rsm = forwardRsm else { return } + if fetchInProgress { return } + + fetchInProgress = true Task { let result = try await client.fetchArchiveMessages(for: roster, query: rsm) - result.complete ? (forwardRsm = nil) : (forwardRsm = .init(after: result.rsm?.last, max: Const.mamRequestLimit)) + result.complete ? (forwardRsm = nil) : (forwardRsm = .init(after: result.rsm?.last, max: Const.mamRequestPageSize)) + fetchInProgress = false } } - func fetchBackward(_ roster: Roster, _ client: Client) { + func fetchBackward(_ roster: Roster, _ client: Client) async { + while !initFetchStarted { + await Task.yield() + } guard let rsm = backwardRsm else { return } + if fetchInProgress { return } + + fetchInProgress = true Task { let result = try await client.fetchArchiveMessages(for: roster, query: rsm) - result.complete ? (backwardRsm = nil) : (backwardRsm = .init(before: result.rsm?.first, max: Const.mamRequestLimit)) + result.complete ? (backwardRsm = nil) : (backwardRsm = .init(before: result.rsm?.first, max: Const.mamRequestPageSize)) + fetchInProgress = false } } - - // func fetchBackward(_ roster: Roster, _ client: Client) { - // guard let rsm = backwardRsm else { return } - // Task { - // let result = try await client.fetchArchiveMessages(for: roster, query: rsm) - // result.complete ? (backwardRsm = nil) : (backwardRsm = .init(before: result.rsm?.first, max: Const.mamRequestLimit)) - // } - // } } - -// MARK: - Archived messages -// extension MessagesStore { -// func requestEarliestArchivedMessages() { -// guard let beforeId = messages.first?.id else { return } -// Task { -// await archiveMessageFetcher.fetchAfterMessages(roster, client, afterId: beforeId) -// // await archiveMessageFetcher.fetchBeforeMessages(roster, client, beforeId: beforeId) -// } -// } -// -// func requestLatestArchivedMessages() { -// guard let afterId = messages.last?.id else { return } -// Task { -// await archiveMessageFetcher.fetchBeforeMessages(roster, client, beforeId: afterId) -// // await archiveMessageFetcher.fetchAfterMessages(roster, client, afterId: afterId) -// } -// } -// -// private func requestLastArchivedMessages() { -// Task { -// await archiveMessageFetcher.fetchLastMessages(roster, client) -// } -// } -// } - -// private actor ArchiveMessageFetcher { -// private var afterAvailable = true -// private var beforeAvailable = true -// private var isFetching = false -// private var fetchingIsPossinle = true -// -// func fetchLastMessages(_ roster: Roster, _ client: Client) async { -// if !fetchingIsPossinle { return } -// while isFetching { -// await Task.yield() -// } -// isFetching = true -// -// let query: RSM.Query = .init(lastItems: Const.mamRequestLimit) -// do { -// _ = try await client.fetchArchiveMessages(for: roster, query: query) -// } catch AppError.featureNotSupported { -// fetchingIsPossinle = false -// } catch { -// logIt(.error, "Error requesting archived messages: \(error)") -// } -// -// isFetching = false -// } -// -// func fetchBeforeMessages(_ roster: Roster, _ client: Client, beforeId: String) async { -// if !fetchingIsPossinle || !beforeAvailable { return } -// while isFetching { -// await Task.yield() -// } -// isFetching = true -// -// let query: RSM.Query = .init(before: beforeId, max: Const.mamRequestLimit) -// do { -// let result = try await client.fetchArchiveMessages(for: roster, query: query) -// if result.complete { -// beforeAvailable = false -// } -// } catch AppError.featureNotSupported { -// fetchingIsPossinle = false -// } catch { -// logIt(.error, "Error requesting archived messages: \(error)") -// } -// -// isFetching = false -// } -// -// func fetchAfterMessages(_ roster: Roster, _ client: Client, afterId: String) async { -// if !fetchingIsPossinle || !afterAvailable { return } -// while isFetching { -// await Task.yield() -// } -// isFetching = true -// -// let query: RSM.Query = .init(after: afterId, max: Const.mamRequestLimit) -// do { -// let result = try await client.fetchArchiveMessages(for: roster, query: query) -// if result.complete { -// afterAvailable = false -// } -// } catch AppError.featureNotSupported { -// fetchingIsPossinle = false -// } catch { -// logIt(.error, "Error requesting archived messages: \(error)") -// } -// -// isFetching = false -// } -// } diff --git a/ConversationsClassic/Helpers/Const.swift b/ConversationsClassic/Helpers/Const.swift index 6bb40c2..6659ade 100644 --- a/ConversationsClassic/Helpers/Const.swift +++ b/ConversationsClassic/Helpers/Const.swift @@ -44,5 +44,5 @@ enum Const { static let attachmentPreviewSize = UIScreen.main.bounds.width * 0.5 // MAM request page size - static let mamRequestLimit = 10 + static let mamRequestPageSize = 50 } diff --git a/ConversationsClassic/View/Entering/LoginScreen.swift b/ConversationsClassic/View/Entering/LoginScreen.swift index 2cf8c4f..596bd1c 100644 --- a/ConversationsClassic/View/Entering/LoginScreen.swift +++ b/ConversationsClassic/View/Entering/LoginScreen.swift @@ -75,7 +75,10 @@ struct LoginScreen: View { ) Button { - Task { + router.showModal { + LoadingScreen() + } + Task(priority: .background) { await tryLogin() } } label: { @@ -102,10 +105,6 @@ struct LoginScreen: View { } private func tryLogin() async { - router.showModal { - LoadingScreen() - } - defer { router.dismissModal() } diff --git a/ConversationsClassic/View/Main/Conversation/ConversationScreen.swift b/ConversationsClassic/View/Main/Conversation/ConversationScreen.swift index a46d116..6c5a021 100644 --- a/ConversationsClassic/View/Main/Conversation/ConversationScreen.swift +++ b/ConversationsClassic/View/Main/Conversation/ConversationScreen.swift @@ -45,9 +45,7 @@ struct ConversationScreen: View { firstIsVisible = true autoScroll = true } - if message.id == messages.last?.id { - messagesStore.fetchBackward() - } + messagesStore.scrolledMessage(message.id) } .onDisappear { if message.id == messages.first?.id {