feat: edit communities

Allow editing of Community name, description, image, colour, and access.
This commit is contained in:
Eric Mastro 2021-05-24 13:09:49 +10:00 committed by Eric Mastro
parent 4e477a5b64
commit 24d8e429b8
12 changed files with 157 additions and 79 deletions

View File

@ -6,6 +6,8 @@ import ./community_item
import ./community_membership_request_list import ./community_membership_request_list
import ./channels_list import ./channels_list
import ../../utils/image_utils import ../../utils/image_utils
import ../../../status/signals/types as signal_types
import ../../../status/libstatus/types
logScope: logScope:
@ -222,9 +224,26 @@ QtObject:
self.joinedCommunityList.addCommunityItemToList(community) self.joinedCommunityList.addCommunityItemToList(community)
self.setActiveCommunity(community.id) self.setActiveCommunity(community.id)
self.communitiesChanged() self.communitiesChanged()
except Exception as e: except RpcException as e:
error "Error creating the community", msg = e.msg error "Error creating the community", msg = e.msg
result = fmt"Error creating the community: {e.msg}" result = StatusGoError(error: e.msg).toJson
proc editCommunity*(self: CommunitiesView, id: string, name: string, description: string, access: int, ensOnly: bool, color: string, imagePath: string, aX: int, aY: int, bX: int, bY: int): string {.slot.} =
result = ""
try:
var image = image_utils.formatImagePath(imagePath)
let community = self.status.chat.editCommunity(id, name, description, access, ensOnly, color, image, aX, aY, bX, bY)
if (community.id == ""):
return "Community was not edited. Please try again later"
self.communityList.replaceCommunity(community)
self.joinedCommunityList.replaceCommunity(community)
self.setActiveCommunity(community.id)
self.communitiesChanged()
self.activeCommunityChanged()
except RpcException as e:
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.} = proc createCommunityChannel*(self: CommunitiesView, communityId: string, name: string, description: string, categoryId: string): string {.slot.} =
result = "" result = ""

View File

@ -143,7 +143,7 @@ QtObject:
let topLeft = self.createIndex(index, index, nil) let topLeft = self.createIndex(index, index, nil)
let bottomRight = self.createIndex(index, index, nil) let bottomRight = self.createIndex(index, index, nil)
self.communities[index] = community self.communities[index] = community
self.dataChanged(topLeft, bottomRight, @[CommunityRoles.Name.int, CommunityRoles.Description.int, CommunityRoles.UnviewedMessagesCount.int]) self.dataChanged(topLeft, bottomRight, @[CommunityRoles.Name.int, CommunityRoles.Description.int, CommunityRoles.UnviewedMessagesCount.int, CommunityRoles.ThumbnailImage.int])
proc removeCategoryFromCommunity*(self: CommunityList, communityId: string, categoryId:string) = proc removeCategoryFromCommunity*(self: CommunityList, communityId: string, categoryId:string) =
var community = self.getCommunityById(communityId) var community = self.getCommunityById(communityId)

View File

@ -447,6 +447,9 @@ proc getJoinedComunities*(self: ChatModel): seq[Community] =
proc createCommunity*(self: ChatModel, name: string, description: string, access: int, ensOnly: bool, color: string, imageUrl: string, aX: int, aY: int, bX: int, bY: int): Community = proc createCommunity*(self: ChatModel, name: string, description: string, access: int, ensOnly: bool, color: string, imageUrl: string, aX: int, aY: int, bX: int, bY: int): Community =
result = status_chat.createCommunity(name, description, access, ensOnly, color, imageUrl, aX, aY, bX, bY) result = status_chat.createCommunity(name, description, access, ensOnly, color, imageUrl, aX, aY, bX, bY)
proc editCommunity*(self: ChatModel, id: string, name: string, description: string, access: int, ensOnly: bool, color: string, imageUrl: string, aX: int, aY: int, bX: int, bY: int): Community =
result = status_chat.editCommunity(id, name, description, access, ensOnly, color, imageUrl, aX, aY, bX, bY)
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)

View File

@ -304,7 +304,34 @@ proc createCommunity*(name: string, description: string, access: int, ensOnly: b
"imageBy": bY "imageBy": bY
}]).parseJSON() }]).parseJSON()
if rpcResult{"result"}.kind != JNull: 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"]["communities"][0].toCommunity()
proc editCommunity*(communityId: string, name: string, description: string, access: int, ensOnly: bool, color: string, imageUrl: string, aX: int, aY: int, bX: int, bY: int): Community =
let rpcResult = callPrivateRPC("editCommunity".prefix, %*[{
# TODO this will need to be renamed membership (small m)
"CommunityID": communityId,
"Membership": access,
"name": name,
"description": description,
"ensOnly": ensOnly,
"color": color,
"image": imageUrl,
"imageAx": aX,
"imageAy": aY,
"imageBx": bX,
"imageBy": bY
}]).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"]["communities"][0].toCommunity() result = rpcResult["result"]["communities"][0].toCommunity()
proc createCommunityChannel*(communityId: string, name: string, description: string): Chat = proc createCommunityChannel*(communityId: string, name: string, description: string): Chat =

View File

@ -213,6 +213,14 @@ Rectangle {
CommunityProfilePopup { CommunityProfilePopup {
id: communityProfilePopup id: communityProfilePopup
communityId: chatsModel.communities.activeCommunity.id
name: chatsModel.communities.activeCommunity.name
description: chatsModel.communities.activeCommunity.description
access: chatsModel.communities.activeCommunity.access
nbMembers: chatsModel.communities.activeCommunity.nbMembers
isAdmin: chatsModel.communities.activeCommunity.admin
source: chatsModel.communities.activeCommunity.thumbnailImage
communityColor: chatsModel.communities.activeCommunity.communityColor
} }
} }
} }

View File

@ -79,15 +79,6 @@ Button {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
anchors.fill: parent anchors.fill: parent
onPressed: { onPressed: {
communityProfilePopup.communityId = chatsModel.communities.activeCommunity.id;
communityProfilePopup.name = chatsModel.communities.activeCommunity.name;
communityProfilePopup.description = chatsModel.communities.activeCommunity.description;
communityProfilePopup.access = chatsModel.communities.activeCommunity.access;
communityProfilePopup.nbMembers = chatsModel.communities.activeCommunity.nbMembers;
communityProfilePopup.isAdmin = chatsModel.communities.activeCommunity.admin
communityProfilePopup.source = chatsModel.communities.activeCommunity.thumbnailImage
communityProfilePopup.communityColor = chatsModel.communities.activeCommunity.communityColor
communityProfilePopup.open(); communityProfilePopup.open();
} }
hoverEnabled: true hoverEnabled: true

View File

@ -10,15 +10,14 @@ import "../../../../shared/status"
import "../ContactsColumn" import "../ContactsColumn"
ModalPopup { ModalPopup {
property QtObject community: chatsModel.communities.activeCommunity property string communityId: chatsModel.communities.activeCommunity.id
property string communityId: community.id property string name: chatsModel.communities.activeCommunity.name
property string name: community.name property string description: chatsModel.communities.activeCommunity.description
property string description: community.description property int access: chatsModel.communities.activeCommunity.access
property int access: community.access property string source: chatsModel.communities.activeCommunity.source
property string source: "" property string communityColor: chatsModel.communities.activeCommunity.communityColor
property string communityColor: "" property int nbMembers: chatsModel.communities.activeCommunity.nbMembers
property int nbMembers: community.nbMembers property bool isAdmin: chatsModel.communities.activeCommunity.isAdmin
property bool isAdmin: false
height: stack.currentItem.height + modalHeader.height + modalFooter.height + Style.current.padding * 3 height: stack.currentItem.height + modalHeader.height + modalFooter.height + Style.current.padding * 3
id: popup id: popup
@ -126,6 +125,7 @@ ModalPopup {
CommunityProfilePopupMembersList { CommunityProfilePopupMembersList {
headerTitle: qsTr("Members") headerTitle: qsTr("Members")
headerDescription: popup.nbMembers.toString() headerDescription: popup.nbMembers.toString()
members: chatsModel.communities.activeCommunity.members
} }
} }
@ -133,7 +133,7 @@ ModalPopup {
id: profileOverview id: profileOverview
CommunityProfilePopupOverview { CommunityProfilePopupOverview {
property bool useLetterIdenticon: !!!popup.source property bool useLetterIdenticon: !!!popup.source
headerTitle: popup.name headerTitle: chatsModel.communities.activeCommunity.name
headerDescription: { headerDescription: {
switch(access) { switch(access) {
//% "Public community" //% "Public community"
@ -146,8 +146,8 @@ ModalPopup {
default: return qsTrId("unknown-community"); default: return qsTrId("unknown-community");
} }
} }
headerImageSource: popup.source headerImageSource: chatsModel.communities.activeCommunity.thumbnailImage
description: popup.description description: chatsModel.communities.activeCommunity.description
} }
} }
} }

View File

@ -12,6 +12,7 @@ Item {
property string headerTitle: "" property string headerTitle: ""
property string headerDescription: "" property string headerDescription: ""
property string headerImageSource: "" property string headerImageSource: ""
property alias members: memberList.model
height: 450 height: 450
CommunityPopupButton { CommunityPopupButton {
@ -74,7 +75,6 @@ Item {
anchors.bottomMargin: Style.current.bigPadding anchors.bottomMargin: Style.current.bigPadding
spacing: 4 spacing: 4
clip: true clip: true
model: community.members
delegate: Rectangle { delegate: Rectangle {
id: contactRow id: contactRow
width: parent.width width: parent.width

View File

@ -202,13 +202,14 @@ Item {
} }
Loader { Loader {
// TODO once Edit is vailable in the app, put back isAdmin // TODO: once Edit is vailable in the app, put back isAdmin
active: false//isAdmin active: isAdmin
width: parent.width width: parent.width
sourceComponent: CommunityPopupButton { sourceComponent: CommunityPopupButton {
//% "Edit community" //% "Edit community"
label: qsTrId("edit-community") label: qsTrId("edit-community")
iconName: "edit" iconName: "edit"
type: globalSettings.theme === Universal.Dark ? "secondary" : "primary"
onClicked: openPopup(editCommunityPopup) onClicked: openPopup(editCommunityPopup)
} }
} }

View File

@ -78,14 +78,6 @@ Rectangle {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: Style.current.padding anchors.bottomMargin: Style.current.padding
onClicked: { onClicked: {
communityProfilePopup.communityId = chatsModel.communities.activeCommunity.id;
communityProfilePopup.name = chatsModel.communities.activeCommunity.name;
communityProfilePopup.description = chatsModel.communities.activeCommunity.description;
communityProfilePopup.access = chatsModel.communities.activeCommunity.access;
communityProfilePopup.nbMembers = chatsModel.communities.activeCommunity.nbMembers;
communityProfilePopup.isAdmin = chatsModel.communities.activeCommunity.admin;
communityProfilePopup.source = chatsModel.communities.activeCommunity.thumbnailImage
communityProfilePopup.communityColor = chatsModel.communities.activeCommunity.communityColor
communityProfilePopup.open() communityProfilePopup.open()
} }
} }

View File

@ -24,6 +24,11 @@ ModalPopup {
if (isEdit) { if (isEdit) {
nameInput.text = community.name; nameInput.text = community.name;
descriptionTextArea.text = community.description; descriptionTextArea.text = community.description;
colorPicker.defaultColor = community.communityColor;
if (community.largeImage) {
addImageButton.selectedImage = community.largeImage
}
membershipRequirementSettingPopup.checkedMembership = community.access
} }
nameInput.forceActiveFocus(Qt.MouseFocusReason) nameInput.forceActiveFocus(Qt.MouseFocusReason)
} }
@ -279,7 +284,7 @@ ModalPopup {
} }
Input { Input {
property string defaultColor: "#4360DF" property string defaultColor: Style.current.blue
property bool isValid: true property bool isValid: true
id: colorPicker id: colorPicker
@ -348,9 +353,9 @@ ModalPopup {
text: qsTr("Membership requirement") text: qsTr("Membership requirement")
currentValue: { currentValue: {
switch (membershipRequirementSettingPopup.checkedMembership) { switch (membershipRequirementSettingPopup.checkedMembership) {
case Constants.communityChatInvitationOnlyAccess: return qsTr("Require invite from another member") case Constants.communityChatInvitationOnlyAccess: return qsTr("Require invite from another member")
case Constants.communityChatOnRequestAccess: return qsTr("Require approval") case Constants.communityChatOnRequestAccess: return qsTr("Require approval")
default: return qsTr("No requirement") default: return qsTr("No requirement")
} }
} }
onClicked: { onClicked: {
@ -418,49 +423,78 @@ ModalPopup {
} }
} }
footer: StatusButton { footer: Item {
text: isEdit ? anchors.left: parent.left
//% "Edit"
qsTrId("edit") :
//% "Create"
qsTrId("create")
anchors.right: parent.right anchors.right: parent.right
onClicked: { anchors.bottom: parent.bottom
if (!validate()) { height: btnCreateEdit.height
scrollView.scrollBackUp()
return
}
let error = false; StatusRoundButton {
if(isEdit) { id: btnBack
console.log("TODO: implement this (not available in status-go yet)"); anchors.left: parent.left
} else { visible: isEdit
error = chatsModel.communities.createCommunity(Utils.filterXSS(nameInput.text), icon.name: "arrow-right"
Utils.filterXSS(descriptionTextArea.text), icon.width: 20
membershipRequirementSettingPopup.checkedMembership, icon.height: 16
false, // ensOnlySwitch.switchChecked, // TODO: rotation: 180
colorPicker.text, onClicked: popup.destroy()
addImageButton.selectedImage,
imageCropperModal.aX,
imageCropperModal.aY,
imageCropperModal.bX,
imageCropperModal.bY)
}
if (error) {
creatingError.text = error
return creatingError.open()
}
popup.close()
} }
StatusButton {
id: btnCreateEdit
text: isEdit ?
//% "Save"
qsTrId("Save") :
//% "Create"
qsTrId("create")
anchors.right: parent.right
onClicked: {
if (!validate()) {
scrollView.scrollBackUp()
return
}
MessageDialog { let error = false;
id: creatingError if(isEdit) {
//% "Error creating the community" error = chatsModel.communities.editCommunity(community.id,
title: qsTrId("error-creating-the-community") Utils.filterXSS(nameInput.text),
icon: StandardIcon.Critical Utils.filterXSS(descriptionTextArea.text),
standardButtons: StandardButton.Ok membershipRequirementSettingPopup.checkedMembership,
false,
colorPicker.text,
// to retain the existing image, pass "" for the image path
addImageButton.selectedImage === community.largeImage ? "" : addImageButton.selectedImage,
imageCropperModal.aX,
imageCropperModal.aY,
imageCropperModal.bX,
imageCropperModal.bY)
} else {
error = chatsModel.communities.createCommunity(Utils.filterXSS(nameInput.text),
Utils.filterXSS(descriptionTextArea.text),
membershipRequirementSettingPopup.checkedMembership,
false, // ensOnlySwitch.switchChecked, // TODO:
colorPicker.text,
addImageButton.selectedImage,
imageCropperModal.aX,
imageCropperModal.aY,
imageCropperModal.bX,
imageCropperModal.bY)
}
if (error) {
creatingError.text = error.error
return creatingError.open()
}
popup.close()
}
MessageDialog {
id: creatingError
//% "Error creating the community"
title: qsTrId("error-creating-the-community")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
} }
} }
} }

View File

@ -274,6 +274,9 @@ RowLayout {
id: editCommunityPopup id: editCommunityPopup
CreateCommunityPopup { CreateCommunityPopup {
isEdit: true isEdit: true
onClosed: {
destroy()
}
} }
} }