feat(discord): Import single channel from discord

Fixes: #12238
This commit is contained in:
Boris Melnik 2023-10-16 21:26:47 +03:00
parent d2439cdf15
commit 99712a076b
12 changed files with 166 additions and 9 deletions

View File

@ -28,6 +28,8 @@ type DiscordCommunityImportProgressSignal* = ref object of Signal
communityId*: string communityId*: string
communityImages*: Images communityImages*: Images
communityName*: string communityName*: string
channelId*: string
channelName*: string
tasks*: seq[DiscordImportTaskProgress] tasks*: seq[DiscordImportTaskProgress]
progress*: float progress*: float
errorsCount*: int errorsCount*: int
@ -89,6 +91,8 @@ proc fromEvent*(T: type DiscordCommunityImportProgressSignal, event: JsonNode):
result.communityId = importProgressObj{"communityId"}.getStr() result.communityId = importProgressObj{"communityId"}.getStr()
result.communityName = importProgressObj{"communityName"}.getStr() result.communityName = importProgressObj{"communityName"}.getStr()
result.channelId = importProgressObj{"channelId"}.getStr()
result.channelName = importProgressObj{"channelName"}.getStr()
result.progress = importProgressObj{"progress"}.getFloat() result.progress = importProgressObj{"progress"}.getFloat()
result.errorsCount = importProgressObj{"errorsCount"}.getInt() result.errorsCount = importProgressObj{"errorsCount"}.getInt()
result.warningsCount = importProgressObj{"warningsCount"}.getInt() result.warningsCount = importProgressObj{"warningsCount"}.getInt()

View File

@ -134,7 +134,7 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_DISCORD_COMMUNITY_IMPORT_PROGRESS) do(e:Args): self.events.on(SIGNAL_DISCORD_COMMUNITY_IMPORT_PROGRESS) do(e:Args):
let args = DiscordImportProgressArgs(e) 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): self.events.on(SIGNAL_COMMUNITY_HISTORY_ARCHIVES_DOWNLOAD_STARTED) do(e:Args):
let args = CommunityIdArgs(e) let args = CommunityIdArgs(e)
@ -281,6 +281,26 @@ proc requestImportDiscordCommunity*(
filesToImport, filesToImport,
fromTimestamp) 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*( proc reorderCommunityChat*(
self: Controller, self: Controller,
communityId: string, communityId: string,
@ -333,6 +353,9 @@ proc requestExtractDiscordChannelsAndCategories*(self: Controller, filesToImport
proc requestCancelDiscordCommunityImport*(self: Controller, id: string) = proc requestCancelDiscordCommunityImport*(self: Controller, id: string) =
self.communityService.requestCancelDiscordCommunityImport(id) self.communityService.requestCancelDiscordCommunityImport(id)
proc requestCancelDiscordChannelImport*(self: Controller, discordChannelId: string) =
self.communityService.requestCancelDiscordChannelImport(discordChannelId)
proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTokenDto] = proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTokenDto] =
self.communityTokensService.getCommunityTokens(communityId) self.communityTokensService.getCommunityTokens(communityId)

View File

@ -51,6 +51,11 @@ method requestImportDiscordCommunity*(self: AccessInterface, name: string, descr
fromTimestamp: int) {.base.} = fromTimestamp: int) {.base.} =
raise newException(ValueError, "No implementation available") 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.} = method isUserMemberOfCommunity*(self: AccessInterface, communityId: string): bool {.base.} =
raise newException(ValueError, "No implementation available") 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.} = 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") 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") raise newException(ValueError, "No implementation available")
method requestCancelDiscordCommunityImport*(self: AccessInterface, id: string) {.base.} = method requestCancelDiscordCommunityImport*(self: AccessInterface, id: string) {.base.} =
raise newException(ValueError, "No implementation available") 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.} = method communityHistoryArchivesDownloadStarted*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -422,6 +422,11 @@ method requestImportDiscordCommunity*(self: Module, name: string, description, i
self.view.setDiscordImportHasCommunityImage(imagePath != "") self.view.setDiscordImportHasCommunityImage(imagePath != "")
self.controller.requestImportDiscordCommunity(name, description, introMessage, outroMessage, access, color, tags, imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled, filesToImport, fromTimestamp) 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 = proc getDiscordImportTaskItem(self: Module, t: DiscordImportTaskProgress): DiscordImportTaskItem =
return initDiscordImportTaskItem( return initDiscordImportTaskItem(
t.`type`, t.`type`,
@ -436,6 +441,8 @@ method discordImportProgressUpdated*(
self: Module, self: Module,
communityId: string, communityId: string,
communityName: string, communityName: string,
channelId: string,
channelName: string,
communityImage: string, communityImage: string,
tasks: seq[DiscordImportTaskProgress], tasks: seq[DiscordImportTaskProgress],
progress: float, progress: float,
@ -453,6 +460,8 @@ method discordImportProgressUpdated*(
self.view.setDiscordImportCommunityId(communityId) self.view.setDiscordImportCommunityId(communityId)
self.view.setDiscordImportCommunityName(communityName) self.view.setDiscordImportCommunityName(communityName)
self.view.setDiscordImportChannelId(channelId)
self.view.setDiscordImportChannelName(channelName)
self.view.setDiscordImportCommunityImage(communityImage) self.view.setDiscordImportCommunityImage(communityImage)
self.view.setDiscordImportErrorsCount(errorsCount) self.view.setDiscordImportErrorsCount(errorsCount)
self.view.setDiscordImportWarningsCount(warningsCount) self.view.setDiscordImportWarningsCount(warningsCount)
@ -469,6 +478,9 @@ method discordImportProgressUpdated*(
method requestCancelDiscordCommunityImport*(self: Module, id: string) = method requestCancelDiscordCommunityImport*(self: Module, id: string) =
self.controller.requestCancelDiscordCommunityImport(id) self.controller.requestCancelDiscordCommunityImport(id)
method requestCancelDiscordChannelImport*(self: Module, discordChannelId: string) =
self.controller.requestCancelDiscordChannelImport(discordChannelId)
method communityInfoAlreadyRequested*(self: Module) = method communityInfoAlreadyRequested*(self: Module) =
self.view.communityInfoAlreadyRequested() self.view.communityInfoAlreadyRequested()

View File

@ -456,7 +456,7 @@ QtObject:
if (self.discordImportCommunityName == name): return if (self.discordImportCommunityName == name): return
self.discordImportCommunityName = name self.discordImportCommunityName = name
self.discordImportCommunityNameChanged() self.discordImportCommunityNameChanged()
QtProperty[string] discordImportCommunityName: QtProperty[string] discordImportCommunityName:
read = getDiscordImportCommunityName read = getDiscordImportCommunityName
notify = discordImportCommunityNameChanged notify = discordImportCommunityNameChanged
@ -525,6 +525,27 @@ QtObject:
imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled, imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled,
filesToImport, fromTimestamp) 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.} = proc cancelRequestToJoinCommunity*(self: View, communityId: string) {.slot.} =
self.delegate.cancelRequestToJoinCommunity(communityId) self.delegate.cancelRequestToJoinCommunity(communityId)
@ -609,6 +630,10 @@ QtObject:
self.delegate.requestCancelDiscordCommunityImport(id) self.delegate.requestCancelDiscordCommunityImport(id)
self.resetDiscordImport(true) 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.} = proc toggleDiscordCategory*(self: View, id: string, selected: bool) {.slot.} =
if selected: if selected:
self.discordCategoriesModel.selectItem(id) self.discordCategoriesModel.selectItem(id)
@ -641,9 +666,19 @@ QtObject:
proc getDiscordImportChannelId(self: View): string {.slot.} = proc getDiscordImportChannelId(self: View): string {.slot.} =
return self.discordImportChannelId return self.discordImportChannelId
proc setDiscordImportChannelId*(self: View, id: string) {.slot.} =
if (self.discordImportChannelId == id): return
self.discordImportChannelId = id
self.discordImportChannelChanged()
QtProperty[string] discordImportChannelId: QtProperty[string] discordImportChannelId:
read = getDiscordImportChannelId read = getDiscordImportChannelId
notify = discordImportChannelChanged 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.} = proc getDiscordImportChannelName(self: View): string {.slot.} =
return self.discordImportChannelName return self.discordImportChannelName

View File

@ -112,6 +112,8 @@ type
communityId*: string communityId*: string
communityImage*: string communityImage*: string
communityName*: string communityName*: string
channelId*: string
channelName*: string
tasks*: seq[DiscordImportTaskProgress] tasks*: seq[DiscordImportTaskProgress]
progress*: float progress*: float
errorsCount*: int errorsCount*: int
@ -366,6 +368,8 @@ QtObject:
communityId: receivedData.communityId, communityId: receivedData.communityId,
communityImage: receivedData.communityImages.thumbnail, communityImage: receivedData.communityImages.thumbnail,
communityName: receivedData.communityName, communityName: receivedData.communityName,
channelId: receivedData.channelId,
channelName: receivedData.channelName,
tasks: receivedData.tasks, tasks: receivedData.tasks,
progress: receivedData.progress, progress: receivedData.progress,
errorsCount: receivedData.errorsCount, errorsCount: receivedData.errorsCount,
@ -1048,6 +1052,34 @@ QtObject:
except Exception as e: except Exception as e:
error "Error importing discord community", msg = e.msg 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*( proc createCommunity*(
self: Service, self: Service,
name: string, name: string,
@ -2084,6 +2116,12 @@ QtObject:
except Exception as e: except Exception as e:
error "Error canceling discord community import", msg = e.msg 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) = proc createOrEditCommunityTokenPermission*(self: Service, communityId: string, tokenPermission: CommunityTokenPermissionDto) =
try: try:
let editing = tokenPermission.id != "" let editing = tokenPermission.id != ""

View File

@ -257,6 +257,27 @@ proc requestImportDiscordCommunity*(
"filesToImport": filesToImport "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].} = proc createCommunityTokenPermission*(communityId: string, permissionType: int, tokenCriteria: string, chatIDs: seq[string], isPrivate: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("createCommunityTokenPermission".prefix, %*[{ result = callPrivateRPC("createCommunityTokenPermission".prefix, %*[{
"communityId": communityId, "communityId": communityId,
@ -285,6 +306,10 @@ proc deleteCommunityTokenPermission*(communityId: string, permissionId: string):
proc requestCancelDiscordCommunityImport*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc requestCancelDiscordCommunityImport*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("requestCancelDiscordCommunityImport".prefix, %*[communityId]) result = callPrivateRPC("requestCancelDiscordCommunityImport".prefix, %*[communityId])
proc requestCancelDiscordChannelImport*(discordChannelId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("requestCancelDiscordChannelImport".prefix, %*[discordChannelId])
proc createCommunityChannel*( proc createCommunityChannel*(
communityId: string, communityId: string,
name: string, name: string,

View File

@ -214,7 +214,7 @@ StatusSectionLayout {
BannerPanel { BannerPanel {
readonly property bool importInProgress: root.communitiesStore.discordImportInProgress && !root.communitiesStore.discordImportCancelled readonly property bool importInProgress: root.communitiesStore.discordImportInProgress && !root.communitiesStore.discordImportCancelled
text: importInProgress ? 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") qsTr("Import existing Discord community into Status")
buttonText: qsTr("Import existing") buttonText: qsTr("Import existing")
icon.name: "download" icon.name: "download"

View File

@ -27,6 +27,7 @@ StatusStackModal {
property bool isEdit: false property bool isEdit: false
property bool isDeleteable: false property bool isDeleteable: false
property string communityId: ""
property string chatId: "" property string chatId: ""
property string categoryId: "" property string categoryId: ""
property string channelName: "" property string channelName: ""
@ -64,6 +65,7 @@ StatusStackModal {
function _getChannelConfig() { function _getChannelConfig() {
return { return {
communityId: root.communityId,
discordChannelId: root.communitiesStore.discordImportChannelId, discordChannelId: root.communitiesStore.discordImportChannelId,
categoryId: root.categoryId, categoryId: root.categoryId,
name: StatusQUtils.Utils.filterXSS(nameInput.input.text), name: StatusQUtils.Utils.filterXSS(nameInput.input.text),
@ -465,6 +467,11 @@ StatusStackModal {
checked: model.selected checked: model.selected
visible: model.categoryId === categoryCheckbox.categoryId visible: model.categoryId === categoryCheckbox.categoryId
onToggled: root.communitiesStore.toggleOneDiscordChannel(model.id) onToggled: root.communitiesStore.toggleOneDiscordChannel(model.id)
Component.onCompleted: {
if (model.selected) {
root.communitiesStore.toggleOneDiscordChannel(model.id)
}
}
} }
} }
} }

View File

@ -350,7 +350,7 @@ StatusScrollView {
cancelButtonLabel: root.importingSingleChannel ? qsTr("Cancel") : qsTr("Continue importing") cancelButtonLabel: root.importingSingleChannel ? qsTr("Cancel") : qsTr("Continue importing")
onConfirmButtonClicked: { onConfirmButtonClicked: {
if (root.importingSingleChannel) if (root.importingSingleChannel)
root.store.requestCancelDiscordChannelImport(root.store.discordImportChannelName) root.store.requestCancelDiscordChannelImport(root.store.discordImportChannelId)
else else
root.store.requestCancelDiscordCommunityImport(root.store.discordImportCommunityId) root.store.requestCancelDiscordCommunityImport(root.store.discordImportCommunityId)
cancelConfirmationPopup.close() cancelConfirmationPopup.close()

View File

@ -192,7 +192,7 @@ QtObject {
} }
function requestCancelDiscordChannelImport(id) { function requestCancelDiscordChannelImport(id) {
console.warn("!!! IMPLEMENT ME requestCancelDiscordChannelImport(id)") // FIXME root.communitiesModuleInst.requestCancelDiscordChannelImport(id)
} }
function resetDiscordImport() { function resetDiscordImport() {
@ -227,6 +227,7 @@ QtObject {
} }
function requestImportDiscordChannel(args = { function requestImportDiscordChannel(args = {
communityId: "",
discordChannelId: "", discordChannelId: "",
name: "", name: "",
description: "", description: "",
@ -236,7 +237,9 @@ QtObject {
// TODO // TODO
} }
}, from = 0) { }, 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 { readonly property Connections connections: Connections {

View File

@ -121,7 +121,9 @@ Item {
text: qsTr("Create channel via Discord import") text: qsTr("Create channel via Discord import")
icon.name: "download" icon.name: "download"
enabled: !d.discordImportInProgress enabled: !d.discordImportInProgress
onTriggered: Global.openPopup(createChannelPopup, {isDiscordImport: true}) onTriggered: {
Global.openPopup(createChannelPopup, {isDiscordImport: true, communityId: communityData.id})
}
} }
StatusAction { StatusAction {
@ -207,7 +209,7 @@ Item {
text: qsTr("Create channel via Discord import") text: qsTr("Create channel via Discord import")
icon.name: "download" icon.name: "download"
enabled: !d.discordImportInProgress enabled: !d.discordImportInProgress
onTriggered: Global.openPopup(createChannelPopup, {isDiscordImport: true}) onTriggered: Global.openPopup(createChannelPopup, {isDiscordImport: true, communityId: root.communityData.id})
} }
StatusAction { StatusAction {