diff --git a/src/app/core/signals/remote_signals/community.nim b/src/app/core/signals/remote_signals/community.nim index 2eff27e7a0..d57fde2e89 100644 --- a/src/app/core/signals/remote_signals/community.nim +++ b/src/app/core/signals/remote_signals/community.nim @@ -28,6 +28,8 @@ type DiscordCommunityImportProgressSignal* = ref object of Signal communityId*: string communityImages*: Images communityName*: string + channelId*: string + channelName*: string tasks*: seq[DiscordImportTaskProgress] progress*: float errorsCount*: int @@ -89,6 +91,8 @@ 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() diff --git a/src/app/modules/main/communities/controller.nim b/src/app/modules/main/communities/controller.nim index 056c4257f2..e85d95f41a 100644 --- a/src/app/modules/main/communities/controller.nim +++ b/src/app/modules/main/communities/controller.nim @@ -134,7 +134,7 @@ 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.communityImage, args.tasks, args.progress, args.errorsCount, args.warningsCount, args.stopped, args.totalChunksCount, args.currentChunk) + 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.events.on(SIGNAL_COMMUNITY_HISTORY_ARCHIVES_DOWNLOAD_STARTED) do(e:Args): let args = CommunityIdArgs(e) @@ -281,6 +281,26 @@ proc requestImportDiscordCommunity*( filesToImport, fromTimestamp) +proc requestImportDiscordChannel*( + self: Controller, + name: string, + discordChannelId: string, + communityId: string, + description: string, + color: string, + emoji: string, + filesToImport: seq[string], + fromTimestamp: int) = + self.communityService.requestImportDiscordChannel( + name, + discordChannelId, + communityId, + description, + color, + emoji, + filesToImport, + fromTimestamp) + proc reorderCommunityChat*( self: Controller, communityId: string, @@ -333,6 +353,9 @@ proc requestExtractDiscordChannelsAndCategories*(self: Controller, filesToImport proc requestCancelDiscordCommunityImport*(self: Controller, id: string) = self.communityService.requestCancelDiscordCommunityImport(id) +proc requestCancelDiscordChannelImport*(self: Controller, discordChannelId: string) = + self.communityService.requestCancelDiscordChannelImport(discordChannelId) + proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTokenDto] = self.communityTokensService.getCommunityTokens(communityId) diff --git a/src/app/modules/main/communities/io_interface.nim b/src/app/modules/main/communities/io_interface.nim index 68bd372cb1..bff7e39764 100644 --- a/src/app/modules/main/communities/io_interface.nim +++ b/src/app/modules/main/communities/io_interface.nim @@ -51,6 +51,11 @@ method requestImportDiscordCommunity*(self: AccessInterface, name: string, descr fromTimestamp: int) {.base.} = raise newException(ValueError, "No implementation available") +method requestImportDiscordChannel*(self: AccessInterface, name: string, discordChannelId: string, communityId: string, description: string, + color: string, emoji: string, filesToImport: seq[string], + fromTimestamp: int) {.base.} = + raise newException(ValueError, "No implementation available") + method isUserMemberOfCommunity*(self: AccessInterface, communityId: string): bool {.base.} = raise newException(ValueError, "No implementation available") @@ -138,12 +143,15 @@ 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, 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, channelId: string, channelName: 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 requestCancelDiscordCommunityImport*(self: AccessInterface, id: string) {.base.} = raise newException(ValueError, "No implementation available") +method requestCancelDiscordChannelImport*(self: AccessInterface, discordChannelId: string) {.base.} = + raise newException(ValueError, "No implementation available") + method communityHistoryArchivesDownloadStarted*(self: AccessInterface, communityId: string) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/communities/module.nim b/src/app/modules/main/communities/module.nim index ca43387a54..a5d4576190 100644 --- a/src/app/modules/main/communities/module.nim +++ b/src/app/modules/main/communities/module.nim @@ -422,6 +422,11 @@ method requestImportDiscordCommunity*(self: Module, name: string, description, i self.view.setDiscordImportHasCommunityImage(imagePath != "") self.controller.requestImportDiscordCommunity(name, description, introMessage, outroMessage, access, color, tags, imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled, filesToImport, fromTimestamp) +method requestImportDiscordChannel*(self: Module, name: string, discordChannelId: string, communityId: string, description: string, + color: string, emoji: string, filesToImport: seq[string], + fromTimestamp: int) = + self.controller.requestImportDiscordChannel(name, discordChannelId, communityId, description, color, emoji, filesToImport, fromTimestamp) + proc getDiscordImportTaskItem(self: Module, t: DiscordImportTaskProgress): DiscordImportTaskItem = return initDiscordImportTaskItem( t.`type`, @@ -436,6 +441,8 @@ method discordImportProgressUpdated*( self: Module, communityId: string, communityName: string, + channelId: string, + channelName: string, communityImage: string, tasks: seq[DiscordImportTaskProgress], progress: float, @@ -453,6 +460,8 @@ method discordImportProgressUpdated*( self.view.setDiscordImportCommunityId(communityId) self.view.setDiscordImportCommunityName(communityName) + self.view.setDiscordImportChannelId(channelId) + self.view.setDiscordImportChannelName(channelName) self.view.setDiscordImportCommunityImage(communityImage) self.view.setDiscordImportErrorsCount(errorsCount) self.view.setDiscordImportWarningsCount(warningsCount) @@ -469,6 +478,9 @@ method discordImportProgressUpdated*( method requestCancelDiscordCommunityImport*(self: Module, id: string) = self.controller.requestCancelDiscordCommunityImport(id) +method requestCancelDiscordChannelImport*(self: Module, discordChannelId: string) = + self.controller.requestCancelDiscordChannelImport(discordChannelId) + method communityInfoAlreadyRequested*(self: Module) = self.view.communityInfoAlreadyRequested() diff --git a/src/app/modules/main/communities/view.nim b/src/app/modules/main/communities/view.nim index 5e66777d63..459c5587be 100644 --- a/src/app/modules/main/communities/view.nim +++ b/src/app/modules/main/communities/view.nim @@ -456,7 +456,7 @@ QtObject: if (self.discordImportCommunityName == name): return self.discordImportCommunityName = name self.discordImportCommunityNameChanged() - + QtProperty[string] discordImportCommunityName: read = getDiscordImportCommunityName notify = discordImportCommunityNameChanged @@ -525,6 +525,27 @@ QtObject: imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled, filesToImport, fromTimestamp) + proc requestImportDiscordChannel*(self: View, name: string, discordChannelId: string, communityId: string, + description: string, color: string, emoji: string, + fromTimestamp: int) {.slot.} = + let selectedItems = self.discordChannelsModel.getSelectedItems() + var filesToImport: seq[string] = @[] + + for i in 0 ..< selectedItems.len: + filesToImport.add(selectedItems[i].getFilePath()) + + self.resetDiscordImport(false) + self.setDiscordImportInProgress(true) + self.delegate.requestImportDiscordChannel( + name, + discordChannelId, + communityId, + description, + color, + emoji, + filesToImport, + fromTimestamp) + proc cancelRequestToJoinCommunity*(self: View, communityId: string) {.slot.} = self.delegate.cancelRequestToJoinCommunity(communityId) @@ -609,6 +630,10 @@ QtObject: self.delegate.requestCancelDiscordCommunityImport(id) self.resetDiscordImport(true) + proc requestCancelDiscordChannelImport*(self: View, discordChannelId: string) {.slot.} = + self.delegate.requestCancelDiscordChannelImport(discordChannelId) + self.resetDiscordImport(true) + proc toggleDiscordCategory*(self: View, id: string, selected: bool) {.slot.} = if selected: self.discordCategoriesModel.selectItem(id) @@ -641,9 +666,19 @@ QtObject: 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() + QtProperty[string] discordImportChannelId: read = getDiscordImportChannelId notify = discordImportChannelChanged + + proc setDiscordImportChannelName*(self: View, name: string) {.slot.} = + if (self.discordImportChannelName == name): return + self.discordImportChannelName = name + self.discordImportChannelChanged() proc getDiscordImportChannelName(self: View): string {.slot.} = return self.discordImportChannelName diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index 0ae1751b00..9ffa7e6c21 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -112,6 +112,8 @@ type communityId*: string communityImage*: string communityName*: string + channelId*: string + channelName*: string tasks*: seq[DiscordImportTaskProgress] progress*: float errorsCount*: int @@ -366,6 +368,8 @@ QtObject: communityId: receivedData.communityId, communityImage: receivedData.communityImages.thumbnail, communityName: receivedData.communityName, + channelId: receivedData.channelId, + channelName: receivedData.channelName, tasks: receivedData.tasks, progress: receivedData.progress, errorsCount: receivedData.errorsCount, @@ -1048,6 +1052,34 @@ QtObject: except Exception as e: error "Error importing discord community", msg = e.msg + proc requestImportDiscordChannel*( + self: Service, + name: string, + discordChannelId: string, + communityId: string, + description: string, + color: string, + emoji: string, + filesToImport: seq[string], + fromTimestamp: int) = + try: + let response = status_go.requestImportDiscordChannel( + name, + discordChannelId, + communityId, + description, + color, + emoji, + filesToImport, + fromTimestamp) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error importing discord channel: " & error.message) + + except Exception as e: + error "Error importing discord channel", msg = e.msg + proc createCommunity*( self: Service, name: string, @@ -2084,6 +2116,12 @@ QtObject: except Exception as e: error "Error canceling discord community import", msg = e.msg + proc requestCancelDiscordChannelImport*(self: Service, discordChannelId: string) = + try: + discard status_go.requestCancelDiscordChannelImport(discordChannelId) + except Exception as e: + error "Error canceling discord channel import", msg = e.msg + proc createOrEditCommunityTokenPermission*(self: Service, communityId: string, tokenPermission: CommunityTokenPermissionDto) = try: let editing = tokenPermission.id != "" diff --git a/src/backend/communities.nim b/src/backend/communities.nim index d4e5c93516..95a8f41090 100644 --- a/src/backend/communities.nim +++ b/src/backend/communities.nim @@ -257,6 +257,27 @@ proc requestImportDiscordCommunity*( "filesToImport": filesToImport }]) +proc requestImportDiscordChannel*( + name: string, + discordChannelId: string, + communityId: string, + description: string, + color: string, + emoji: string, + filesToImport: seq[string], + fromTimestamp: int, + ): RpcResponse[JsonNode] {.raises: [Exception].} = + result = callPrivateRPC("requestImportDiscordChannel".prefix, %*[{ + "name": name, + "discordChannelId": discordChannelId, + "communityId": communityId, + "description": description, + "color": color, + "emoji": emoji, + "filesToImport": filesToImport, + "from": fromTimestamp + }]) + proc createCommunityTokenPermission*(communityId: string, permissionType: int, tokenCriteria: string, chatIDs: seq[string], isPrivate: bool): RpcResponse[JsonNode] {.raises: [Exception].} = result = callPrivateRPC("createCommunityTokenPermission".prefix, %*[{ "communityId": communityId, @@ -285,6 +306,10 @@ proc deleteCommunityTokenPermission*(communityId: string, permissionId: string): proc requestCancelDiscordCommunityImport*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} = result = callPrivateRPC("requestCancelDiscordCommunityImport".prefix, %*[communityId]) +proc requestCancelDiscordChannelImport*(discordChannelId: string): RpcResponse[JsonNode] {.raises: [Exception].} = + result = callPrivateRPC("requestCancelDiscordChannelImport".prefix, %*[discordChannelId]) + + proc createCommunityChannel*( communityId: string, name: string, diff --git a/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml b/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml index 388905dc8a..bb5101a48c 100644 --- a/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml +++ b/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml @@ -214,7 +214,7 @@ StatusSectionLayout { BannerPanel { readonly property bool importInProgress: root.communitiesStore.discordImportInProgress && !root.communitiesStore.discordImportCancelled text: importInProgress ? - qsTr("'%1' import in progress...").arg(root.communitiesStore.discordImportCommunityName) : + qsTr("'%1' import in progress...").arg(root.communitiesStore.discordImportCommunityName || root.communitiesStore.discordImportChannelName) : qsTr("Import existing Discord community into Status") buttonText: qsTr("Import existing") icon.name: "download" diff --git a/ui/app/AppLayouts/Communities/popups/CreateChannelPopup.qml b/ui/app/AppLayouts/Communities/popups/CreateChannelPopup.qml index d2ee31f3e1..79f0598167 100644 --- a/ui/app/AppLayouts/Communities/popups/CreateChannelPopup.qml +++ b/ui/app/AppLayouts/Communities/popups/CreateChannelPopup.qml @@ -27,6 +27,7 @@ StatusStackModal { property bool isEdit: false property bool isDeleteable: false + property string communityId: "" property string chatId: "" property string categoryId: "" property string channelName: "" @@ -64,6 +65,7 @@ StatusStackModal { function _getChannelConfig() { return { + communityId: root.communityId, discordChannelId: root.communitiesStore.discordImportChannelId, categoryId: root.categoryId, name: StatusQUtils.Utils.filterXSS(nameInput.input.text), @@ -465,6 +467,11 @@ StatusStackModal { checked: model.selected visible: model.categoryId === categoryCheckbox.categoryId onToggled: root.communitiesStore.toggleOneDiscordChannel(model.id) + Component.onCompleted: { + if (model.selected) { + root.communitiesStore.toggleOneDiscordChannel(model.id) + } + } } } } diff --git a/ui/app/AppLayouts/Communities/popups/DiscordImportProgressContents.qml b/ui/app/AppLayouts/Communities/popups/DiscordImportProgressContents.qml index 9266812184..ce90e7dd83 100644 --- a/ui/app/AppLayouts/Communities/popups/DiscordImportProgressContents.qml +++ b/ui/app/AppLayouts/Communities/popups/DiscordImportProgressContents.qml @@ -350,7 +350,7 @@ StatusScrollView { cancelButtonLabel: root.importingSingleChannel ? qsTr("Cancel") : qsTr("Continue importing") onConfirmButtonClicked: { if (root.importingSingleChannel) - root.store.requestCancelDiscordChannelImport(root.store.discordImportChannelName) + root.store.requestCancelDiscordChannelImport(root.store.discordImportChannelId) else root.store.requestCancelDiscordCommunityImport(root.store.discordImportCommunityId) cancelConfirmationPopup.close() diff --git a/ui/app/AppLayouts/Communities/stores/CommunitiesStore.qml b/ui/app/AppLayouts/Communities/stores/CommunitiesStore.qml index a57062bdb2..b377bc4591 100644 --- a/ui/app/AppLayouts/Communities/stores/CommunitiesStore.qml +++ b/ui/app/AppLayouts/Communities/stores/CommunitiesStore.qml @@ -192,7 +192,7 @@ QtObject { } function requestCancelDiscordChannelImport(id) { - console.warn("!!! IMPLEMENT ME requestCancelDiscordChannelImport(id)") // FIXME + root.communitiesModuleInst.requestCancelDiscordChannelImport(id) } function resetDiscordImport() { @@ -227,6 +227,7 @@ QtObject { } function requestImportDiscordChannel(args = { + communityId: "", discordChannelId: "", name: "", description: "", @@ -236,7 +237,9 @@ QtObject { // TODO } }, from = 0) { - console.warn("!!! IMPLEMENT ME requestImportDiscordChannel") // FIXME + 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/AppLayouts/Communities/views/CommunityColumnView.qml b/ui/app/AppLayouts/Communities/views/CommunityColumnView.qml index 00e5377a78..91c89f564e 100644 --- a/ui/app/AppLayouts/Communities/views/CommunityColumnView.qml +++ b/ui/app/AppLayouts/Communities/views/CommunityColumnView.qml @@ -121,7 +121,9 @@ Item { text: qsTr("Create channel via Discord import") icon.name: "download" enabled: !d.discordImportInProgress - onTriggered: Global.openPopup(createChannelPopup, {isDiscordImport: true}) + onTriggered: { + Global.openPopup(createChannelPopup, {isDiscordImport: true, communityId: communityData.id}) + } } StatusAction { @@ -207,7 +209,7 @@ Item { text: qsTr("Create channel via Discord import") icon.name: "download" enabled: !d.discordImportInProgress - onTriggered: Global.openPopup(createChannelPopup, {isDiscordImport: true}) + onTriggered: Global.openPopup(createChannelPopup, {isDiscordImport: true, communityId: root.communityData.id}) } StatusAction {