diff --git a/src/app/core/signals/remote_signals/community.nim b/src/app/core/signals/remote_signals/community.nim index d57fde2e89..f85f250405 100644 --- a/src/app/core/signals/remote_signals/community.nim +++ b/src/app/core/signals/remote_signals/community.nim @@ -28,6 +28,15 @@ type DiscordCommunityImportProgressSignal* = ref object of Signal communityId*: string communityImages*: Images communityName*: string + tasks*: seq[DiscordImportTaskProgress] + progress*: float + errorsCount*: int + warningsCount*: int + stopped*: bool + totalChunksCount*: int + currentChunk*: int + +type DiscordChannelImportProgressSignal* = ref object of Signal channelId*: string channelName*: string tasks*: seq[DiscordImportTaskProgress] @@ -38,9 +47,19 @@ type DiscordCommunityImportProgressSignal* = ref object of Signal totalChunksCount*: int currentChunk*: int +type DiscordCommunityImportCancelledSignal* = ref object of Signal + communityId*: string + type DiscordCommunityImportFinishedSignal* = ref object of Signal communityId*: string +type DiscordChannelImportCancelledSignal* = ref object of Signal + channelId*: string + +type DiscordChannelImportFinishedSignal* = ref object of Signal + communityId*: string + channelId*: string + proc fromEvent*(T: type CommunitySignal, event: JsonNode): CommunitySignal = result = CommunitySignal() result.signalType = SignalType.CommunityFound @@ -91,8 +110,6 @@ proc fromEvent*(T: type DiscordCommunityImportProgressSignal, event: JsonNode): result.communityId = importProgressObj{"communityId"}.getStr() result.communityName = importProgressObj{"communityName"}.getStr() - result.channelId = importProgressObj{"channelId"}.getStr() - result.channelName = importProgressObj{"channelName"}.getStr() result.progress = importProgressObj{"progress"}.getFloat() result.errorsCount = importProgressObj{"errorsCount"}.getInt() result.warningsCount = importProgressObj{"warningsCount"}.getInt() @@ -107,11 +124,48 @@ proc fromEvent*(T: type DiscordCommunityImportProgressSignal, event: JsonNode): for task in importProgressObj["tasks"]: result.tasks.add(task.toDiscordImportTaskProgress()) +proc fromEvent*(T: type DiscordChannelImportProgressSignal, event: JsonNode): DiscordChannelImportProgressSignal = + result = DiscordChannelImportProgressSignal() + result.signalType = SignalType.DiscordChannelImportProgress + result.tasks = @[] + + if event["event"]["importProgress"].kind == JObject: + let importProgressObj = event["event"]["importProgress"] + + result.channelId = importProgressObj{"channelId"}.getStr() + result.channelName = importProgressObj{"channelName"}.getStr() + result.progress = importProgressObj{"progress"}.getFloat() + result.errorsCount = importProgressObj{"errorsCount"}.getInt() + result.warningsCount = importProgressObj{"warningsCount"}.getInt() + result.stopped = importProgressObj{"stopped"}.getBool() + result.totalChunksCount = importProgressObj{"totalChunksCount"}.getInt() + result.currentChunk = importProgressObj{"currentChunk"}.getInt() + + if importProgressObj["tasks"].kind == JArray: + for task in importProgressObj["tasks"]: + result.tasks.add(task.toDiscordImportTaskProgress()) + proc fromEvent*(T: type DiscordCommunityImportFinishedSignal, event: JsonNode): DiscordCommunityImportFinishedSignal = result = DiscordCommunityImportFinishedSignal() result.signalType = SignalType.DiscordCommunityImportFinished result.communityId = event["event"]{"communityId"}.getStr() +proc fromEvent*(T: type DiscordCommunityImportCancelledSignal, event: JsonNode): DiscordCommunityImportCancelledSignal = + result = DiscordCommunityImportCancelledSignal() + result.signalType = SignalType.DiscordCommunityImportCancelled + result.communityId = event["event"]{"communityId"}.getStr() + +proc fromEvent*(T: type DiscordChannelImportFinishedSignal, event: JsonNode): DiscordChannelImportFinishedSignal = + result = DiscordChannelImportFinishedSignal() + result.signalType = SignalType.DiscordChannelImportFinished + result.communityId = event["event"]{"communityId"}.getStr() + result.channelId = event["event"]{"channelId"}.getStr() + +proc fromEvent*(T: type DiscordChannelImportCancelledSignal, event: JsonNode): DiscordChannelImportCancelledSignal = + result = DiscordChannelImportCancelledSignal() + result.signalType = SignalType.DiscordChannelImportCancelled + result.channelId = event["event"]{"channelId"}.getStr() + proc createFromEvent*(T: type HistoryArchivesSignal, event: JsonNode): HistoryArchivesSignal = result = HistoryArchivesSignal() result.communityId = event["event"]{"communityId"}.getStr() diff --git a/src/app/core/signals/remote_signals/signal_type.nim b/src/app/core/signals/remote_signals/signal_type.nim index 51755c8cb0..b56f490144 100644 --- a/src/app/core/signals/remote_signals/signal_type.nim +++ b/src/app/core/signals/remote_signals/signal_type.nim @@ -47,6 +47,10 @@ type SignalType* {.pure.} = enum StatusUpdatesTimedout = "status.updates.timedout" DiscordCommunityImportFinished = "community.discordCommunityImportFinished" DiscordCommunityImportProgress = "community.discordCommunityImportProgress" + DiscordCommunityImportCancelled = "community.discordCommunityImportCancelled" + DiscordChannelImportFinished = "community.discordChannelImportFinished" + DiscordChannelImportProgress = "community.discordChannelImportProgress" + DiscordChannelImportCancelled = "community.discordChannelImportCancelled" WakuFetchingBackupProgress = "waku.fetching.backup.progress" WakuBackedUpProfile = "waku.backedup.profile" WakuBackedUpSettings = "waku.backedup.settings" diff --git a/src/app/core/signals/signals_manager.nim b/src/app/core/signals/signals_manager.nim index bc85b9c1d2..ab41ed1ac3 100644 --- a/src/app/core/signals/signals_manager.nim +++ b/src/app/core/signals/signals_manager.nim @@ -106,6 +106,10 @@ QtObject: of SignalType.StatusUpdatesTimedout: StatusUpdatesTimedoutSignal.fromEvent(jsonSignal) of SignalType.DiscordCommunityImportFinished: DiscordCommunityImportFinishedSignal.fromEvent(jsonSignal) of SignalType.DiscordCommunityImportProgress: DiscordCommunityImportProgressSignal.fromEvent(jsonSignal) + of SignalType.DiscordCommunityImportCancelled: DiscordCommunityImportCancelledSignal.fromEvent(jsonSignal) + of SignalType.DiscordChannelImportFinished: DiscordChannelImportFinishedSignal.fromEvent(jsonSignal) + of SignalType.DiscordChannelImportProgress: DiscordChannelImportProgressSignal.fromEvent(jsonSignal) + of SignalType.DiscordChannelImportCancelled: DiscordChannelImportCancelledSignal.fromEvent(jsonSignal) # sync from waku part of SignalType.WakuFetchingBackupProgress: WakuFetchingBackupProgressSignal.fromEvent(jsonSignal) of SignalType.WakuBackedUpProfile: WakuBackedUpProfileSignal.fromEvent(jsonSignal) diff --git a/src/app/modules/main/communities/controller.nim b/src/app/modules/main/communities/controller.nim index e85d95f41a..8fe4b8ff03 100644 --- a/src/app/modules/main/communities/controller.nim +++ b/src/app/modules/main/communities/controller.nim @@ -134,7 +134,19 @@ proc init*(self: Controller) = self.events.on(SIGNAL_DISCORD_COMMUNITY_IMPORT_PROGRESS) do(e:Args): let args = DiscordImportProgressArgs(e) - self.delegate.discordImportProgressUpdated(args.communityId, args.communityName, args.channelId, args.channelName, args.communityImage, args.tasks, args.progress, args.errorsCount, args.warningsCount, args.stopped, args.totalChunksCount, args.currentChunk) + self.delegate.discordImportProgressUpdated(args.communityId, args.communityName, args.communityImage, args.tasks, args.progress, args.errorsCount, args.warningsCount, args.stopped, args.totalChunksCount, args.currentChunk) + + self.events.on(SIGNAL_DISCORD_CHANNEL_IMPORT_PROGRESS) do(e:Args): + let args = DiscordImportChannelProgressArgs(e) + self.delegate.discordImportChannelProgressUpdated(args.channelId, args.channelName, args.tasks, args.progress, args.errorsCount, args.warningsCount, args.stopped, args.totalChunksCount, args.currentChunk) + + self.events.on(SIGNAL_DISCORD_CHANNEL_IMPORT_FINISHED) do(e:Args): + let args = CommunityChatIdArgs(e) + self.delegate.discordImportChannelFinished(args.chatId) + + self.events.on(SIGNAL_DISCORD_CHANNEL_IMPORT_CANCELED) do(e:Args): + let args = ChannelIdArgs(e) + self.delegate.discordImportChannelCanceled(args.channelId) self.events.on(SIGNAL_COMMUNITY_HISTORY_ARCHIVES_DOWNLOAD_STARTED) do(e:Args): let args = CommunityIdArgs(e) diff --git a/src/app/modules/main/communities/io_interface.nim b/src/app/modules/main/communities/io_interface.nim index bff7e39764..f5963a583f 100644 --- a/src/app/modules/main/communities/io_interface.nim +++ b/src/app/modules/main/communities/io_interface.nim @@ -143,7 +143,27 @@ method requestExtractDiscordChannelsAndCategories*(self: AccessInterface, filesT method discordCategoriesAndChannelsExtracted*(self: AccessInterface, categories: seq[DiscordCategoryDto], channels: seq[DiscordChannelDto], oldestMessageTimestamp: int, errors: Table[string, DiscordImportError], errorsCount: int) {.base.} = raise newException(ValueError, "No implementation available") -method discordImportProgressUpdated*(self: AccessInterface, communityId: string, communityName: string, channelId: string, channelName: string, communityImage: string, tasks: seq[DiscordImportTaskProgress], progress: float, errorsCount: int, warningsCount: int, stopped: bool, totalChunksCount: int, currentChunk: int) {.base.} = +method discordImportProgressUpdated*(self: AccessInterface, communityId: string, communityName: string, communityImage: string, tasks: seq[DiscordImportTaskProgress], progress: float, errorsCount: int, warningsCount: int, stopped: bool, totalChunksCount: int, currentChunk: int) {.base.} = + raise newException(ValueError, "No implementation available") + +method discordImportChannelProgressUpdated*( + self: AccessInterface, + channelId: string, + channelName: string, + tasks: seq[DiscordImportTaskProgress], + progress: float, + errorsCount: int, + warningsCount: int, + stopped: bool, + totalChunksCount: int, + currentChunk: int + ) {.base.} = + raise newException(ValueError, "No implementation available") + +method discordImportChannelFinished*(self: AccessInterface, channelId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method discordImportChannelCanceled*(self: AccessInterface, channelId: string) {.base.} = raise newException(ValueError, "No implementation available") method requestCancelDiscordCommunityImport*(self: AccessInterface, id: string) {.base.} = diff --git a/src/app/modules/main/communities/module.nim b/src/app/modules/main/communities/module.nim index a5d4576190..c74e7fd4b7 100644 --- a/src/app/modules/main/communities/module.nim +++ b/src/app/modules/main/communities/module.nim @@ -39,6 +39,7 @@ type Imported = 0 ImportingInProgress ImportingError + ImportingCanceled type Action {.pure.} = enum @@ -411,6 +412,9 @@ method importCommunity*(self: Module, communityId: string) = method onImportCommunityErrorOccured*(self: Module, communityId: string, error: string) = self.view.emitImportingCommunityStateChangedSignal(communityId, ImportCommunityState.ImportingError.int, error) +method onImportCommunityCanceled*(self: Module, communityId: string) = + self.view.emitImportingCommunityStateChangedSignal(communityId, ImportCommunityState.ImportingCanceled.int, errorMsg = "") + method requestExtractDiscordChannelsAndCategories*(self: Module, filesToImport: seq[string]) = self.view.setDiscordDataExtractionInProgress(true) self.controller.requestExtractDiscordChannelsAndCategories(filesToImport) @@ -441,8 +445,6 @@ method discordImportProgressUpdated*( self: Module, communityId: string, communityName: string, - channelId: string, - channelName: string, communityImage: string, tasks: seq[DiscordImportTaskProgress], progress: float, @@ -460,9 +462,51 @@ method discordImportProgressUpdated*( self.view.setDiscordImportCommunityId(communityId) self.view.setDiscordImportCommunityName(communityName) + self.view.setDiscordImportCommunityImage(communityImage) + self.view.setDiscordImportErrorsCount(errorsCount) + self.view.setDiscordImportWarningsCount(warningsCount) + # For some reason, exposing the global `progress` as QtProperty[float]` + # doesn't translate well into QML. + # That's why we pass it as integer instead. + self.view.setDiscordImportProgress((progress*100).int) + self.view.setDiscordImportProgressStopped(stopped) + self.view.setDiscordImportProgressTotalChunksCount(totalChunksCount) + self.view.setDiscordImportProgressCurrentChunk(currentChunk) + if stopped or progress.int >= 1: + self.view.setDiscordImportInProgress(false) + +method discordImportChannelFinished*(self: Module, channelId: string) = + if self.view.getDiscordImportChannelId() == channelId: + self.view.setDiscordImportProgress(100) + self.view.setDiscordImportProgressStopped(true) + self.view.setDiscordImportInProgress(false) + +method discordImportChannelCanceled*(self: Module, channelId: string) = + if self.view.getDiscordImportChannelId() == channelId: + self.view.setDiscordImportProgress(0) + self.view.setDiscordImportProgressStopped(true) + self.view.setDiscordImportInProgress(false) + +method discordImportChannelProgressUpdated*( + self: Module, + channelId: string, + channelName: string, + tasks: seq[DiscordImportTaskProgress], + progress: float, + errorsCount: int, + warningsCount: int, + stopped: bool, + totalChunksCount: int, + currentChunk: int + ) = + for task in tasks: + if not self.view.discordImportTasksModel().hasItemByType(task.`type`): + self.view.discordImportTasksModel().addItem(self.getDiscordImportTaskItem(task)) + else: + self.view.discordImportTasksModel().updateItem(task) + self.view.setDiscordImportChannelId(channelId) self.view.setDiscordImportChannelName(channelName) - self.view.setDiscordImportCommunityImage(communityImage) self.view.setDiscordImportErrorsCount(errorsCount) self.view.setDiscordImportWarningsCount(warningsCount) # For some reason, exposing the global `progress` as QtProperty[float]` diff --git a/src/app/modules/main/communities/view.nim b/src/app/modules/main/communities/view.nim index 459c5587be..506de7ba4b 100644 --- a/src/app/modules/main/communities/view.nim +++ b/src/app/modules/main/communities/view.nim @@ -662,15 +662,15 @@ QtObject: self.discordImportChannelId = id self.discordImportChannelName = item.getName() self.discordImportChannelChanged() - - proc getDiscordImportChannelId(self: View): string {.slot.} = - return self.discordImportChannelId - + proc setDiscordImportChannelId*(self: View, id: string) {.slot.} = if (self.discordImportChannelId == id): return self.discordImportChannelId = id self.discordImportChannelChanged() + proc getDiscordImportChannelId*(self: View): string {.slot.} = + return self.discordImportChannelId + QtProperty[string] discordImportChannelId: read = getDiscordImportChannelId notify = discordImportChannelChanged diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index 9ffa7e6c21..7ae8c128d8 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -42,6 +42,9 @@ type CommunityIdArgs* = ref object of Args communityId*: string + ChannelIdArgs* = ref object of Args + channelId*: string + CommunityChatIdArgs* = ref object of Args communityId*: string chatId*: string @@ -112,6 +115,15 @@ type communityId*: string communityImage*: string communityName*: string + tasks*: seq[DiscordImportTaskProgress] + progress*: float + errorsCount*: int + warningsCount*: int + stopped*: bool + totalChunksCount*: int + currentChunk*: int + + DiscordImportChannelProgressArgs* = ref object of Args channelId*: string channelName*: string tasks*: seq[DiscordImportTaskProgress] @@ -198,6 +210,11 @@ const SIGNAL_COMMUNITY_HISTORY_ARCHIVES_DOWNLOAD_FINISHED* = "communityHistoryAr const SIGNAL_DISCORD_CATEGORIES_AND_CHANNELS_EXTRACTED* = "discordCategoriesAndChannelsExtracted" const SIGNAL_DISCORD_COMMUNITY_IMPORT_FINISHED* = "discordCommunityImportFinished" const SIGNAL_DISCORD_COMMUNITY_IMPORT_PROGRESS* = "discordCommunityImportProgress" +const SIGNAL_DISCORD_COMMUNITY_IMPORT_CANCELED* = "discordCommunityImportCanceled" +const SIGNAL_DISCORD_CHANNEL_IMPORT_FINISHED* = "discordChannelImportFinished" +const SIGNAL_DISCORD_CHANNEL_IMPORT_PROGRESS* = "discordChannelImportProgress" +const SIGNAL_DISCORD_CHANNEL_IMPORT_CANCELED* = "discordChannelImportCanceled" + const SIGNAL_COMMUNITY_TOKEN_PERMISSION_CREATED* = "communityTokenPermissionCreated" const SIGNAL_COMMUNITY_TOKEN_PERMISSION_CREATION_FAILED* = "communityTokenPermissionCreationFailed" const SIGNAL_COMMUNITY_TOKEN_PERMISSION_UPDATED* = "communityTokenPermissionUpdated" @@ -362,12 +379,36 @@ QtObject: var receivedData = DiscordCommunityImportFinishedSignal(e) self.events.emit(SIGNAL_DISCORD_COMMUNITY_IMPORT_FINISHED, CommunityIdArgs(communityId: receivedData.communityId)) + self.events.on(SignalType.DiscordCommunityImportCancelled.event) do(e: Args): + var receivedData = DiscordCommunityImportCancelledSignal(e) + self.events.emit(SIGNAL_DISCORD_COMMUNITY_IMPORT_CANCELED, CommunityIdArgs(communityId: receivedData.communityId)) + + self.events.on(SignalType.DiscordChannelImportFinished.event) do(e: Args): + var receivedData = DiscordChannelImportFinishedSignal(e) + self.events.emit(SIGNAL_DISCORD_CHANNEL_IMPORT_FINISHED, CommunityChatIdArgs(chatId: receivedData.channelId, communityId: receivedData.communityId)) + + self.events.on(SignalType.DiscordChannelImportCancelled.event) do(e: Args): + var receivedData = DiscordChannelImportCancelledSignal(e) + self.events.emit(SIGNAL_DISCORD_CHANNEL_IMPORT_CANCELED, ChannelIdArgs(channelId: receivedData.channelId)) + self.events.on(SignalType.DiscordCommunityImportProgress.event) do(e: Args): var receivedData = DiscordCommunityImportProgressSignal(e) self.events.emit(SIGNAL_DISCORD_COMMUNITY_IMPORT_PROGRESS, DiscordImportProgressArgs( communityId: receivedData.communityId, communityImage: receivedData.communityImages.thumbnail, communityName: receivedData.communityName, + tasks: receivedData.tasks, + progress: receivedData.progress, + errorsCount: receivedData.errorsCount, + warningsCount: receivedData.warningsCount, + stopped: receivedData.stopped, + totalChunksCount: receivedData.totalChunksCount, + currentChunk: receivedData.currentChunk, + )) + + self.events.on(SignalType.DiscordChannelImportProgress.event) do(e: Args): + var receivedData = DiscordChannelImportProgressSignal(e) + self.events.emit(SIGNAL_DISCORD_CHANNEL_IMPORT_PROGRESS, DiscordImportChannelProgressArgs( channelId: receivedData.channelId, channelName: receivedData.channelName, tasks: receivedData.tasks, diff --git a/src/app_service/service/message/service.nim b/src/app_service/service/message/service.nim index 954d92765a..3dd80948f7 100644 --- a/src/app_service/service/message/service.nim +++ b/src/app_service/service/message/service.nim @@ -411,6 +411,11 @@ QtObject: self.events.on(SignalType.DiscordCommunityImportFinished.event) do(e: Args): var receivedData = DiscordCommunityImportFinishedSignal(e) self.handleMessagesReload(receivedData.communityId) + + self.events.on(SignalType.DiscordChannelImportFinished.event) do(e: Args): + var receivedData = DiscordChannelImportFinishedSignal(e) + self.resetMessageCursor(receivedData.channelId) + self.asyncLoadMoreMessagesForChat(receivedData.channelId) proc getTransactionDetails*(self: Service, message: MessageDto): (string, string) = let networksDto = self.networkService.getNetworks() diff --git a/ui/app/AppLayouts/Communities/popups/DiscordImportProgressContents.qml b/ui/app/AppLayouts/Communities/popups/DiscordImportProgressContents.qml index ce90e7dd83..6f68f79892 100644 --- a/ui/app/AppLayouts/Communities/popups/DiscordImportProgressContents.qml +++ b/ui/app/AppLayouts/Communities/popups/DiscordImportProgressContents.qml @@ -123,7 +123,7 @@ StatusScrollView { return DiscordImportProgressContents.ImportStatus.Stopped } if (importProgress >= 100) { - if (hasWarnings) + if (hasWarnings || hasErrors) return DiscordImportProgressContents.ImportStatus.CompletedWithWarnings return DiscordImportProgressContents.ImportStatus.CompletedSuccessfully } diff --git a/ui/app/AppLayouts/Communities/stores/CommunitiesStore.qml b/ui/app/AppLayouts/Communities/stores/CommunitiesStore.qml index b377bc4591..f5a0595103 100644 --- a/ui/app/AppLayouts/Communities/stores/CommunitiesStore.qml +++ b/ui/app/AppLayouts/Communities/stores/CommunitiesStore.qml @@ -239,7 +239,6 @@ QtObject { }, from = 0) { communitiesModuleInst.requestImportDiscordChannel(args.name, args.discordChannelId, args.communityId, args.description, args.color, args.emoji, from) -// console.warn("!!! IMPLEMENT ME requestImportDiscordChannel") // FIXME } readonly property Connections connections: Connections { diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index 7a50f1a136..56e1e446f3 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -354,6 +354,9 @@ Item { title = qsTr("Failed to import community '%1'").arg(communityId) subTitle = errorMsg break + case Constants.communityImportingCanceled: + title = qsTr("Import community '%1' was canceled").arg(community.name) + break; default: console.error("unknown state while importing community: %1").arg(state) return diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index acedf97907..b88f30df0f 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -820,6 +820,7 @@ QtObject { readonly property int communityImported: 0 readonly property int communityImportingInProgress: 1 readonly property int communityImportingError: 2 + readonly property int communityImportingCanceled: 3 readonly property int communityChatPublicAccess: 1 readonly property int communityChatInvitationOnlyAccess: 2 diff --git a/vendor/status-go b/vendor/status-go index ce121710d9..1d08b403e6 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit ce121710d9f3b13fd9a6562ca97c947c294564e2 +Subproject commit 1d08b403e6818b6efd31785fbc73ece3d44e4926