feat: edit community channels
Closes #2344. Add ability to edit name, description, and private fields of a community channel. feat: Display community channel description Ensure the width of the description does not surpass the context menu and instead wraps to the next line. feat: After channel is created, set it as the active channel
This commit is contained in:
parent
a564b48f61
commit
21e6affa98
|
@ -20,6 +20,29 @@ toc: true
|
|||
|
||||
### `createCommunity`
|
||||
|
||||
### `createCommunityChannel`
|
||||
Creates a community channel with the given name and description, belonging to the community specified by the `communityId`.
|
||||
Returns a `Chat` object containing the created community channel.
|
||||
Throws an`RpcException` if there is an error returned from status-go.
|
||||
*Parameters*
|
||||
| Name | Type | Description |
|
||||
|---------------|----------|--------------|
|
||||
| `communityId` | `string` | community id |
|
||||
| `name` | `string` | community name |
|
||||
| `description` | `string` | community description |
|
||||
|
||||
### `editCommunityChannel`
|
||||
Edits a community channel, specified by `communityId` and `channelId`, with the given name and description.
|
||||
Returns a `Chat` object with the edited community channel.
|
||||
Throws an `RpcException` if there is an error returned from status-go.
|
||||
*Parameters*
|
||||
| Name | Type | Description |
|
||||
|---------------|----------|--------------|
|
||||
| `communityId` | `string` | community id |
|
||||
| `channelId` | `string` | channel id |
|
||||
| `name` | `string` | community name |
|
||||
| `description` | `string` | community description |
|
||||
|
||||
### `createCommunityChat`
|
||||
|
||||
### `createCommunityCategory`
|
||||
|
|
|
@ -33,7 +33,7 @@ toc: true
|
|||
- [`src/app/chat/view.nim`](https://github.com/status-im/status-desktop/blob/358091a8eb19f36c9843b42d61473e35ea87d05b/src/app/chat/view.nim#L166)
|
||||
- [`src/app/chat/views/community_list.nim`](https://github.com/status-im/status-desktop/blob/358091a8eb19f36c9843b42d61473e35ea87d05b/src/app/chat/views/community_list.nim#L40)
|
||||
- [`src/app/chat/views/communities.nim`](https://github.com/status-im/status-desktop/blob/358091a8eb19f36c9843b42d61473e35ea87d05b/src/app/chat/views/communities.nim#L109)
|
||||
- [`src/status/chat.nim#](https://github.com/status-im/status-desktop/blob/358091a8eb19f36c9843b42d61473e35ea87d05b/src/status/chat.nim#L441)
|
||||
- [`src/status/chat.nim`](https://github.com/status-im/status-desktop/blob/358091a8eb19f36c9843b42d61473e35ea87d05b/src/status/chat.nim#L441)
|
||||
- [`src/status/libstatus/chat.nim`](https://github.com/status-im/status-desktop/blob/358091a8eb19f36c9843b42d61473e35ea87d05b/src/status/libstatus/chat.nim#L272)
|
||||
|
||||
#### selecting a community
|
||||
|
@ -78,6 +78,24 @@ toc: true
|
|||
## Manage Community
|
||||
|
||||
### Creating Channels
|
||||
**Key source files**
|
||||
- [`ui/app/AppLayouts/Chat/CommunityComponents/CreateChannelPopup.qml`](https://github.com/status-im/status-desktop/blob/4a407d920499e3c31244f019afc0ab20f2c8f5e3/ui/app/AppLayouts/Chat/CommunityComponents/CreateChannelPopup.qml)
|
||||
- [`ui/app/AppLayouts/Chat/CommunityColumn.qml`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/ui/app/AppLayouts/Chat/CommunityColumn.qml#L84-L92)
|
||||
- [`src/status/chat.nim`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/src/status/chat.nim#L478-L479)
|
||||
- [`src/status/libstatus/chat.nim`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/src/status/libstatus/chat.nim#L337-L364)
|
||||
- [`src/app/chat/view.nim#L978-L990`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/src/app/chat/view.nim#L978-L990)
|
||||
|
||||
### Editing Channels
|
||||
**Key source files**
|
||||
- [`ui/app/AppLayouts/Chat/CommunityComponents/CreateChannelPopup.qml`](https://github.com/status-im/status-desktop/blob/4a407d920499e3c31244f019afc0ab20f2c8f5e3/ui/app/AppLayouts/Chat/CommunityComponents/CreateChannelPopup.qml#L179-L182)
|
||||
- [`ui/app/AppLayouts/Chat/components/ChannelContextMenu.qml`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/ui/app/AppLayouts/Chat/components/ChannelContextMenu.qml#L109-L116)
|
||||
- [`ui/app/AppMain.qml`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/ui/app/AppMain.qml#L283-L291)
|
||||
- [`src/status/chat.nim`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/src/status/chat.nim#L481-L482)
|
||||
- [`src/status/libstatus/chat.nim`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/src/status/libstatus/chat.nim#L366-L394)
|
||||
- [`src/app/chat/view.nim`](https://github.com/status-im/status-desktop/blob/1f585d159b9814198863b729ed26a218c09ea56d/src/app/chat/view.nim#L992-L1002)
|
||||
|
||||
**Notes**
|
||||
Editing a channel reuses the same modal popup used to create a channel, the difference being that it's prefilled with information from the selected channel, and has the `isEdit` attribute set to true, which determines the UI behavior for editing the channel as well as knowing the right slot to call.
|
||||
|
||||
### Categories
|
||||
Channels within a community might be organized in categories. Only the community admin might create/edit/delete a category. Creating a channel in a category works by calling `wakuext_reorderCommunityChat` after the chat is created, then the `Chat` is immediatly assigned a `categoryId`.
|
||||
|
|
|
@ -61,6 +61,11 @@ toc: true
|
|||
![url_bar](/images/communities/community_menu.png)
|
||||
|
||||
![url_bar](/images/communities/new_channel.png)
|
||||
### Editing Channels
|
||||
|
||||
![url_bar](/images/communities/community_edit_menu.png)
|
||||
|
||||
![url_bar](/images/communities/edit_channel.png)
|
||||
|
||||
### Creating Categories
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
|
@ -44,7 +44,8 @@ proc handleChatEvents(self: ChatController) =
|
|||
if (self.view.communities.activeCommunity.active and self.view.communities.activeCommunity.communityItem.id == community.id):
|
||||
if (self.view.activeChannel.chatItem != nil):
|
||||
let communityChannel = self.view.communities.activeCommunity.chats.getChannelById(self.view.activeChannel.chatItem.id)
|
||||
self.view.activeChannel.chatItem.canPost = communityChannel.canPost
|
||||
if communityChannel != nil:
|
||||
self.view.activeChannel.chatItem.canPost = communityChannel.canPost
|
||||
self.view.activeChannelChanged()
|
||||
|
||||
if (evArgs.communityMembershipRequests.len > 0):
|
||||
|
|
|
@ -17,6 +17,8 @@ import views/[channels_list, message_list, chat_item, suggestions_list, reaction
|
|||
import ../utils/image_utils
|
||||
import ../../status/tasks/[qt, task_runner_impl]
|
||||
import ../../status/tasks/marathon/mailserver/worker
|
||||
import ../../status/signals/types as signal_types
|
||||
import ../../status/libstatus/types
|
||||
|
||||
logScope:
|
||||
topics = "chats-view"
|
||||
|
@ -972,3 +974,29 @@ QtObject:
|
|||
proc formatInputCode(self: ChatsView, inputText: string): string {.slot.} =
|
||||
let strikeThroughRegex = re"""(?<!\>)`(?!<span style=" font-family:'monospace';">)([^*]+)(?!<\/span>)`"""
|
||||
self.formatInputStuff(strikeThroughRegex, inputText)
|
||||
|
||||
proc createCommunityChannel*(self: ChatsView, communityId: string, name: string, description: string, categoryId: string): string {.slot.} =
|
||||
try:
|
||||
let chat = self.status.chat.createCommunityChannel(communityId, name, description)
|
||||
if categoryId != "":
|
||||
self.status.chat.reorderCommunityChannel(communityId, categoryId, chat.id.replace(communityId, ""), 0)
|
||||
|
||||
chat.categoryId = categoryId
|
||||
self.communities.joinedCommunityList.addChannelToCommunity(communityId, chat)
|
||||
self.communities.activeCommunity.addChatItemToList(chat)
|
||||
self.setActiveChannel(chat.id)
|
||||
except RpcException as e:
|
||||
error "Error creating channel", msg=e.msg, name, description
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
||||
proc editCommunityChannel*(self: ChatsView, communityId: string, channelId: string, name: string, description: string, categoryId: string): string {.slot.} =
|
||||
try:
|
||||
let chat = self.status.chat.editCommunityChannel(communityId, channelId, name, description)
|
||||
|
||||
chat.categoryId = categoryId
|
||||
self.communities.joinedCommunityList.replaceChannelInCommunity(communityId, chat)
|
||||
self.communities.activeCommunity.updateChatItemInList(chat)
|
||||
self.setActiveChannel(chat.id)
|
||||
except RpcException as e:
|
||||
error "Error editing channel", msg=e.msg, channelId, name, description
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
|
|
@ -39,6 +39,16 @@ QtObject:
|
|||
QtProperty[string] id:
|
||||
read = id
|
||||
|
||||
proc description*(self: ChatItemView): string {.slot.} = result = ?.self.chatItem.description
|
||||
|
||||
QtProperty[string] description:
|
||||
read = description
|
||||
|
||||
proc private*(self: ChatItemView): bool {.slot.} = result = ?.self.chatItem.private
|
||||
|
||||
QtProperty[bool] private:
|
||||
read = private
|
||||
|
||||
proc contactsUpdated*(self: ChatItemView) {.signal}
|
||||
|
||||
proc userNameOrAlias(self: ChatItemView, pubKey: string): string {.slot.} =
|
||||
|
|
|
@ -245,23 +245,6 @@ QtObject:
|
|||
error "Error editing the community", msg = e.msg
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
||||
proc createCommunityChannel*(self: CommunitiesView, communityId: string, name: string, description: string, categoryId: string): string {.slot.} =
|
||||
result = ""
|
||||
try:
|
||||
let chat = self.status.chat.createCommunityChannel(communityId, name, description)
|
||||
|
||||
if (chat.id == ""):
|
||||
return "Chat was not created. Please try again later"
|
||||
|
||||
if categoryId != "":
|
||||
self.status.chat.reorderCommunityChannel(communityId, categoryId, chat.id.replace(communityId, ""), 0)
|
||||
|
||||
chat.categoryId = categoryId
|
||||
self.joinedCommunityList.addChannelToCommunity(communityId, chat)
|
||||
self.activeCommunity.addChatItemToList(chat)
|
||||
except Exception as e:
|
||||
error "Error creating the channel", msg = e.msg
|
||||
result = fmt"Error creating the channel: {e.msg}"
|
||||
|
||||
proc createCommunityCategory*(self: CommunitiesView, communityId: string, name: string, channels: string): string {.slot.} =
|
||||
result = ""
|
||||
|
@ -295,7 +278,6 @@ QtObject:
|
|||
error "Error creating the category", msg = e.msg
|
||||
result = fmt"Error creating the category: {e.msg}"
|
||||
|
||||
|
||||
proc observedCommunityChanged*(self: CommunitiesView) {.signal.}
|
||||
|
||||
proc setObservedCommunity*(self: CommunitiesView, communityId: string) {.slot.} =
|
||||
|
|
|
@ -155,6 +155,10 @@ QtObject:
|
|||
self.communityItem.chats.add(chat)
|
||||
discard self.chats.addChatItemToList(chat)
|
||||
self.chatsChanged()
|
||||
|
||||
proc updateChatItemInList*(self: CommunityItemView, chat: Chat) =
|
||||
self.chats.updateChat(chat)
|
||||
self.chatsChanged()
|
||||
|
||||
proc addCategoryToList*(self: CommunityItemView, category: CommunityCategory) =
|
||||
self.communityItem.categories.add(category)
|
||||
|
|
|
@ -128,6 +128,13 @@ QtObject:
|
|||
|
||||
let index = self.communities.findIndexById(communityId)
|
||||
self.communities[index] = community
|
||||
|
||||
proc replaceChannelInCommunity*(self: CommunityList, communityId: string, channel: Chat) =
|
||||
var community = self.getCommunityById(communityId)
|
||||
if community.id != "":
|
||||
let channelIdx = community.chats.findIndexById(channel.id)
|
||||
if channelIdx > -1:
|
||||
community.chats[channelIdx] = channel
|
||||
|
||||
proc addCategoryToCommunity*(self: CommunityList, communityId: string, category: CommunityCategory) =
|
||||
var community = self.getCommunityById(communityId)
|
||||
|
|
|
@ -478,6 +478,9 @@ proc editCommunity*(self: ChatModel, id: string, name: string, description: stri
|
|||
proc createCommunityChannel*(self: ChatModel, communityId: string, name: string, description: string): Chat =
|
||||
result = status_chat.createCommunityChannel(communityId, name, description)
|
||||
|
||||
proc editCommunityChannel*(self: ChatModel, communityId: string, channelId: string, name: string, description: string): Chat =
|
||||
result = status_chat.editCommunityChannel(communityId, channelId, name, description)
|
||||
|
||||
proc createCommunityCategory*(self: ChatModel, communityId: string, name: string, channels: seq[string]): CommunityCategory =
|
||||
result = status_chat.createCommunityCategory(communityId, name, channels)
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ proc toJsonNode*(self: seq[ChatMembershipEvent]): seq[JsonNode] =
|
|||
type Chat* = ref object
|
||||
id*: string # ID is the id of the chat, for public chats it is the name e.g. status, for one-to-one is the hex encoded public key and for group chats is a random uuid appended with the hex encoded pk of the creator of the chat
|
||||
communityId*: string
|
||||
private*: bool
|
||||
categoryId*: string
|
||||
name*: string
|
||||
description*: string
|
||||
|
|
|
@ -356,7 +356,41 @@ proc createCommunityChannel*(communityId: string, name: string, description: str
|
|||
}
|
||||
}]).parseJSON()
|
||||
|
||||
if rpcResult{"result"}.kind != JNull:
|
||||
if rpcResult{"error"} != nil:
|
||||
let error = Json.decode($rpcResult{"error"}, RpcError)
|
||||
raise newException(RpcException, "Error creating community channel: " & error.message)
|
||||
|
||||
if rpcResult{"result"} != nil and rpcResult{"result"}.kind != JNull:
|
||||
result = rpcResult["result"]["chats"][0].toChat()
|
||||
|
||||
proc editCommunityChannel*(communityId: string, channelId: string, name: string, description: string): Chat =
|
||||
let rpcResult = callPrivateRPC("editCommunityChat".prefix, %*[
|
||||
communityId,
|
||||
channelId.replace(communityId, ""),
|
||||
{
|
||||
"permissions": {
|
||||
"access": 1 # TODO get this from user selected privacy setting
|
||||
},
|
||||
"identity": {
|
||||
"display_name": name,
|
||||
"description": description#,
|
||||
# "color": color#,
|
||||
# TODO add images once it is supported by Status-Go
|
||||
# "images": [
|
||||
# {
|
||||
# "payload": image,
|
||||
# # TODO get that from an enum
|
||||
# "image_type": 1 # 1 is a raw payload
|
||||
# }
|
||||
# ]
|
||||
}
|
||||
}]).parseJSON()
|
||||
|
||||
if rpcResult{"error"} != nil:
|
||||
let error = Json.decode($rpcResult{"error"}, RpcError)
|
||||
raise newException(RpcException, "Error editing community channel: " & error.message)
|
||||
|
||||
if rpcResult{"result"} != nil and rpcResult{"result"}.kind != JNull:
|
||||
result = rpcResult["result"]["chats"][0].toChat()
|
||||
|
||||
proc createCommunityCategory*(communityId: string, name: string, channels: seq[string]): CommunityCategory =
|
||||
|
|
|
@ -150,6 +150,7 @@ proc toChat*(jsonChat: JsonNode): Chat =
|
|||
id: jsonChat{"id"}.getStr,
|
||||
communityId: jsonChat{"communityId"}.getStr,
|
||||
name: jsonChat{"name"}.getStr,
|
||||
description: jsonChat{"description"}.getStr,
|
||||
identicon: "",
|
||||
color: jsonChat{"color"}.getStr,
|
||||
isActive: jsonChat{"active"}.getBool,
|
||||
|
@ -161,7 +162,8 @@ proc toChat*(jsonChat: JsonNode): Chat =
|
|||
hasMentions: false,
|
||||
muted: false,
|
||||
ensName: "",
|
||||
joined: 0
|
||||
joined: 0,
|
||||
private: jsonChat{"private"}.getBool
|
||||
)
|
||||
|
||||
if jsonChat.hasKey("muted") and jsonChat["muted"].kind != JNull:
|
||||
|
@ -223,8 +225,10 @@ proc toCommunity*(jsonCommunity: JsonNode): Community =
|
|||
categoryId: chat{"categoryID"}.getStr(),
|
||||
communityId: result.id,
|
||||
name: chat{"name"}.getStr,
|
||||
description: chat{"description"}.getStr,
|
||||
canPost: chat{"canPost"}.getBool,
|
||||
chatType: ChatType.CommunityChat
|
||||
chatType: ChatType.CommunityChat,
|
||||
private: chat{"permissions"}{"private"}.getBool
|
||||
))
|
||||
|
||||
if jsonCommunity.hasKey("categories") and jsonCommunity["categories"].kind != JNull:
|
||||
|
|
|
@ -18,6 +18,8 @@ Item {
|
|||
anchors.leftMargin: this.isGroupChatOrOneToOne ? Style.current.padding : Style.current.padding + 4
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 4
|
||||
anchors.right: moreActionsBtn.left
|
||||
anchors.rightMargin: Style.current.padding + moreActionsBtn.width
|
||||
sourceComponent: this.isGroupChatOrOneToOne ? chatInfoButton : chatInfo
|
||||
}
|
||||
|
||||
|
@ -64,78 +66,74 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
height: parent.height
|
||||
StatusContextMenuButton {
|
||||
id: moreActionsBtn
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
spacing: 12
|
||||
|
||||
StatusContextMenuButton {
|
||||
id: moreActionsBtn
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
onClicked: {
|
||||
var menu = chatContextMenu;
|
||||
var isPrivateGroupChat = chatsModel.activeChannel.chatType === Constants.chatTypePrivateGroupChat
|
||||
if(isPrivateGroupChat){
|
||||
menu = groupContextMenu
|
||||
}
|
||||
|
||||
if (menu.opened) {
|
||||
return menu.close()
|
||||
}
|
||||
|
||||
if (isPrivateGroupChat) {
|
||||
menu.popup(moreActionsBtn.x, moreActionsBtn.height)
|
||||
} else {
|
||||
menu.openMenu(chatsModel.activeChannel, chatsModel.getActiveChannelIdx(),
|
||||
moreActionsBtn.x - chatContextMenu.width + moreActionsBtn.width + 4,
|
||||
moreActionsBtn.height - 4)
|
||||
}
|
||||
onClicked: {
|
||||
var menu = chatContextMenu;
|
||||
var isPrivateGroupChat = chatsModel.activeChannel.chatType === Constants.chatTypePrivateGroupChat
|
||||
if(isPrivateGroupChat){
|
||||
menu = groupContextMenu
|
||||
}
|
||||
|
||||
ChannelContextMenu {
|
||||
id: chatContextMenu
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
if (menu.opened) {
|
||||
return menu.close()
|
||||
}
|
||||
|
||||
PopupMenu {
|
||||
id: groupContextMenu
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
Action {
|
||||
icon.source: "../../../img/group_chat.svg"
|
||||
icon.width: chatTopBarContent.iconSize
|
||||
icon.height: chatTopBarContent.iconSize
|
||||
//% "Group Information"
|
||||
text: qsTrId("group-information")
|
||||
onTriggered: openPopup(groupInfoPopupComponent, {channel: chatsModel.activeChannel})
|
||||
}
|
||||
Action {
|
||||
icon.source: "../../../img/close.svg"
|
||||
icon.width: chatTopBarContent.iconSize
|
||||
icon.height: chatTopBarContent.iconSize
|
||||
//% "Clear History"
|
||||
text: qsTrId("clear-history")
|
||||
onTriggered: chatsModel.clearChatHistory(chatsModel.activeChannel.id)
|
||||
}
|
||||
Action {
|
||||
icon.source: "../../../img/leave_chat.svg"
|
||||
icon.width: chatTopBarContent.iconSize
|
||||
icon.height: chatTopBarContent.iconSize
|
||||
if (isPrivateGroupChat) {
|
||||
menu.popup(moreActionsBtn.x, moreActionsBtn.height)
|
||||
} else {
|
||||
menu.openMenu(chatsModel.activeChannel, chatsModel.getActiveChannelIdx(),
|
||||
moreActionsBtn.x - chatContextMenu.width + moreActionsBtn.width + 4,
|
||||
moreActionsBtn.height - 4)
|
||||
}
|
||||
}
|
||||
|
||||
ChannelContextMenu {
|
||||
id: chatContextMenu
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
}
|
||||
|
||||
PopupMenu {
|
||||
id: groupContextMenu
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
Action {
|
||||
icon.source: "../../../img/group_chat.svg"
|
||||
icon.width: chatTopBarContent.iconSize
|
||||
icon.height: chatTopBarContent.iconSize
|
||||
//% "Group Information"
|
||||
text: qsTrId("group-information")
|
||||
onTriggered: openPopup(groupInfoPopupComponent, {channel: chatsModel.activeChannel})
|
||||
}
|
||||
Action {
|
||||
icon.source: "../../../img/close.svg"
|
||||
icon.width: chatTopBarContent.iconSize
|
||||
icon.height: chatTopBarContent.iconSize
|
||||
//% "Clear History"
|
||||
text: qsTrId("clear-history")
|
||||
onTriggered: chatsModel.clearChatHistory(chatsModel.activeChannel.id)
|
||||
}
|
||||
Action {
|
||||
icon.source: "../../../img/leave_chat.svg"
|
||||
icon.width: chatTopBarContent.iconSize
|
||||
icon.height: chatTopBarContent.iconSize
|
||||
//% "Leave group"
|
||||
text: qsTrId("leave-group")
|
||||
onTriggered: {
|
||||
//% "Leave group"
|
||||
text: qsTrId("leave-group")
|
||||
onTriggered: {
|
||||
//% "Leave group"
|
||||
deleteChatConfirmationDialog.title = qsTrId("leave-group")
|
||||
//% "Leave group"
|
||||
deleteChatConfirmationDialog.confirmButtonLabel = qsTrId("leave-group")
|
||||
//% "Are you sure you want to leave this chat?"
|
||||
deleteChatConfirmationDialog.confirmationText = qsTrId("are-you-sure-you-want-to-leave-this-chat-")
|
||||
deleteChatConfirmationDialog.open()
|
||||
}
|
||||
deleteChatConfirmationDialog.title = qsTrId("leave-group")
|
||||
//% "Leave group"
|
||||
deleteChatConfirmationDialog.confirmButtonLabel = qsTrId("leave-group")
|
||||
//% "Are you sure you want to leave this chat?"
|
||||
deleteChatConfirmationDialog.confirmationText = qsTrId("are-you-sure-you-want-to-leave-this-chat-")
|
||||
deleteChatConfirmationDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rectangle {
|
||||
// id: separator
|
||||
|
@ -180,7 +178,7 @@ Item {
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// }
|
||||
|
||||
ActivityCenter {
|
||||
id: activityCenter
|
||||
|
|
|
@ -8,7 +8,7 @@ import "../components"
|
|||
import "./"
|
||||
|
||||
Button {
|
||||
implicitWidth: Math.max(communityImage.width + communityName.width + Style.current.padding, 200)
|
||||
implicitWidth: Math.max(communityImage.width + communityName.width + (Style.current.halfPadding * 3), 200)
|
||||
implicitHeight: communityImage.height + Style.current.padding
|
||||
|
||||
background: Rectangle {
|
||||
|
|
|
@ -8,6 +8,8 @@ import "../../../../shared/status"
|
|||
|
||||
ModalPopup {
|
||||
property string communityId
|
||||
property QtObject channel
|
||||
property bool isEdit: false
|
||||
property string categoryId: ""
|
||||
readonly property int maxDescChars: 140
|
||||
property string nameValidationError: ""
|
||||
|
@ -16,10 +18,16 @@ ModalPopup {
|
|||
descriptionTextArea.isValid
|
||||
|
||||
id: popup
|
||||
height: 500
|
||||
height: 400
|
||||
|
||||
onOpened: {
|
||||
nameInput.text = "";
|
||||
if (isEdit) {
|
||||
nameInput.text = channel.name;
|
||||
descriptionTextArea.text = channel.description;
|
||||
// TODO: re-enable once private channels are implemented
|
||||
// privateSwitch.checked = channel.private
|
||||
}
|
||||
nameInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
onClosed: destroy()
|
||||
|
@ -59,7 +67,7 @@ ModalPopup {
|
|||
placeholderText: qsTrId("a-cool-name")
|
||||
validationError: popup.nameValidationError
|
||||
|
||||
property bool isValid: false
|
||||
property bool isValid: false || isEdit
|
||||
|
||||
onTextEdited: {
|
||||
if (text.includes(" ")) {
|
||||
|
@ -97,7 +105,7 @@ ModalPopup {
|
|||
anchors.topMargin: Style.current.bigPadding
|
||||
customHeight: 88
|
||||
|
||||
property bool isValid: false
|
||||
property bool isValid: false || isEdit
|
||||
onTextChanged: validate()
|
||||
|
||||
function resetValidation() {
|
||||
|
@ -127,62 +135,80 @@ ModalPopup {
|
|||
color: !descriptionTextArea.validationError ? Style.current.textColor : Style.current.danger
|
||||
}
|
||||
|
||||
Separator {
|
||||
id: separator1
|
||||
anchors.top: charLimit.bottom
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
}
|
||||
// Separator {
|
||||
// id: separator1
|
||||
// anchors.top: charLimit.bottom
|
||||
// anchors.topMargin: Style.current.bigPadding
|
||||
// }
|
||||
|
||||
Item {
|
||||
id: privateSwitcher
|
||||
height: privateSwitch.height
|
||||
width: parent.width
|
||||
visible: false
|
||||
anchors.top: separator1.bottom
|
||||
anchors.topMargin: Style.current.smallPadding * 2
|
||||
// TODO: use the switch below to enable private channels
|
||||
// Item {
|
||||
// id: privateSwitcher
|
||||
// height: privateSwitch.height
|
||||
// width: parent.width
|
||||
// anchors.top: separator1.bottom
|
||||
// anchors.topMargin: Style.current.smallPadding * 2
|
||||
|
||||
StyledText {
|
||||
//% "Private channel"
|
||||
text: qsTrId("private-channel")
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
// StyledText {
|
||||
// //% "Private channel"
|
||||
// text: qsTrId("private-channel")
|
||||
// anchors.verticalCenter: parent.verticalCenter
|
||||
// }
|
||||
|
||||
StatusSwitch {
|
||||
id: privateSwitch
|
||||
anchors.right: parent.right
|
||||
}
|
||||
}
|
||||
// StatusSwitch {
|
||||
// id: privateSwitch
|
||||
// anchors.right: parent.right
|
||||
// }
|
||||
// }
|
||||
|
||||
StyledText {
|
||||
id: privateExplanation
|
||||
anchors.top: separator1.bottom
|
||||
color: Style.current.secondaryText
|
||||
wrapMode: Text.WordWrap
|
||||
anchors.topMargin: Style.current.smallPadding * 2
|
||||
width: parent.width
|
||||
//% "By making a channel private, only members with selected permission will be able to access it"
|
||||
text: qsTrId("by-making-a-channel-private--only-members-with-selected-permission-will-be-able-to-access-it")
|
||||
}
|
||||
// StyledText {
|
||||
// id: privateExplanation
|
||||
// anchors.top: privateSwitcher.bottom
|
||||
// color: Style.current.secondaryText
|
||||
// wrapMode: Text.WordWrap
|
||||
// anchors.topMargin: Style.current.smallPadding * 2
|
||||
// width: parent.width
|
||||
// //% "By making a channel private, only members with selected permission will be able to access it"
|
||||
// text: qsTrId("by-making-a-channel-private--only-members-with-selected-permission-will-be-able-to-access-it")
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
footer: StatusButton {
|
||||
enabled: popup.isValid
|
||||
//% "Create"
|
||||
text: qsTrId("create")
|
||||
text: isEdit ?
|
||||
qsTr("Save") :
|
||||
//% "Create"
|
||||
qsTrId("create")
|
||||
anchors.right: parent.right
|
||||
onClicked: {
|
||||
if (!validate()) {
|
||||
scrollView.scrollBackUp()
|
||||
return
|
||||
}
|
||||
const error = chatsModel.communities.createCommunityChannel(communityId,
|
||||
let error = "";
|
||||
if (!isEdit) {
|
||||
error = chatsModel.createCommunityChannel(communityId,
|
||||
Utils.filterXSS(nameInput.text),
|
||||
Utils.filterXSS(descriptionTextArea.text),
|
||||
categoryId)
|
||||
categoryId)
|
||||
// TODO: pass the private value when private channels
|
||||
// are implemented
|
||||
//privateSwitch.checked)
|
||||
} else {
|
||||
error = chatsModel.editCommunityChannel(communityId,
|
||||
channel.id,
|
||||
Utils.filterXSS(nameInput.text),
|
||||
Utils.filterXSS(descriptionTextArea.text),
|
||||
categoryId)
|
||||
// TODO: pass the private value when private channels
|
||||
// are implemented
|
||||
//privateSwitch.checked)
|
||||
}
|
||||
|
||||
if (error) {
|
||||
creatingError.text = error
|
||||
const errorJson = JSON.parse(error)
|
||||
creatingError.text = errorJson.error
|
||||
return creatingError.open()
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,14 @@ PopupMenu {
|
|||
icon.height: 16
|
||||
onTriggered: chatsModel.clearChatHistoryByIndex(channelContextMenu.channelIndex)
|
||||
}
|
||||
Action {
|
||||
enabled: chatsModel.communities.activeCommunity.active && chatsModel.communities.activeCommunity.admin
|
||||
text: qsTr("Edit Channel")
|
||||
icon.source: "../../../img/edit.svg"
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
onTriggered: openPopup(editChannelPopup, {communityId: chatsModel.communities.activeCommunity.id, channel: chatsModel.activeChannel})
|
||||
}
|
||||
|
||||
Separator {
|
||||
visible: deleteAction.enabled
|
||||
|
|
|
@ -280,6 +280,16 @@ RowLayout {
|
|||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: editChannelPopup
|
||||
CreateChannelPopup {
|
||||
isEdit: true
|
||||
onClosed: {
|
||||
destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ToastMessage {
|
||||
id: toastMessage
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ Item {
|
|||
property string profileImage: realChatType === Constants.chatTypeOneToOne ? appMain.getProfileImage(chatId) || "" : ""
|
||||
|
||||
height: 48
|
||||
width: nameAndInfo.width + chatIdenticon.width + Style.current.smallPadding
|
||||
|
||||
Connections {
|
||||
enabled: realChatType === Constants.chatTypeOneToOne
|
||||
|
@ -52,7 +51,7 @@ Item {
|
|||
Item {
|
||||
id: nameAndInfo
|
||||
height: chatName.height + chatInfo.height
|
||||
width: childrenRect.width
|
||||
width: parent.width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: chatIdenticon.right
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
|
@ -116,7 +115,13 @@ Item {
|
|||
StyledText {
|
||||
id: chatInfo
|
||||
color: Style.current.secondaryText
|
||||
wrapMode: Text.Wrap
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
text: {
|
||||
if (root.chatType === Constants.chatTypeCommunity) {
|
||||
return chatsModel.activeChannel.description
|
||||
}
|
||||
switch(root.realChatType){
|
||||
//% "Public chat"
|
||||
case Constants.chatTypePublic: return qsTrId("public-chat")
|
||||
|
@ -139,6 +144,7 @@ Item {
|
|||
}
|
||||
font.pixelSize: 12
|
||||
anchors.top: chatName.bottom
|
||||
anchors.topMargin: 2
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 10becb490228d416ff361bdb8a965537b4803af5
|
||||
Subproject commit b395144704f29c9e1f4fd11714d1031a10160ad1
|
Loading…
Reference in New Issue