feat(@desktop/chat): Add setting image in group chat

Image and cropping information are sent to status-go.

Issue #6466
This commit is contained in:
Michal Iskierko 2022-08-11 12:58:09 +02:00 committed by Michał Iskierko
parent a01e0822b7
commit d6a061a517
21 changed files with 80 additions and 26 deletions

View File

@ -86,6 +86,9 @@ method getChatType*(self: AccessInterface): int {.base.} =
method getChatColor*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method getChatIcon*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method amIChatAdmin*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -379,6 +379,10 @@ method getChatColor*(self: Module): string =
let chatDto = self.controller.getChatDetails()
return chatDto.color
method getChatIcon*(self: Module): string =
let chatDto = self.controller.getChatDetails()
return chatDto.icon
method amIChatAdmin*(self: Module): bool =
if(not self.controller.belongsToCommunity()):
let chatDto = self.controller.getChatDetails()

View File

@ -68,6 +68,9 @@ QtObject:
proc getChatColor*(self: View): string {.slot.} =
return self.delegate.getChatColor()
proc getChatIcon*(self: View): string {.slot.} =
return self.delegate.getChatIcon()
proc amIChatAdmin*(self: View): bool {.slot.} =
return self.delegate.amIChatAdmin()

View File

@ -338,7 +338,7 @@ method onNotificationsUpdated*(self: Module, hasUnreadMessages: bool, notificati
self.view.updateChatDetailsNotifications(hasUnreadMessages, notificationCount)
method onChatEdited*(self: Module, chatDto: ChatDto) =
self.view.updateChatDetails(chatDto.name, chatDto.description, chatDto.emoji, chatDto.color, chatDto.chatType == ChatType.OneToOne)
self.view.updateChatDetails(chatDto.name, chatDto.description, chatDto.emoji, chatDto.color, chatDto.icon, chatDto.chatType == ChatType.OneToOne)
self.messagesModule.updateChatIdentifier()
method onChatRenamed*(self: Module, newName: string) =

View File

@ -122,12 +122,13 @@ QtObject:
proc amIChatAdmin*(self: View): bool {.slot.} =
return self.delegate.amIChatAdmin()
proc updateChatDetails*(self: View, name, description, emoji, color: string, ignoreName: bool) =
proc updateChatDetails*(self: View, name, description, emoji, color, icon: string, ignoreName: bool) =
if not ignoreName:
self.chatDetails.setName(name)
self.chatDetails.setDescription(description)
self.chatDetails.setEmoji(emoji)
self.chatDetails.setColor(color)
self.chatDetails.setIcon(icon)
self.chatDetailsChanged()
proc updateChatDetailsName*(self: View, name: string) =

View File

@ -345,9 +345,9 @@ proc renameGroupChat*(self: Controller, chatId: string, newName: string) =
let communityId = if self.isCommunitySection: self.sectionId else: ""
self.chatService.renameGroupChat(communityId, chatId, newName)
proc updateGroupChatDetails*(self: Controller, chatId: string, newGroupName: string, newGroupColor: string, newGroupImage: string) =
proc updateGroupChatDetails*(self: Controller, chatId: string, newGroupName: string, newGroupColor: string, newGroupImageJson: string) =
let communityId = if self.isCommunitySection: self.sectionId else: ""
self.chatService.updateGroupChatDetails(communityId, chatId, newGroupName, newGroupColor, newGroupImage)
self.chatService.updateGroupChatDetails(communityId, chatId, newGroupName, newGroupColor, newGroupImageJson)
proc makeAdmin*(self: Controller, communityID: string, chatId: string, pubKey: string) =
self.chatService.makeAdmin(communityID, chatId, pubKey)

View File

@ -115,7 +115,7 @@ method onCommunityChannelDeletedOrChatLeft*(self: AccessInterface, chatId: strin
method onChatRenamed*(self: AccessInterface, chatId: string, newName: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onGroupChatDetailsUpdated*(self: AccessInterface, chatId: string, newName: string, newColor: string, newImage: string) {.base.} =
method onGroupChatDetailsUpdated*(self: AccessInterface, chatId: string, newName: string, newColor: string, newImageJson: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityChannelEdited*(self: AccessInterface, chat: ChatDto) {.base.} =

View File

@ -146,6 +146,8 @@ proc buildChatSectionUI(
blocked = contactDetails.details.isBlocked()
colorHash = self.controller.getColorHash(chatDto.id)
colorId = self.controller.getColorId(chatDto.id)
elif(chatDto.chatType == ChatType.PrivateGroupChat):
chatImage = chatDto.icon
# for group chats only member.admin should be checked,
# because channelGroup.admin is alway true
@ -726,8 +728,8 @@ method removeMembersFromGroupChat*(self: Module, communityID: string, chatId: st
method renameGroupChat*(self: Module, chatId: string, newName: string) =
self.controller.renameGroupChat(chatId, newName)
method updateGroupChatDetails*(self: Module, chatId: string, newGroupName: string, newGroupColor: string, newGroupImage: string) =
self.controller.updateGroupChatDetails(chatId, newGroupName, newGroupColor, newGroupImage)
method updateGroupChatDetails*(self: Module, chatId: string, newGroupName: string, newGroupColor: string, newGroupImageJson: string) =
self.controller.updateGroupChatDetails(chatId, newGroupName, newGroupColor, newGroupImageJson)
method makeAdmin*(self: Module, communityID: string, chatId: string, pubKey: string) =
self.controller.makeAdmin(communityID, chatId, pubKey)

View File

@ -207,7 +207,6 @@ proc toChatDto*(jsonObj: JsonNode): ChatDto =
discard jsonObj.getProp("unviewedMentionsCount", result.unviewedMentionsCount)
discard jsonObj.getProp("canPost", result.canPost)
discard jsonObj.getProp("alias", result.alias)
discard jsonObj.getProp("identicon", result.icon)
discard jsonObj.getProp("muted", result.muted)
discard jsonObj.getProp("categoryId", result.categoryId)
if (result.categoryId == ""):
@ -231,6 +230,13 @@ proc toChatDto*(jsonObj: JsonNode): ChatDto =
(chatTypeInt >= ord(low(ChatType)) or chatTypeInt <= ord(high(ChatType)))):
result.chatType = ChatType(chatTypeInt)
var chatImage: string
discard jsonObj.getProp("image", chatImage)
if (result.chatType == ChatType.PrivateGroupChat and len(chatImage) > 0):
result.icon = chatImage
else:
discard jsonObj.getProp("identicon", result.icon)
var membersObj: JsonNode
if(jsonObj.getProp("members", membersObj)):
if(membersObj.kind == JArray):

View File

@ -509,21 +509,23 @@ QtObject:
except Exception as e:
error "error while renaming group chat: ", msg = e.msg
proc updateGroupChatDetails*(self: Service, communityID: string, chatID: string, name: string, color: string, image: string) =
proc updateGroupChatDetails*(self: Service, communityID: string, chatID: string, name: string, color: string, imageJson: string) =
try:
let response = status_chat.editChat(communityID, chatID, name, color, image)
let response = status_chat.editChat(communityID, chatID, name, color, imageJson)
if (not response.error.isNil):
let msg = response.error.message & " chatId=" & chatId
error "error while editing group chat details", msg
return
let resultedChat = response.result.toChatDto()
var chat = self.chats[chatID]
chat.name = name
chat.color = color
# TODO set image
chat.icon = resultedChat.icon
self.updateOrAddChat(chat)
self.events.emit(SIGNAL_GROUP_CHAT_DETAILS_UPDATED, ChatUpdateDetailsArgs(id: chatID, newName: name, newColor: color, newImage: image))
self.events.emit(SIGNAL_GROUP_CHAT_DETAILS_UPDATED, ChatUpdateDetailsArgs(id: chatID, newName: name, newColor: color, newImage: resultedChat.icon))
except Exception as e:
error "error while updating group chat: ", msg = e.msg

View File

@ -1,6 +1,7 @@
import json, sequtils, sugar, strutils
import core, utils
import response_type
import interpret/cropped_image
export response_type
@ -134,6 +135,7 @@ proc getLinkPreviewData*(link: string): RpcResponse[JsonNode] {.raises: [Excepti
proc getMembers*(communityId, chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("chat_getMembers", %* [communityId, chatId])
proc editChat*(communityID: string, chatID: string, name: string, color: string, image: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatID, name, color, image]
proc editChat*(communityID: string, chatID: string, name: string, color: string, imageJson: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let croppedImage = newCroppedImage(imageJson)
let payload = %* [communityID, chatID, name, color, croppedImage]
return core.callPrivateRPC("chat_editChat", payload)

View File

@ -66,11 +66,19 @@ StatusModal {
}
}
header.editable: !addMembers && popup.isAdmin
header.icon.isLetterIdenticon: true
header.icon.isLetterIdenticon: {
if (popup.chatDetails && popup.chatDetails.icon !== "") {
return false
}
return true
}
header.icon.name: popup.chatDetails ? popup.chatDetails.name : ""
header.icon.background.color: popup.chatDetails ? popup.chatDetails.color : "transparent"
header.image.source: popup.chatDetails ? popup.chatDetails.icon : ""
onEditButtonClicked: renameGroupPopup.open()
onEditButtonClicked: {
renameGroupPopup.open()
}
onClosed: {
chatSectionModule.clearMyContacts()
@ -284,6 +292,7 @@ StatusModal {
id: renameGroupPopup
activeGroupName: popup.chatDetails ? popup.chatDetails.name : ""
activeGroupColor: popup.chatDetails ? popup.chatDetails.color: ""
activeGroupImageData: popup.chatDetails ? popup.chatDetails.icon: ""
onUpdateGroupChatDetails: {
popup.chatSectionModule.updateGroupChatDetails(popup.chatSectionModule.activeItem.id, groupName, groupColor, groupImage)
popup.header.title = groupName

View File

@ -43,9 +43,7 @@ StatusDialog {
colorSelectionGrid.selectedColorIndex = i
}
// TODO next phase
// imageEditor.dataImage: root.activeGroupImageData
imageEditor.dataImage = activeGroupImageData
}
ColumnLayout {
@ -142,9 +140,12 @@ StatusDialog {
id: saveBtn
text: qsTr("Save changes")
enabled: groupName.text.trim().length > 0 &&
((groupName.text != root.activeGroupName) || (root.activeGroupColor != colorSelectionGrid.selectedColor))
((groupName.text != root.activeGroupName) ||
(root.activeGroupColor != colorSelectionGrid.selectedColor) ||
(String(imageEditor.source).length > 0))
onClicked : {
updateGroupChatDetails(groupName.text, colorSelectionGrid.selectedColor, ""/*imageEditor.dataImage*/)
updateGroupChatDetails(groupName.text, colorSelectionGrid.selectedColor,
Utils.getImageAndCropInfoJson(imageEditor.source, imageEditor.cropRect))
}
}
}

View File

@ -93,6 +93,13 @@ QtObject {
return messageModule.getChatColor()
}
function getChatIcon () {
if(!messageModule)
return ""
return messageModule.getChatIcon()
}
function amIChatAdmin () {
if(!messageModule)
return false

View File

@ -209,6 +209,7 @@ ColumnLayout {
chatDescription = chatContentModule.chatDetails.description
chatEmoji = chatContentModule.chatDetails.emoji
chatColor = chatContentModule.chatDetails.color
chatIcon = chatContentModule.chatDetails.icon
chatType = chatContentModule.chatDetails.type
chatMuted = chatContentModule.chatDetails.muted
channelPosition = chatContentModule.chatDetails.position

View File

@ -92,7 +92,8 @@ StatusPopupMenu {
onTriggered: {
Global.openPopup(renameGroupPopupComponent, {
activeGroupName: root.chatName,
activeGroupColor: root.chatColor
activeGroupColor: root.chatColor,
activeGroupImageData: root.chatIcon
});
}
}

View File

@ -313,7 +313,7 @@ Item {
chatId = obj.itemId
chatName = obj.name
chatDescription = obj.description
chatIcon = obj.icon
chatEmoji = obj.emoji
chatColor = obj.color
chatType = obj.type

View File

@ -156,8 +156,8 @@ StatusAppTwoPanelLayout {
item.options.requestToJoinEnabled ? Constants.communityChatOnRequestAccess : Constants.communityChatPublicAccess,
item.color.toString().toUpperCase(),
item.selectedTags,
JSON.stringify({imagePath: String(item.logoImagePath).replace("file://", ""), cropRect: item.logoCropRect}),
JSON.stringify({imagePath: String(item.bannerPath).replace("file://", ""), cropRect: item.bannerCropRect}),
Utils.getImageAndCropInfoJson(item.logoImagePath, item.logoCropRect),
Utils.getImageAndCropInfoJson(item.bannerPath, item.bannerCropRect),
item.options.archiveSupportEnabled,
item.options.pinMessagesEnabled
)

View File

@ -184,6 +184,7 @@ Item {
chatDescription = obj.description
chatEmoji = obj.emoji
chatColor = obj.color
chatIcon = obj.icon
chatType = obj.type
chatMuted = obj.muted
}

View File

@ -298,7 +298,13 @@ Loader {
chatColor: root.messageStore.getChatColor()
chatEmoji: root.channelEmoji
amIChatAdmin: root.messageStore.amIChatAdmin()
chatIcon: root.senderIconToShow
chatIcon: {
if ((root.messageStore.getChatType() === Constants.chatType.privateGroupChat) &&
root.messageStore.getChatIcon() !== "") {
return root.messageStore.getChatIcon()
}
return root.senderIconToShow
}
}
}

View File

@ -697,6 +697,11 @@ QtObject {
return msg.includes("account already exists")
}
// See also: backend/interpret/cropped_image.nim
function getImageAndCropInfoJson(imgPath, cropRect) {
return JSON.stringify({imagePath: String(imgPath).replace("file://", ""), cropRect: cropRect})
}
// Leave this function at the bottom of the file as QT Creator messes up the code color after this
function isPunct(c) {
return /(!|\@|#|\$|%|\^|&|\*|\(|\)|_|\+|\||-|=|\\|{|}|[|]|"|;|'|<|>|\?|,|\.|\/)/.test(c)