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`
|
### `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`
|
### `createCommunityChat`
|
||||||
|
|
||||||
### `createCommunityCategory`
|
### `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/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/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/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)
|
- [`src/status/libstatus/chat.nim`](https://github.com/status-im/status-desktop/blob/358091a8eb19f36c9843b42d61473e35ea87d05b/src/status/libstatus/chat.nim#L272)
|
||||||
|
|
||||||
#### selecting a community
|
#### selecting a community
|
||||||
|
@ -78,6 +78,24 @@ toc: true
|
||||||
## Manage Community
|
## Manage Community
|
||||||
|
|
||||||
### Creating Channels
|
### 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
|
### 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`.
|
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/community_menu.png)
|
||||||
|
|
||||||
![url_bar](/images/communities/new_channel.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
|
### Creating Categories
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
|
@ -44,6 +44,7 @@ proc handleChatEvents(self: ChatController) =
|
||||||
if (self.view.communities.activeCommunity.active and self.view.communities.activeCommunity.communityItem.id == community.id):
|
if (self.view.communities.activeCommunity.active and self.view.communities.activeCommunity.communityItem.id == community.id):
|
||||||
if (self.view.activeChannel.chatItem != nil):
|
if (self.view.activeChannel.chatItem != nil):
|
||||||
let communityChannel = self.view.communities.activeCommunity.chats.getChannelById(self.view.activeChannel.chatItem.id)
|
let communityChannel = self.view.communities.activeCommunity.chats.getChannelById(self.view.activeChannel.chatItem.id)
|
||||||
|
if communityChannel != nil:
|
||||||
self.view.activeChannel.chatItem.canPost = communityChannel.canPost
|
self.view.activeChannel.chatItem.canPost = communityChannel.canPost
|
||||||
self.view.activeChannelChanged()
|
self.view.activeChannelChanged()
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ import views/[channels_list, message_list, chat_item, suggestions_list, reaction
|
||||||
import ../utils/image_utils
|
import ../utils/image_utils
|
||||||
import ../../status/tasks/[qt, task_runner_impl]
|
import ../../status/tasks/[qt, task_runner_impl]
|
||||||
import ../../status/tasks/marathon/mailserver/worker
|
import ../../status/tasks/marathon/mailserver/worker
|
||||||
|
import ../../status/signals/types as signal_types
|
||||||
|
import ../../status/libstatus/types
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "chats-view"
|
topics = "chats-view"
|
||||||
|
@ -972,3 +974,29 @@ QtObject:
|
||||||
proc formatInputCode(self: ChatsView, inputText: string): string {.slot.} =
|
proc formatInputCode(self: ChatsView, inputText: string): string {.slot.} =
|
||||||
let strikeThroughRegex = re"""(?<!\>)`(?!<span style=" font-family:'monospace';">)([^*]+)(?!<\/span>)`"""
|
let strikeThroughRegex = re"""(?<!\>)`(?!<span style=" font-family:'monospace';">)([^*]+)(?!<\/span>)`"""
|
||||||
self.formatInputStuff(strikeThroughRegex, inputText)
|
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:
|
QtProperty[string] id:
|
||||||
read = 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 contactsUpdated*(self: ChatItemView) {.signal}
|
||||||
|
|
||||||
proc userNameOrAlias(self: ChatItemView, pubKey: string): string {.slot.} =
|
proc userNameOrAlias(self: ChatItemView, pubKey: string): string {.slot.} =
|
||||||
|
|
|
@ -245,23 +245,6 @@ QtObject:
|
||||||
error "Error editing the community", msg = e.msg
|
error "Error editing the community", msg = e.msg
|
||||||
result = StatusGoError(error: e.msg).toJson
|
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.} =
|
proc createCommunityCategory*(self: CommunitiesView, communityId: string, name: string, channels: string): string {.slot.} =
|
||||||
result = ""
|
result = ""
|
||||||
|
@ -295,7 +278,6 @@ QtObject:
|
||||||
error "Error creating the category", msg = e.msg
|
error "Error creating the category", msg = e.msg
|
||||||
result = fmt"Error creating the category: {e.msg}"
|
result = fmt"Error creating the category: {e.msg}"
|
||||||
|
|
||||||
|
|
||||||
proc observedCommunityChanged*(self: CommunitiesView) {.signal.}
|
proc observedCommunityChanged*(self: CommunitiesView) {.signal.}
|
||||||
|
|
||||||
proc setObservedCommunity*(self: CommunitiesView, communityId: string) {.slot.} =
|
proc setObservedCommunity*(self: CommunitiesView, communityId: string) {.slot.} =
|
||||||
|
|
|
@ -156,6 +156,10 @@ QtObject:
|
||||||
discard self.chats.addChatItemToList(chat)
|
discard self.chats.addChatItemToList(chat)
|
||||||
self.chatsChanged()
|
self.chatsChanged()
|
||||||
|
|
||||||
|
proc updateChatItemInList*(self: CommunityItemView, chat: Chat) =
|
||||||
|
self.chats.updateChat(chat)
|
||||||
|
self.chatsChanged()
|
||||||
|
|
||||||
proc addCategoryToList*(self: CommunityItemView, category: CommunityCategory) =
|
proc addCategoryToList*(self: CommunityItemView, category: CommunityCategory) =
|
||||||
self.communityItem.categories.add(category)
|
self.communityItem.categories.add(category)
|
||||||
discard self.categories.addCategoryToList(category)
|
discard self.categories.addCategoryToList(category)
|
||||||
|
|
|
@ -129,6 +129,13 @@ QtObject:
|
||||||
let index = self.communities.findIndexById(communityId)
|
let index = self.communities.findIndexById(communityId)
|
||||||
self.communities[index] = community
|
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) =
|
proc addCategoryToCommunity*(self: CommunityList, communityId: string, category: CommunityCategory) =
|
||||||
var community = self.getCommunityById(communityId)
|
var community = self.getCommunityById(communityId)
|
||||||
community.categories.add(category)
|
community.categories.add(category)
|
||||||
|
|
|
@ -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 =
|
proc createCommunityChannel*(self: ChatModel, communityId: string, name: string, description: string): Chat =
|
||||||
result = status_chat.createCommunityChannel(communityId, name, description)
|
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 =
|
proc createCommunityCategory*(self: ChatModel, communityId: string, name: string, channels: seq[string]): CommunityCategory =
|
||||||
result = status_chat.createCommunityCategory(communityId, name, channels)
|
result = status_chat.createCommunityCategory(communityId, name, channels)
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ proc toJsonNode*(self: seq[ChatMembershipEvent]): seq[JsonNode] =
|
||||||
type Chat* = ref object
|
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
|
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
|
communityId*: string
|
||||||
|
private*: bool
|
||||||
categoryId*: string
|
categoryId*: string
|
||||||
name*: string
|
name*: string
|
||||||
description*: string
|
description*: string
|
||||||
|
|
|
@ -356,7 +356,41 @@ proc createCommunityChannel*(communityId: string, name: string, description: str
|
||||||
}
|
}
|
||||||
}]).parseJSON()
|
}]).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()
|
result = rpcResult["result"]["chats"][0].toChat()
|
||||||
|
|
||||||
proc createCommunityCategory*(communityId: string, name: string, channels: seq[string]): CommunityCategory =
|
proc createCommunityCategory*(communityId: string, name: string, channels: seq[string]): CommunityCategory =
|
||||||
|
|
|
@ -150,6 +150,7 @@ proc toChat*(jsonChat: JsonNode): Chat =
|
||||||
id: jsonChat{"id"}.getStr,
|
id: jsonChat{"id"}.getStr,
|
||||||
communityId: jsonChat{"communityId"}.getStr,
|
communityId: jsonChat{"communityId"}.getStr,
|
||||||
name: jsonChat{"name"}.getStr,
|
name: jsonChat{"name"}.getStr,
|
||||||
|
description: jsonChat{"description"}.getStr,
|
||||||
identicon: "",
|
identicon: "",
|
||||||
color: jsonChat{"color"}.getStr,
|
color: jsonChat{"color"}.getStr,
|
||||||
isActive: jsonChat{"active"}.getBool,
|
isActive: jsonChat{"active"}.getBool,
|
||||||
|
@ -161,7 +162,8 @@ proc toChat*(jsonChat: JsonNode): Chat =
|
||||||
hasMentions: false,
|
hasMentions: false,
|
||||||
muted: false,
|
muted: false,
|
||||||
ensName: "",
|
ensName: "",
|
||||||
joined: 0
|
joined: 0,
|
||||||
|
private: jsonChat{"private"}.getBool
|
||||||
)
|
)
|
||||||
|
|
||||||
if jsonChat.hasKey("muted") and jsonChat["muted"].kind != JNull:
|
if jsonChat.hasKey("muted") and jsonChat["muted"].kind != JNull:
|
||||||
|
@ -223,8 +225,10 @@ proc toCommunity*(jsonCommunity: JsonNode): Community =
|
||||||
categoryId: chat{"categoryID"}.getStr(),
|
categoryId: chat{"categoryID"}.getStr(),
|
||||||
communityId: result.id,
|
communityId: result.id,
|
||||||
name: chat{"name"}.getStr,
|
name: chat{"name"}.getStr,
|
||||||
|
description: chat{"description"}.getStr,
|
||||||
canPost: chat{"canPost"}.getBool,
|
canPost: chat{"canPost"}.getBool,
|
||||||
chatType: ChatType.CommunityChat
|
chatType: ChatType.CommunityChat,
|
||||||
|
private: chat{"permissions"}{"private"}.getBool
|
||||||
))
|
))
|
||||||
|
|
||||||
if jsonCommunity.hasKey("categories") and jsonCommunity["categories"].kind != JNull:
|
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.leftMargin: this.isGroupChatOrOneToOne ? Style.current.padding : Style.current.padding + 4
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 4
|
anchors.topMargin: 4
|
||||||
|
anchors.right: moreActionsBtn.left
|
||||||
|
anchors.rightMargin: Style.current.padding + moreActionsBtn.width
|
||||||
sourceComponent: this.isGroupChatOrOneToOne ? chatInfoButton : chatInfo
|
sourceComponent: this.isGroupChatOrOneToOne ? chatInfoButton : chatInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,15 +66,11 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
|
||||||
height: parent.height
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Style.current.smallPadding
|
|
||||||
spacing: 12
|
|
||||||
|
|
||||||
StatusContextMenuButton {
|
StatusContextMenuButton {
|
||||||
id: moreActionsBtn
|
id: moreActionsBtn
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.smallPadding
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var menu = chatContextMenu;
|
var menu = chatContextMenu;
|
||||||
|
@ -180,7 +178,7 @@ Item {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
ActivityCenter {
|
ActivityCenter {
|
||||||
id: activityCenter
|
id: activityCenter
|
||||||
|
|
|
@ -8,7 +8,7 @@ import "../components"
|
||||||
import "./"
|
import "./"
|
||||||
|
|
||||||
Button {
|
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
|
implicitHeight: communityImage.height + Style.current.padding
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
|
|
|
@ -8,6 +8,8 @@ import "../../../../shared/status"
|
||||||
|
|
||||||
ModalPopup {
|
ModalPopup {
|
||||||
property string communityId
|
property string communityId
|
||||||
|
property QtObject channel
|
||||||
|
property bool isEdit: false
|
||||||
property string categoryId: ""
|
property string categoryId: ""
|
||||||
readonly property int maxDescChars: 140
|
readonly property int maxDescChars: 140
|
||||||
property string nameValidationError: ""
|
property string nameValidationError: ""
|
||||||
|
@ -16,10 +18,16 @@ ModalPopup {
|
||||||
descriptionTextArea.isValid
|
descriptionTextArea.isValid
|
||||||
|
|
||||||
id: popup
|
id: popup
|
||||||
height: 500
|
height: 400
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
nameInput.text = "";
|
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)
|
nameInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
}
|
}
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
|
@ -59,7 +67,7 @@ ModalPopup {
|
||||||
placeholderText: qsTrId("a-cool-name")
|
placeholderText: qsTrId("a-cool-name")
|
||||||
validationError: popup.nameValidationError
|
validationError: popup.nameValidationError
|
||||||
|
|
||||||
property bool isValid: false
|
property bool isValid: false || isEdit
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
if (text.includes(" ")) {
|
if (text.includes(" ")) {
|
||||||
|
@ -97,7 +105,7 @@ ModalPopup {
|
||||||
anchors.topMargin: Style.current.bigPadding
|
anchors.topMargin: Style.current.bigPadding
|
||||||
customHeight: 88
|
customHeight: 88
|
||||||
|
|
||||||
property bool isValid: false
|
property bool isValid: false || isEdit
|
||||||
onTextChanged: validate()
|
onTextChanged: validate()
|
||||||
|
|
||||||
function resetValidation() {
|
function resetValidation() {
|
||||||
|
@ -127,62 +135,80 @@ ModalPopup {
|
||||||
color: !descriptionTextArea.validationError ? Style.current.textColor : Style.current.danger
|
color: !descriptionTextArea.validationError ? Style.current.textColor : Style.current.danger
|
||||||
}
|
}
|
||||||
|
|
||||||
Separator {
|
// Separator {
|
||||||
id: separator1
|
// id: separator1
|
||||||
anchors.top: charLimit.bottom
|
// anchors.top: charLimit.bottom
|
||||||
anchors.topMargin: Style.current.bigPadding
|
// anchors.topMargin: Style.current.bigPadding
|
||||||
}
|
// }
|
||||||
|
|
||||||
Item {
|
// TODO: use the switch below to enable private channels
|
||||||
id: privateSwitcher
|
// Item {
|
||||||
height: privateSwitch.height
|
// id: privateSwitcher
|
||||||
width: parent.width
|
// height: privateSwitch.height
|
||||||
visible: false
|
// width: parent.width
|
||||||
anchors.top: separator1.bottom
|
// anchors.top: separator1.bottom
|
||||||
anchors.topMargin: Style.current.smallPadding * 2
|
// anchors.topMargin: Style.current.smallPadding * 2
|
||||||
|
|
||||||
StyledText {
|
// StyledText {
|
||||||
//% "Private channel"
|
// //% "Private channel"
|
||||||
text: qsTrId("private-channel")
|
// text: qsTrId("private-channel")
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
// anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
// }
|
||||||
|
|
||||||
StatusSwitch {
|
// StatusSwitch {
|
||||||
id: privateSwitch
|
// id: privateSwitch
|
||||||
anchors.right: parent.right
|
// anchors.right: parent.right
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
StyledText {
|
// StyledText {
|
||||||
id: privateExplanation
|
// id: privateExplanation
|
||||||
anchors.top: separator1.bottom
|
// anchors.top: privateSwitcher.bottom
|
||||||
color: Style.current.secondaryText
|
// color: Style.current.secondaryText
|
||||||
wrapMode: Text.WordWrap
|
// wrapMode: Text.WordWrap
|
||||||
anchors.topMargin: Style.current.smallPadding * 2
|
// anchors.topMargin: Style.current.smallPadding * 2
|
||||||
width: parent.width
|
// width: parent.width
|
||||||
//% "By making a channel private, only members with selected permission will be able to access it"
|
// //% "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")
|
// text: qsTrId("by-making-a-channel-private--only-members-with-selected-permission-will-be-able-to-access-it")
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: StatusButton {
|
footer: StatusButton {
|
||||||
enabled: popup.isValid
|
enabled: popup.isValid
|
||||||
|
text: isEdit ?
|
||||||
|
qsTr("Save") :
|
||||||
//% "Create"
|
//% "Create"
|
||||||
text: qsTrId("create")
|
qsTrId("create")
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (!validate()) {
|
if (!validate()) {
|
||||||
scrollView.scrollBackUp()
|
scrollView.scrollBackUp()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const error = chatsModel.communities.createCommunityChannel(communityId,
|
let error = "";
|
||||||
|
if (!isEdit) {
|
||||||
|
error = chatsModel.createCommunityChannel(communityId,
|
||||||
Utils.filterXSS(nameInput.text),
|
Utils.filterXSS(nameInput.text),
|
||||||
Utils.filterXSS(descriptionTextArea.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) {
|
if (error) {
|
||||||
creatingError.text = error
|
const errorJson = JSON.parse(error)
|
||||||
|
creatingError.text = errorJson.error
|
||||||
return creatingError.open()
|
return creatingError.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,14 @@ PopupMenu {
|
||||||
icon.height: 16
|
icon.height: 16
|
||||||
onTriggered: chatsModel.clearChatHistoryByIndex(channelContextMenu.channelIndex)
|
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 {
|
Separator {
|
||||||
visible: deleteAction.enabled
|
visible: deleteAction.enabled
|
||||||
|
|
|
@ -280,6 +280,16 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: editChannelPopup
|
||||||
|
CreateChannelPopup {
|
||||||
|
isEdit: true
|
||||||
|
onClosed: {
|
||||||
|
destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ToastMessage {
|
ToastMessage {
|
||||||
id: toastMessage
|
id: toastMessage
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ Item {
|
||||||
property string profileImage: realChatType === Constants.chatTypeOneToOne ? appMain.getProfileImage(chatId) || "" : ""
|
property string profileImage: realChatType === Constants.chatTypeOneToOne ? appMain.getProfileImage(chatId) || "" : ""
|
||||||
|
|
||||||
height: 48
|
height: 48
|
||||||
width: nameAndInfo.width + chatIdenticon.width + Style.current.smallPadding
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
enabled: realChatType === Constants.chatTypeOneToOne
|
enabled: realChatType === Constants.chatTypeOneToOne
|
||||||
|
@ -52,7 +51,7 @@ Item {
|
||||||
Item {
|
Item {
|
||||||
id: nameAndInfo
|
id: nameAndInfo
|
||||||
height: chatName.height + chatInfo.height
|
height: chatName.height + chatInfo.height
|
||||||
width: childrenRect.width
|
width: parent.width
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: chatIdenticon.right
|
anchors.left: chatIdenticon.right
|
||||||
anchors.leftMargin: Style.current.smallPadding
|
anchors.leftMargin: Style.current.smallPadding
|
||||||
|
@ -116,7 +115,13 @@ Item {
|
||||||
StyledText {
|
StyledText {
|
||||||
id: chatInfo
|
id: chatInfo
|
||||||
color: Style.current.secondaryText
|
color: Style.current.secondaryText
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
text: {
|
text: {
|
||||||
|
if (root.chatType === Constants.chatTypeCommunity) {
|
||||||
|
return chatsModel.activeChannel.description
|
||||||
|
}
|
||||||
switch(root.realChatType){
|
switch(root.realChatType){
|
||||||
//% "Public chat"
|
//% "Public chat"
|
||||||
case Constants.chatTypePublic: return qsTrId("public-chat")
|
case Constants.chatTypePublic: return qsTrId("public-chat")
|
||||||
|
@ -139,6 +144,7 @@ Item {
|
||||||
}
|
}
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
anchors.top: chatName.bottom
|
anchors.top: chatName.bottom
|
||||||
|
anchors.topMargin: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 10becb490228d416ff361bdb8a965537b4803af5
|
Subproject commit b395144704f29c9e1f4fd11714d1031a10160ad1
|
Loading…
Reference in New Issue