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 ./channels_list
import ../../utils/image_utils
import ../../../status/signals/types as signal_types
import ../../../status/libstatus/types
logScope:
@ -222,9 +224,26 @@ QtObject:
self.joinedCommunityList.addCommunityItemToList(community)
self.setActiveCommunity(community.id)
self.communitiesChanged()
except Exception as e:
except RpcException as e:
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.} =
result = ""

View File

@ -143,7 +143,7 @@ QtObject:
let topLeft = self.createIndex(index, index, nil)
let bottomRight = self.createIndex(index, index, nil)
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) =
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 =
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 =
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
}]).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()
proc createCommunityChannel*(communityId: string, name: string, description: string): Chat =

View File

@ -213,6 +213,14 @@ Rectangle {
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
anchors.fill: parent
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();
}
hoverEnabled: true

View File

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

View File

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

View File

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

View File

@ -78,14 +78,6 @@ Rectangle {
anchors.bottom: parent.bottom
anchors.bottomMargin: Style.current.padding
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()
}
}

View File

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