Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev/fix/messaging fixes #414

Merged
merged 4 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,8 @@
C6AE670D2AA1CA260061D87D /* Debug-Tools-Dev.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302EAF3126332DC200CAFE8B /* Debug-Tools-Dev.swift */; };
C6AF12402A67C72200F89D2E /* MessagingServiceDataRefreshManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6AF123F2A67C72200F89D2E /* MessagingServiceDataRefreshManager.swift */; };
C6B0A8CD2A4D7DDA00284022 /* MessagingImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B0A8CC2A4D7DDA00284022 /* MessagingImageLoader.swift */; };
C6B2E1FF2B96C51B00CEA1F9 /* MessagingChatMessageUnsupportedTypeDisplayInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B2E1FE2B96C51B00CEA1F9 /* MessagingChatMessageUnsupportedTypeDisplayInfo.swift */; };
C6B2E2002B96C51B00CEA1F9 /* MessagingChatMessageUnsupportedTypeDisplayInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B2E1FE2B96C51B00CEA1F9 /* MessagingChatMessageUnsupportedTypeDisplayInfo.swift */; };
C6B366CD2A1BA1A700DE512B /* NavBarItemsTransitionPerformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B366CC2A1BA1A700DE512B /* NavBarItemsTransitionPerformer.swift */; };
C6B366D22A1BA35A00DE512B /* NavBarBackButtonTransitionPerformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B366D12A1BA35A00DE512B /* NavBarBackButtonTransitionPerformer.swift */; };
C6B366D72A1C715000DE512B /* PushRESTAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B366D62A1C715000DE512B /* PushRESTAPIService.swift */; };
Expand Down Expand Up @@ -3285,6 +3287,7 @@
C6AD180E28D319BF0008A479 /* CollectionViewShowHideCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CollectionViewShowHideCell.xib; sourceTree = "<group>"; };
C6AF123F2A67C72200F89D2E /* MessagingServiceDataRefreshManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingServiceDataRefreshManager.swift; sourceTree = "<group>"; };
C6B0A8CC2A4D7DDA00284022 /* MessagingImageLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingImageLoader.swift; sourceTree = "<group>"; };
C6B2E1FE2B96C51B00CEA1F9 /* MessagingChatMessageUnsupportedTypeDisplayInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingChatMessageUnsupportedTypeDisplayInfo.swift; sourceTree = "<group>"; };
C6B366CC2A1BA1A700DE512B /* NavBarItemsTransitionPerformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavBarItemsTransitionPerformer.swift; sourceTree = "<group>"; };
C6B366D12A1BA35A00DE512B /* NavBarBackButtonTransitionPerformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavBarBackButtonTransitionPerformer.swift; sourceTree = "<group>"; };
C6B366D62A1C715000DE512B /* PushRESTAPIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushRESTAPIService.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5454,6 +5457,7 @@
C603D7992A56B11800CEC696 /* MessagingChatMessageUnknownTypeDisplayInfo.swift */,
C6157AFD2A7108B400081574 /* MessagingChatMessageRemoteContentTypeDisplayInfo.swift */,
C623967B2A288A8A00363F60 /* MessagingChatMessageDisplayType.swift */,
C6B2E1FE2B96C51B00CEA1F9 /* MessagingChatMessageUnsupportedTypeDisplayInfo.swift */,
C6FAED882B8C717100CC1844 /* MessagingChatMessageReplyTypeDisplayInfo.swift */,
C631DFA62B7B530800040221 /* MessagingChatMessageReactionTypeDisplayInfo.swift */,
C62396802A288A9400363F60 /* MessagingChatMessageDisplayInfo.swift */,
Expand Down Expand Up @@ -9005,6 +9009,7 @@
C663A4D62B7D09490099BCE8 /* UpdateToWalletGreetingsView.swift in Sources */,
C630BC7D2B18448A00E29318 /* AppContextEnvironmentKeys.swift in Sources */,
C6DDF2592B147F5E006D1F0B /* UDTitleText.swift in Sources */,
C6B2E1FF2B96C51B00CEA1F9 /* MessagingChatMessageUnsupportedTypeDisplayInfo.swift in Sources */,
C6D8FF362B8318310094A21E /* ChatListView.swift in Sources */,
C6109E9328E6AA7A0027D5D8 /* AppContextType.swift in Sources */,
295506F02954D14400EDA42D /* WCConnectedAppsStorageV2.swift in Sources */,
Expand Down Expand Up @@ -9788,6 +9793,7 @@
C6D645F62B1DBF0B00D724AC /* UDConfigurableButton.swift in Sources */,
C6D646342B1DC43D00D724AC /* TextTertiaryButton.swift in Sources */,
C61808322B19ADF10032E543 /* PreviewCoreAppCoordinator.swift in Sources */,
C6B2E2002B96C51B00CEA1F9 /* MessagingChatMessageUnsupportedTypeDisplayInfo.swift in Sources */,
C6D645AA2B1DBB3800D724AC /* UICollectionViewLayout.swift in Sources */,
C6C8F9372B2183D100A9834D /* DomainImageDetailsViewPresenter.swift in Sources */,
C6D6470D2B1ED7D000D724AC /* MessagingChatMessageDisplayInfo.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct ChatNavTitleView: View {
Text(title)
.foregroundStyle(Color.foregroundDefault)
.font(.currentFont(size: 16, weight: .semibold))
.lineLimit(1)
}
.onChange(of: titleType, perform: { newValue in
loadIconNonBlocking()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ final class ChatViewModel: ObservableObject, ViewAnalyticsLogger {
private let messagingService: MessagingServiceProtocol
private let featureFlagsService: UDFeatureFlagsServiceProtocol
private(set) var conversationState: MessagingChatConversationState
private let fetchLimit: Int = 30
@Published private(set) var isLoadingMessages = false
@Published private(set) var blockStatus: MessagingPrivateChatBlockingStatus = .unblocked
@Published private(set) var isChannelEncrypted: Bool = true
Expand Down Expand Up @@ -424,6 +423,7 @@ private extension ChatViewModel {
func loadAndShowData() {
Task {
isLoading = true
let fetchLimit = ChatConstants.fetchLimit
do {
switch conversationState {
case .existingChat(let chat):
Expand Down Expand Up @@ -455,19 +455,24 @@ private extension ChatViewModel {
}
}

func loadMoreInitialMessagesIfNeeded(in chat: MessagingChatDisplayInfo) async throws {
func loadMoreInitialMessagesIfNeeded(in chat: MessagingChatDisplayInfo, startTime: Date = Date()) async throws {
guard isNeedToLoadMoreInitialMessages(),
let earliestMessage = getEarliestMessageInCache() else { return }
let earliestMessage = getEarliestMessageInCache(),
!shouldBreakLoadMoreLoopDueToTimeout(startTime: startTime) else { return }

let messages = try await createTaskAndLoadMoreMessagesIn(chat: chat,
beforeMessage: earliestMessage)
await addMessages(messages, scrollToBottom: true)
try await loadMoreInitialMessagesIfNeeded(in: chat) // Call recursively until sufficient number of visible messages is loaded
try await loadMoreInitialMessagesIfNeeded(in: chat, startTime: startTime) // Call recursively until sufficient number of visible messages is loaded
}

func shouldBreakLoadMoreLoopDueToTimeout(startTime: Date) -> Bool {
Date().timeIntervalSince(startTime) > ChatConstants.loadMoreMessagesLimitSec
}

func isNeedToLoadMoreInitialMessages() -> Bool {
// Number of visible messages (not including reactions, system messages, etc.) should be at least 20
messages.count < 20 &&
messages.count < ChatConstants.minRequiredNumberOfVisibleMessagesOnLaunch &&
!didReachFirstMessageInChat()
}

Expand Down Expand Up @@ -503,7 +508,7 @@ private extension ChatViewModel {
try await messagingService.getMessagesForChat(chat,
before: beforeMessage,
cachedOnly: false,
limit: fetchLimit)
limit: ChatConstants.fetchLimit)
}
self.loadMoreMessagesTask = task
let result = try await task.value
Expand All @@ -517,7 +522,7 @@ private extension ChatViewModel {
let cachedMessages = try await messagingService.getMessagesForChat(chat,
before: nil,
cachedOnly: true,
limit: fetchLimit)
limit: ChatConstants.fetchLimit)
await addMessages(cachedMessages, scrollToBottom: false)
}
}
Expand All @@ -530,7 +535,8 @@ private extension ChatViewModel {

let messages = serialQueue.sync {
messages.filter { message in
if case .reaction(let info) = message.type {
switch message.type {
case .reaction(let info):
let counter = MessageReactionDescription(content: info.content,
messageId: message.id,
referenceMessageId: info.messageId,
Expand All @@ -541,7 +547,9 @@ private extension ChatViewModel {
try? messagingService.markMessage(message, isRead: true, wallet: chat.thisUserDetails.wallet)
}
return false
} else {
case .unsupported:
return false
default:
return true
}
}
Expand Down Expand Up @@ -1159,6 +1167,15 @@ extension ChatViewModel: UDFeatureFlagsListener {
}
}

// MARK: - Open methods
extension ChatViewModel {
struct ChatConstants {
static let fetchLimit = 30
static let loadMoreMessagesLimitSec: TimeInterval = 30
static let minRequiredNumberOfVisibleMessagesOnLaunch = 20
}
}

#Preview {
NavigationViewWithCustomTitle(content: {
ChatView(viewModel: .init(profile: .init(id: "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ private extension MessageRowView {
referenceMessageId: info.messageId)
case .reaction(let info):
Text(info.content)
case .unsupported:
Text(String.Constants.messageNotSupported.localized())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct MessagingChatMessageDisplayInfo: Hashable {
time = Date()
}
switch type {
case .text, .unknown, .remoteContent, .reaction, .reply:
case .text, .unknown, .remoteContent, .reaction, .reply, .unsupported:
return
case .imageData(var info):
if info.image == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ indirect enum MessagingChatMessageDisplayType: Hashable {
case remoteContent(MessagingChatMessageRemoteContentTypeDisplayInfo)
case reaction(MessagingChatMessageReactionTypeDisplayInfo)
case reply(MessagingChatMessageReplyTypeDisplayInfo)
case unsupported(MessagingChatMessageUnsupportedTypeDisplayInfo)

var analyticName: String {
switch self {
Expand All @@ -30,6 +31,8 @@ indirect enum MessagingChatMessageDisplayType: Hashable {
return "Reaction"
case .reply:
return "Reply"
case .unsupported:
return "Unsupported"
}
}
}
Expand All @@ -42,7 +45,7 @@ extension MessagingChatMessageDisplayType {
return description.text
case .imageBase64, .imageData:
return String.Constants.photo.localized()
case .unknown:
case .unknown, .unsupported:
return String.Constants.messageNotSupported.localized()
case .remoteContent:
return String.Constants.messagingRemoteContent.localized()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// MessagingChatMessageUnsupportedTypeDisplayInfo.swift
// domains-manager-ios
//
// Created by Oleg Kuplin on 05.03.2024.
//

import Foundation

struct MessagingChatMessageUnsupportedTypeDisplayInfo: Hashable {
let data: Data
}
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ extension MessagingService: MessagingServiceProtocol {
let profile = try await getUserProfileWith(wallet: chat.thisUserDetails.wallet, serviceIdentifier: serviceIdentifier)

switch chatMessage.displayInfo.type {
case .text, .imageData, .imageBase64, .unknown, .reaction:
case .text, .imageData, .imageBase64, .unknown, .reaction, .unsupported:
return message
case .remoteContent(let info):
let loadedType = try await apiService.loadRemoteContentFor(chatMessage,
Expand All @@ -340,7 +340,7 @@ extension MessagingService: MessagingServiceProtocol {
return chatMessage.displayInfo
case .reply(var info):
switch info.contentType {
case .text, .imageData, .imageBase64, .unknown, .reaction, .reply:
case .text, .imageData, .imageBase64, .unknown, .reaction, .reply, .unsupported:
return message
case .remoteContent(let remoteInfo):
let loadedType = try await apiService.loadRemoteContentFor(chatMessage,
Expand Down
Loading