feat(ChannelPermissions): Add permissions section in create/edit channel popup
Changes: 1. Make PermissionsView/EditPermissionsView configurable to support channel permissions config 2. Adding channel permissions support in the create/edit channel popup 3. Connect the channel permissions to backend 4. Cleaning unneeded emojiPopup
This commit is contained in:
parent
56d67f5ba2
commit
cf82772aed
|
@ -27,6 +27,14 @@ Item {
|
|||
property int padding: Style.current.halfPadding
|
||||
|
||||
signal searchButtonClicked()
|
||||
signal displayEditChannelPopup(string chatId,
|
||||
string chatName,
|
||||
string chatDescription,
|
||||
string chatEmoji,
|
||||
string chatColor,
|
||||
string chatCategoryId,
|
||||
int channelPosition,
|
||||
var deleteDialog)
|
||||
|
||||
function addRemoveGroupMember() {
|
||||
root.state = d.stateMembersSelectorContent
|
||||
|
@ -140,7 +148,6 @@ Item {
|
|||
ChatContextMenuView {
|
||||
id: contextMenu
|
||||
objectName: "moreOptionsContextMenu"
|
||||
emojiPopup: root.emojiPopup
|
||||
showDebugOptions: root.rootStore.isDebugEnabled
|
||||
openHandler: function () {
|
||||
if(!chatContentModule) {
|
||||
|
@ -218,17 +225,11 @@ Item {
|
|||
onDisplayProfilePopup: {
|
||||
Global.openProfilePopup(publicKey)
|
||||
}
|
||||
|
||||
onEditCommunityChannel: {
|
||||
root.rootStore.editCommunityChannel(
|
||||
chatId,
|
||||
newName,
|
||||
newDescription,
|
||||
newEmoji,
|
||||
newColor,
|
||||
newCategory,
|
||||
channelPosition // TODO change this to the signal once it is modifiable
|
||||
)
|
||||
onDisplayEditChannelPopup: {
|
||||
root.displayEditChannelPopup(chatId, chatName, chatDescription,
|
||||
chatEmoji, chatColor,
|
||||
chatCategoryId, channelPosition,
|
||||
contextMenu.deleteChatConfirmationDialog);
|
||||
}
|
||||
onAddRemoveGroupMember: {
|
||||
root.addRemoveGroupMember()
|
||||
|
|
|
@ -166,6 +166,19 @@ StatusSectionLayout {
|
|||
rootStore: root.rootStore
|
||||
emojiPopup: root.emojiPopup
|
||||
onSearchButtonClicked: root.openAppSearch()
|
||||
onDisplayEditChannelPopup: {
|
||||
Global.openPopup(contactColumnLoader.item.createChannelPopup, {
|
||||
isEdit: true,
|
||||
chatId: chatId,
|
||||
channelName: chatName,
|
||||
channelDescription: chatDescription,
|
||||
channelEmoji: chatEmoji,
|
||||
channelColor: chatColor,
|
||||
categoryId: chatCategoryId,
|
||||
channelPosition: channelPosition,
|
||||
deleteChatConfirmationDialog: deleteDialog
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,6 @@ Item {
|
|||
|
||||
popupMenu: ChatContextMenuView {
|
||||
id: chatContextMenuView
|
||||
emojiPopup: root.emojiPopup
|
||||
showDebugOptions: root.store.isDebugEnabled
|
||||
|
||||
openHandler: function (id) {
|
||||
|
|
|
@ -58,23 +58,9 @@ QtObject {
|
|||
d.editPermission(key, permissionType, holdings, channels, isPrivate)
|
||||
}
|
||||
|
||||
// Function duplicating a permission. The new permission will be have a different id and key
|
||||
function duplicatePermission(index) {
|
||||
const permission = channelPermissionsModel.get(index)
|
||||
|
||||
if (!permission)
|
||||
return
|
||||
|
||||
permission.id = Utils.uuid()
|
||||
permission.key = Utils.uuid()
|
||||
permission.holdingsListModel = d.newHoldingsModel(StatusQUtils.ModelUtils.modelToArray(permission.holdingsListModel))
|
||||
permission.channelsListModel = d.newChannelsModel(StatusQUtils.ModelUtils.modelToArray(permission.channelsListModel))
|
||||
channelPermissionsModel.append(permission)
|
||||
}
|
||||
|
||||
// Function removing a permission by index
|
||||
function removePermission(index) {
|
||||
channelPermissionsModel.remove(index, 1);
|
||||
return channelPermissionsModel.remove(index, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,9 +5,11 @@ import AppLayouts.Communities.controls 1.0
|
|||
import AppLayouts.Communities.layouts 1.0
|
||||
import AppLayouts.Communities.views 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared.popups 1.0
|
||||
|
||||
StackView {
|
||||
|
@ -17,6 +19,8 @@ StackView {
|
|||
required property var assetsModel
|
||||
required property var collectiblesModel
|
||||
required property var channelsModel
|
||||
property bool showChannelSelector: true
|
||||
property alias initialPage: initialItem
|
||||
|
||||
// id, name, image, color, owner properties expected
|
||||
required property var communityDetails
|
||||
|
@ -38,8 +42,13 @@ StackView {
|
|||
pop(StackView.Immediate)
|
||||
}
|
||||
|
||||
function pushEditView(properties) {
|
||||
root.push(newPermissionView, properties, StackView.Immediate);
|
||||
}
|
||||
|
||||
// Community Permissions possible view contents:
|
||||
initialItem: SettingsPage {
|
||||
id: initialItem
|
||||
implicitWidth: 0
|
||||
|
||||
title: qsTr("Permissions")
|
||||
|
@ -52,7 +61,12 @@ StackView {
|
|||
onClicked: root.push(newPermissionView, StackView.Immediate)
|
||||
}
|
||||
|
||||
contentItem: PermissionsView {
|
||||
contentItem: StatusScrollView {
|
||||
contentHeight: (permissionsView.height + topPadding)
|
||||
topPadding: permissionsView.topPadding
|
||||
padding: 0
|
||||
PermissionsView {
|
||||
id: permissionsView
|
||||
permissionsModel: root.permissionsModel
|
||||
assetsModel: root.assetsModel
|
||||
collectiblesModel: root.collectiblesModel
|
||||
|
@ -72,7 +86,7 @@ StackView {
|
|||
isPrivateToEditValue: item.isPrivate
|
||||
}
|
||||
|
||||
root.push(newPermissionView, properties, StackView.Immediate)
|
||||
root.pushEditView(properties);
|
||||
}
|
||||
|
||||
onDuplicatePermissionRequested: {
|
||||
|
@ -85,7 +99,7 @@ StackView {
|
|||
isPrivateToEditValue: item.isPrivate
|
||||
}
|
||||
|
||||
root.push(newPermissionView, properties, StackView.Immediate)
|
||||
root.pushEditView(properties);
|
||||
}
|
||||
|
||||
onRemovePermissionRequested: {
|
||||
|
@ -94,26 +108,40 @@ StackView {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: newPermissionView
|
||||
|
||||
SettingsPage {
|
||||
id: newPermissionViewPage
|
||||
|
||||
implicitWidth: 0
|
||||
|
||||
title: isEditState ? qsTr("Edit permission") : qsTr("New permission")
|
||||
|
||||
property alias isDirty: editPermissionView.dirty
|
||||
property alias isFullyFilled: editPermissionView.isFullyFilled
|
||||
property alias isPrivateToEditValue: editPermissionView.isPrivate
|
||||
property alias permissionTypeToEdit: editPermissionView.permissionType
|
||||
property alias holdingsToEditModel: editPermissionView.selectedHoldingsModel
|
||||
property alias channelsToEditModel: editPermissionView.selectedChannelsModel
|
||||
property alias permissionTypeToEdit: editPermissionView.permissionType
|
||||
property alias isPrivateToEditValue: editPermissionView.isPrivate
|
||||
|
||||
property bool holdingsRequired: editPermissionView.dirtyValues.holdingsRequired
|
||||
|
||||
property string permissionKeyToEdit
|
||||
readonly property bool isEditState: !!permissionKeyToEdit
|
||||
|
||||
readonly property alias toast: settingsDirtyToastMessage
|
||||
|
||||
function resetChanges() {
|
||||
editPermissionView.resetChanges();
|
||||
}
|
||||
function updatePermission() {
|
||||
editPermissionView.saveChanges();
|
||||
}
|
||||
function createPermission() {
|
||||
editPermissionView.createPermissionClicked();
|
||||
}
|
||||
|
||||
contentItem: EditPermissionView {
|
||||
id: editPermissionView
|
||||
|
||||
|
@ -123,7 +151,7 @@ StackView {
|
|||
collectiblesModel: root.collectiblesModel
|
||||
channelsModel: root.channelsModel
|
||||
communityDetails: root.communityDetails
|
||||
|
||||
showChannelSelector: root.showChannelSelector
|
||||
isEditState: newPermissionViewPage.isEditState
|
||||
holdingsRequired: selectedHoldingsModel
|
||||
? selectedHoldingsModel.count > 0 : false
|
||||
|
@ -191,15 +219,19 @@ StackView {
|
|||
dirtyValues.selectedHoldingsModel,
|
||||
["key", "type", "amount"]) : []
|
||||
|
||||
const channels = ModelUtils.modelToArray(
|
||||
dirtyValues.selectedChannelsModel, ["key"])
|
||||
const channels = root.showChannelSelector ?
|
||||
ModelUtils.modelToArray(
|
||||
dirtyValues.selectedChannelsModel, ["key"]) :
|
||||
ModelUtils.modelToArray(selectedChannelsModel, ["key"])
|
||||
|
||||
root.createPermissionRequested(
|
||||
dirtyValues.permissionType, holdings, channels,
|
||||
dirtyValues.isPrivate)
|
||||
|
||||
if (root.showChannelSelector) {
|
||||
root.pop(StackView.Immediate)
|
||||
}
|
||||
}
|
||||
|
||||
onNavigateToMintTokenSettings: root.navigateToMintTokenSettings(isAssetType)
|
||||
|
||||
|
@ -261,7 +293,8 @@ StackView {
|
|||
// delay to avoid toast blinking on entry
|
||||
settingsDirtyToastMessage.active = Qt.binding(
|
||||
() => editPermissionView.isEditState &&
|
||||
editPermissionView.dirty)
|
||||
editPermissionView.dirty &&
|
||||
root.showChannelSelector)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,14 @@ import QtQuick 2.15
|
|||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Dialogs 1.3
|
||||
import QtQml 2.15
|
||||
import QtQml.Models 2.15
|
||||
|
||||
import utils 1.0
|
||||
import shared.panels 1.0
|
||||
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||
|
@ -15,8 +18,10 @@ import StatusQ.Controls.Validators 0.1
|
|||
import StatusQ.Components 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import AppLayouts.Communities.controls 1.0
|
||||
import AppLayouts.Communities.views 1.0
|
||||
import AppLayouts.Communities.panels 1.0
|
||||
import AppLayouts.Communities.models 1.0
|
||||
import AppLayouts.Communities.controls 1.0
|
||||
|
||||
StatusStackModal {
|
||||
id: root
|
||||
|
@ -26,9 +31,12 @@ StatusStackModal {
|
|||
property bool isDiscordImport // creating new or importing from discord?
|
||||
property bool isEdit: false
|
||||
property bool isDeleteable: false
|
||||
property bool viewOnlyCanAddReaction
|
||||
property bool hideIfPermissionsNotMet
|
||||
|
||||
property string communityId: ""
|
||||
property string chatId: ""
|
||||
property string chatId: "_newChannel"
|
||||
|
||||
property string categoryId: ""
|
||||
property string channelName: ""
|
||||
property string channelDescription: ""
|
||||
|
@ -39,20 +47,90 @@ StatusStackModal {
|
|||
readonly property int communityColorValidator: Utils.Validate.NoEmpty
|
||||
| Utils.Validate.TextHexColor
|
||||
|
||||
property var activeCommunity
|
||||
required property var assetsModel
|
||||
required property var collectiblesModel
|
||||
required property var permissionsModel
|
||||
|
||||
required property var channelsModel
|
||||
|
||||
readonly property int maxChannelNameLength: 24
|
||||
readonly property int maxChannelDescLength: 140
|
||||
|
||||
// channel signals
|
||||
signal createCommunityChannel(string chName, string chDescription, string chEmoji, string chColor, string chCategoryId)
|
||||
signal editCommunityChannel(string chName, string chDescription, string chEmoji, string chColor, string chCategoryId)
|
||||
signal deleteCommunityChannel()
|
||||
|
||||
// Permissions signals:
|
||||
// permissions arg is a list of objects with the following properties:
|
||||
// - key: string
|
||||
// - id: string
|
||||
// - permissionType: string
|
||||
// - holdings: list of objects with the following properties:
|
||||
// - key: string
|
||||
// - type: string
|
||||
// - amount: string
|
||||
// - channels: list of objects with the following properties:
|
||||
// - key: string
|
||||
// - isPrivate: bool
|
||||
signal addPermissions(var permissions)
|
||||
signal removePermissions(var permissions)
|
||||
signal editPermissions(var permissions)
|
||||
signal setViewOnlyCanAddReaction(bool checked)
|
||||
signal setHideIfPermissionsNotMet(bool checked)
|
||||
|
||||
width: 640
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
currentIndex: d.currentPage
|
||||
|
||||
enum CurrentPage {
|
||||
ChannelDetails, //0
|
||||
ColorPicker, //1
|
||||
ChannelPermissions, //2
|
||||
DiscordImportUploadFile, //3
|
||||
DiscordImportUploadStart //4
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property int currentPage: CreateChannelPopup.CurrentPage.ChannelDetails
|
||||
|
||||
readonly property QtObject communityDetails: QtObject {
|
||||
readonly property string id: root.activeCommunity.id
|
||||
readonly property string name: root.activeCommunity.name
|
||||
readonly property string image: root.activeCommunity.image
|
||||
readonly property string color: root.activeCommunity.color
|
||||
readonly property bool owner: root.activeCommunity.memberRole === Constants.memberRole.owner
|
||||
readonly property bool admin: root.activeCommunity.memberRole === Constants.memberRole.admin
|
||||
readonly property bool tokenMaster: root.activeCommunity.memberRole === Constants.memberRole.tokenMaster
|
||||
}
|
||||
|
||||
readonly property ChannelPermissionsModelEditor channelEditModel: ChannelPermissionsModelEditor {
|
||||
channelId: root.chatId
|
||||
name: nameInput.input.text
|
||||
emoji: nameInput.input.asset.emoji
|
||||
color: colorPanel.color.toString().toUpperCase()
|
||||
channelsModel: root.channelsModel
|
||||
permissionsModel: root.permissionsModel
|
||||
newChannelMode: !root.isEdit
|
||||
|
||||
property Connections rootConnection: Connections {
|
||||
target: root
|
||||
function onClosed() {
|
||||
d.channelEditModel.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property bool viewOnlyCanAddReaction: root.viewOnlyCanAddReaction
|
||||
property bool hideIfPermissionsNotMet: root.hideIfPermissionsNotMet
|
||||
property bool colorPickerOpened: false
|
||||
|
||||
function isFormValid() {
|
||||
return nameInput.valid && descriptionTextArea.valid &&
|
||||
Utils.validateAndReturnError(colorDialog.color.toString().toUpperCase(), communityColorValidator) === ""
|
||||
Utils.validateAndReturnError(colorPanel.color.toString().toUpperCase(), communityColorValidator) === ""
|
||||
}
|
||||
|
||||
function openEmojiPopup(leftSide = false) {
|
||||
|
@ -70,7 +148,7 @@ StatusStackModal {
|
|||
categoryId: root.categoryId,
|
||||
name: StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
||||
description: StatusQUtils.Utils.filterXSS(descriptionTextArea.text),
|
||||
color: colorDialog.color.toString().toUpperCase(),
|
||||
color: colorPanel.color.toString().toUpperCase(),
|
||||
emoji: StatusQUtils.Emoji.deparse(nameInput.input.asset.emoji),
|
||||
options: {
|
||||
// TODO
|
||||
|
@ -85,66 +163,99 @@ StatusStackModal {
|
|||
creatingError.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stackTitle: isDiscordImport ? qsTr("New Channel With Imported Chat History") :
|
||||
isEdit ? qsTr("Edit #%1").arg(root.channelName)
|
||||
: qsTr("New channel")
|
||||
|
||||
nextButton: StatusButton {
|
||||
objectName: "createChannelNextBtn"
|
||||
font.weight: Font.Medium
|
||||
text: typeof currentItem.nextButtonText !== "undefined" ? currentItem.nextButtonText : qsTr("Import chat history")
|
||||
enabled: typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext
|
||||
loading: root.communitiesStore.discordDataExtractionInProgress
|
||||
onClicked: {
|
||||
const nextAction = currentItem.nextAction
|
||||
if (typeof(nextAction) == "function") {
|
||||
return nextAction()
|
||||
}
|
||||
root.currentIndex++
|
||||
}
|
||||
}
|
||||
|
||||
finishButton: StatusButton {
|
||||
objectName: "createOrEditCommunityChannelBtn"
|
||||
font.weight: Font.Medium
|
||||
text: isDiscordImport ? qsTr("Import chat history") : isEdit ? qsTr("Save changes") : qsTr("Create channel")
|
||||
enabled: typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext
|
||||
onClicked: {
|
||||
let nextAction = currentItem.nextAction
|
||||
if (typeof (nextAction) == "function") {
|
||||
return nextAction()
|
||||
}
|
||||
if (!root.isDiscordImport) {
|
||||
if (!d.isFormValid()) {
|
||||
scrollView.scrollBackUp()
|
||||
return
|
||||
}
|
||||
function saveAndClose() {
|
||||
let emoji = StatusQUtils.Emoji.deparse(nameInput.input.asset.emoji)
|
||||
|
||||
if (!isEdit) {
|
||||
root.createCommunityChannel(StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
||||
StatusQUtils.Utils.filterXSS(descriptionTextArea.text),
|
||||
emoji,
|
||||
colorDialog.color.toString().toUpperCase(),
|
||||
colorPanel.color.toString().toUpperCase(),
|
||||
root.categoryId)
|
||||
} else {
|
||||
root.editCommunityChannel(StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
||||
StatusQUtils.Utils.filterXSS(descriptionTextArea.text),
|
||||
emoji,
|
||||
colorDialog.color.toString().toUpperCase(),
|
||||
colorPanel.color.toString().toUpperCase(),
|
||||
root.categoryId)
|
||||
}
|
||||
|
||||
if (d.channelEditModel.dirtyPermissions) {
|
||||
var newPermissions = d.channelEditModel.getAddedPermissions();
|
||||
if (newPermissions.length > 0) {
|
||||
root.addPermissions(newPermissions);
|
||||
}
|
||||
|
||||
var editedPermissions = d.channelEditModel.getEditedPermissions();
|
||||
if (editedPermissions.length > 0) {
|
||||
root.editPermissions(editedPermissions);
|
||||
}
|
||||
|
||||
var removedPermissions = d.channelEditModel.getRemovedPermissions();
|
||||
if (removedPermissions.length > 0) {
|
||||
root.removePermissions(removedPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
if (root.viewOnlyCanAddReaction !== d.viewOnlyCanAddReaction) {
|
||||
root.setViewOnlyCanAddReaction(d.viewOnlyCanAddReaction);
|
||||
}
|
||||
|
||||
if (root.hideIfPermissionsNotMet !== d.hideIfPermissionsNotMet) {
|
||||
root.setHideIfPermissionsNotMet(d.hideIfPermissionsNotMet);
|
||||
}
|
||||
|
||||
// TODO Open the channel once we have designs for it
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
stackTitle: isDiscordImport ? qsTr("New Channel With Imported Chat History") :
|
||||
!!currentItem.stackTitleText ? currentItem.stackTitleText :
|
||||
(isEdit ? qsTr("Edit #%1").arg(root.channelName) : qsTr("New channel"))
|
||||
|
||||
nextButton: StatusButton {
|
||||
objectName: "createOrEditCommunityChannelBtn"
|
||||
font.weight: Font.Medium
|
||||
height: 44
|
||||
visible: !d.colorPickerOpened
|
||||
enabled: typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext
|
||||
text: !!currentItem.nextButtonText ? currentItem.nextButtonText :
|
||||
d.colorPickerOpened ? qsTr("Set channel color") : (
|
||||
isDiscordImport ? qsTr("Import chat history") :
|
||||
isEdit ? qsTr("Save changes") : qsTr("Create channel"))
|
||||
loading: root.communitiesStore.discordDataExtractionInProgress
|
||||
onClicked: {
|
||||
let nextAction = currentItem.nextAction
|
||||
if (typeof (nextAction) == "function") {
|
||||
return nextAction()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finishButton: StatusButton {
|
||||
objectName: "createChannelNextBtn"
|
||||
font.weight: Font.Medium
|
||||
height: 44
|
||||
text: (typeof currentItem.nextButtonText !== "undefined") ? currentItem.nextButtonText :
|
||||
qsTr("Import chat history")
|
||||
enabled: typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext
|
||||
onClicked: {
|
||||
const nextAction = currentItem.nextAction
|
||||
if (typeof(nextAction) == "function") {
|
||||
return nextAction()
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO
|
||||
onCurrentIndexChanged: {
|
||||
d.colorPickerOpened = false;
|
||||
}
|
||||
|
||||
readonly property StatusButton clearFilesButton: StatusButton {
|
||||
font.weight: Font.Medium
|
||||
text: qsTr("Clear all")
|
||||
height: 44
|
||||
type: StatusBaseButton.Type.Danger
|
||||
visible: typeof currentItem.isFileListView !== "undefined" && currentItem.isFileListView
|
||||
enabled: !fileListView.fileListModelEmpty && !root.communitiesStore.discordDataExtractionInProgress
|
||||
|
@ -153,12 +264,32 @@ StatusStackModal {
|
|||
|
||||
readonly property StatusButton deleteChannelButton: StatusButton {
|
||||
objectName: "deleteCommunityChannelBtn"
|
||||
visible: isEdit && isDeleteable && !isDiscordImport && typeof(replaceItem) === "undefined"
|
||||
text: qsTr("Delete channel")
|
||||
height: 44
|
||||
visible: isEdit && isDeleteable && !isDiscordImport && (d.currentPage === CreateChannelPopup.CurrentPage.ChannelDetails) ||
|
||||
!!currentItem.deleteButtonText
|
||||
text: (d.currentPage === CreateChannelPopup.CurrentPage.ChannelPermissions) ? currentItem.deleteButtonText : qsTr("Delete channel")
|
||||
enabled: (d.currentPage === CreateChannelPopup.CurrentPage.ChannelPermissions) ? currentItem.deleteButtonEnabled : true
|
||||
type: StatusBaseButton.Type.Danger
|
||||
onClicked: root.deleteCommunityChannel()
|
||||
onClicked: {
|
||||
const nextAction = currentItem.nextDeleteAction
|
||||
if (typeof(nextAction) == "function") {
|
||||
return nextAction()
|
||||
} else {
|
||||
root.deleteCommunityChannel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Item backButton: StatusBackButton {
|
||||
visible: d.currentPage !== CreateChannelPopup.CurrentPage.ChannelDetails
|
||||
onClicked: {
|
||||
d.currentPage = (d.currentPage === CreateChannelPopup.CurrentPage.DiscordImportUploadStart) ?
|
||||
CreateChannelPopup.CurrentPage.DiscordImportUploadFile : CreateChannelPopup.CurrentPage.ChannelDetails
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
leftButtons: [ backButton ]
|
||||
rightButtons: [clearFilesButton, deleteChannelButton, nextButton, finishButton]
|
||||
|
||||
onAboutToShow: {
|
||||
|
@ -179,7 +310,7 @@ StatusStackModal {
|
|||
if (root.channelEmoji) {
|
||||
nameInput.input.asset.emoji = root.channelEmoji
|
||||
}
|
||||
colorDialog.color = root.channelColor
|
||||
colorPanel.color = root.channelColor
|
||||
} else {
|
||||
nameInput.input.asset.isLetterIdenticon = true;
|
||||
}
|
||||
|
@ -188,10 +319,8 @@ StatusStackModal {
|
|||
}
|
||||
|
||||
readonly property list<Item> discordPages: [
|
||||
ColumnLayout {
|
||||
id: fileListView
|
||||
spacing: 24
|
||||
|
||||
Item {
|
||||
id: fileListViewItem
|
||||
readonly property bool isFileListView: true
|
||||
|
||||
readonly property var fileListModel: root.communitiesStore.discordFileList
|
||||
|
@ -205,11 +334,17 @@ StatusStackModal {
|
|||
: fileListModel.selectedCount ? qsTr("Validate (%1/%2) files").arg(fileListModel.selectedCount).arg(fileListModel.count)
|
||||
: qsTr("Start channel import")
|
||||
readonly property var nextAction: function () {
|
||||
if (!fileListView.fileListModel.selectedFilesValid)
|
||||
if (!fileListViewItem.fileListModel.selectedFilesValid)
|
||||
return root.communitiesStore.requestExtractChannelsAndCategories()
|
||||
|
||||
root.currentIndex++
|
||||
d.currentPage = CreateChannelPopup.CurrentPage.DiscordImportUploadStart;
|
||||
}
|
||||
ColumnLayout {
|
||||
id: fileListView
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
spacing: 24
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
@ -219,12 +354,12 @@ StatusStackModal {
|
|||
maximumLineCount: 2
|
||||
wrapMode: Text.Wrap
|
||||
elide: Text.ElideRight
|
||||
text: fileListView.fileListModelEmpty ? qsTr("Select Discord channel JSON files to import") :
|
||||
text: fileListViewItem.fileListModelEmpty ? qsTr("Select Discord channel JSON files to import") :
|
||||
root.communitiesStore.discordImportErrorsCount ? qsTr("Some of your community files cannot be used") :
|
||||
qsTr("Uncheck any files you would like to exclude from the import")
|
||||
}
|
||||
StatusBaseText {
|
||||
visible: fileListView.fileListModelEmpty && !issuePill.visible
|
||||
visible: fileListViewItem.fileListModelEmpty && !issuePill.visible
|
||||
font.pixelSize: 12
|
||||
color: Theme.palette.baseColor1
|
||||
text: qsTr("(JSON file format only)")
|
||||
|
@ -233,7 +368,7 @@ StatusStackModal {
|
|||
id: issuePill
|
||||
type: root.communitiesStore.discordImportErrorsCount ? IssuePill.Type.Error : IssuePill.Type.Warning
|
||||
count: root.communitiesStore.discordImportErrorsCount || root.communitiesStore.discordImportWarningsCount || 0
|
||||
visible: !!count && !fileListView.fileListModelEmpty
|
||||
visible: !!count && !fileListViewItem.fileListModelEmpty
|
||||
}
|
||||
StatusButton {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
@ -250,7 +385,7 @@ StatusStackModal {
|
|||
color: Theme.palette.baseColor4
|
||||
|
||||
ColumnLayout {
|
||||
visible: fileListView.fileListModelEmpty
|
||||
visible: fileListViewItem.fileListModelEmpty
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 60
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
@ -261,32 +396,29 @@ StatusStackModal {
|
|||
asset.name: "info"
|
||||
}
|
||||
StatusBaseText {
|
||||
id: infoText1
|
||||
Layout.topMargin: 8
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
text: qsTr("Export the Discord channel’s chat history data using %1").arg("<a href='https://github.com/Tyrrrz/DiscordChatExporter/releases/tag/2.40.4'>DiscordChatExporter</a>")
|
||||
onLinkActivated: Global.openLink(link)
|
||||
HoverHandler {
|
||||
id: handler1
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: handler1.hovered && parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
StatusBaseText {
|
||||
id: infoText2
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
text: qsTr("Refer to this <a href='https://github.com/Tyrrrz/DiscordChatExporter/blob/master/.docs/Readme.md'>documentation</a> if you have any queries")
|
||||
onLinkActivated: Global.openLink(link)
|
||||
HoverHandler {
|
||||
id: handler2
|
||||
}
|
||||
onHoveredLinkChanged: print(hoveredLink)
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: handler2.hovered && parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,12 +434,12 @@ StatusStackModal {
|
|||
}
|
||||
|
||||
StatusListView {
|
||||
visible: !fileListView.fileListModelEmpty
|
||||
visible: !fileListViewItem.fileListModelEmpty
|
||||
enabled: !root.communitiesStore.discordDataExtractionInProgress
|
||||
anchors.fill: parent
|
||||
leftMargin: 8
|
||||
rightMargin: 8
|
||||
model: fileListView.fileListModel
|
||||
model: fileListViewItem.fileListModel
|
||||
header: !atYBeginning ? floatingDivComp : null
|
||||
headerPositioning: ListView.OverlayHeader
|
||||
footer: !atYEnd ? floatingDivComp : null
|
||||
|
@ -352,7 +484,7 @@ StatusStackModal {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
title: qsTr("Choose files to import")
|
||||
|
@ -368,11 +500,7 @@ StatusStackModal {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
ColumnLayout {
|
||||
id: categoriesAndChannelsView
|
||||
spacing: 24
|
||||
|
||||
Item {
|
||||
readonly property bool canGoNext: root.communitiesStore.discordChannelsModel.hasSelectedItems
|
||||
readonly property var nextAction: function () {
|
||||
d.requestImportDiscordChannel()
|
||||
|
@ -382,6 +510,13 @@ StatusStackModal {
|
|||
root.replace(progressComponent)
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: categoriesAndChannelsView
|
||||
spacing: 24
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
Component {
|
||||
id: progressComponent
|
||||
DiscordImportProgressContents {
|
||||
|
@ -480,6 +615,7 @@ StatusStackModal {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Connections {
|
||||
|
@ -512,18 +648,17 @@ StatusStackModal {
|
|||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
|
||||
width: scrollView.availableWidth
|
||||
spacing: 0
|
||||
|
||||
spacing: Style.current.padding
|
||||
StatusInput {
|
||||
id: nameInput
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
input.edit.objectName: "createOrEditCommunityChannelNameInput"
|
||||
label: qsTr("Channel name")
|
||||
charLimit: root.maxChannelNameLength
|
||||
placeholderText: qsTr("# Name the channel")
|
||||
|
||||
input.onTextChanged: {
|
||||
const cursorPosition = input.cursorPosition
|
||||
input.text = Utils.convertSpacesToDashes(input.text)
|
||||
|
@ -532,7 +667,7 @@ StatusStackModal {
|
|||
input.letterIconName = text
|
||||
}
|
||||
}
|
||||
input.asset.color: colorDialog.color.toString()
|
||||
input.asset.color: colorPanel.color.toString()
|
||||
input.rightComponent: StatusRoundButton {
|
||||
objectName: "StatusChannelPopup_emojiButton"
|
||||
implicitWidth: 32
|
||||
|
@ -559,48 +694,48 @@ StatusStackModal {
|
|||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredHeight: 16
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 82
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
StatusBaseText {
|
||||
width: parent.width
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
text: qsTr("Channel colour")
|
||||
}
|
||||
StatusPickerButton {
|
||||
id: colorSelectorButton
|
||||
|
||||
ColorPicker {
|
||||
id: colorDialog
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Channel colour")
|
||||
color: root.isEdit && root.channelColor ? root.channelColor : Theme.palette.primaryColor1
|
||||
onPick: root.replace(colorPanel)
|
||||
|
||||
Component {
|
||||
id: colorPanel
|
||||
ColorPanel {
|
||||
title: qsTr("Channel colour")
|
||||
buttonText: qsTr("Select Colour")
|
||||
Component.onCompleted: color = colorDialog.color
|
||||
onAccepted: {
|
||||
colorDialog.color = color
|
||||
root.replaceItem = undefined
|
||||
property string validationError: ""
|
||||
width: parent.width
|
||||
anchors.bottom: parent.bottom
|
||||
bgColor: colorPanel.colorSelected ? colorPanel.color : Theme.palette.baseColor2
|
||||
contentColor: colorPanel.colorSelected ? Theme.palette.white : Theme.palette.baseColor1
|
||||
text: colorPanel.colorSelected ? colorPanel.color.toString().toUpperCase() : qsTr("Pick a colour")
|
||||
onClicked: { d.currentPage = CreateChannelPopup.CurrentPage.ColorPicker; d.colorPickerOpened = true; }
|
||||
onTextChanged: {
|
||||
if (colorPanel.colorSelected) {
|
||||
validationError = Utils.validateAndReturnError(text, communityColorValidator)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredHeight: 16
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: descriptionTextArea
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.current.halfPadding
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
input.edit.objectName: "createOrEditCommunityChannelDescriptionInput"
|
||||
input.verticalAlignment: TextEdit.AlignTop
|
||||
label: qsTr("Description")
|
||||
charLimit: 140
|
||||
|
||||
placeholderText: qsTr("Describe the channel")
|
||||
input.multiline: true
|
||||
minimumHeight: 88
|
||||
maximumHeight: 88
|
||||
minimumHeight: 108
|
||||
maximumHeight: 108
|
||||
validators: [
|
||||
StatusMinLengthValidator {
|
||||
minLength: 1
|
||||
|
@ -612,6 +747,189 @@ StatusStackModal {
|
|||
}
|
||||
]
|
||||
}
|
||||
Separator {
|
||||
Layout.fillWidth: true
|
||||
visible: viewOnlyCanAddReactionCheckbox.visible
|
||||
}
|
||||
StatusCheckBox {
|
||||
id: viewOnlyCanAddReactionCheckbox
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 48
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
leftSide: false
|
||||
text: qsTr("Hide channel from members who don't have permissions to view the channel")
|
||||
visible: false //TODO: Enable connect to the backend when it's ready https://github.com/status-im/status-desktop/issues/13291
|
||||
checked: d.hideIfPermissionsNotMet
|
||||
onToggled: {
|
||||
d.hideIfPermissionsNotMet = checked;
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 56
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
StatusBaseText {
|
||||
text: qsTr("Permissions")
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
StatusButton {
|
||||
text: qsTr("Add permission")
|
||||
enabled: !!nameInput.text
|
||||
property ListModel channelToAddPermission: ListModel { }
|
||||
onClicked: {
|
||||
channelToAddPermission.clear();
|
||||
channelToAddPermission.append({"key": root.chatId, "name": nameInput.text});
|
||||
const propertiess = {
|
||||
channelsToEditModel: channelToAddPermission,
|
||||
header: null,
|
||||
topPadding: -root.subHeaderPadding - 8,
|
||||
leftPadding: 0,
|
||||
rightPadding: 16,
|
||||
viewWidth: scrollView.availableWidth - 32
|
||||
};
|
||||
editPermissionView.pushEditView(propertiess);
|
||||
d.currentPage = CreateChannelPopup.CurrentPage.ChannelPermissions;
|
||||
}
|
||||
}
|
||||
}
|
||||
PermissionsView {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
viewWidth: (scrollView.availableWidth - 32)
|
||||
permissionsModel: d.channelEditModel.channelPermissionsModel
|
||||
assetsModel: root.assetsModel
|
||||
collectiblesModel: root.collectiblesModel
|
||||
viewOnlyCanAddReaction: root.viewOnlyCanAddReaction
|
||||
channelsModel: d.channelEditModel.liveChannelsModel
|
||||
communityDetails: d.communityDetails
|
||||
showChannelOptions: true
|
||||
allowIntroPanel: false
|
||||
onRemovePermissionRequested: {
|
||||
console.assert(d.channelEditModel.removePermission(index))
|
||||
}
|
||||
onDuplicatePermissionRequested: {
|
||||
const item = StatusQUtils.ModelUtils.get(d.channelEditModel.channelPermissionsModel, index);
|
||||
const properties = {
|
||||
holdingsToEditModel: item.holdingsListModel,
|
||||
channelsToEditModel: item.channelsListModel,
|
||||
permissionTypeToEdit: item.permissionType,
|
||||
isPrivateToEditValue: item.isPrivate,
|
||||
header: null,
|
||||
topPadding: -root.subHeaderPadding - 8,
|
||||
leftPadding: 0,
|
||||
rightPadding: 16,
|
||||
viewWidth: scrollView.availableWidth - 32
|
||||
}
|
||||
editPermissionView.pushEditView(properties);
|
||||
editPermissionView.currentItem.resetChanges()
|
||||
d.currentPage = CreateChannelPopup.CurrentPage.ChannelPermissions;
|
||||
}
|
||||
|
||||
onEditPermissionRequested: {
|
||||
const item = d.channelEditModel.channelPermissionsModel.get(index);
|
||||
const requireHoldings = (item.holdingsListModel.count ?? item.holdingsListModel.rowCount()) > 0;
|
||||
const properties = {
|
||||
permissionKeyToEdit: item.key,
|
||||
holdingsToEditModel: item.holdingsListModel,
|
||||
channelsToEditModel: item.channelsListModel,
|
||||
permissionTypeToEdit: item.permissionType,
|
||||
isPrivateToEditValue: item.isPrivate,
|
||||
header: null,
|
||||
topPadding: -root.subHeaderPadding - 8,
|
||||
leftPadding: 0,
|
||||
rightPadding: 16,
|
||||
viewWidth: scrollView.availableWidth - 32
|
||||
}
|
||||
editPermissionView.pushEditView(properties);
|
||||
editPermissionView.currentItem.resetChanges()
|
||||
|
||||
d.currentPage = CreateChannelPopup.CurrentPage.ChannelPermissions;
|
||||
}
|
||||
onUserRestrictionsToggled: {
|
||||
d.viewOnlyCanAddReaction = checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
readonly property var nextAction: function () {
|
||||
if (!root.isDiscordImport) {
|
||||
if (!d.isFormValid()) {
|
||||
scrollView.scrollBackUp()
|
||||
return
|
||||
}
|
||||
|
||||
d.saveAndClose()
|
||||
} else {
|
||||
d.currentPage = CreateChannelPopup.CurrentPage.DiscordImportUploadFile;
|
||||
}
|
||||
}
|
||||
},
|
||||
ColorPanel {
|
||||
id: colorPanel
|
||||
readonly property string stackTitleText: qsTr("Channel Colour")
|
||||
readonly property string nextButtonText: qsTr("Select Channel Colour")
|
||||
padding: 0
|
||||
leftPadding: 16
|
||||
rightPadding: 16
|
||||
height: Math.min(parent.height, 624)
|
||||
property bool colorSelected: root.isEdit && root.channelColor
|
||||
color: root.isEdit && root.channelColor ? root.channelColor : Theme.palette.primaryColor1
|
||||
onAccepted: {
|
||||
colorSelected = true; d.colorPickerOpened = false; d.currentPage = CreateChannelPopup.CurrentPage.ChannelDetails;
|
||||
}
|
||||
readonly property var nextAction: function () {
|
||||
accepted();
|
||||
}
|
||||
},
|
||||
PermissionsSettingsPanel {
|
||||
id: editPermissionView
|
||||
|
||||
leftPadding: 16
|
||||
rightPadding: 16
|
||||
initialPage.header: null
|
||||
initialPage.topPadding: 0
|
||||
initialPage.leftPadding: 0
|
||||
viewWidth: scrollView.availableWidth - 32
|
||||
readonly property string nextButtonText: !!currentItem.permissionKeyToEdit ?
|
||||
qsTr("Update permission") : qsTr("Create permission")
|
||||
readonly property string stackTitleText: !!currentItem.permissionKeyToEdit ?
|
||||
qsTr("Edit #%1 permission").arg(nameInput.text) : qsTr("New #%1 permission").arg(nameInput.text)
|
||||
readonly property string deleteButtonText: !!currentItem.permissionKeyToEdit ?
|
||||
qsTr("Revert changes") : ""
|
||||
readonly property bool canGoNext: !!currentItem && currentItem.isDirty && currentItem.isFullyFilled ? currentItem.isDirty && currentItem.isFullyFilled : false
|
||||
readonly property bool deleteButtonEnabled: editPermissionView.canGoNext
|
||||
assetsModel: root.assetsModel
|
||||
collectiblesModel: root.collectiblesModel
|
||||
permissionsModel: d.channelEditModel.channelPermissionsModel
|
||||
channelsModel: d.channelEditModel.liveChannelsModel
|
||||
communityDetails: d.communityDetails
|
||||
showChannelSelector: false
|
||||
readonly property var nextDeleteAction: function () {
|
||||
if (!!currentItem.permissionKeyToEdit) {
|
||||
currentItem.resetChanges();
|
||||
}
|
||||
}
|
||||
readonly property var nextAction: function () {
|
||||
if (!!currentItem.permissionKeyToEdit) {
|
||||
currentItem.updatePermission();
|
||||
} else {
|
||||
currentItem.createPermission();
|
||||
}
|
||||
}
|
||||
onCreatePermissionRequested: {
|
||||
d.channelEditModel.appendPermission(holdings, channels, permissionType, isPrivate)
|
||||
d.currentPage = CreateChannelPopup.CurrentPage.ChannelDetails;
|
||||
}
|
||||
|
||||
onUpdatePermissionRequested: {
|
||||
d.channelEditModel.editPermission(key, permissionType, holdings, channels, isPrivate)
|
||||
d.currentPage = CreateChannelPopup.CurrentPage.ChannelDetails;
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -16,6 +16,7 @@ StatusDropdown {
|
|||
|
||||
property int mode: PermissionsDropdown.Mode.Add
|
||||
property int initialPermissionType: PermissionTypes.Type.None
|
||||
property bool allowCommunityOptions: true
|
||||
|
||||
property bool enableAdminPermission: true
|
||||
|
||||
|
@ -97,13 +98,14 @@ StatusDropdown {
|
|||
CustomSeparator {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: d.sectionHeight
|
||||
|
||||
visible: root.allowCommunityOptions
|
||||
text: qsTr("Community")
|
||||
}
|
||||
|
||||
CustomPermissionListItem {
|
||||
permissionType: PermissionTypes.Type.Admin
|
||||
enabled: root.enableAdminPermission
|
||||
visible: root.allowCommunityOptions
|
||||
|
||||
Layout.fillWidth: true
|
||||
objectName: "becomeAdmin"
|
||||
|
@ -112,6 +114,7 @@ StatusDropdown {
|
|||
CustomPermissionListItem {
|
||||
permissionType: PermissionTypes.Type.Member
|
||||
|
||||
visible: root.allowCommunityOptions
|
||||
Layout.fillWidth: true
|
||||
objectName: "becomeMember"
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ Item {
|
|||
required property CurrenciesStore currencyStore
|
||||
property bool hasAddedContacts: false
|
||||
property var communityData
|
||||
property alias createChannelPopup: createChannelPopup
|
||||
|
||||
// Community transfer ownership related props:
|
||||
required property bool isPendingOwnershipRequest
|
||||
|
@ -52,6 +53,11 @@ Item {
|
|||
communityData.memberRole === Constants.memberRole.admin ||
|
||||
communityData.memberRole === Constants.memberRole.tokenMaster
|
||||
|
||||
readonly property var permissionsModel: {
|
||||
root.store.prepareTokenModelForCommunity(communityData.id)
|
||||
return root.store.permissionsModel
|
||||
}
|
||||
|
||||
signal infoButtonClicked
|
||||
signal manageButtonClicked
|
||||
|
||||
|
@ -297,7 +303,6 @@ Item {
|
|||
|
||||
chatListPopupMenu: ChatContextMenuView {
|
||||
id: chatContextMenuView
|
||||
emojiPopup: root.emojiPopup
|
||||
showDebugOptions: root.store.isDebugEnabledfir
|
||||
|
||||
// TODO pass the chatModel in its entirety instead of fetching the JSOn using just the id
|
||||
|
@ -368,17 +373,18 @@ Item {
|
|||
onDisplayProfilePopup: {
|
||||
Global.openProfilePopup(publicKey)
|
||||
}
|
||||
|
||||
onEditCommunityChannel: {
|
||||
communitySectionModule.editCommunityChannel(
|
||||
chatId,
|
||||
newName,
|
||||
newDescription,
|
||||
newEmoji,
|
||||
newColor,
|
||||
newCategory,
|
||||
channelPosition // TODO change this to the signal once it is modifiable
|
||||
)
|
||||
onDisplayEditChannelPopup: {
|
||||
Global.openPopup(createChannelPopup, {
|
||||
isEdit: true,
|
||||
channelName: chatName,
|
||||
channelDescription: chatDescription,
|
||||
channelEmoji: chatEmoji,
|
||||
channelColor: chatColor,
|
||||
categoryId: chatCategoryId,
|
||||
chatId: chatContextMenuView.chatId,
|
||||
channelPosition: channelPosition,
|
||||
deleteChatConfirmationDialog: deleteChatConfirmationDialog
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -607,11 +613,63 @@ Item {
|
|||
id: createChannelPopup
|
||||
CreateChannelPopup {
|
||||
communitiesStore: root.communitiesStore
|
||||
assetsModel: root.store.assetsModel
|
||||
collectiblesModel: root.store.collectiblesModel
|
||||
permissionsModel: root.store.permissionsModel
|
||||
channelsModel: root.store.chatCommunitySectionModule.model
|
||||
emojiPopup: root.emojiPopup
|
||||
activeCommunity: root.communityData
|
||||
|
||||
property int channelPosition: -1
|
||||
property var deleteChatConfirmationDialog
|
||||
|
||||
onCreateCommunityChannel: function (chName, chDescription, chEmoji, chColor,
|
||||
chCategoryId) {
|
||||
root.store.createCommunityChannel(chName, chDescription, chEmoji, chColor,
|
||||
chCategoryId)
|
||||
chatId = root.store.currentChatContentModule().chatDetails.id
|
||||
}
|
||||
onEditCommunityChannel: {
|
||||
root.store.editCommunityChannel(chatId,
|
||||
chName,
|
||||
chDescription,
|
||||
chEmoji,
|
||||
chColor,
|
||||
chCategoryId,
|
||||
channelPosition);
|
||||
}
|
||||
|
||||
onAddPermissions: function (permissions) {
|
||||
for (var i = 0; i < permissions.length; i++) {
|
||||
root.store.permissionsStore.createPermission(permissions[i].holdingsListModel,
|
||||
permissions[i].permissionType,
|
||||
permissions[i].isPrivate,
|
||||
permissions[i].channelsListModel)
|
||||
}
|
||||
}
|
||||
onRemovePermissions: function (permissions) {
|
||||
for (var i = 0; i < permissions.length; i++) {
|
||||
root.store.permissionsStore.removePermission(permissions[i].id)
|
||||
}
|
||||
}
|
||||
onEditPermissions: function (permissions) {
|
||||
for (var i = 0; i < permissions.length; i++) {
|
||||
root.store.permissionsStore.editPermission(permissions[i].id,
|
||||
permissions[i].holdingsListModel,
|
||||
permissions[i].permissionType,
|
||||
permissions[i].channelsListModel,
|
||||
permissions[i].isPrivate)
|
||||
}
|
||||
}
|
||||
onSetViewOnlyCanAddReaction: function (checked) {
|
||||
root.store.permissionsStore.setViewOnlyCanAddReaction(chatId, checked)
|
||||
}
|
||||
onSetHideIfPermissionsNotMet: function (checked) {
|
||||
root.store.permissionsStore.setHideIfPermissionsNotMet(chatId, checked)
|
||||
}
|
||||
onDeleteCommunityChannel: {
|
||||
Global.openPopup(deleteChatConfirmationDialog);
|
||||
close()
|
||||
}
|
||||
onClosed: {
|
||||
destroy()
|
||||
|
|
|
@ -38,14 +38,14 @@ StatusScrollView {
|
|||
|
||||
readonly property alias dirtyValues: d.dirtyValues
|
||||
|
||||
readonly property bool isFullyFilled:
|
||||
(dirtyValues.selectedHoldingsModel.count > 0 || !whoHoldsSwitch.checked) &&
|
||||
readonly property bool isFullyFilled: (dirtyValues.selectedHoldingsModel.count > 0 || !whoHoldsSwitch.checked) &&
|
||||
dirtyValues.permissionType !== PermissionTypes.Type.None &&
|
||||
(d.isCommunityPermission || dirtyValues.selectedChannelsModel.count > 0)
|
||||
(d.isCommunityPermission || !showChannelSelector || dirtyValues.selectedChannelsModel.count > 0)
|
||||
|
||||
property int permissionType: PermissionTypes.Type.None
|
||||
property bool isPrivate: false
|
||||
property bool holdingsRequired: true
|
||||
property bool showChannelSelector: true
|
||||
|
||||
// roles: type, key, name, amount, imageSource
|
||||
property var selectedHoldingsModel: ListModel {}
|
||||
|
@ -430,6 +430,7 @@ StatusScrollView {
|
|||
PermissionsDropdown {
|
||||
id: permissionsDropdown
|
||||
|
||||
allowCommunityOptions: root.showChannelSelector
|
||||
initialPermissionType: d.dirtyValues.permissionType
|
||||
enableAdminPermission: root.communityDetails.owner
|
||||
|
||||
|
@ -454,7 +455,7 @@ StatusScrollView {
|
|||
}
|
||||
}
|
||||
|
||||
SequenceColumnLayout.Separator {}
|
||||
SequenceColumnLayout.Separator { visible: root.showChannelSelector }
|
||||
|
||||
StatusItemSelector {
|
||||
id: inSelector
|
||||
|
@ -463,7 +464,7 @@ StatusScrollView {
|
|||
|
||||
addButton.visible: editable
|
||||
itemsClickable: editable
|
||||
|
||||
visible: root.showChannelSelector
|
||||
Layout.fillWidth: true
|
||||
icon: d.isCommunityPermission ? Style.svg("communities") : Style.svg("create-category")
|
||||
title: qsTr("In")
|
||||
|
@ -566,7 +567,7 @@ StatusScrollView {
|
|||
color: Theme.palette.baseColor2
|
||||
}
|
||||
|
||||
HidePermissionPanel {
|
||||
StatusIconSwitch {
|
||||
Layout.topMargin: 12
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
|
@ -574,6 +575,9 @@ StatusScrollView {
|
|||
|
||||
enabled: d.dirtyValues.permissionType !== PermissionTypes.Type.Admin
|
||||
checked: d.dirtyValues.isPrivate
|
||||
title: qsTr("Hide permission")
|
||||
subTitle: qsTr("Make this permission hidden from members who don’t meet its requirements")
|
||||
icon: "hide"
|
||||
onToggled: d.dirtyValues.isPrivate = checked
|
||||
}
|
||||
|
||||
|
@ -600,7 +604,7 @@ StatusScrollView {
|
|||
StatusWarningBox {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.current.padding
|
||||
|
||||
visible: root.showChannelSelector
|
||||
icon: "desktop"
|
||||
text: qsTr("Any changes to community permissions will take effect after the control node receives and processes them")
|
||||
borderColor: Theme.palette.baseColor1
|
||||
|
@ -613,7 +617,7 @@ StatusScrollView {
|
|||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.current.bigPadding
|
||||
|
||||
visible: !root.isEditState
|
||||
visible: !root.isEditState && root.showChannelSelector
|
||||
text: qsTr("Create permission")
|
||||
enabled: root.isFullyFilled
|
||||
&& !root.permissionDuplicated
|
||||
|
|
|
@ -2,16 +2,27 @@ import QtQuick 2.14
|
|||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
import shared.status 1.0
|
||||
import shared.popups 1.0
|
||||
import utils 1.0
|
||||
|
||||
import AppLayouts.Communities.controls 1.0
|
||||
import AppLayouts.Communities.panels 1.0
|
||||
|
||||
StatusScrollView {
|
||||
ColumnLayout {
|
||||
id: root
|
||||
width: root.viewWidth
|
||||
property int topPadding: count ? 16 : 0
|
||||
spacing: 24
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property int permissionIndexToRemove
|
||||
}
|
||||
|
||||
required property var permissionsModel
|
||||
required property var assetsModel
|
||||
|
@ -22,27 +33,16 @@ StatusScrollView {
|
|||
required property var communityDetails
|
||||
|
||||
property int viewWidth: 560 // by design
|
||||
property bool viewOnlyCanAddReaction
|
||||
property bool showChannelOptions: false
|
||||
property bool allowIntroPanel: true
|
||||
|
||||
signal editPermissionRequested(int index)
|
||||
signal duplicatePermissionRequested(int index)
|
||||
signal removePermissionRequested(int index)
|
||||
signal userRestrictionsToggled(bool checked)
|
||||
|
||||
readonly property alias count: repeater.count
|
||||
|
||||
padding: 0
|
||||
topPadding: count ? 16 : 0
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property int permissionIndexToRemove
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: mainLayout
|
||||
width: root.viewWidth
|
||||
spacing: 24
|
||||
|
||||
ListModel {
|
||||
id: communityItemModel
|
||||
|
||||
|
@ -58,7 +58,7 @@ StatusScrollView {
|
|||
IntroPanel {
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: root.count === 0
|
||||
visible: (root.count === 0 && root.allowIntroPanel)
|
||||
|
||||
image: Style.png("community/permissions2_3")
|
||||
title: qsTr("Permissions")
|
||||
|
@ -100,8 +100,8 @@ StatusScrollView {
|
|||
|
||||
showButtons: (model.permissionType !== PermissionTypes.Type.TokenMaster &&
|
||||
model.permissionType !== PermissionTypes.Type.Owner) &&
|
||||
(root.communityDetails.owner ||
|
||||
((root.communityDetails.admin || root.communityDetails.tokenMaster) && model.permissionType !== PermissionTypes.Type.Admin))
|
||||
(!!root.communityDetails && (root.communityDetails.owner ||
|
||||
((root.communityDetails.admin || root.communityDetails.tokenMaster) && model.permissionType !== PermissionTypes.Type.Admin)))
|
||||
|
||||
onEditClicked: root.editPermissionRequested(model.index)
|
||||
onDuplicateClicked: root.duplicatePermissionRequested(model.index)
|
||||
|
@ -112,8 +112,31 @@ StatusScrollView {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: noPermissionsLabel
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: (root.count === 0 && root.showChannelOptions)
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: qsTr("No channel permissions")
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
|
||||
StatusIconSwitch {
|
||||
Layout.fillWidth: true
|
||||
padding: 0
|
||||
|
||||
visible: false //TODO: enable this when we have the backend support https://github.com/status-im/status-desktop/issues/13292
|
||||
//visible: root.showChannelOptions
|
||||
title: qsTr("Users with view only permissions can add reactions")
|
||||
icon: "emojis"
|
||||
checked: root.viewOnlyCanAddReaction
|
||||
onToggled: {
|
||||
root.userRestrictionsToggled(checked);
|
||||
}
|
||||
}
|
||||
ConfirmationDialog {
|
||||
id: declineAllDialog
|
||||
|
||||
|
|
|
@ -26,10 +26,11 @@ StatusMenu {
|
|||
property bool chatMuted: false
|
||||
property int channelPosition: -1
|
||||
property string chatCategoryId: ""
|
||||
property var emojiPopup
|
||||
property bool showDebugOptions: false
|
||||
property alias deleteChatConfirmationDialog: deleteChatConfirmationDialogComponent
|
||||
|
||||
signal displayProfilePopup(string publicKey)
|
||||
signal displayEditChannelPopup(string chatId)
|
||||
signal requestAllHistoricMessages(string chatId)
|
||||
signal unmuteChat(string chatId)
|
||||
signal muteChat(string chatId, int interval)
|
||||
|
@ -140,38 +141,7 @@ StatusMenu {
|
|||
icon.name: "edit"
|
||||
enabled: root.isCommunityChat && root.amIChatAdmin
|
||||
onTriggered: {
|
||||
Global.openPopup(editChannelPopup, {
|
||||
isEdit: true,
|
||||
channelName: root.chatName,
|
||||
channelDescription: root.chatDescription,
|
||||
channelEmoji: root.chatEmoji,
|
||||
channelColor: root.chatColor,
|
||||
categoryId: root.chatCategoryId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: editChannelPopup
|
||||
CreateChannelPopup {
|
||||
anchors.centerIn: parent
|
||||
isEdit: true
|
||||
isDeleteable: root.isCommunityChat
|
||||
emojiPopup: root.emojiPopup
|
||||
onCreateCommunityChannel: {
|
||||
root.createCommunityChannel(root.chatId, chName, chDescription, chEmoji, chColor);
|
||||
}
|
||||
onEditCommunityChannel: {
|
||||
root.editCommunityChannel(root.chatId, chName, chDescription, chEmoji, chColor,
|
||||
chCategoryId);
|
||||
}
|
||||
onDeleteCommunityChannel: {
|
||||
Global.openPopup(deleteChatConfirmationDialogComponent)
|
||||
close()
|
||||
}
|
||||
onClosed: {
|
||||
destroy()
|
||||
}
|
||||
root.displayEditChannelPopup(root.chatId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue