fix(@desktop/chat): Fix moving channels between categories

Fix #7422
This commit is contained in:
Michal Iskierko 2022-10-04 16:21:19 +02:00 committed by Michał Iskierko
parent ce178da4b4
commit 060072da2d
6 changed files with 113 additions and 29 deletions

View File

@ -159,7 +159,7 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_COMMUNITY_CATEGORY_REORDERED) do(e:Args):
let args = CommunityChatOrderArgs(e)
if (args.communityId == self.sectionId):
self.delegate.onReorderChatOrCategory(args.categoryId, args.position)
self.delegate.onReorderChatOrCategory(args.categoryId, args.position, args.categoryId)
self.events.on(SIGNAL_COMMUNITY_CATEGORY_NAME_EDITED) do(e:Args):
let args = CommunityCategoryArgs(e)
@ -169,7 +169,7 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_COMMUNITY_CHANNEL_REORDERED) do(e:Args):
let args = CommunityChatOrderArgs(e)
if (args.communityId == self.sectionId):
self.delegate.onReorderChatOrCategory(args.chatId, args.position)
self.delegate.onReorderChatOrCategory(args.chatId, args.position, args.categoryId)
self.events.on(SIGNAL_RELOAD_MESSAGES) do(e: Args):
let args = ReloadMessagesArgs(e)

View File

@ -121,7 +121,7 @@ method onGroupChatDetailsUpdated*(self: AccessInterface, chatId: string, newName
method onCommunityChannelEdited*(self: AccessInterface, chat: ChatDto) {.base.} =
raise newException(ValueError, "No implementation available")
method onReorderChatOrCategory*(self: AccessInterface, chatOrCatId: string, position: int) {.base.} =
method onReorderChatOrCategory*(self: AccessInterface, chatOrCatId: string, position: int, newCategoryIdForChat: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityCategoryCreated*(self: AccessInterface, category: Category, chats: seq[ChatDto]) {.base.} =

View File

@ -173,8 +173,15 @@ QtObject:
idx.inc
return -1
proc removeItemById*(self: Model, id: string) =
let idx = self.getItemIdxById(id)
proc getItemIdxByCategory*(self: Model, category: string): int =
var idx = 0
for it in self.items:
if(it.categoryId == category):
return idx
idx.inc
return -1
proc removeItemByIndex(self: Model, idx: int) =
if idx == -1:
return
@ -187,6 +194,23 @@ QtObject:
self.countChanged()
proc removeItemById*(self: Model, id: string) =
let idx = self.getItemIdxById(id)
if idx != -1:
self.removeItemByIndex(idx)
proc removeItemOrSubitemById*(self: Model, id: string) =
let idx = self.getItemIdxById(id)
if idx != -1:
self.removeItemByIndex(idx)
return
else:
for it in self.items:
let subItemIndex = it.subItems.getItemIdxById(id)
if subItemIndex != -1:
it.subItems.removeItemById(id)
return
proc getItemAtIndex*(self: Model, index: int): Item =
if(index < 0 or index >= self.items.len):
return
@ -204,6 +228,17 @@ QtObject:
if(it.id == id):
return it
proc getCategoryAndPosition*(self: Model, id: string): (string, int) =
let item = self.getItemById(id)
if (not item.isNil):
return ("", item.position)
else:
for it in self.items:
let item = it.subItems.getItemById(id)
if(not item.isNil):
return (it.categoryId, item.position)
return ("", -1)
proc getSubItemById*(self: Model, id: string): SubItem =
for it in self.items:
let item = it.subItems.getItemById(id)
@ -234,6 +269,14 @@ QtObject:
if(found):
return jsonObj
proc getItemOrSubItemByIdAsBase*(self: Model, id: string): BaseItem =
for it in self.items:
if(it.id == id):
return BaseItem(it)
let subItem = it.subItems.getItemById(id)
if (not subItem.isNil):
return BaseItem(subItem)
proc muteUnmuteItemOrSubItemById*(self: Model, id: string, mute: bool) =
for i in 0 ..< self.items.len:
if(self.items[i].id == id):
@ -353,24 +396,64 @@ QtObject:
result.hasNotifications = result.hasNotifications or self.items[i].BaseItem.hasUnreadMessages
result.notificationsCount = result.notificationsCount + self.items[i].BaseItem.notificationsCount
proc reorderModel*(self: Model, id: string, position: int) =
let index = self.getItemIdxById(id)
if index == -1:
return
if(self.items[index].BaseItem.position == position):
return
self.items[index].BaseItem.position = position
let modelIndex = self.createIndex(index, 0, nil)
self.dataChanged(modelIndex, modelIndex, @[ModelRole.Position.int])
proc reorderSubModel(self: Model, chatId: string, position: int) =
for it in self.items:
if(it.subItems.getCount() > 0):
it.subItems.reorder(chatId, position)
proc reorder*(self: Model, chatOrCategoryId: string, position: int) =
let index = self.getItemIdxById(chatOrCategoryId)
if(index == -1):
self.reorderSubModel(chatOrCategoryId, position)
proc moveItemFromTo(self: Model, chatId: string, oldCategoryId: string, oldPosition: int, newCategoryId: string, newPosition: int) =
if (oldCategoryId == newCategoryId):
# move position only
if (oldCategoryId == ""):
self.reorderModel(chatId, newPosition)
else:
self.reorderSubModel(chatId, newPosition)
else:
# move between categories
let baseItemToMove = self.getItemOrSubItemByIdAsBase(chatId)
var oldCategoryItem = self.getItemById(oldCategoryId)
if not oldCategoryItem.isNil:
oldCategoryItem.subItems().removeItemById(chatId)
else:
self.removeItemById(chatId)
if newCategoryId != "":
let channelItem = initSubItem(baseItemToMove.id, newCategoryId, baseItemToMove.name, baseItemToMove.icon,
baseItemToMove.color, baseItemToMove.emoji, baseItemToMove.description, baseItemToMove.type,
baseItemToMove.amIChatAdmin, baseItemToMove.lastMessageTimestamp, baseItemToMove.hasUnreadMessages,
baseItemToMove.notificationsCount, baseItemToMove.muted, baseItemToMove.blocked,
baseItemToMove.active, newPosition)
let newCategoryItem = self.getItemById(newCategoryId)
newCategoryItem.appendSubItem(channelItem)
else:
let channelItem = initItem(baseItemToMove.id, baseItemToMove.name, baseItemToMove.icon,
baseItemToMove.color, baseItemToMove.emoji, baseItemToMove.description, baseItemToMove.type, baseItemToMove.amIChatAdmin,
baseItemToMove.lastMessageTimestamp, baseItemToMove.hasUnreadMessages, baseItemToMove.notificationsCount,
baseItemToMove.muted, baseItemToMove.blocked, baseItemToMove.active, newPosition, categoryId="")
self.appendItem(channelItem)
proc reorder*(self: Model, chatOrCategoryId: string, position: int, newCategoryIdForChat: string) =
let indexOfCategoryItem = self.getItemIdxByCategory(chatOrCategoryId) # chats have empty categoryId
if(indexOfCategoryItem == -1):
# reorder chat
let (currentCat, currentPos) = self.getCategoryAndPosition(chatOrCategoryId)
if (currentPos != -1):
self.moveItemFromTo(chatOrCategoryId, currentCat, currentPos, newCategoryIdForChat, position)
return
if(self.items[index].BaseItem.position == position):
return
self.items[index].BaseItem.position = position
let modelIndex = self.createIndex(index, 0, nil)
self.dataChanged(modelIndex, modelIndex, @[ModelRole.Position.int])
# reorder categories
self.reorderModel(chatOrCategoryId, position)
proc clearItems*(self: Model) =
self.beginResetModel()

View File

@ -433,7 +433,7 @@ method addNewChat*(
if chatDto.categoryId.len == 0:
let item = initItem(chatDto.id, chatName, chatImage, chatDto.color, chatDto.emoji,
chatDto.description, chatDto.chatType.int, amIChatAdmin, chatDto.timestamp.int, hasNotification, notificationsCount,
chatDto.muted, blocked=false, active=false, position = 0, chatDto.categoryId, colorId, colorHash, chatDto.highlight,
chatDto.muted, blocked=false, active=false, chatDto.position, chatDto.categoryId, colorId, colorHash, chatDto.highlight,
onlineStatus = onlineStatus)
self.addSubmodule(chatDto.id, belongsToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService,
communityService, messageService, gifService, mailserversService)
@ -480,7 +480,6 @@ method doesTopLevelChatExist*(self: Module, chatId: string): bool =
method removeCommunityChat*(self: Module, chatId: string) =
if(not self.chatContentModules.contains(chatId)):
return
self.controller.removeCommunityChat(chatId)
method onCommunityCategoryCreated*(self: Module, cat: Category, chats: seq[ChatDto]) =
@ -537,8 +536,8 @@ method setFirstChannelAsActive*(self: Module) =
let subItem = item.subItems.getItemAtIndex(0)
self.setActiveItemSubItem(item.id, subItem.id)
method onReorderChatOrCategory*(self: Module, chatOrCatId: string, position: int) =
self.view.chatsModel().reorder(chatOrCatId, position)
method onReorderChatOrCategory*(self: Module, chatOrCatId: string, position: int, newCategoryIdForChat: string) =
self.view.chatsModel().reorder(chatOrCatId, position, newCategoryIdForChat)
method onCategoryNameChanged*(self: Module, category: Category) =
self.view.chatsModel().renameItem(category.id, category.name)
@ -572,7 +571,7 @@ method onCommunityCategoryEdited*(self: Module, cat: Category, chats: seq[ChatDt
method onCommunityChannelDeletedOrChatLeft*(self: Module, chatId: string) =
if(not self.chatContentModules.contains(chatId)):
return
self.view.chatsModel().removeItemById(chatId)
self.view.chatsModel().removeItemOrSubitemById(chatId)
self.removeSubmodule(chatId)
self.setFirstChannelAsActive()

View File

@ -57,5 +57,6 @@ proc toJsonNode*(self: SubItem): JsonNode =
"muted": self.muted,
"blocked": self.blocked,
"active": self.active,
"position": self.position
"position": self.position,
"categoryId": ""
}

View File

@ -187,7 +187,6 @@ QtObject:
self.events.on(SignalType.Message.event) do(e: Args):
var receivedData = MessageSignal(e)
# Handling community updates
if (receivedData.communities.len > 0):
# Channel added removed is notified in the chats param
@ -305,7 +304,6 @@ QtObject:
proc handleCommunityUpdates(self: Service, communities: seq[CommunityDto], updatedChats: seq[ChatDto]) =
var community = communities[0]
if(not self.allCommunities.hasKey(community.id)):
self.allCommunities[community.id] = community
self.events.emit(SIGNAL_COMMUNITY_ADDED, CommunityArgs(community: community))
@ -391,7 +389,7 @@ QtObject:
# but something is different
for prev_chat in prev_community.chats:
# Handle position changes
if(chat.id == prev_chat.id and chat.position != prev_chat.position):
if(chat.id == prev_chat.id and (chat.position != prev_chat.position or chat.categoryId != prev_chat.categoryId)):
self.events.emit(SIGNAL_COMMUNITY_CHANNEL_REORDERED, CommunityChatOrderArgs(communityId: community.id,
chatId: chat.id, categoryId: chat.categoryId, position: chat.position))
@ -913,9 +911,14 @@ QtObject:
if(not response.result.getProp("chats", chatsJArr)):
raise newException(RpcException, fmt"createCommunityChannel; there is no `chats` key in the response for community id: {communityId}")
let chatsForCategory = self.getChats(communityId, categoryId)
let maxPosition = if chatsForCategory.len > 0: chatsForCategory[^1].position else: -1
for chatObj in chatsJArr:
var chatDto = chatObj.toChatDto(communityId)
chatDto.position = maxPosition + 1
self.chatService.updateOrAddChat(chatDto)
self.joinedCommunities[communityId].chats.add(chatDto)
let data = CommunityChatArgs(chat: chatDto)
self.events.emit(SIGNAL_COMMUNITY_CHANNEL_CREATED, data)
except Exception as e:
@ -1004,7 +1007,6 @@ QtObject:
proc deleteCommunityChat*(self: Service, communityId: string, chatId: string) =
try:
let response = status_go.deleteCommunityChat(communityId, chatId)
if not response.error.isNil:
let error = Json.decode($response.error, RpcError)
raise newException(RpcException, "Error deleting community chat: " & error.message)
@ -1012,8 +1014,7 @@ QtObject:
if response.result.isNil or response.result.kind == JNull:
error "response is invalid", procName="deleteCommunityChat"
var shortChatId = chatId.replace(communityId, "")
let idx = findIndexById(shortChatId, self.joinedCommunities[communityId].chats)
let idx = findIndexById(chatId, self.joinedCommunities[communityId].chats)
if (idx != -1):
self.joinedCommunities[communityId].chats.delete(idx)