From d5a3ead0b61beffeb147b39202e63ecec0de2ae3 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 16 Dec 2021 12:14:55 -0500 Subject: [PATCH] refactor(community): add all community function in the backend --- .../modules/main/app_search/controller.nim | 4 +- .../chat_section/chat_content/controller.nim | 4 +- .../chat_content/input_area/controller.nim | 4 +- .../chat_content/input_area/module.nim | 4 +- .../main/chat_section/chat_content/module.nim | 2 +- .../chat_content/users/controller.nim | 6 +- .../chat_content/users/module.nim | 4 +- .../modules/main/chat_section/controller.nim | 6 +- src/app/modules/main/chat_section/module.nim | 14 +- .../module_access_interface.nim | 4 +- .../module_controller_delegate_interface.nim | 2 +- .../modules/main/communities/controller.nim | 134 +++++ .../main/communities/controller_interface.nim | 39 ++ src/app/modules/main/controller.nim | 4 +- src/app/modules/main/controller_interface.nim | 2 +- src/app/modules/main/module.nim | 2 +- .../module_controller_delegate_interface.nim | 2 +- .../service/community/dto/community.nim | 28 +- src/app_service/service/community/service.nim | 561 +++++++++++++----- .../service/community/service_interface.nim | 42 ++ 20 files changed, 693 insertions(+), 175 deletions(-) diff --git a/src/app/modules/main/app_search/controller.nim b/src/app/modules/main/app_search/controller.nim index 4082f226b3..bd19791abf 100644 --- a/src/app/modules/main/app_search/controller.nim +++ b/src/app/modules/main/app_search/controller.nim @@ -18,7 +18,7 @@ type events: EventEmitter contactsService: contact_service.Service chatService: chat_service.Service - communityService: community_service.ServiceInterface + communityService: community_service.Service messageService: message_service.Service activeSectionId: string activeChatId: string @@ -27,7 +27,7 @@ type searchTerm: string proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, contactsService: contact_service.Service, - chatService: chat_service.Service, communityService: community_service.ServiceInterface, + chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service): Controller = result = Controller() result.delegate = delegate diff --git a/src/app/modules/main/chat_section/chat_content/controller.nim b/src/app/modules/main/chat_section/chat_content/controller.nim index 84287588c4..c49e3b0bb3 100644 --- a/src/app/modules/main/chat_section/chat_content/controller.nim +++ b/src/app/modules/main/chat_section/chat_content/controller.nim @@ -22,12 +22,12 @@ type isUsersListAvailable: bool #users list is not available for 1:1 chat contactService: contact_service.Service chatService: chat_service.Service - communityService: community_service.ServiceInterface + communityService: community_service.Service messageService: message_service.Service proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, chatId: string, belongsToCommunity: bool, isUsersListAvailable: bool, contactService: contact_service.Service, - chatService: chat_service.Service, communityService: community_service.ServiceInterface, + chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service): Controller = result = Controller() result.delegate = delegate diff --git a/src/app/modules/main/chat_section/chat_content/input_area/controller.nim b/src/app/modules/main/chat_section/chat_content/input_area/controller.nim index 9bcc3e010a..4ad90fe659 100644 --- a/src/app/modules/main/chat_section/chat_content/input_area/controller.nim +++ b/src/app/modules/main/chat_section/chat_content/input_area/controller.nim @@ -11,7 +11,7 @@ type delegate: io_interface.AccessInterface chatId: string belongsToCommunity: bool - communityService: community_service.ServiceInterface + communityService: community_service.Service chatService: chat_service.Service proc newController*( @@ -19,7 +19,7 @@ proc newController*( chatId: string, belongsToCommunity: bool, chatService: chat_service.Service, - communityService: community_service.ServiceInterface + communityService: community_service.Service ): Controller = result = Controller() result.delegate = delegate diff --git a/src/app/modules/main/chat_section/chat_content/input_area/module.nim b/src/app/modules/main/chat_section/chat_content/input_area/module.nim index abe5e8e7c2..c568f923f4 100644 --- a/src/app/modules/main/chat_section/chat_content/input_area/module.nim +++ b/src/app/modules/main/chat_section/chat_content/input_area/module.nim @@ -5,7 +5,7 @@ import view, controller import ../../../../../global/global_singleton import ../../../../../../app_service/service/chat/service as chat_service -import ../../../../../../app_service/service/community/service_interface as community_service +import ../../../../../../app_service/service/community/service as community_service export io_interface @@ -22,7 +22,7 @@ proc newModule*( chatId: string, belongsToCommunity: bool, chatService: chat_service.Service, - communityService: community_service.ServiceInterface + communityService: community_service.Service ): Module = result = Module() diff --git a/src/app/modules/main/chat_section/chat_content/module.nim b/src/app/modules/main/chat_section/chat_content/module.nim index c899e46b98..9f0643a0a5 100644 --- a/src/app/modules/main/chat_section/chat_content/module.nim +++ b/src/app/modules/main/chat_section/chat_content/module.nim @@ -35,7 +35,7 @@ type proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string, belongsToCommunity: bool, isUsersListAvailable: bool, contactService: contact_service.Service, - chatService: chat_service.Service, communityService: community_service.ServiceInterface, + chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service): Module = result = Module() diff --git a/src/app/modules/main/chat_section/chat_content/users/controller.nim b/src/app/modules/main/chat_section/chat_content/users/controller.nim index f5caeee122..65992e4cc7 100644 --- a/src/app/modules/main/chat_section/chat_content/users/controller.nim +++ b/src/app/modules/main/chat_section/chat_content/users/controller.nim @@ -3,7 +3,7 @@ import controller_interface import io_interface import ../../../../../../app_service/service/contacts/service as contact_service -import ../../../../../../app_service/service/community/service_interface as community_service +import ../../../../../../app_service/service/community/service as community_service import ../../../../../../app_service/service/message/service as message_service import eventemitter @@ -19,12 +19,12 @@ type belongsToCommunity: bool isUsersListAvailable: bool #users list is not available for 1:1 chat contactService: contact_service.Service - communityService: community_service.ServiceInterface + communityService: community_service.Service messageService: message_service.Service proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string, belongsToCommunity: bool, isUsersListAvailable: bool, contactService: contact_service.Service, - communityService: community_service.ServiceInterface, messageService: message_service.Service): + communityService: community_service.Service, messageService: message_service.Service): Controller = result = Controller() result.delegate = delegate diff --git a/src/app/modules/main/chat_section/chat_content/users/module.nim b/src/app/modules/main/chat_section/chat_content/users/module.nim index fa12c188ae..cc85fecab7 100644 --- a/src/app/modules/main/chat_section/chat_content/users/module.nim +++ b/src/app/modules/main/chat_section/chat_content/users/module.nim @@ -5,7 +5,7 @@ import view, item, model, controller import ../../../../../global/global_singleton import ../../../../../../app_service/service/contacts/service as contact_service -import ../../../../../../app_service/service/community/service_interface as community_service +import ../../../../../../app_service/service/community/service as community_service import ../../../../../../app_service/service/message/service as message_service import eventemitter @@ -22,7 +22,7 @@ type proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string, belongsToCommunity: bool, isUsersListAvailable: bool, contactService: contact_service.Service, - communityService: community_service.ServiceInterface, messageService: message_service.Service): + communityService: community_service.Service, messageService: message_service.Service): Module = result = Module() result.delegate = delegate diff --git a/src/app/modules/main/chat_section/controller.nim b/src/app/modules/main/chat_section/controller.nim index 5f4a13b46b..a0414c693b 100644 --- a/src/app/modules/main/chat_section/controller.nim +++ b/src/app/modules/main/chat_section/controller.nim @@ -5,7 +5,7 @@ import io_interface import ../../../../app_service/service/contacts/service as contact_service import ../../../../app_service/service/chat/service as chat_service -import ../../../../app_service/service/community/service_interface as community_service +import ../../../../app_service/service/community/service as community_service import ../../../../app_service/service/message/service as message_service import eventemitter @@ -22,12 +22,12 @@ type events: EventEmitter contactService: contact_service.Service chatService: chat_service.Service - communityService: community_service.ServiceInterface + communityService: community_service.Service messageService: message_service.Service proc newController*(delegate: io_interface.AccessInterface, sectionId: string, isCommunity: bool, events: EventEmitter, contactService: contact_service.Service, chatService: chat_service.Service, - communityService: community_service.ServiceInterface, messageService: message_service.Service): Controller = + communityService: community_service.Service, messageService: message_service.Service): Controller = result = Controller() result.delegate = delegate result.sectionId = sectionId diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index c4b932d3a2..edef7e832c 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -7,7 +7,7 @@ import chat_content/module as chat_content_module import ../../../../app_service/service/contacts/service as contact_service import ../../../../app_service/service/chat/service as chat_service -import ../../../../app_service/service/community/service_interface as community_service +import ../../../../app_service/service/community/service as community_service import ../../../../app_service/service/message/service as message_service import eventemitter @@ -34,7 +34,7 @@ proc newModule*( isCommunity: bool, contactService: contact_service.Service, chatService: chat_service.Service, - communityService: community_service.ServiceInterface, + communityService: community_service.Service, messageService: message_service.Service ): Module = result = Module() @@ -60,7 +60,7 @@ method isCommunity*(self: Module): bool = proc addSubmodule(self: Module, chatId: string, belongToCommunity: bool, isUsersListAvailable: bool, events: EventEmitter, contactService: contact_service.Service, chatService: chat_service.Service, - communityService: community_service.ServiceInterface, messageService: message_service.Service) = + communityService: community_service.Service, messageService: message_service.Service) = self.chatContentModule[chatId] = chat_content_module.newModule(self, events, self.controller.getMySectionId(), chatId, belongToCommunity, isUsersListAvailable, contactService, chatService, communityService, messageService) @@ -70,7 +70,7 @@ proc removeSubmodule(self: Module, chatId: string) = self.chatContentModule.del(chatId) proc buildChatUI(self: Module, events: EventEmitter, contactService: contact_service.Service, - chatService: chat_service.Service, communityService: community_service.ServiceInterface, + chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service) = let types = @[ChatType.OneToOne, ChatType.Public, ChatType.PrivateGroupChat] let chats = self.controller.getChatDetailsForChatTypes(types) @@ -99,7 +99,7 @@ proc buildChatUI(self: Module, events: EventEmitter, contactService: contact_ser self.setActiveItemSubItem(selectedItemId, "") proc buildCommunityUI(self: Module, events: EventEmitter, contactService: contact_service.Service, - chatService: chat_service.Service, communityService: community_service.ServiceInterface, + chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service) = var selectedItemId = "" var selectedSubItemId = "" @@ -160,7 +160,7 @@ proc buildCommunityUI(self: Module, events: EventEmitter, contactService: contac self.setActiveItemSubItem(selectedItemId, selectedSubItemId) method load*(self: Module, events: EventEmitter, contactService: contact_service.Service, - chatService: chat_service.Service, communityService: community_service.ServiceInterface, + chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service) = self.controller.init() self.view.load() @@ -243,7 +243,7 @@ method createPublicChat*(self: Module, chatId: string) = self.controller.createPublicChat(chatId) method addNewChat*(self: Module, chatDto: ChatDto, events: EventEmitter, contactService: contact_service.Service, - chatService: chat_service.Service, communityService: community_service.ServiceInterface, + chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service) = let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0 let notificationsCount = chatDto.unviewedMentionsCount diff --git a/src/app/modules/main/chat_section/private_interfaces/module_access_interface.nim b/src/app/modules/main/chat_section/private_interfaces/module_access_interface.nim index 74143730bf..f9f193071e 100644 --- a/src/app/modules/main/chat_section/private_interfaces/module_access_interface.nim +++ b/src/app/modules/main/chat_section/private_interfaces/module_access_interface.nim @@ -2,7 +2,7 @@ import NimQml import ../../../../../app_service/service/contacts/service as contact_service import ../../../../../app_service/service/chat/service as chat_service -import ../../../../../app_service/service/community/service_interface as community_service +import ../../../../../app_service/service/community/service as community_service import ../../../../../app_service/service/message/service as message_service import eventemitter @@ -11,7 +11,7 @@ method delete*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") method load*(self: AccessInterface, events: EventEmitter, contactService: contact_service.Service, - chatService: chat_service.Service, communityService: community_service.ServiceInterface, + chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim b/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim index 936578d79c..fab05044d6 100644 --- a/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim +++ b/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim @@ -3,7 +3,7 @@ method activeItemSubItemSet*(self: AccessInterface, itemId: string, subItemId: s method addNewChat*(self: AccessInterface, chatDto: ChatDto, events: EventEmitter, contactService: contact_service.Service, chatService: chat_service.Service, - communityService: community_service.ServiceInterface, messageService: message_service.Service) {.base.} = + communityService: community_service.Service, messageService: message_service.Service) {.base.} = raise newException(ValueError, "No implementation available") method onChatMuted*(self: AccessInterface, chatId: string) {.base.} = diff --git a/src/app/modules/main/communities/controller.nim b/src/app/modules/main/communities/controller.nim index 008c5a9855..1997b6dd02 100644 --- a/src/app/modules/main/communities/controller.nim +++ b/src/app/modules/main/communities/controller.nim @@ -31,6 +31,140 @@ method init*[T](self: Controller[T]) = let communities = self.communityService.getAllCommunities() self.delegate.setAllCommunities(communities) + self.events.on(SIGNAL_COMMUNITY_MY_REQUEST_ADDED) do(e:Args): + let args = CommunityRequestArgs(e) + # TODO process the request being added + + self.events.on(SIGNAL_COMMUNITY_LEFT) do(e:Args): + let args = CommunityIdArgs(e) + # TODO process the community being left + + self.events.on(SIGNAL_COMMUNITY_CREATED) do(e:Args): + let args = CommunityArgs(e) + # TODO process the community being created + + self.events.on(SIGNAL_COMMUNITY_CHANNEL_CREATED) do(e:Args): + let args = CommunityChatArgs(e) + # TODO process the community chat being created + + self.events.on(SIGNAL_COMMUNITY_CHANNEL_EDITED) do(e:Args): + let args = CommunityChatArgs(e) + # TODO process the community chat being edited + + self.events.on(SIGNAL_COMMUNITY_CHANNEL_REORDERED) do(e:Args): + let args = CommunityChatOrderArgs(e) + # TODO process the community chat being reordered + + self.events.on(SIGNAL_COMMUNITY_CHANNEL_DELETED) do(e:Args): + let args = CommunityChatIdArgs(e) + # TODO process the community chat being deleted + + self.events.on(SIGNAL_COMMUNITY_CATEGORY_CREATED) do(e:Args): + let args = CommunityCategoryArgs(e) + # TODO process the community category being created + + self.events.on(SIGNAL_COMMUNITY_CATEGORY_EDITED) do(e:Args): + let args = CommunityCategoryArgs(e) + # TODO process the community category being edited + + self.events.on(SIGNAL_COMMUNITY_CATEGORY_DELETED) do(e:Args): + let args = CommunityCategoryArgs(e) + # TODO process the community category being deleted + method joinCommunity*[T](self: Controller[T], communityId: string): string = self.communityService.joinCommunity(communityId) +method requestToJoinCommunity*[T](self: Controller[T], communityId: string, ensName: string) = + self.communityService.requestToJoinCommunity(communityId, ensName) + +method leaveCommunity*[T](self: Controller[T], communityId: string) = + self.communityService.leaveCommunity(communityId) + +method createCommunity*[T]( + self: Controller[T], + name: string, + description: string, + access: int, + ensOnly: bool, + color: string, + imageUrl: string, + aX: int, aY: int, bX: int, bY: int) = + self.communityService.createCommunity( + name, + description, + access, + ensOnly, + color, + imageUrl, + aX, aY, bX, bY) + +method createCommunityChannel*[T]( + self: Controller[T], + communityId: string, + name: string, + description: string) = + self.communityService.createCommunityChannel(communityId, name, description) + +method editCommunityChannel*[T]( + self: Controller[T], + communityId: string, + channelId: string, + name: string, + description: string, + categoryId: string, + position: int) = + self.communityService.editCommunityChannel( + communityId, + channelId, + name, + description, + categoryId, + position) + +method reorderCommunityChat*[T]( + self: Controller[T], + communityId: string, + categoryId: string, + chatId: string, + position: int) = + self.communityService.reorderCommunityChat( + communityId, + categoryId, + chatId, + position) + +method deleteCommunityChat*[T]( + self: Controller[T], + communityId: string, + chatId: string) = + self.communityService.deleteCommunityChat(communityId, chatId) + +method createCommunityCategory*[T]( + self: Controller[T], + communityId: string, + name: string, + channels: seq[string]) = + self.communityService.createCommunityCategory(communityId, name, channels) + +method editCommunityCategory*[T]( + self: Controller[T], + communityId: string, + categoryId: string, + name: string, + channels: seq[string]) = + self.communityService.editCommunityCategory(communityId, categoryId, name, channels) + +method deleteCommunityCategory*[T]( + self: Controller[T], + communityId: string, + categoryId: string) = + self.communityService.deleteCommunityCategory(communityId, categoryId) + +method requestCommunityInfo*[T](self: Controller[T], communityId: string) = + self.communityService.requestCommunityInfo(communityId) + +method importCommunity*[T](self: Controller[T], communityKey: string) = + self.communityService.importCommunity(communityKey) + +method exportCommunity*[T](self: Controller[T], communityId: string): string = + self.communityService.exportCommunity(communityId) diff --git a/src/app/modules/main/communities/controller_interface.nim b/src/app/modules/main/communities/controller_interface.nim index aa301c59ac..9aa7735abb 100644 --- a/src/app/modules/main/communities/controller_interface.nim +++ b/src/app/modules/main/communities/controller_interface.nim @@ -13,6 +13,45 @@ method init*(self: AccessInterface) {.base.} = method joinCommunity*(self: AccessInterface, communityId: string): string {.base.} = raise newException(ValueError, "No implementation available") +method requestToJoinCommunity*(self: AccessInterface, communityId: string, ensName: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method leaveCommunity*(self: AccessInterface, communityId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method createCommunity*(self: AccessInterface, name: string, description: string, access: int, ensOnly: bool, color: string, imageUrl: string, aX: int, aY: int, bX: int, bY: int) {.base.} = + raise newException(ValueError, "No implementation available") + +method createCommunityChannel*(self: AccessInterface, communityId: string, name: string, description: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method editCommunityChannel*(self: AccessInterface, communityId: string, chatId: string, name: string, description: string, categoryId: string, position: int) {.base.} = + raise newException(ValueError, "No implementation available") + +method reorderCommunityChat*(self: AccessInterface, communityId: string, categoryId: string, chatId: string, position: int) {.base.} = + raise newException(ValueError, "No implementation available") + +method deleteCommunityChat*(self: AccessInterface, communityId: string, chatId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method createCommunityCategory*(self: AccessInterface, communityId: string, name: string, channels: seq[string]) {.base.} = + raise newException(ValueError, "No implementation available") + +method editCommunityCategory*(self: AccessInterface, communityId: string, categoryId: string, name: string, channels: seq[string]) {.base.} = + raise newException(ValueError, "No implementation available") + +method deleteCommunityCategory*(self: AccessInterface, communityId: string, categoryId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method requestCommunityInfo*(self: AccessInterface, communityId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method importCommunity*(self: AccessInterface, communityKey: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method exportCommunity*(self: AccessInterface, communityId: string) {.base.} = + raise newException(ValueError, "No implementation available") + type ## Abstract class (concept) which must be implemented by object/s used in this ## module. diff --git a/src/app/modules/main/controller.nim b/src/app/modules/main/controller.nim index f92eafde22..78c2bcc3b8 100644 --- a/src/app/modules/main/controller.nim +++ b/src/app/modules/main/controller.nim @@ -25,7 +25,7 @@ type keychainService: keychain_service.Service accountsService: accounts_service.ServiceInterface chatService: chat_service.Service - communityService: community_service.ServiceInterface + communityService: community_service.Service messageService: message_service.Service contactsService: contacts_service.Service activeSectionId: string @@ -36,7 +36,7 @@ proc newController*(delegate: io_interface.AccessInterface, keychainService: keychain_service.Service, accountsService: accounts_service.ServiceInterface, chatService: chat_service.Service, - communityService: community_service.ServiceInterface, + communityService: community_service.Service, contactsService: contacts_service.Service, messageService: message_service.Service): Controller = diff --git a/src/app/modules/main/controller_interface.nim b/src/app/modules/main/controller_interface.nim index fbb9ae549e..291403bbd6 100644 --- a/src/app/modules/main/controller_interface.nim +++ b/src/app/modules/main/controller_interface.nim @@ -1,5 +1,5 @@ import ../shared_models/section_item -import ../../../app_service/service/community/service_interface as community_service +import ../../../app_service/service/community/service as community_service type AccessInterface* {.pure inheritable.} = ref object of RootObj diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index 367eaed7da..1df160e037 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -395,7 +395,7 @@ method communityJoined*[T]( events: EventEmitter, contactsService: contacts_service.Service, chatService: chat_service.Service, - communityService: community_service.ServiceInterface, + communityService: community_service.Service, messageService: message_service.Service ) = self.communitySectionsModule[community.id] = chat_section_module.newModule( diff --git a/src/app/modules/main/private_interfaces/module_controller_delegate_interface.nim b/src/app/modules/main/private_interfaces/module_controller_delegate_interface.nim index 7256234cb1..7f60eea781 100644 --- a/src/app/modules/main/private_interfaces/module_controller_delegate_interface.nim +++ b/src/app/modules/main/private_interfaces/module_controller_delegate_interface.nim @@ -18,5 +18,5 @@ method enableSection*(self: AccessInterface, sectionType: SectionType) {.base.} method disableSection*(self: AccessInterface, sectionType: SectionType) {.base.} = raise newException(ValueError, "No implementation available") -method communityJoined*(self: AccessInterface, community: CommunityDto, events: EventEmitter, contactsService: contacts_service.Service, chatService: chat_service.Service, communityService: community_service.ServiceInterface, messageService: message_service.Service) {.base.} = +method communityJoined*(self: AccessInterface, community: CommunityDto, events: EventEmitter, contactsService: contacts_service.Service, chatService: chat_service.Service, communityService: community_service.Service, messageService: message_service.Service) {.base.} = raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app_service/service/community/dto/community.nim b/src/app_service/service/community/dto/community.nim index 65ac6b35c6..6c25c01f7c 100644 --- a/src/app_service/service/community/dto/community.nim +++ b/src/app_service/service/community/dto/community.nim @@ -56,7 +56,15 @@ type CommunityDto* = object requestedToJoinAt*: int64 isMember*: bool muted*: bool - + +type CommunityMembershipRequestDto* = object + id*: string + publicKey*: string + chatId*: string + communityId*: string + state*: int + our*: string + proc toPermission(jsonObj: JsonNode): Permission = result = Permission() discard jsonObj.getProp("access", result.access) @@ -73,7 +81,7 @@ proc toImages(jsonObj: JsonNode): Images = if(jsonObj.getProp("thumbnail", thumbnailObj)): discard thumbnailObj.getProp("uri", result.thumbnail) -proc toChat(jsonObj: JsonNode): Chat = +proc toChat*(jsonObj: JsonNode): Chat = result = Chat() discard jsonObj.getProp("id", result.id) discard jsonObj.getProp("name", result.name) @@ -87,13 +95,14 @@ proc toChat(jsonObj: JsonNode): Chat = discard jsonObj.getProp("position", result.position) discard jsonObj.getProp("categoryID", result.categoryId) -proc toCategory(jsonObj: JsonNode): Category = +proc toCategory*(jsonObj: JsonNode): Category = result = Category() - discard jsonObj.getProp("id", result.id) + if (not jsonObj.getProp("category_id", result.id)): + discard jsonObj.getProp("id", result.id) discard jsonObj.getProp("name", result.name) discard jsonObj.getProp("position", result.position) -proc toMember(jsonObj: JsonNode, memberId: string): Member = +proc toMember*(jsonObj: JsonNode, memberId: string): Member = # Mapping this DTO is not strightforward since only keys are used for id. We # handle it a bit different. result = Member() @@ -144,6 +153,15 @@ proc toCommunityDto*(jsonObj: JsonNode): CommunityDto = discard jsonObj.getProp("isMember", result.isMember) discard jsonObj.getProp("muted", result.muted) +proc toCommunityMembershipRequestDto*(jsonObj: JsonNode): CommunityMembershipRequestDto = + result = CommunityMembershipRequestDto() + discard jsonObj.getProp("id", result.id) + discard jsonObj.getProp("publicKey", result.publicKey) + discard jsonObj.getProp("chatId", result.chatId) + discard jsonObj.getProp("state", result.state) + discard jsonObj.getProp("communityId", result.communityId) + discard jsonObj.getProp("our", result.our) + proc parseCommunities*(response: RpcResponse[JsonNode]): seq[CommunityDto] = result = map(response.result.getElems(), proc(x: JsonNode): CommunityDto = x.toCommunityDto()) \ No newline at end of file diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index ed627673da..494cb85d01 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -1,14 +1,11 @@ -import Tables, json, sequtils, std/algorithm, strformat, chronicles +import NimQml, Tables, json, sequtils, std/algorithm, strformat, chronicles, json_serialization import eventemitter -import service_interface, ./dto/community - -import ../chat/service as chat_service +import ./dto/community as community_dto +export community_dto import status/statusgo_backend_new/communities as status_go -export service_interface - logScope: topics = "community-service" @@ -17,147 +14,435 @@ type CommunityArgs* = ref object of Args community*: CommunityDto + CommunityChatArgs* = ref object of Args + chat*: Chat + + CommunityIdArgs* = ref object of Args + communityId*: string + + CommunityChatIdArgs* = ref object of Args + communityId*: string + chatId*: string + + CommunityRequestArgs* = ref object of Args + communityRequest*: CommunityMembershipRequestDto + + CommunityChatOrderArgs* = ref object of Args + communityId*: string + chatId*: string + categoryId*: string + position*: int + + CommunityCategoryArgs* = ref object of Args + communityId*: string + category*: Category + channels*: seq[string] + # Signals which may be emitted by this service: const SIGNAL_COMMUNITY_JOINED* = "SIGNAL_COMMUNITY_JOINED" +const SIGNAL_COMMUNITY_MY_REQUEST_ADDED* = "SIGNAL_COMMUNITY_MY_REQUEST_ADDED" +const SIGNAL_COMMUNITY_LEFT* = "SIGNAL_COMMUNITY_LEFT" +const SIGNAL_COMMUNITY_CREATED* = "SIGNAL_COMMUNITY_CREATED" +const SIGNAL_COMMUNITY_CHANNEL_CREATED* = "SIGNAL_COMMUNITY_CHANNEL_CREATED" +const SIGNAL_COMMUNITY_CHANNEL_EDITED* = "SIGNAL_COMMUNITY_CHANNEL_EDITED" +const SIGNAL_COMMUNITY_CHANNEL_REORDERED* = "SIGNAL_COMMUNITY_CHANNEL_REORDERED" +const SIGNAL_COMMUNITY_CHANNEL_DELETED* = "SIGNAL_COMMUNITY_CHANNEL_DELETED" +const SIGNAL_COMMUNITY_CATEGORY_CREATED* = "SIGNAL_COMMUNITY_CATEGORY_CREATED" +const SIGNAL_COMMUNITY_CATEGORY_EDITED* = "SIGNAL_COMMUNITY_CATEGORY_EDITED" +const SIGNAL_COMMUNITY_CATEGORY_DELETED* = "SIGNAL_COMMUNITY_CATEGORY_DELETED" -type - Service* = ref object of service_interface.ServiceInterface - events: EventEmitter - joinedCommunities: Table[string, CommunityDto] # [community_id, CommunityDto] - allCommunities: Table[string, CommunityDto] # [community_id, CommunityDto] +QtObject: + type + Service* = ref object of QObject + events: EventEmitter + joinedCommunities: Table[string, CommunityDto] # [community_id, CommunityDto] + allCommunities: Table[string, CommunityDto] # [community_id, CommunityDto] + myCommunityRequests*: seq[CommunityMembershipRequestDto] -# Forward declaration -method loadAllCommunities(self: Service): seq[CommunityDto] -method loadJoinedComunities(self: Service): seq[CommunityDto] + # Forward declaration + proc loadAllCommunities(self: Service): seq[CommunityDto] + proc loadJoinedComunities(self: Service): seq[CommunityDto] + proc loadMyPendingRequestsToJoin*(self: Service) -method delete*(self: Service) = - discard + proc delete*(self: Service) = + discard -proc newService*(events: EventEmitter): Service = - result = Service() - result.events = events - result.joinedCommunities = initTable[string, CommunityDto]() - result.allCommunities = initTable[string, CommunityDto]() + proc newService*(events: EventEmitter): Service = + result = Service() + result.events = events + result.joinedCommunities = initTable[string, CommunityDto]() + result.allCommunities = initTable[string, CommunityDto]() + result.myCommunityRequests = @[] -method init*(self: Service) = - try: - let joinedCommunities = self.loadJoinedComunities() - for community in joinedCommunities: - self.joinedCommunities[community.id] = community + proc init*(self: Service) = + try: + let joinedCommunities = self.loadJoinedComunities() + for community in joinedCommunities: + self.joinedCommunities[community.id] = community - let allCommunities = self.loadAllCommunities() - for community in allCommunities: - self.allCommunities[community.id] = community + let allCommunities = self.loadAllCommunities() + for community in allCommunities: + self.allCommunities[community.id] = community - except Exception as e: - let errDesription = e.msg - error "error: ", errDesription - return + self.loadMyPendingRequestsToJoin() -method loadAllCommunities(self: Service): seq[CommunityDto] = - let response = status_go.getAllCommunities() - return parseCommunities(response) - -method loadJoinedComunities(self: Service): seq[CommunityDto] = - let response = status_go.getJoinedComunities() - return parseCommunities(response) - -method getJoinedCommunities*(self: Service): seq[CommunityDto] = - return toSeq(self.joinedCommunities.values) - -method getAllCommunities*(self: Service): seq[CommunityDto] = - return toSeq(self.allCommunities.values) - -method getCommunityById*(self: Service, communityId: string): CommunityDto = - if(not self.joinedCommunities.hasKey(communityId)): - error "error: requested community doesn't exists" - return - - return self.joinedCommunities[communityId] - -method getCommunityIds*(self: Service): seq[string] = - return toSeq(self.joinedCommunities.keys) - -proc sortAsc[T](t1, t2: T): int = - if(t1.position > t2.position): - return 1 - elif (t1.position < t2.position): - return -1 - else: - return 0 - -proc sortDesc[T](t1, t2: T): int = - if(t1.position < t2.position): - return 1 - elif (t1.position > t2.position): - return -1 - else: - return 0 - -method getCategories*(self: Service, communityId: string, order: SortOrder = SortOrder.Ascending): seq[Category] = - if(not self.joinedCommunities.contains(communityId)): - error "trying to get community categories for an unexisting community id" - return - - result = self.joinedCommunities[communityId].categories - if(order == SortOrder.Ascending): - result.sort(sortAsc[Category]) - else: - result.sort(sortDesc[Category]) - -method getChats*(self: Service, communityId: string, categoryId = "", order = SortOrder.Ascending): seq[Chat] = - ## By default returns chats which don't belong to any category, for passed `communityId`. - ## If `categoryId` is set then only chats belonging to that category for passed `communityId` will be returned. - ## Returned chats are sorted by position following set `order` parameter. - if(not self.joinedCommunities.contains(communityId)): - error "trying to get community chats for an unexisting community id" - return - - for chat in self.joinedCommunities[communityId].chats: - if(chat.categoryId != categoryId): - continue - - result.add(chat) - - if(order == SortOrder.Ascending): - result.sort(sortAsc[Chat]) - else: - result.sort(sortDesc[Chat]) - -method getAllChats*(self: Service, communityId: string, order = SortOrder.Ascending): seq[Chat] = - ## Returns all chats belonging to the community with passed `communityId`, sorted by position. - ## Returned chats are sorted by position following set `order` parameter. - if(not self.joinedCommunities.contains(communityId)): - error "trying to get all community chats for an unexisting community id" - return - - result = self.joinedCommunities[communityId].chats - - if(order == SortOrder.Ascending): - result.sort(sortAsc[Chat]) - else: - result.sort(sortDesc[Chat]) - -method isUserMemberOfCommunity*(self: Service, communityId: string): bool = - if(not self.allCommunities.contains(communityId)): - return false - return self.allCommunities[communityId].joined and self.allCommunities[communityId].isMember - -method userCanJoin*(self: Service, communityId: string): bool = - if(not self.allCommunities.contains(communityId)): - return false - return self.allCommunities[communityId].canJoin - -method joinCommunity*(self: Service, communityId: string): string = - result = "" - try: - if (not self.userCanJoin(communityId) or self.isUserMemberOfCommunity(communityId)): + except Exception as e: + let errDesription = e.msg + error "error: ", errDesription return - discard status_go.joinCommunity(communityId) - var community = self.allCommunities[communityId] - self.joinedCommunities[communityId] = community - self.events.emit(SIGNAL_COMMUNITY_JOINED, CommunityArgs(community: community)) - except Exception as e: - error "Error joining the community", msg = e.msg - result = fmt"Error joining the community: {e.msg}" \ No newline at end of file + proc loadAllCommunities(self: Service): seq[CommunityDto] = + let response = status_go.getAllCommunities() + return parseCommunities(response) + + proc loadJoinedComunities(self: Service): seq[CommunityDto] = + let response = status_go.getJoinedComunities() + return parseCommunities(response) + + proc getJoinedCommunities*(self: Service): seq[CommunityDto] = + return toSeq(self.joinedCommunities.values) + + proc getAllCommunities*(self: Service): seq[CommunityDto] = + return toSeq(self.allCommunities.values) + + proc getCommunityById*(self: Service, communityId: string): CommunityDto = + if(not self.joinedCommunities.hasKey(communityId)): + error "error: requested community doesn't exists" + return + + return self.joinedCommunities[communityId] + + proc getCommunityIds*(self: Service): seq[string] = + return toSeq(self.joinedCommunities.keys) + + proc sortAsc[T](t1, t2: T): int = + if(t1.position > t2.position): + return 1 + elif (t1.position < t2.position): + return -1 + else: + return 0 + + proc sortDesc[T](t1, t2: T): int = + if(t1.position < t2.position): + return 1 + elif (t1.position > t2.position): + return -1 + else: + return 0 + + proc getCategories*(self: Service, communityId: string, order: SortOrder = SortOrder.Ascending): seq[Category] = + if(not self.joinedCommunities.contains(communityId)): + error "trying to get community categories for an unexisting community id" + return + + result = self.joinedCommunities[communityId].categories + if(order == SortOrder.Ascending): + result.sort(sortAsc[Category]) + else: + result.sort(sortDesc[Category]) + + proc getChats*(self: Service, communityId: string, categoryId = "", order = SortOrder.Ascending): seq[Chat] = + ## By default returns chats which don't belong to any category, for passed `communityId`. + ## If `categoryId` is set then only chats belonging to that category for passed `communityId` will be returned. + ## Returned chats are sorted by position following set `order` parameter. + if(not self.joinedCommunities.contains(communityId)): + error "trying to get community chats for an unexisting community id" + return + + for chat in self.joinedCommunities[communityId].chats: + if(chat.categoryId != categoryId): + continue + + result.add(chat) + + if(order == SortOrder.Ascending): + result.sort(sortAsc[Chat]) + else: + result.sort(sortDesc[Chat]) + + proc getAllChats*(self: Service, communityId: string, order = SortOrder.Ascending): seq[Chat] = + ## Returns all chats belonging to the community with passed `communityId`, sorted by position. + ## Returned chats are sorted by position following set `order` parameter. + if(not self.joinedCommunities.contains(communityId)): + error "trying to get all community chats for an unexisting community id" + return + + result = self.joinedCommunities[communityId].chats + + if(order == SortOrder.Ascending): + result.sort(sortAsc[Chat]) + else: + result.sort(sortDesc[Chat]) + + proc isUserMemberOfCommunity*(self: Service, communityId: string): bool = + if(not self.allCommunities.contains(communityId)): + return false + return self.allCommunities[communityId].joined and self.allCommunities[communityId].isMember + + proc userCanJoin*(self: Service, communityId: string): bool = + if(not self.allCommunities.contains(communityId)): + return false + return self.allCommunities[communityId].canJoin + + proc joinCommunity*(self: Service, communityId: string): string = + result = "" + try: + if (not self.userCanJoin(communityId) or self.isUserMemberOfCommunity(communityId)): + return + discard status_go.joinCommunity(communityId) + var community = self.allCommunities[communityId] + self.joinedCommunities[communityId] = community + + self.events.emit(SIGNAL_COMMUNITY_JOINED, CommunityArgs(community: community)) + except Exception as e: + error "Error joining the community", msg = e.msg + result = fmt"Error joining the community: {e.msg}" + + proc requestToJoinCommunity*(self: Service, communityId: string, ensName: string) = + try: + let response = status_go.requestToJoinCommunity(communityId, ensName) + + if response.result{"requestsToJoinCommunity"} != nil and response.result{"requestsToJoinCommunity"}.kind != JNull: + for jsonCommunityReqest in response.result["requestsToJoinCommunity"]: + let communityRequest = jsonCommunityReqest.toCommunityMembershipRequestDto() + self.myCommunityRequests.add(communityRequest) + self.events.emit(SIGNAL_COMMUNITY_MY_REQUEST_ADDED, CommunityRequestArgs(communityRequest: communityRequest)) + except Exception as e: + error "Error requesting to join the community", msg = e.msg, communityId, ensName + + proc loadMyPendingRequestsToJoin*(self: Service) = + try: + let response = status_go.myPendingRequestsToJoin() + + if response.result.kind != JNull: + for jsonCommunityReqest in response.result: + let communityRequest = jsonCommunityReqest.toCommunityMembershipRequestDto() + self.myCommunityRequests.add(communityRequest) + self.events.emit(SIGNAL_COMMUNITY_MY_REQUEST_ADDED, CommunityRequestArgs(communityRequest: communityRequest)) + except Exception as e: + error "Error fetching my community requests", msg = e.msg + + proc leaveCommunity*(self: Service, communityId: string) = + try: + discard status_go.leaveCommunity(communityId) + + self.events.emit(SIGNAL_COMMUNITY_LEFT, CommunityIdArgs(communityId: communityId)) + except Exception as e: + error "Error leaving community", msg = e.msg, communityId + + proc createCommunity*( + self: Service, + name: string, + description: string, + access: int, + ensOnly: bool, + color: string, + imageUrl: string, + aX: int, aY: int, bX: int, bY: int) = + try: + let response = status_go.createCommunity( + name, + description, + access, + ensOnly, + color, + imageUrl, + aX, aY, bX, bY) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error creating community: " & error.message) + + if response.result != nil and response.result.kind != JNull: + let community = response.result["communities"][0].toCommunityDto() + self.events.emit(SIGNAL_COMMUNITY_CREATED, CommunityArgs(community: community)) + except Exception as e: + error "Error creating community", msg = e.msg + raise newException(RpcException, "Error creating community: " & e.msg) + + proc createCommunityChannel*( + self: Service, + communityId: string, + name: string, + description: string) = + try: + let response = status_go.createCommunityChannel(communityId, name, description) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error creating community channel: " & error.message) + + if response.result != nil and response.result.kind != JNull: + let chat = response.result["chats"][0].toChat() + self.events.emit(SIGNAL_COMMUNITY_CHANNEL_CREATED, CommunityChatArgs(chat: chat)) + except Exception as e: + error "Error creating community channel", msg = e.msg, communityId, name, description + raise newException(RpcException, "Error creating community channel: " & e.msg) + + proc editCommunityChannel*( + self: Service, + communityId: string, + channelId: string, + name: string, + description: string, + categoryId: string, + position: int) = + try: + let response = status_go.editCommunityChannel( + communityId, + channelId, + name, + description, + categoryId, + position) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error editing community channel: " & error.message) + + if response.result != nil and response.result.kind != JNull: + let chat = response.result["chats"][0].toChat() + self.events.emit(SIGNAL_COMMUNITY_CHANNEL_EDITED, CommunityChatArgs(chat: chat)) + except Exception as e: + error "Error editing community channel", msg = e.msg, communityId, channelId + raise newException(RpcException, "Error editing community channel: " & e.msg) + + proc reorderCommunityChat*( + self: Service, + communityId: string, + categoryId: string, + chatId: string, + position: int) = + try: + let response = status_go.reorderCommunityChat( + communityId, + categoryId, + chatId, + position) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error reordering community channel: " & error.message) + + self.events.emit(SIGNAL_COMMUNITY_CHANNEL_REORDERED, + CommunityChatOrderArgs( + communityId: communityId, + categoryId: categoryId, + chatId: chatId, + position: position + ) + ) + except Exception as e: + error "Error reordering community channel", msg = e.msg, communityId, chatId, position + raise newException(RpcException, "Error reordering community channel: " & e.msg) + + proc deleteCommunityChat*(self: Service, communityId: string, chatId: string) = + try: + let response = status_go.deleteCommunityChat(communityId, chatId) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error deleting community chat: " & error.message) + + self.events.emit(SIGNAL_COMMUNITY_CHANNEL_DELETED, + CommunityChatIdArgs( + communityId: communityId, + chatId: chatId + ) + ) + except Exception as e: + error "Error deleting community channel", msg = e.msg, communityId, chatId + raise newException(RpcException, "Error deleting community channel: " & e.msg) + + proc createCommunityCategory*( + self: Service, + communityId: string, + name: string, + channels: seq[string]) = + try: + let response = status_go.createCommunityCategory(communityId, name, channels) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error creating community category: " & error.message) + + if response.result != nil and response.result.kind != JNull: + for k, v in response.result["communityChanges"].getElems()[0]["categoriesAdded"].pairs(): + let category = v.toCategory() + self.events.emit(SIGNAL_COMMUNITY_CATEGORY_CREATED, + CommunityCategoryArgs(communityId: communityId, category: category, channels: channels)) + + except Exception as e: + error "Error creating community category", msg = e.msg, communityId, name + raise newException(RpcException, "Error creating community category: " & e.msg) + + proc editCommunityCategory*( + self: Service, + communityId: string, + categoryId: string, + name: string, + channels: seq[string]) = + try: + let response = status_go.editCommunityCategory(communityId, categoryId, name, channels) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error creating community category: " & error.message) + + if response.result != nil and response.result.kind != JNull: + for k, v in response.result["communityChanges"].getElems()[0]["categoriesModified"].pairs(): + let category = v.toCategory() + self.events.emit(SIGNAL_COMMUNITY_CATEGORY_EDITED, + CommunityCategoryArgs(communityId: communityId, category: category, channels: channels)) + except Exception as e: + error "Error creating community category", msg = e.msg, communityId, name + raise newException(RpcException, "Error creating community category: " & e.msg) + + proc deleteCommunityCategory*(self: Service, communityId: string, categoryId: string) = + try: + let response = status_go.deleteCommunityCategory(communityId, categoryId) + + if response.error != nil: + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, "Error deleting community category: " & error.message) + + self.events.emit(SIGNAL_COMMUNITY_CATEGORY_DELETED, + CommunityCategoryArgs( + communityId: communityId, + category: Category(id: categoryId) + ) + ) + except Exception as e: + error "Error deleting community category", msg = e.msg, communityId, categoryId + raise newException(RpcException, "Error deleting community category: " & e.msg) + + proc requestCommunityInfo*(self: Service, communityId: string) = + try: + let response = status_go.requestCommunityInfo(communityId) + if (response.error != nil): + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, fmt"Error requesting community info: {error.message}") + except Exception as e: + error "Error requesting community info", msg = e.msg, communityId + raise newException(RpcException, "Error requesting community info: " & e.msg) + + + proc importCommunity*(self: Service, communityKey: string) = + try: + let response = status_go.importCommunity(communityKey) + if (response.error != nil): + let error = Json.decode($response.error, RpcError) + raise newException(RpcException, fmt"Error importing the community: {error.message}") + except Exception as e: + error "Error requesting community info", msg = e.msg + raise newException(RpcException, "Error requesting community info: " & e.msg) + + proc exportCommunity*(self: Service, communityId: string): string = + try: + let response = status_go.exportCommunity(communityId) + if (response.result != nil): + return response.result.getStr + except Exception as e: + error "Error exporting community", msg = e.msg + raise newException(RpcException, "Error exporting community: " & e.msg) \ No newline at end of file diff --git a/src/app_service/service/community/service_interface.nim b/src/app_service/service/community/service_interface.nim index f46d1cf8fa..8730c0f485 100644 --- a/src/app_service/service/community/service_interface.nim +++ b/src/app_service/service/community/service_interface.nim @@ -46,4 +46,46 @@ method userCanJoin*(self: ServiceInterface, communityId: string) {.base.} = raise newException(ValueError, "No implementation available") method joinCommunity*(self: ServiceInterface, communityId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method requestToJoinCommunity*(self: ServiceInterface, communityId: string, ensName: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method loadMyPendingRequestsToJoin*(self: ServiceInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method leaveCommunity*(self: ServiceInterface, communityId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method createCommunity*(self: ServiceInterface, name: string, description: string, access: int, ensOnly: bool, color: string, imageUrl: string, aX: int, aY: int, bX: int, bY: int) {.base.} = + raise newException(ValueError, "No implementation available") + +method createCommunityChannel*(self: ServiceInterface, communityId: string, name: string, description: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method editCommunityChannel*(self: ServiceInterface, communityId: string, channelId: string, name: string, description: string, categoryId: string, position: int) {.base.} = + raise newException(ValueError, "No implementation available") + +method reorderCommunityChat*(self: ServiceInterface, communityId: string, categoryId: string, chatId: string, position: int) {.base.} = + raise newException(ValueError, "No implementation available") + +method deleteCommunityChat*(self: ServiceInterface, communityId: string, chatId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method createCommunityCategory*(self: ServiceInterface, communityId: string, name: string, channels: seq[string]) {.base.} = + raise newException(ValueError, "No implementation available") + +method editCommunityCategory*(self: ServiceInterface, communityId: string, categoryId: string, name: string, channels: seq[string]) {.base.} = + raise newException(ValueError, "No implementation available") + +method deleteCommunityCategory*(self: ServiceInterface, communityId: string, categoryId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method requestCommunityInfo*(self: ServiceInterface, communityId: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method importCommunity*(self: ServiceInterface, communityKey: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method exportCommunity*(self: ServiceInterface, communityId: string) {.base.} = raise newException(ValueError, "No implementation available") \ No newline at end of file