import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Controls 0.1 import StatusQ.Components 0.1 import StatusQ.Popups 0.1 import utils 1.0 import shared.panels 1.0 import shared.controls 1.0 import "../stores" import "../controls" import "../panels" import "../popups" SettingsContentBase { id: root property NotificationsStore notificationsStore Component.onCompleted: root.notificationsStore.loadExemptions() content: ColumnLayout { id: contentColumn spacing: Constants.settingsSection.itemSpacing ButtonGroup { id: messageSetting } Loader { id: exemptionNotificationsModal active: false function open(item) { active = true exemptionNotificationsModal.item.item = item exemptionNotificationsModal.item.open() } function close() { active = false } sourceComponent: ExemptionNotificationsModal { anchors.centerIn: parent notificationsStore: root.notificationsStore onClosed: { exemptionNotificationsModal.close(); } } } Component { id: exemptionDelegateComponent StatusListItem { property string lowerCaseSearchString: searchBox.text.toLowerCase() width: ListView.view.width height: visible ? implicitHeight : 0 visible: lowerCaseSearchString === "" || model.itemId.toLowerCase().includes(lowerCaseSearchString) || model.name.toLowerCase().includes(lowerCaseSearchString) title: model.name subTitle: { if(model.type === Constants.settingsSection.exemptions.community) return qsTr("Community") else if(model.type === Constants.settingsSection.exemptions.oneToOneChat) return qsTr("1:1 Chat") else if(model.type === Constants.settingsSection.exemptions.groupChat) return qsTr("Group Chat") else return "" } label: { if(!model.customized) return "" let l = "" if(model.muteAllMessages) l += qsTr("Muted") else { let nbOfChanges = 0 if(model.personalMentions !== Constants.settingsSection.notifications.sendAlertsValue) { nbOfChanges++ let valueText = model.personalMentions === Constants.settingsSection.notifications.turnOffValue? qsTr("Off") : qsTr("Quiet") l = qsTr("Personal @ Mentions %1").arg(valueText) } if(model.globalMentions !== Constants.settingsSection.notifications.sendAlertsValue) { nbOfChanges++ let valueText = model.globalMentions === Constants.settingsSection.notifications.turnOffValue? qsTr("Off") : qsTr("Quiet") l = qsTr("Global @ Mentions %1").arg(valueText) } if(model.otherMessages !== Constants.settingsSection.notifications.turnOffValue) { nbOfChanges++ let valueText = model.otherMessages === Constants.settingsSection.notifications.sendAlertsValue? qsTr("Alerts") : qsTr("Quiet") l = qsTr("Other Messages %1").arg(valueText) } if(nbOfChanges > 1) l = qsTr("Multiple Exemptions") } return l } // Maybe we need to redo `StatusListItem` to display identicon ring, but that's not in Figma design for now. ringSettings.ringSpecModel: model.type === Constants.settingsSection.exemptions.oneToOneChat ? Utils.getColorHashAsJson(model.itemId) : undefined asset: StatusAssetSettings { name: model.image isImage: !!model.image && model.image !== "" color: model.type === Constants.settingsSection.exemptions.oneToOneChat? Utils.colorForPubkey(model.itemId) : model.color charactersLen: model.type === Constants.settingsSection.exemptions.oneToOneChat? 2 : 1 isLetterIdenticon: !model.image || model.image === "" height: 40 width: 40 } components: [ StatusIcon { visible: model.customized icon: "next" color: Theme.palette.baseColor1 MouseArea { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { exemptionNotificationsModal.open(model) } } }, StatusIcon { visible: !model.customized icon: "add" color: Theme.palette.primaryColor1 MouseArea { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { exemptionNotificationsModal.open(model) } } }] } } Rectangle { Layout.preferredWidth: root.contentWidth implicitHeight: col1.height + 2 * Theme.padding visible: Qt.platform.os == Constants.mac radius: Constants.settingsSection.radius color: Theme.palette.primaryColor3 ColumnLayout { id: col1 anchors.margins: Theme.padding anchors.left: parent.left anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter spacing: Constants.settingsSection.infoSpacing StatusBaseText { Layout.preferredWidth: parent.width text: qsTr("Enable Notifications in macOS Settings") font.pixelSize: Constants.settingsSection.infoFontSize lineHeight: Constants.settingsSection.infoLineHeight lineHeightMode: Text.FixedHeight color: Theme.palette.primaryColor1 } StatusBaseText { Layout.preferredWidth: parent.width text: qsTr("To receive Status notifications, make sure you've enabled them in your computer's settings under System Preferences > Notifications") font.pixelSize: Constants.settingsSection.infoFontSize lineHeight: Constants.settingsSection.infoLineHeight lineHeightMode: Text.FixedHeight color: Theme.palette.baseColor1 wrapMode: Text.WordWrap } } } StatusListItem { Layout.preferredWidth: root.contentWidth title: qsTr("Allow Notification Bubbles") components: [ StatusSwitch { id: allowNotifSwitch checked: appSettings.notifSettingAllowNotifications onClicked: { appSettings.notifSettingAllowNotifications = !appSettings.notifSettingAllowNotifications } } ] onClicked: { allowNotifSwitch.clicked() } } StatusBaseText { Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding text: qsTr("Messages") font.pixelSize: Constants.settingsSection.subHeaderFontSize color: Theme.palette.baseColor1 } StatusListItem { Layout.preferredWidth: root.contentWidth title: qsTr("1:1 Chats") components: [ NotificationSelect { selected: appSettings.notifSettingOneToOneChats onSendAlertsClicked: appSettings.notifSettingOneToOneChats = Constants.settingsSection.notifications.sendAlertsValue onDeliverQuietlyClicked: appSettings.notifSettingOneToOneChats = Constants.settingsSection.notifications.deliverQuietlyValue onTurnOffClicked: appSettings.notifSettingOneToOneChats = Constants.settingsSection.notifications.turnOffValue } ] } StatusListItem { Layout.preferredWidth: root.contentWidth title: qsTr("Group Chats") components: [ NotificationSelect { selected: appSettings.notifSettingGroupChats onSendAlertsClicked: appSettings.notifSettingGroupChats = Constants.settingsSection.notifications.sendAlertsValue onDeliverQuietlyClicked: appSettings.notifSettingGroupChats = Constants.settingsSection.notifications.deliverQuietlyValue onTurnOffClicked: appSettings.notifSettingGroupChats = Constants.settingsSection.notifications.turnOffValue } ] } StatusListItem { Layout.preferredWidth: root.contentWidth title: qsTr("Personal @ Mentions") tertiaryTitle: qsTr("Messages containing @%1").arg(userProfile.name) components: [ NotificationSelect { selected: appSettings.notifSettingPersonalMentions onSendAlertsClicked: appSettings.notifSettingPersonalMentions = Constants.settingsSection.notifications.sendAlertsValue onDeliverQuietlyClicked: appSettings.notifSettingPersonalMentions = Constants.settingsSection.notifications.deliverQuietlyValue onTurnOffClicked: appSettings.notifSettingPersonalMentions = Constants.settingsSection.notifications.turnOffValue } ] } StatusListItem { Layout.preferredWidth: root.contentWidth title: qsTr("Global @ Mentions") tertiaryTitle: qsTr("Messages containing @everyone") components: [ NotificationSelect { selected: appSettings.notifSettingGlobalMentions onSendAlertsClicked: appSettings.notifSettingGlobalMentions = Constants.settingsSection.notifications.sendAlertsValue onDeliverQuietlyClicked: appSettings.notifSettingGlobalMentions = Constants.settingsSection.notifications.deliverQuietlyValue onTurnOffClicked: appSettings.notifSettingGlobalMentions = Constants.settingsSection.notifications.turnOffValue } ] } StatusListItem { Layout.preferredWidth: root.contentWidth title: qsTr("All Messages") components: [ NotificationSelect { selected: appSettings.notifSettingAllMessages onSendAlertsClicked: appSettings.notifSettingAllMessages = Constants.settingsSection.notifications.sendAlertsValue onDeliverQuietlyClicked: appSettings.notifSettingAllMessages = Constants.settingsSection.notifications.deliverQuietlyValue onTurnOffClicked: appSettings.notifSettingAllMessages = Constants.settingsSection.notifications.turnOffValue } ] } StatusBaseText { Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding text: qsTr("Others") font.pixelSize: Constants.settingsSection.subHeaderFontSize color: Theme.palette.baseColor1 } StatusListItem { Layout.preferredWidth: root.contentWidth title: qsTr("Contact Requests") components: [ NotificationSelect { selected: appSettings.notifSettingContactRequests onSendAlertsClicked: appSettings.notifSettingContactRequests = Constants.settingsSection.notifications.sendAlertsValue onDeliverQuietlyClicked: appSettings.notifSettingContactRequests = Constants.settingsSection.notifications.deliverQuietlyValue onTurnOffClicked: appSettings.notifSettingContactRequests = Constants.settingsSection.notifications.turnOffValue } ] } StatusListItem { // Hidden since 2.29 since it's not mature enough visible: false Layout.preferredWidth: root.contentWidth title: qsTr("Identity Verification Requests") components: [ NotificationSelect { selected: appSettings.notifSettingIdentityVerificationRequests onSendAlertsClicked: appSettings.notifSettingIdentityVerificationRequests = Constants.settingsSection.notifications.sendAlertsValue onDeliverQuietlyClicked: appSettings.notifSettingIdentityVerificationRequests = Constants.settingsSection.notifications.deliverQuietlyValue onTurnOffClicked: appSettings.notifSettingIdentityVerificationRequests = Constants.settingsSection.notifications.turnOffValue } ] } Separator { Layout.preferredWidth: root.contentWidth Layout.preferredHeight: Theme.bigPadding } StatusBaseText { Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding text: qsTr("Notification Content") font.pixelSize: Constants.settingsSection.subHeaderFontSize color: Theme.palette.directColor1 } NotificationAppearancePreviewPanel { id: notifNameAndMsg Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding name: qsTr("Show Name and Message") notificationTitle: "Vitalik Buterin" notificationMessage: qsTr("Hi there! So EIP-1559 will defini...") buttonGroup: messageSetting checked: appSettings.notificationMessagePreview === Constants.settingsSection.notificationsBubble.previewNameAndMessage onRadioCheckedChanged: { if (checked) { appSettings.notificationMessagePreview = Constants.settingsSection.notificationsBubble.previewNameAndMessage } } } NotificationAppearancePreviewPanel { Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding name: qsTr("Name Only") notificationTitle: "Vitalik Buterin" notificationMessage: qsTr("You have a new message") buttonGroup: messageSetting checked: appSettings.notificationMessagePreview === Constants.settingsSection.notificationsBubble.previewNameOnly onRadioCheckedChanged: { if (checked) { appSettings.notificationMessagePreview = Constants.settingsSection.notificationsBubble.previewNameOnly } } } NotificationAppearancePreviewPanel { Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding name: qsTr("Anonymous") notificationTitle: "Status" notificationMessage: qsTr("You have a new message") buttonGroup: messageSetting checked: appSettings.notificationMessagePreview === Constants.settingsSection.notificationsBubble.previewAnonymous onRadioCheckedChanged: { if (checked) { appSettings.notificationMessagePreview = Constants.settingsSection.notificationsBubble.previewAnonymous } } } StatusListItem { Layout.preferredWidth: root.contentWidth title: qsTr("Play a Sound When Receiving a Notification") components: [ StatusSwitch { id: soundSwitch checked: appSettings.notificationSoundsEnabled onClicked: { appSettings.notificationSoundsEnabled = !appSettings.notificationSoundsEnabled } } ] onClicked: { soundSwitch.clicked() } } StatusBaseText { Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding text: qsTr("Volume") font.pixelSize: Constants.settingsSection.subHeaderFontSize color: Theme.palette.directColor1 } Item { Layout.preferredWidth: root.contentWidth Layout.preferredHeight: Constants.settingsSection.itemHeight + Theme.padding StatusSlider { id: volumeSlider anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right anchors.topMargin: Theme.bigPadding anchors.leftMargin: Theme.padding anchors.rightMargin: Theme.padding from: 0 to: 100 stepSize: 1 onValueChanged: { appSettings.volume = value } Component.onCompleted: { value = appSettings.volume volumeSlider.valueChanged.connect(() => { // play a sound preview, but not on startup Global.playNotificationSound() }); } } RowLayout { anchors.top: volumeSlider.bottom anchors.left: volumeSlider.left anchors.topMargin: Theme.halfPadding width: volumeSlider.width StatusBaseText { font.pixelSize: 15 text: volumeSlider.from Layout.preferredWidth: volumeSlider.width/2 color: Theme.palette.baseColor1 } StatusBaseText { font.pixelSize: 15 text: volumeSlider.to Layout.alignment: Qt.AlignRight color: Theme.palette.baseColor1 } } } StatusButton { Layout.leftMargin: Theme.padding text: qsTr("Send a Test Notification") onClicked: { root.notificationsStore.sendTestNotification(notifNameAndMsg.notificationTitle, notifNameAndMsg.notificationMessage) } } Separator { Layout.preferredWidth: root.contentWidth Layout.preferredHeight: Theme.bigPadding } StatusBaseText { Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding text: qsTr("Exemptions") font.pixelSize: Constants.settingsSection.subHeaderFontSize color: Theme.palette.directColor1 } SearchBox { id: searchBox Layout.preferredWidth: root.contentWidth - 2 * Theme.padding Layout.leftMargin: Theme.padding Layout.rightMargin: Theme.padding placeholderText: qsTr("Search Communities, Group Chats and 1:1 Chats") } StatusBaseText { Layout.preferredWidth: root.contentWidth Layout.leftMargin: Theme.padding text: qsTr("Most recent") font.pixelSize: Constants.settingsSection.subHeaderFontSize color: Theme.palette.baseColor1 } StatusListView { Layout.preferredWidth: root.contentWidth Layout.preferredHeight: this.contentHeight visible: root.notificationsStore.exemptionsModel.count > 0 model: root.notificationsStore.exemptionsModel delegate: exemptionDelegateComponent } } }