feat(community): enable choosing and changing community channel color

Fixes #4953
This commit is contained in:
Jonathan Rainville 2022-03-10 14:28:37 -05:00 committed by Iuri Matias
parent f9c2d20d65
commit aef8d0c4ab
18 changed files with 142 additions and 42 deletions

View File

@ -76,6 +76,9 @@ method `isIdenticon=`*(self: var BaseItem, value: bool) {.inline base.} =
method color*(self: BaseItem): string {.inline base.} =
self.color
method `color=`*(self: var BaseItem, value: string) {.inline base.} =
self.color = value
method emoji*(self: BaseItem): string {.inline base.} =
self.emoji

View File

@ -328,7 +328,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)
self.view.updateChatDetails(chatDto.name, chatDto.description, chatDto.emoji, chatDto.color)
self.messagesModule.updateChatIdentifier()
method onChatRenamed*(self: Module, newName: string) =

View File

@ -111,10 +111,11 @@ QtObject:
proc amIChatAdmin*(self: View): bool {.slot.} =
return self.delegate.amIChatAdmin()
proc updateChatDetails*(self: View, name, description, emoji: string) =
proc updateChatDetails*(self: View, name, description, emoji, color: string) =
self.chatDetails.setName(name)
self.chatDetails.setDescription(description)
self.chatDetails.setEmoji(emoji)
self.chatDetails.setColor(color)
self.chatDetailsChanged()
proc updateChatDetailsName*(self: View, name: string) =

View File

@ -318,8 +318,10 @@ method createCommunityChannel*(
name: string,
description: string,
emoji: string,
color: string,
categoryId: string) =
self.communityService.createCommunityChannel(self.sectionId, name, description, emoji, categoryId)
self.communityService.createCommunityChannel(self.sectionId, name, description, emoji, color,
categoryId)
method editCommunityChannel*(
self: Controller,
@ -327,6 +329,7 @@ method editCommunityChannel*(
name: string,
description: string,
emoji: string,
color: string,
categoryId: string,
position: int) =
self.communityService.editCommunityChannel(
@ -335,6 +338,7 @@ method editCommunityChannel*(
name,
description,
emoji,
color,
categoryId,
position)

View File

@ -119,10 +119,12 @@ method acceptRequestToJoinCommunity*(self: AccessInterface, requestId: string) {
method declineRequestToJoinCommunity*(self: AccessInterface, requestId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method createCommunityChannel*(self: AccessInterface, name: string, description: string, emoji: string, categoryId: string) {.base.} =
method createCommunityChannel*(self: AccessInterface, name: string, description: string,
emoji: string, color: string, categoryId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method editCommunityChannel*(self: AccessInterface, channelId: string, name: string, description: string, emoji: string, categoryId: string, position: int) {.base.} =
method editCommunityChannel*(self: AccessInterface, channelId: string, name: string,
description: string, emoji: string, color: string, categoryId: string, position: int) {.base.} =
raise newException(ValueError, "No implementation available")
method createCommunityCategory*(self: AccessInterface, name: string, channels: seq[string]) {.base.} =

View File

@ -272,16 +272,17 @@ QtObject:
self.dataChanged(index, index, @[ModelRole.Name.int])
return
proc updateItemDetails*(self: Model, id, name, description, emoji: string) =
proc updateItemDetails*(self: Model, id, name, description, emoji, color: string) =
## This updates only first level items, it doesn't update subitems, since subitems cannot have custom icon.
for i in 0 ..< self.items.len:
if(self.items[i].id == id):
self.items[i].BaseItem.name = name
self.items[i].BaseItem.description = description
self.items[i].BaseItem.emoji = emoji
self.items[i].BaseItem.color = color
let index = self.createIndex(i, 0, nil)
self.dataChanged(index, index,
@[ModelRole.Name.int, ModelRole.Description.int, ModelRole.Emoji.int])
@[ModelRole.Name.int, ModelRole.Description.int, ModelRole.Emoji.int, ModelRole.Color.int])
return
proc updateNotificationsForItemOrSubItemById*(self: Model, id: string, hasUnreadMessages: bool,

View File

@ -552,7 +552,8 @@ method onCommunityChannelDeletedOrChatLeft*(self: Module, chatId: string) =
method onCommunityChannelEdited*(self: Module, chat: ChatDto) =
if(not self.chatContentModules.contains(chat.id)):
return
self.view.chatsModel().updateItemDetails(chat.id, chat.name, chat.description, chat.emoji)
self.view.chatsModel().updateItemDetails(chat.id, chat.name, chat.description, chat.emoji,
chat.color)
method createOneToOneChat*(self: Module, communityID: string, chatId: string, ensName: string) =
if(self.controller.isCommunity()):
@ -694,12 +695,13 @@ method acceptRequestToJoinCommunity*(self: Module, requestId: string) =
method declineRequestToJoinCommunity*(self: Module, requestId: string) =
self.controller.declineRequestToJoinCommunity(requestId)
method createCommunityChannel*(self: Module, name, description, emoji, categoryId: string) =
self.controller.createCommunityChannel(name, description, emoji, categoryId)
method createCommunityChannel*(self: Module, name, description, emoji, color, categoryId: string) =
self.controller.createCommunityChannel(name, description, emoji, color, categoryId)
method editCommunityChannel*(self: Module, channelId, name, description, emoji, categoryId: string,
position: int) =
self.controller.editCommunityChannel(channelId, name, description, emoji, categoryId, position)
method editCommunityChannel*(self: Module, channelId, name, description, emoji, color,
categoryId: string, position: int) =
self.controller.editCommunityChannel(channelId, name, description, emoji, color, categoryId,
position)
method createCommunityCategory*(self: Module, name: string, channels: seq[string]) =
self.controller.createCommunityCategory(name, channels)

View File

@ -94,10 +94,12 @@ method acceptRequestToJoinCommunity*(self: AccessInterface, requestId: string) {
method declineRequestToJoinCommunity*(self: AccessInterface, requestId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method createCommunityChannel*(self: AccessInterface, name: string, description: string, emoji: string, categoryId: string) {.base.} =
method createCommunityChannel*(self: AccessInterface, name: string, description: string,
emoji: string, color: string, categoryId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method editCommunityChannel*(self: AccessInterface, channelId, name, description, emoji, categoryId: string, position: int) {.base.} =
method editCommunityChannel*(self: AccessInterface, channelId, name, description, emoji, color,
categoryId: string, position: int) {.base.} =
raise newException(ValueError, "No implementation available")
method leaveCommunity*(self: AccessInterface) {.base.} =

View File

@ -213,9 +213,10 @@ QtObject:
name: string,
description: string,
emoji: string,
color: string,
categoryId: string
) {.slot.} =
self.delegate.createCommunityChannel(name, description, emoji, categoryId)
self.delegate.createCommunityChannel(name, description, emoji, color, categoryId)
proc editCommunityChannel*(
self: View,
@ -223,6 +224,7 @@ QtObject:
name: string,
description: string,
emoji: string,
color: string,
categoryId: string,
position: int
) {.slot.} =
@ -231,6 +233,7 @@ QtObject:
name,
description,
emoji,
color,
categoryId,
position
)

View File

@ -581,9 +581,11 @@ QtObject:
name: string,
description: string,
emoji: string,
color: string,
categoryId: string) =
try:
let response = status_go.createCommunityChannel(communityId, name, description, emoji, categoryId)
let response = status_go.createCommunityChannel(communityId, name, description, emoji, color,
categoryId)
if not response.error.isNil:
let error = Json.decode($response.error, RpcError)
@ -611,6 +613,7 @@ QtObject:
name: string,
description: string,
emoji: string,
color: string,
categoryId: string,
position: int) =
try:
@ -620,6 +623,7 @@ QtObject:
name,
description,
emoji,
color,
categoryId,
position)

View File

@ -85,6 +85,7 @@ proc createCommunityChannel*(
name: string,
description: string,
emoji: string,
color: string,
categoryId: string
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("createCommunityChat".prefix, %*[
@ -96,8 +97,8 @@ proc createCommunityChannel*(
"identity": {
"display_name": name,
"description": description,
"emoji": emoji#,
# "color": color#
"emoji": emoji,
"color": color
},
"category_id": categoryId
}])
@ -108,6 +109,7 @@ proc editCommunityChannel*(
name: string,
description: string,
emoji: string,
color: string,
categoryId: string,
position: int
): RpcResponse[JsonNode] {.raises: [Exception].} =
@ -121,8 +123,8 @@ proc editCommunityChannel*(
"identity": {
"display_name": name,
"description": description,
"emoji": emoji#,
# "color": color
"emoji": emoji,
"color": color
},
"category_id": categoryId,
"position": position

View File

@ -20,15 +20,20 @@ StatusModal {
property string channelName: ""
property string channelDescription: ""
property string channelEmoji: ""
property string channelColor: ""
property bool emojiPopupOpened: false
property var emojiPopup: null
readonly property string emojiRegexStr: 'alt="(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])"'
readonly property var communityColorValidator: Utils.Validate.NoEmpty
| Utils.Validate.TextHexColor
readonly property int maxChannelNameLength: 30
readonly property int maxChannelDescLength: 140
signal createCommunityChannel(string chName, string chDescription, string chEmoji, string chCategoryId)
signal editCommunityChannel(string chName, string chDescription, string chEmoji, string chCategoryId)
signal createCommunityChannel(string chName, string chDescription, string chEmoji,
string chColor, string chCategoryId)
signal editCommunityChannel(string chName, string chDescription, string chEmoji, string chColor,
string chCategoryId)
//% "New channel"
header.title: qsTrId("create-channel-title")
@ -61,7 +66,9 @@ StatusModal {
function isFormValid() {
return (scrollView.channelName.valid &&
scrollView.channelDescription.valid)
scrollView.channelDescription.valid) &&
Utils.validateAndReturnError(scrollView.channelColorDialog.color.toString().toUpperCase(),
communityColorValidator) === ""
}
contentItem: ScrollView {
@ -72,6 +79,7 @@ StatusModal {
property alias channelName: nameInput
property alias channelDescription: descriptionTextArea
property alias channelColorDialog: colorDialog
property alias channelEmoji: emojiText
contentHeight: content.height
@ -91,8 +99,9 @@ StatusModal {
StatusInput {
id: nameInput
label: qsTr("Channel name")
charLimit: popup.maxChannelNameLength
input.placeholderText: qsTr("Channel name")
input.placeholderText: qsTr("Name the channel")
input.onTextChanged: {
input.text = Utils.convertSpacesToDashesAndUpperToLowerCase(input.text);
input.cursorPosition = input.text.length
@ -104,9 +113,63 @@ StatusModal {
}]
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
Item {
id: spacer1
height: 16
width: parent.width
}
StatusBaseText {
text: qsTr("Channel colour")
font.pixelSize: 15
color: Theme.palette.directColor1
anchors.left: parent.left
anchors.leftMargin: 16
}
Item {
anchors.horizontalCenter: parent.horizontalCenter
height: colorSelectorButton.height + 16
width: parent.width - 32
StatusPickerButton {
id: colorSelectorButton
property string validationError: ""
bgColor: colorDialog.colorSelected ?
colorDialog.color : Theme.palette.baseColor2
// TODO adjust text color depending on the background color to make it readable
// contentColor: colorDialog.colorSelected ? Theme.palette.indirectColor1 : Theme.palette.baseColor1
text: colorDialog.colorSelected ?
colorDialog.color.toString().toUpperCase() :
//% "Pick a color"
qsTrId("pick-a-color")
onClicked: colorDialog.open();
onTextChanged: {
if (colorDialog.colorSelected) {
validationError = Utils.validateAndReturnError(text, communityColorValidator)
}
}
ColorDialog {
id: colorDialog
property bool colorSelected: popup.isEdit && popup.channelColor
color: popup.isEdit && popup.channelColor ? popup.channelColor :
Theme.palette.primaryColor1
onAccepted: colorSelected = true
}
}
StatusBaseText {
text: colorSelectorButton.validationError
visible: !!text
color: Theme.palette.dangerColor1
anchors.top: colorSelectorButton.bottom
anchors.topMargin: 4
anchors.right: colorSelectorButton.right
}
}
StatusInput {
@ -245,14 +308,17 @@ StatusModal {
emoji = found[1]
}
if (!isEdit) {
//popup.contentItem.communityColor.color.toString().toUpperCase()
popup.createCommunityChannel(Utils.filterXSS(popup.contentItem.channelName.input.text),
Utils.filterXSS(popup.contentItem.channelDescription.input.text),
emoji,
popup.contentItem.channelColorDialog.color.toString().toUpperCase(),
popup.categoryId)
} else {
popup.editCommunityChannel(Utils.filterXSS(popup.contentItem.channelName.input.text),
Utils.filterXSS(popup.contentItem.channelDescription.input.text),
emoji,
popup.contentItem.channelColorDialog.color.toString().toUpperCase(),
popup.categoryId)
}

View File

@ -21,8 +21,7 @@ StatusModal {
property var store
property var communitySectionModule
property bool isEdit: false
// Not Refactored Yet
property QtObject community: null //popup.store.chatsModelInst.communities.activeCommunity
property QtObject community: null
property var onSave: () => {}
readonly property int maxCommunityNameLength: 30
readonly property int maxCommunityDescLength: 140

View File

@ -189,19 +189,20 @@ QtObject {
chatCommunitySectionModule.removeUserFromCommunity(pubKey);
}
function createCommunityChannel(channelName, channelDescription, channelEmoji, categoryId) {
chatCommunitySectionModule.createCommunityChannel(channelName, channelDescription, channelEmoji, categoryId);
function createCommunityChannel(channelName, channelDescription, channelEmoji, channelColor,
categoryId) {
chatCommunitySectionModule.createCommunityChannel(channelName, channelDescription,
channelEmoji, channelColor, categoryId);
}
function editCommunityChannel(chatId, newName, newDescription, newEmoji, newCategory, channelPosition) {
// TODO: pass the private value when private channels
// are implemented
//privateSwitch.checked)
function editCommunityChannel(chatId, newName, newDescription, newEmoji, newColor,
newCategory, channelPosition) {
chatCommunitySectionModule.editCommunityChannel(
chatId,
newName,
newDescription,
newEmoji,
newColor,
newCategory,
channelPosition
)

View File

@ -177,6 +177,7 @@ ColumnLayout {
chatName = chatContentModule.chatDetails.name
chatDescription = chatContentModule.chatDetails.description
chatEmoji = chatContentModule.chatDetails.emoji
chatColor = chatContentModule.chatDetails.color
chatType = chatContentModule.chatDetails.type
chatMuted = chatContentModule.chatDetails.muted
channelPosition = chatContentModule.chatDetails.position
@ -249,6 +250,7 @@ ColumnLayout {
newName,
newDescription,
newEmoji,
newColor,
newCategory,
channelPosition // TODO change this to the signal once it is modifiable
)

View File

@ -20,6 +20,7 @@ StatusPopupMenu {
property string chatName: ""
property string chatDescription: ""
property string chatEmoji: ""
property string chatColor: ""
property string chatIcon: ""
property int chatType: -1
property bool chatMuted: false
@ -39,8 +40,8 @@ StatusPopupMenu {
signal leaveChat(string chatId)
signal leaveGroup(string chatId)
signal createCommunityChannel(string chatId, string newName, string newDescription, string newEmoji)
signal editCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newCategory)
signal createCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newColor)
signal editCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newColor, string newCategory)
signal fetchMoreMessages(int timeFrame)
signal addRemoveGroupMember()
@ -190,6 +191,7 @@ StatusPopupMenu {
channelName: root.chatName,
channelDescription: root.chatDescription,
channelEmoji: root.chatEmoji,
channelColor: root.chatColor,
categoryId: root.chatCategoryId
});
}
@ -202,10 +204,11 @@ StatusPopupMenu {
isEdit: true
emojiPopup: root.emojiPopup
onCreateCommunityChannel: {
root.createCommunityChannel(root.chatId, chName, chDescription, chEmoji);
root.createCommunityChannel(root.chatId, chName, chDescription, chEmoji, chColor);
}
onEditCommunityChannel: {
root.editCommunityChannel(root.chatId, chName, chDescription, chEmoji, chCategoryId);
root.editCommunityChannel(root.chatId, chName, chDescription, chEmoji, chColor,
chCategoryId);
}
onClosed: {
destroy()

View File

@ -277,6 +277,7 @@ Item {
chatDescription = obj.description
chatEmoji = obj.emoji
chatColor = obj.color
chatType = obj.type
chatMuted = obj.muted
channelPosition = obj.position
@ -332,6 +333,7 @@ Item {
newName,
newDescription,
newEmoji,
newColor,
newCategory,
channelPosition // TODO change this to the signal once it is modifiable
)
@ -405,8 +407,10 @@ Item {
CreateChannelPopup {
anchors.centerIn: parent
emojiPopup: root.emojiPopup
onCreateCommunityChannel: function (chName, chDescription, chEmoji, chCategoryId) {
root.store.createCommunityChannel(chName, chDescription, chEmoji, chCategoryId)
onCreateCommunityChannel: function (chName, chDescription, chEmoji, chColor,
chCategoryId) {
root.store.createCommunityChannel(chName, chDescription, chEmoji, chColor,
chCategoryId)
}
onClosed: {
destroy()

View File

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