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
|
property int padding: Style.current.halfPadding
|
||||||
|
|
||||||
signal searchButtonClicked()
|
signal searchButtonClicked()
|
||||||
|
signal displayEditChannelPopup(string chatId,
|
||||||
|
string chatName,
|
||||||
|
string chatDescription,
|
||||||
|
string chatEmoji,
|
||||||
|
string chatColor,
|
||||||
|
string chatCategoryId,
|
||||||
|
int channelPosition,
|
||||||
|
var deleteDialog)
|
||||||
|
|
||||||
function addRemoveGroupMember() {
|
function addRemoveGroupMember() {
|
||||||
root.state = d.stateMembersSelectorContent
|
root.state = d.stateMembersSelectorContent
|
||||||
|
@ -140,7 +148,6 @@ Item {
|
||||||
ChatContextMenuView {
|
ChatContextMenuView {
|
||||||
id: contextMenu
|
id: contextMenu
|
||||||
objectName: "moreOptionsContextMenu"
|
objectName: "moreOptionsContextMenu"
|
||||||
emojiPopup: root.emojiPopup
|
|
||||||
showDebugOptions: root.rootStore.isDebugEnabled
|
showDebugOptions: root.rootStore.isDebugEnabled
|
||||||
openHandler: function () {
|
openHandler: function () {
|
||||||
if(!chatContentModule) {
|
if(!chatContentModule) {
|
||||||
|
@ -218,17 +225,11 @@ Item {
|
||||||
onDisplayProfilePopup: {
|
onDisplayProfilePopup: {
|
||||||
Global.openProfilePopup(publicKey)
|
Global.openProfilePopup(publicKey)
|
||||||
}
|
}
|
||||||
|
onDisplayEditChannelPopup: {
|
||||||
onEditCommunityChannel: {
|
root.displayEditChannelPopup(chatId, chatName, chatDescription,
|
||||||
root.rootStore.editCommunityChannel(
|
chatEmoji, chatColor,
|
||||||
chatId,
|
chatCategoryId, channelPosition,
|
||||||
newName,
|
contextMenu.deleteChatConfirmationDialog);
|
||||||
newDescription,
|
|
||||||
newEmoji,
|
|
||||||
newColor,
|
|
||||||
newCategory,
|
|
||||||
channelPosition // TODO change this to the signal once it is modifiable
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
onAddRemoveGroupMember: {
|
onAddRemoveGroupMember: {
|
||||||
root.addRemoveGroupMember()
|
root.addRemoveGroupMember()
|
||||||
|
|
|
@ -166,6 +166,19 @@ StatusSectionLayout {
|
||||||
rootStore: root.rootStore
|
rootStore: root.rootStore
|
||||||
emojiPopup: root.emojiPopup
|
emojiPopup: root.emojiPopup
|
||||||
onSearchButtonClicked: root.openAppSearch()
|
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 {
|
popupMenu: ChatContextMenuView {
|
||||||
id: chatContextMenuView
|
id: chatContextMenuView
|
||||||
emojiPopup: root.emojiPopup
|
|
||||||
showDebugOptions: root.store.isDebugEnabled
|
showDebugOptions: root.store.isDebugEnabled
|
||||||
|
|
||||||
openHandler: function (id) {
|
openHandler: function (id) {
|
||||||
|
|
|
@ -58,23 +58,9 @@ QtObject {
|
||||||
d.editPermission(key, permissionType, holdings, channels, isPrivate)
|
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 removing a permission by index
|
||||||
function removePermission(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.layouts 1.0
|
||||||
import AppLayouts.Communities.views 1.0
|
import AppLayouts.Communities.views 1.0
|
||||||
|
|
||||||
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Controls 0.1
|
||||||
import StatusQ.Core.Utils 0.1
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
import shared.popups 1.0
|
import shared.popups 1.0
|
||||||
|
|
||||||
StackView {
|
StackView {
|
||||||
|
@ -17,6 +19,8 @@ StackView {
|
||||||
required property var assetsModel
|
required property var assetsModel
|
||||||
required property var collectiblesModel
|
required property var collectiblesModel
|
||||||
required property var channelsModel
|
required property var channelsModel
|
||||||
|
property bool showChannelSelector: true
|
||||||
|
property alias initialPage: initialItem
|
||||||
|
|
||||||
// id, name, image, color, owner properties expected
|
// id, name, image, color, owner properties expected
|
||||||
required property var communityDetails
|
required property var communityDetails
|
||||||
|
@ -38,8 +42,13 @@ StackView {
|
||||||
pop(StackView.Immediate)
|
pop(StackView.Immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pushEditView(properties) {
|
||||||
|
root.push(newPermissionView, properties, StackView.Immediate);
|
||||||
|
}
|
||||||
|
|
||||||
// Community Permissions possible view contents:
|
// Community Permissions possible view contents:
|
||||||
initialItem: SettingsPage {
|
initialItem: SettingsPage {
|
||||||
|
id: initialItem
|
||||||
implicitWidth: 0
|
implicitWidth: 0
|
||||||
|
|
||||||
title: qsTr("Permissions")
|
title: qsTr("Permissions")
|
||||||
|
@ -52,7 +61,12 @@ StackView {
|
||||||
onClicked: root.push(newPermissionView, StackView.Immediate)
|
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
|
permissionsModel: root.permissionsModel
|
||||||
assetsModel: root.assetsModel
|
assetsModel: root.assetsModel
|
||||||
collectiblesModel: root.collectiblesModel
|
collectiblesModel: root.collectiblesModel
|
||||||
|
@ -72,7 +86,7 @@ StackView {
|
||||||
isPrivateToEditValue: item.isPrivate
|
isPrivateToEditValue: item.isPrivate
|
||||||
}
|
}
|
||||||
|
|
||||||
root.push(newPermissionView, properties, StackView.Immediate)
|
root.pushEditView(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDuplicatePermissionRequested: {
|
onDuplicatePermissionRequested: {
|
||||||
|
@ -85,7 +99,7 @@ StackView {
|
||||||
isPrivateToEditValue: item.isPrivate
|
isPrivateToEditValue: item.isPrivate
|
||||||
}
|
}
|
||||||
|
|
||||||
root.push(newPermissionView, properties, StackView.Immediate)
|
root.pushEditView(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemovePermissionRequested: {
|
onRemovePermissionRequested: {
|
||||||
|
@ -94,26 +108,40 @@ StackView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: newPermissionView
|
id: newPermissionView
|
||||||
|
|
||||||
SettingsPage {
|
SettingsPage {
|
||||||
id: newPermissionViewPage
|
id: newPermissionViewPage
|
||||||
|
|
||||||
implicitWidth: 0
|
implicitWidth: 0
|
||||||
|
|
||||||
title: isEditState ? qsTr("Edit permission") : qsTr("New permission")
|
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 holdingsToEditModel: editPermissionView.selectedHoldingsModel
|
||||||
property alias channelsToEditModel: editPermissionView.selectedChannelsModel
|
property alias channelsToEditModel: editPermissionView.selectedChannelsModel
|
||||||
property alias permissionTypeToEdit: editPermissionView.permissionType
|
|
||||||
property alias isPrivateToEditValue: editPermissionView.isPrivate
|
property bool holdingsRequired: editPermissionView.dirtyValues.holdingsRequired
|
||||||
|
|
||||||
property string permissionKeyToEdit
|
property string permissionKeyToEdit
|
||||||
readonly property bool isEditState: !!permissionKeyToEdit
|
readonly property bool isEditState: !!permissionKeyToEdit
|
||||||
|
|
||||||
readonly property alias toast: settingsDirtyToastMessage
|
readonly property alias toast: settingsDirtyToastMessage
|
||||||
|
|
||||||
|
function resetChanges() {
|
||||||
|
editPermissionView.resetChanges();
|
||||||
|
}
|
||||||
|
function updatePermission() {
|
||||||
|
editPermissionView.saveChanges();
|
||||||
|
}
|
||||||
|
function createPermission() {
|
||||||
|
editPermissionView.createPermissionClicked();
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: EditPermissionView {
|
contentItem: EditPermissionView {
|
||||||
id: editPermissionView
|
id: editPermissionView
|
||||||
|
|
||||||
|
@ -123,7 +151,7 @@ StackView {
|
||||||
collectiblesModel: root.collectiblesModel
|
collectiblesModel: root.collectiblesModel
|
||||||
channelsModel: root.channelsModel
|
channelsModel: root.channelsModel
|
||||||
communityDetails: root.communityDetails
|
communityDetails: root.communityDetails
|
||||||
|
showChannelSelector: root.showChannelSelector
|
||||||
isEditState: newPermissionViewPage.isEditState
|
isEditState: newPermissionViewPage.isEditState
|
||||||
holdingsRequired: selectedHoldingsModel
|
holdingsRequired: selectedHoldingsModel
|
||||||
? selectedHoldingsModel.count > 0 : false
|
? selectedHoldingsModel.count > 0 : false
|
||||||
|
@ -191,15 +219,19 @@ StackView {
|
||||||
dirtyValues.selectedHoldingsModel,
|
dirtyValues.selectedHoldingsModel,
|
||||||
["key", "type", "amount"]) : []
|
["key", "type", "amount"]) : []
|
||||||
|
|
||||||
const channels = ModelUtils.modelToArray(
|
const channels = root.showChannelSelector ?
|
||||||
dirtyValues.selectedChannelsModel, ["key"])
|
ModelUtils.modelToArray(
|
||||||
|
dirtyValues.selectedChannelsModel, ["key"]) :
|
||||||
|
ModelUtils.modelToArray(selectedChannelsModel, ["key"])
|
||||||
|
|
||||||
root.createPermissionRequested(
|
root.createPermissionRequested(
|
||||||
dirtyValues.permissionType, holdings, channels,
|
dirtyValues.permissionType, holdings, channels,
|
||||||
dirtyValues.isPrivate)
|
dirtyValues.isPrivate)
|
||||||
|
|
||||||
|
if (root.showChannelSelector) {
|
||||||
root.pop(StackView.Immediate)
|
root.pop(StackView.Immediate)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onNavigateToMintTokenSettings: root.navigateToMintTokenSettings(isAssetType)
|
onNavigateToMintTokenSettings: root.navigateToMintTokenSettings(isAssetType)
|
||||||
|
|
||||||
|
@ -261,7 +293,8 @@ StackView {
|
||||||
// delay to avoid toast blinking on entry
|
// delay to avoid toast blinking on entry
|
||||||
settingsDirtyToastMessage.active = Qt.binding(
|
settingsDirtyToastMessage.active = Qt.binding(
|
||||||
() => editPermissionView.isEditState &&
|
() => editPermissionView.isEditState &&
|
||||||
editPermissionView.dirty)
|
editPermissionView.dirty &&
|
||||||
|
root.showChannelSelector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,14 @@ import QtQuick 2.15
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Dialogs 1.3
|
import QtQuick.Dialogs 1.3
|
||||||
|
import QtQml 2.15
|
||||||
import QtQml.Models 2.15
|
import QtQml.Models 2.15
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import shared.panels 1.0
|
import shared.panels 1.0
|
||||||
|
|
||||||
|
|
||||||
|
import StatusQ 0.1
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
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.Components 0.1
|
||||||
import StatusQ.Popups 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.panels 1.0
|
||||||
|
import AppLayouts.Communities.models 1.0
|
||||||
|
import AppLayouts.Communities.controls 1.0
|
||||||
|
|
||||||
StatusStackModal {
|
StatusStackModal {
|
||||||
id: root
|
id: root
|
||||||
|
@ -26,9 +31,12 @@ StatusStackModal {
|
||||||
property bool isDiscordImport // creating new or importing from discord?
|
property bool isDiscordImport // creating new or importing from discord?
|
||||||
property bool isEdit: false
|
property bool isEdit: false
|
||||||
property bool isDeleteable: false
|
property bool isDeleteable: false
|
||||||
|
property bool viewOnlyCanAddReaction
|
||||||
|
property bool hideIfPermissionsNotMet
|
||||||
|
|
||||||
property string communityId: ""
|
property string communityId: ""
|
||||||
property string chatId: ""
|
property string chatId: "_newChannel"
|
||||||
|
|
||||||
property string categoryId: ""
|
property string categoryId: ""
|
||||||
property string channelName: ""
|
property string channelName: ""
|
||||||
property string channelDescription: ""
|
property string channelDescription: ""
|
||||||
|
@ -39,20 +47,90 @@ StatusStackModal {
|
||||||
readonly property int communityColorValidator: Utils.Validate.NoEmpty
|
readonly property int communityColorValidator: Utils.Validate.NoEmpty
|
||||||
| Utils.Validate.TextHexColor
|
| 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 maxChannelNameLength: 24
|
||||||
readonly property int maxChannelDescLength: 140
|
readonly property int maxChannelDescLength: 140
|
||||||
|
|
||||||
|
// channel signals
|
||||||
signal createCommunityChannel(string chName, string chDescription, string chEmoji, string chColor, string chCategoryId)
|
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 editCommunityChannel(string chName, string chDescription, string chEmoji, string chColor, string chCategoryId)
|
||||||
signal deleteCommunityChannel()
|
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
|
width: 640
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
currentIndex: d.currentPage
|
||||||
|
|
||||||
|
enum CurrentPage {
|
||||||
|
ChannelDetails, //0
|
||||||
|
ColorPicker, //1
|
||||||
|
ChannelPermissions, //2
|
||||||
|
DiscordImportUploadFile, //3
|
||||||
|
DiscordImportUploadStart //4
|
||||||
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
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() {
|
function isFormValid() {
|
||||||
return nameInput.valid && descriptionTextArea.valid &&
|
return nameInput.valid && descriptionTextArea.valid &&
|
||||||
Utils.validateAndReturnError(colorDialog.color.toString().toUpperCase(), communityColorValidator) === ""
|
Utils.validateAndReturnError(colorPanel.color.toString().toUpperCase(), communityColorValidator) === ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function openEmojiPopup(leftSide = false) {
|
function openEmojiPopup(leftSide = false) {
|
||||||
|
@ -70,7 +148,7 @@ StatusStackModal {
|
||||||
categoryId: root.categoryId,
|
categoryId: root.categoryId,
|
||||||
name: StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
name: StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
||||||
description: StatusQUtils.Utils.filterXSS(descriptionTextArea.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),
|
emoji: StatusQUtils.Emoji.deparse(nameInput.input.asset.emoji),
|
||||||
options: {
|
options: {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -85,66 +163,99 @@ StatusStackModal {
|
||||||
creatingError.open()
|
creatingError.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
stackTitle: isDiscordImport ? qsTr("New Channel With Imported Chat History") :
|
function saveAndClose() {
|
||||||
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
|
|
||||||
}
|
|
||||||
let emoji = StatusQUtils.Emoji.deparse(nameInput.input.asset.emoji)
|
let emoji = StatusQUtils.Emoji.deparse(nameInput.input.asset.emoji)
|
||||||
|
|
||||||
if (!isEdit) {
|
if (!isEdit) {
|
||||||
root.createCommunityChannel(StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
root.createCommunityChannel(StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
||||||
StatusQUtils.Utils.filterXSS(descriptionTextArea.text),
|
StatusQUtils.Utils.filterXSS(descriptionTextArea.text),
|
||||||
emoji,
|
emoji,
|
||||||
colorDialog.color.toString().toUpperCase(),
|
colorPanel.color.toString().toUpperCase(),
|
||||||
root.categoryId)
|
root.categoryId)
|
||||||
} else {
|
} else {
|
||||||
root.editCommunityChannel(StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
root.editCommunityChannel(StatusQUtils.Utils.filterXSS(nameInput.input.text),
|
||||||
StatusQUtils.Utils.filterXSS(descriptionTextArea.text),
|
StatusQUtils.Utils.filterXSS(descriptionTextArea.text),
|
||||||
emoji,
|
emoji,
|
||||||
colorDialog.color.toString().toUpperCase(),
|
colorPanel.color.toString().toUpperCase(),
|
||||||
root.categoryId)
|
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
|
// TODO Open the channel once we have designs for it
|
||||||
root.close()
|
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 {
|
readonly property StatusButton clearFilesButton: StatusButton {
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
text: qsTr("Clear all")
|
text: qsTr("Clear all")
|
||||||
|
height: 44
|
||||||
type: StatusBaseButton.Type.Danger
|
type: StatusBaseButton.Type.Danger
|
||||||
visible: typeof currentItem.isFileListView !== "undefined" && currentItem.isFileListView
|
visible: typeof currentItem.isFileListView !== "undefined" && currentItem.isFileListView
|
||||||
enabled: !fileListView.fileListModelEmpty && !root.communitiesStore.discordDataExtractionInProgress
|
enabled: !fileListView.fileListModelEmpty && !root.communitiesStore.discordDataExtractionInProgress
|
||||||
|
@ -153,12 +264,32 @@ StatusStackModal {
|
||||||
|
|
||||||
readonly property StatusButton deleteChannelButton: StatusButton {
|
readonly property StatusButton deleteChannelButton: StatusButton {
|
||||||
objectName: "deleteCommunityChannelBtn"
|
objectName: "deleteCommunityChannelBtn"
|
||||||
visible: isEdit && isDeleteable && !isDiscordImport && typeof(replaceItem) === "undefined"
|
height: 44
|
||||||
text: qsTr("Delete channel")
|
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
|
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]
|
rightButtons: [clearFilesButton, deleteChannelButton, nextButton, finishButton]
|
||||||
|
|
||||||
onAboutToShow: {
|
onAboutToShow: {
|
||||||
|
@ -179,7 +310,7 @@ StatusStackModal {
|
||||||
if (root.channelEmoji) {
|
if (root.channelEmoji) {
|
||||||
nameInput.input.asset.emoji = root.channelEmoji
|
nameInput.input.asset.emoji = root.channelEmoji
|
||||||
}
|
}
|
||||||
colorDialog.color = root.channelColor
|
colorPanel.color = root.channelColor
|
||||||
} else {
|
} else {
|
||||||
nameInput.input.asset.isLetterIdenticon = true;
|
nameInput.input.asset.isLetterIdenticon = true;
|
||||||
}
|
}
|
||||||
|
@ -188,10 +319,8 @@ StatusStackModal {
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property list<Item> discordPages: [
|
readonly property list<Item> discordPages: [
|
||||||
ColumnLayout {
|
Item {
|
||||||
id: fileListView
|
id: fileListViewItem
|
||||||
spacing: 24
|
|
||||||
|
|
||||||
readonly property bool isFileListView: true
|
readonly property bool isFileListView: true
|
||||||
|
|
||||||
readonly property var fileListModel: root.communitiesStore.discordFileList
|
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)
|
: fileListModel.selectedCount ? qsTr("Validate (%1/%2) files").arg(fileListModel.selectedCount).arg(fileListModel.count)
|
||||||
: qsTr("Start channel import")
|
: qsTr("Start channel import")
|
||||||
readonly property var nextAction: function () {
|
readonly property var nextAction: function () {
|
||||||
if (!fileListView.fileListModel.selectedFilesValid)
|
if (!fileListViewItem.fileListModel.selectedFilesValid)
|
||||||
return root.communitiesStore.requestExtractChannelsAndCategories()
|
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 {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -219,12 +354,12 @@ StatusStackModal {
|
||||||
maximumLineCount: 2
|
maximumLineCount: 2
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
elide: Text.ElideRight
|
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") :
|
root.communitiesStore.discordImportErrorsCount ? qsTr("Some of your community files cannot be used") :
|
||||||
qsTr("Uncheck any files you would like to exclude from the import")
|
qsTr("Uncheck any files you would like to exclude from the import")
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
visible: fileListView.fileListModelEmpty && !issuePill.visible
|
visible: fileListViewItem.fileListModelEmpty && !issuePill.visible
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: Theme.palette.baseColor1
|
color: Theme.palette.baseColor1
|
||||||
text: qsTr("(JSON file format only)")
|
text: qsTr("(JSON file format only)")
|
||||||
|
@ -233,7 +368,7 @@ StatusStackModal {
|
||||||
id: issuePill
|
id: issuePill
|
||||||
type: root.communitiesStore.discordImportErrorsCount ? IssuePill.Type.Error : IssuePill.Type.Warning
|
type: root.communitiesStore.discordImportErrorsCount ? IssuePill.Type.Error : IssuePill.Type.Warning
|
||||||
count: root.communitiesStore.discordImportErrorsCount || root.communitiesStore.discordImportWarningsCount || 0
|
count: root.communitiesStore.discordImportErrorsCount || root.communitiesStore.discordImportWarningsCount || 0
|
||||||
visible: !!count && !fileListView.fileListModelEmpty
|
visible: !!count && !fileListViewItem.fileListModelEmpty
|
||||||
}
|
}
|
||||||
StatusButton {
|
StatusButton {
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
|
@ -250,7 +385,7 @@ StatusStackModal {
|
||||||
color: Theme.palette.baseColor4
|
color: Theme.palette.baseColor4
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
visible: fileListView.fileListModelEmpty
|
visible: fileListViewItem.fileListModelEmpty
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 60
|
anchors.topMargin: 60
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
@ -261,32 +396,29 @@ StatusStackModal {
|
||||||
asset.name: "info"
|
asset.name: "info"
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
|
id: infoText1
|
||||||
Layout.topMargin: 8
|
Layout.topMargin: 8
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
horizontalAlignment: 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>")
|
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)
|
onLinkActivated: Global.openLink(link)
|
||||||
HoverHandler {
|
|
||||||
id: handler1
|
|
||||||
}
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
acceptedButtons: Qt.NoButton
|
acceptedButtons: Qt.NoButton
|
||||||
cursorShape: handler1.hovered && parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
|
id: infoText2
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
horizontalAlignment: 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")
|
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)
|
onLinkActivated: Global.openLink(link)
|
||||||
HoverHandler {
|
onHoveredLinkChanged: print(hoveredLink)
|
||||||
id: handler2
|
|
||||||
}
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
acceptedButtons: Qt.NoButton
|
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 {
|
StatusListView {
|
||||||
visible: !fileListView.fileListModelEmpty
|
visible: !fileListViewItem.fileListModelEmpty
|
||||||
enabled: !root.communitiesStore.discordDataExtractionInProgress
|
enabled: !root.communitiesStore.discordDataExtractionInProgress
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
leftMargin: 8
|
leftMargin: 8
|
||||||
rightMargin: 8
|
rightMargin: 8
|
||||||
model: fileListView.fileListModel
|
model: fileListViewItem.fileListModel
|
||||||
header: !atYBeginning ? floatingDivComp : null
|
header: !atYBeginning ? floatingDivComp : null
|
||||||
headerPositioning: ListView.OverlayHeader
|
headerPositioning: ListView.OverlayHeader
|
||||||
footer: !atYEnd ? floatingDivComp : null
|
footer: !atYEnd ? floatingDivComp : null
|
||||||
|
@ -352,7 +484,7 @@ StatusStackModal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: fileDialog
|
id: fileDialog
|
||||||
title: qsTr("Choose files to import")
|
title: qsTr("Choose files to import")
|
||||||
|
@ -368,11 +500,7 @@ StatusStackModal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Item {
|
||||||
ColumnLayout {
|
|
||||||
id: categoriesAndChannelsView
|
|
||||||
spacing: 24
|
|
||||||
|
|
||||||
readonly property bool canGoNext: root.communitiesStore.discordChannelsModel.hasSelectedItems
|
readonly property bool canGoNext: root.communitiesStore.discordChannelsModel.hasSelectedItems
|
||||||
readonly property var nextAction: function () {
|
readonly property var nextAction: function () {
|
||||||
d.requestImportDiscordChannel()
|
d.requestImportDiscordChannel()
|
||||||
|
@ -382,6 +510,13 @@ StatusStackModal {
|
||||||
root.replace(progressComponent)
|
root.replace(progressComponent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: categoriesAndChannelsView
|
||||||
|
spacing: 24
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: progressComponent
|
id: progressComponent
|
||||||
DiscordImportProgressContents {
|
DiscordImportProgressContents {
|
||||||
|
@ -480,6 +615,7 @@ StatusStackModal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -512,18 +648,17 @@ StatusStackModal {
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
width: scrollView.availableWidth
|
width: scrollView.availableWidth
|
||||||
spacing: 0
|
spacing: Style.current.padding
|
||||||
|
|
||||||
StatusInput {
|
StatusInput {
|
||||||
id: nameInput
|
id: nameInput
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: Style.current.padding
|
||||||
|
Layout.rightMargin: Style.current.padding
|
||||||
input.edit.objectName: "createOrEditCommunityChannelNameInput"
|
input.edit.objectName: "createOrEditCommunityChannelNameInput"
|
||||||
label: qsTr("Channel name")
|
label: qsTr("Channel name")
|
||||||
charLimit: root.maxChannelNameLength
|
charLimit: root.maxChannelNameLength
|
||||||
placeholderText: qsTr("# Name the channel")
|
placeholderText: qsTr("# Name the channel")
|
||||||
|
|
||||||
input.onTextChanged: {
|
input.onTextChanged: {
|
||||||
const cursorPosition = input.cursorPosition
|
const cursorPosition = input.cursorPosition
|
||||||
input.text = Utils.convertSpacesToDashes(input.text)
|
input.text = Utils.convertSpacesToDashes(input.text)
|
||||||
|
@ -532,7 +667,7 @@ StatusStackModal {
|
||||||
input.letterIconName = text
|
input.letterIconName = text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input.asset.color: colorDialog.color.toString()
|
input.asset.color: colorPanel.color.toString()
|
||||||
input.rightComponent: StatusRoundButton {
|
input.rightComponent: StatusRoundButton {
|
||||||
objectName: "StatusChannelPopup_emojiButton"
|
objectName: "StatusChannelPopup_emojiButton"
|
||||||
implicitWidth: 32
|
implicitWidth: 32
|
||||||
|
@ -559,48 +694,48 @@ StatusStackModal {
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.preferredHeight: 16
|
|
||||||
Layout.fillWidth: true
|
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 {
|
property string validationError: ""
|
||||||
id: colorDialog
|
width: parent.width
|
||||||
Layout.fillWidth: true
|
anchors.bottom: parent.bottom
|
||||||
title: qsTr("Channel colour")
|
bgColor: colorPanel.colorSelected ? colorPanel.color : Theme.palette.baseColor2
|
||||||
color: root.isEdit && root.channelColor ? root.channelColor : Theme.palette.primaryColor1
|
contentColor: colorPanel.colorSelected ? Theme.palette.white : Theme.palette.baseColor1
|
||||||
onPick: root.replace(colorPanel)
|
text: colorPanel.colorSelected ? colorPanel.color.toString().toUpperCase() : qsTr("Pick a colour")
|
||||||
|
onClicked: { d.currentPage = CreateChannelPopup.CurrentPage.ColorPicker; d.colorPickerOpened = true; }
|
||||||
Component {
|
onTextChanged: {
|
||||||
id: colorPanel
|
if (colorPanel.colorSelected) {
|
||||||
ColorPanel {
|
validationError = Utils.validateAndReturnError(text, communityColorValidator)
|
||||||
title: qsTr("Channel colour")
|
|
||||||
buttonText: qsTr("Select Colour")
|
|
||||||
Component.onCompleted: color = colorDialog.color
|
|
||||||
onAccepted: {
|
|
||||||
colorDialog.color = color
|
|
||||||
root.replaceItem = undefined
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.preferredHeight: 16
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusInput {
|
StatusInput {
|
||||||
id: descriptionTextArea
|
id: descriptionTextArea
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.current.halfPadding
|
||||||
|
Layout.leftMargin: Style.current.padding
|
||||||
|
Layout.rightMargin: Style.current.padding
|
||||||
input.edit.objectName: "createOrEditCommunityChannelDescriptionInput"
|
input.edit.objectName: "createOrEditCommunityChannelDescriptionInput"
|
||||||
input.verticalAlignment: TextEdit.AlignTop
|
input.verticalAlignment: TextEdit.AlignTop
|
||||||
label: qsTr("Description")
|
label: qsTr("Description")
|
||||||
charLimit: 140
|
charLimit: 140
|
||||||
|
|
||||||
placeholderText: qsTr("Describe the channel")
|
placeholderText: qsTr("Describe the channel")
|
||||||
input.multiline: true
|
input.multiline: true
|
||||||
minimumHeight: 88
|
minimumHeight: 108
|
||||||
maximumHeight: 88
|
maximumHeight: 108
|
||||||
validators: [
|
validators: [
|
||||||
StatusMinLengthValidator {
|
StatusMinLengthValidator {
|
||||||
minLength: 1
|
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 mode: PermissionsDropdown.Mode.Add
|
||||||
property int initialPermissionType: PermissionTypes.Type.None
|
property int initialPermissionType: PermissionTypes.Type.None
|
||||||
|
property bool allowCommunityOptions: true
|
||||||
|
|
||||||
property bool enableAdminPermission: true
|
property bool enableAdminPermission: true
|
||||||
|
|
||||||
|
@ -97,13 +98,14 @@ StatusDropdown {
|
||||||
CustomSeparator {
|
CustomSeparator {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: d.sectionHeight
|
Layout.preferredHeight: d.sectionHeight
|
||||||
|
visible: root.allowCommunityOptions
|
||||||
text: qsTr("Community")
|
text: qsTr("Community")
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomPermissionListItem {
|
CustomPermissionListItem {
|
||||||
permissionType: PermissionTypes.Type.Admin
|
permissionType: PermissionTypes.Type.Admin
|
||||||
enabled: root.enableAdminPermission
|
enabled: root.enableAdminPermission
|
||||||
|
visible: root.allowCommunityOptions
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
objectName: "becomeAdmin"
|
objectName: "becomeAdmin"
|
||||||
|
@ -112,6 +114,7 @@ StatusDropdown {
|
||||||
CustomPermissionListItem {
|
CustomPermissionListItem {
|
||||||
permissionType: PermissionTypes.Type.Member
|
permissionType: PermissionTypes.Type.Member
|
||||||
|
|
||||||
|
visible: root.allowCommunityOptions
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
objectName: "becomeMember"
|
objectName: "becomeMember"
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ Item {
|
||||||
required property CurrenciesStore currencyStore
|
required property CurrenciesStore currencyStore
|
||||||
property bool hasAddedContacts: false
|
property bool hasAddedContacts: false
|
||||||
property var communityData
|
property var communityData
|
||||||
|
property alias createChannelPopup: createChannelPopup
|
||||||
|
|
||||||
// Community transfer ownership related props:
|
// Community transfer ownership related props:
|
||||||
required property bool isPendingOwnershipRequest
|
required property bool isPendingOwnershipRequest
|
||||||
|
@ -52,6 +53,11 @@ Item {
|
||||||
communityData.memberRole === Constants.memberRole.admin ||
|
communityData.memberRole === Constants.memberRole.admin ||
|
||||||
communityData.memberRole === Constants.memberRole.tokenMaster
|
communityData.memberRole === Constants.memberRole.tokenMaster
|
||||||
|
|
||||||
|
readonly property var permissionsModel: {
|
||||||
|
root.store.prepareTokenModelForCommunity(communityData.id)
|
||||||
|
return root.store.permissionsModel
|
||||||
|
}
|
||||||
|
|
||||||
signal infoButtonClicked
|
signal infoButtonClicked
|
||||||
signal manageButtonClicked
|
signal manageButtonClicked
|
||||||
|
|
||||||
|
@ -297,7 +303,6 @@ Item {
|
||||||
|
|
||||||
chatListPopupMenu: ChatContextMenuView {
|
chatListPopupMenu: ChatContextMenuView {
|
||||||
id: chatContextMenuView
|
id: chatContextMenuView
|
||||||
emojiPopup: root.emojiPopup
|
|
||||||
showDebugOptions: root.store.isDebugEnabledfir
|
showDebugOptions: root.store.isDebugEnabledfir
|
||||||
|
|
||||||
// TODO pass the chatModel in its entirety instead of fetching the JSOn using just the id
|
// TODO pass the chatModel in its entirety instead of fetching the JSOn using just the id
|
||||||
|
@ -368,17 +373,18 @@ Item {
|
||||||
onDisplayProfilePopup: {
|
onDisplayProfilePopup: {
|
||||||
Global.openProfilePopup(publicKey)
|
Global.openProfilePopup(publicKey)
|
||||||
}
|
}
|
||||||
|
onDisplayEditChannelPopup: {
|
||||||
onEditCommunityChannel: {
|
Global.openPopup(createChannelPopup, {
|
||||||
communitySectionModule.editCommunityChannel(
|
isEdit: true,
|
||||||
chatId,
|
channelName: chatName,
|
||||||
newName,
|
channelDescription: chatDescription,
|
||||||
newDescription,
|
channelEmoji: chatEmoji,
|
||||||
newEmoji,
|
channelColor: chatColor,
|
||||||
newColor,
|
categoryId: chatCategoryId,
|
||||||
newCategory,
|
chatId: chatContextMenuView.chatId,
|
||||||
channelPosition // TODO change this to the signal once it is modifiable
|
channelPosition: channelPosition,
|
||||||
)
|
deleteChatConfirmationDialog: deleteChatConfirmationDialog
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -607,11 +613,63 @@ Item {
|
||||||
id: createChannelPopup
|
id: createChannelPopup
|
||||||
CreateChannelPopup {
|
CreateChannelPopup {
|
||||||
communitiesStore: root.communitiesStore
|
communitiesStore: root.communitiesStore
|
||||||
|
assetsModel: root.store.assetsModel
|
||||||
|
collectiblesModel: root.store.collectiblesModel
|
||||||
|
permissionsModel: root.store.permissionsModel
|
||||||
|
channelsModel: root.store.chatCommunitySectionModule.model
|
||||||
emojiPopup: root.emojiPopup
|
emojiPopup: root.emojiPopup
|
||||||
|
activeCommunity: root.communityData
|
||||||
|
|
||||||
|
property int channelPosition: -1
|
||||||
|
property var deleteChatConfirmationDialog
|
||||||
|
|
||||||
onCreateCommunityChannel: function (chName, chDescription, chEmoji, chColor,
|
onCreateCommunityChannel: function (chName, chDescription, chEmoji, chColor,
|
||||||
chCategoryId) {
|
chCategoryId) {
|
||||||
root.store.createCommunityChannel(chName, chDescription, chEmoji, chColor,
|
root.store.createCommunityChannel(chName, chDescription, chEmoji, chColor,
|
||||||
chCategoryId)
|
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: {
|
onClosed: {
|
||||||
destroy()
|
destroy()
|
||||||
|
|
|
@ -38,14 +38,14 @@ StatusScrollView {
|
||||||
|
|
||||||
readonly property alias dirtyValues: d.dirtyValues
|
readonly property alias dirtyValues: d.dirtyValues
|
||||||
|
|
||||||
readonly property bool isFullyFilled:
|
readonly property bool isFullyFilled: (dirtyValues.selectedHoldingsModel.count > 0 || !whoHoldsSwitch.checked) &&
|
||||||
(dirtyValues.selectedHoldingsModel.count > 0 || !whoHoldsSwitch.checked) &&
|
|
||||||
dirtyValues.permissionType !== PermissionTypes.Type.None &&
|
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 int permissionType: PermissionTypes.Type.None
|
||||||
property bool isPrivate: false
|
property bool isPrivate: false
|
||||||
property bool holdingsRequired: true
|
property bool holdingsRequired: true
|
||||||
|
property bool showChannelSelector: true
|
||||||
|
|
||||||
// roles: type, key, name, amount, imageSource
|
// roles: type, key, name, amount, imageSource
|
||||||
property var selectedHoldingsModel: ListModel {}
|
property var selectedHoldingsModel: ListModel {}
|
||||||
|
@ -430,6 +430,7 @@ StatusScrollView {
|
||||||
PermissionsDropdown {
|
PermissionsDropdown {
|
||||||
id: permissionsDropdown
|
id: permissionsDropdown
|
||||||
|
|
||||||
|
allowCommunityOptions: root.showChannelSelector
|
||||||
initialPermissionType: d.dirtyValues.permissionType
|
initialPermissionType: d.dirtyValues.permissionType
|
||||||
enableAdminPermission: root.communityDetails.owner
|
enableAdminPermission: root.communityDetails.owner
|
||||||
|
|
||||||
|
@ -454,7 +455,7 @@ StatusScrollView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SequenceColumnLayout.Separator {}
|
SequenceColumnLayout.Separator { visible: root.showChannelSelector }
|
||||||
|
|
||||||
StatusItemSelector {
|
StatusItemSelector {
|
||||||
id: inSelector
|
id: inSelector
|
||||||
|
@ -463,7 +464,7 @@ StatusScrollView {
|
||||||
|
|
||||||
addButton.visible: editable
|
addButton.visible: editable
|
||||||
itemsClickable: editable
|
itemsClickable: editable
|
||||||
|
visible: root.showChannelSelector
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
icon: d.isCommunityPermission ? Style.svg("communities") : Style.svg("create-category")
|
icon: d.isCommunityPermission ? Style.svg("communities") : Style.svg("create-category")
|
||||||
title: qsTr("In")
|
title: qsTr("In")
|
||||||
|
@ -566,7 +567,7 @@ StatusScrollView {
|
||||||
color: Theme.palette.baseColor2
|
color: Theme.palette.baseColor2
|
||||||
}
|
}
|
||||||
|
|
||||||
HidePermissionPanel {
|
StatusIconSwitch {
|
||||||
Layout.topMargin: 12
|
Layout.topMargin: 12
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
@ -574,6 +575,9 @@ StatusScrollView {
|
||||||
|
|
||||||
enabled: d.dirtyValues.permissionType !== PermissionTypes.Type.Admin
|
enabled: d.dirtyValues.permissionType !== PermissionTypes.Type.Admin
|
||||||
checked: d.dirtyValues.isPrivate
|
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
|
onToggled: d.dirtyValues.isPrivate = checked
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +604,7 @@ StatusScrollView {
|
||||||
StatusWarningBox {
|
StatusWarningBox {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.current.padding
|
Layout.topMargin: Style.current.padding
|
||||||
|
visible: root.showChannelSelector
|
||||||
icon: "desktop"
|
icon: "desktop"
|
||||||
text: qsTr("Any changes to community permissions will take effect after the control node receives and processes them")
|
text: qsTr("Any changes to community permissions will take effect after the control node receives and processes them")
|
||||||
borderColor: Theme.palette.baseColor1
|
borderColor: Theme.palette.baseColor1
|
||||||
|
@ -613,7 +617,7 @@ StatusScrollView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.current.bigPadding
|
Layout.topMargin: Style.current.bigPadding
|
||||||
|
|
||||||
visible: !root.isEditState
|
visible: !root.isEditState && root.showChannelSelector
|
||||||
text: qsTr("Create permission")
|
text: qsTr("Create permission")
|
||||||
enabled: root.isFullyFilled
|
enabled: root.isFullyFilled
|
||||||
&& !root.permissionDuplicated
|
&& !root.permissionDuplicated
|
||||||
|
|
|
@ -2,16 +2,27 @@ import QtQuick 2.14
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.14
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
import SortFilterProxyModel 0.2
|
||||||
|
import shared.status 1.0
|
||||||
import shared.popups 1.0
|
import shared.popups 1.0
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import AppLayouts.Communities.controls 1.0
|
import AppLayouts.Communities.controls 1.0
|
||||||
import AppLayouts.Communities.panels 1.0
|
import AppLayouts.Communities.panels 1.0
|
||||||
|
|
||||||
StatusScrollView {
|
ColumnLayout {
|
||||||
id: root
|
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 permissionsModel
|
||||||
required property var assetsModel
|
required property var assetsModel
|
||||||
|
@ -22,27 +33,16 @@ StatusScrollView {
|
||||||
required property var communityDetails
|
required property var communityDetails
|
||||||
|
|
||||||
property int viewWidth: 560 // by design
|
property int viewWidth: 560 // by design
|
||||||
|
property bool viewOnlyCanAddReaction
|
||||||
|
property bool showChannelOptions: false
|
||||||
|
property bool allowIntroPanel: true
|
||||||
|
|
||||||
signal editPermissionRequested(int index)
|
signal editPermissionRequested(int index)
|
||||||
signal duplicatePermissionRequested(int index)
|
signal duplicatePermissionRequested(int index)
|
||||||
signal removePermissionRequested(int index)
|
signal removePermissionRequested(int index)
|
||||||
|
signal userRestrictionsToggled(bool checked)
|
||||||
|
|
||||||
readonly property alias count: repeater.count
|
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 {
|
ListModel {
|
||||||
id: communityItemModel
|
id: communityItemModel
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ StatusScrollView {
|
||||||
IntroPanel {
|
IntroPanel {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
visible: root.count === 0
|
visible: (root.count === 0 && root.allowIntroPanel)
|
||||||
|
|
||||||
image: Style.png("community/permissions2_3")
|
image: Style.png("community/permissions2_3")
|
||||||
title: qsTr("Permissions")
|
title: qsTr("Permissions")
|
||||||
|
@ -100,8 +100,8 @@ StatusScrollView {
|
||||||
|
|
||||||
showButtons: (model.permissionType !== PermissionTypes.Type.TokenMaster &&
|
showButtons: (model.permissionType !== PermissionTypes.Type.TokenMaster &&
|
||||||
model.permissionType !== PermissionTypes.Type.Owner) &&
|
model.permissionType !== PermissionTypes.Type.Owner) &&
|
||||||
(root.communityDetails.owner ||
|
(!!root.communityDetails && (root.communityDetails.owner ||
|
||||||
((root.communityDetails.admin || root.communityDetails.tokenMaster) && model.permissionType !== PermissionTypes.Type.Admin))
|
((root.communityDetails.admin || root.communityDetails.tokenMaster) && model.permissionType !== PermissionTypes.Type.Admin)))
|
||||||
|
|
||||||
onEditClicked: root.editPermissionRequested(model.index)
|
onEditClicked: root.editPermissionRequested(model.index)
|
||||||
onDuplicateClicked: root.duplicatePermissionRequested(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 {
|
ConfirmationDialog {
|
||||||
id: declineAllDialog
|
id: declineAllDialog
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,11 @@ StatusMenu {
|
||||||
property bool chatMuted: false
|
property bool chatMuted: false
|
||||||
property int channelPosition: -1
|
property int channelPosition: -1
|
||||||
property string chatCategoryId: ""
|
property string chatCategoryId: ""
|
||||||
property var emojiPopup
|
|
||||||
property bool showDebugOptions: false
|
property bool showDebugOptions: false
|
||||||
|
property alias deleteChatConfirmationDialog: deleteChatConfirmationDialogComponent
|
||||||
|
|
||||||
signal displayProfilePopup(string publicKey)
|
signal displayProfilePopup(string publicKey)
|
||||||
|
signal displayEditChannelPopup(string chatId)
|
||||||
signal requestAllHistoricMessages(string chatId)
|
signal requestAllHistoricMessages(string chatId)
|
||||||
signal unmuteChat(string chatId)
|
signal unmuteChat(string chatId)
|
||||||
signal muteChat(string chatId, int interval)
|
signal muteChat(string chatId, int interval)
|
||||||
|
@ -140,38 +141,7 @@ StatusMenu {
|
||||||
icon.name: "edit"
|
icon.name: "edit"
|
||||||
enabled: root.isCommunityChat && root.amIChatAdmin
|
enabled: root.isCommunityChat && root.amIChatAdmin
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
Global.openPopup(editChannelPopup, {
|
root.displayEditChannelPopup(root.chatId);
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue