mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-05-04 19:42:08 -04:00
feat(DMS FrameMode): A New Connected Unified Surface & Animation Overhaul
- Introduces Standalone & Connected Modes - Updated Animations & Motion effects for both modes - Numerous QOL tweaks and updates throughout the system - Highly inspired to the OG Caelestia Shell / @Soramanew
This commit is contained in:
@@ -16,8 +16,7 @@ DankListView {
|
||||
property bool listInitialized: false
|
||||
property int swipingCardIndex: -1
|
||||
property real swipingCardOffset: 0
|
||||
property real __pendingStableHeight: 0
|
||||
property real __heightUpdateThreshold: 20
|
||||
property bool _stableHeightUpdatePending: false
|
||||
readonly property real shadowBlurPx: Theme.elevationEnabled ? ((Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined) ? Theme.elevationLevel1.blurPx : 4) : 0
|
||||
readonly property real shadowHorizontalGutter: Theme.snap(Math.max(Theme.spacingS, Math.min(32, shadowBlurPx * 1.5 + 6)), 1)
|
||||
readonly property real shadowVerticalGutter: Theme.snap(Math.max(Theme.spacingXS, 6), 1)
|
||||
@@ -27,51 +26,52 @@ DankListView {
|
||||
Qt.callLater(() => {
|
||||
if (listView) {
|
||||
listView.listInitialized = true;
|
||||
listView.stableContentHeight = listView.contentHeight;
|
||||
listView.syncStableContentHeight(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: heightUpdateDebounce
|
||||
interval: Theme.mediumDuration + 20
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (!listView.isAnimatingExpansion && Math.abs(listView.__pendingStableHeight - listView.stableContentHeight) > listView.__heightUpdateThreshold) {
|
||||
listView.stableContentHeight = listView.__pendingStableHeight;
|
||||
}
|
||||
function targetContentHeight() {
|
||||
if (count <= 0)
|
||||
return contentHeight;
|
||||
|
||||
let total = topMargin + bottomMargin + Math.max(0, count - 1) * spacing;
|
||||
for (let i = 0; i < count; i++) {
|
||||
const item = itemAtIndex(i);
|
||||
if (!item || item.nonAnimHeight === undefined)
|
||||
return contentHeight;
|
||||
total += item.nonAnimHeight;
|
||||
}
|
||||
return Math.max(0, total);
|
||||
}
|
||||
|
||||
function syncStableContentHeight(useTarget) {
|
||||
const nextHeight = useTarget ? targetContentHeight() : contentHeight;
|
||||
if (Math.abs(nextHeight - stableContentHeight) <= 0.5)
|
||||
return;
|
||||
stableContentHeight = nextHeight;
|
||||
}
|
||||
|
||||
function queueStableContentHeightUpdate(useTarget) {
|
||||
if (_stableHeightUpdatePending)
|
||||
return;
|
||||
_stableHeightUpdatePending = true;
|
||||
Qt.callLater(() => {
|
||||
_stableHeightUpdatePending = false;
|
||||
syncStableContentHeight(useTarget || isAnimatingExpansion);
|
||||
});
|
||||
}
|
||||
|
||||
onContentHeightChanged: {
|
||||
if (!isAnimatingExpansion) {
|
||||
__pendingStableHeight = contentHeight;
|
||||
if (Math.abs(contentHeight - stableContentHeight) > __heightUpdateThreshold) {
|
||||
heightUpdateDebounce.restart();
|
||||
} else {
|
||||
stableContentHeight = contentHeight;
|
||||
}
|
||||
}
|
||||
if (!isAnimatingExpansion)
|
||||
queueStableContentHeightUpdate(false);
|
||||
}
|
||||
|
||||
onIsAnimatingExpansionChanged: {
|
||||
if (isAnimatingExpansion) {
|
||||
heightUpdateDebounce.stop();
|
||||
let delta = 0;
|
||||
for (let i = 0; i < count; i++) {
|
||||
const item = itemAtIndex(i);
|
||||
if (item && item.children[0] && item.children[0].isAnimating) {
|
||||
const targetDelegateHeight = item.children[0].targetHeight + listView.delegateShadowGutter;
|
||||
delta += targetDelegateHeight - item.height;
|
||||
}
|
||||
}
|
||||
const targetHeight = contentHeight + delta;
|
||||
// During expansion, always update immediately without threshold check
|
||||
stableContentHeight = targetHeight;
|
||||
syncStableContentHeight(true);
|
||||
} else {
|
||||
__pendingStableHeight = contentHeight;
|
||||
heightUpdateDebounce.stop();
|
||||
stableContentHeight = __pendingStableHeight;
|
||||
queueStableContentHeightUpdate(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,11 +148,14 @@ DankListView {
|
||||
readonly property real adjacentScaleInfluence: isAdjacentToSwipe ? 1.0 - Math.abs(listView.swipingCardOffset) / width * 0.02 : 1.0
|
||||
readonly property real swipeFadeStartOffset: width * 0.75
|
||||
readonly property real swipeFadeDistance: Math.max(1, width - swipeFadeStartOffset)
|
||||
readonly property real nonAnimHeight: notificationCard.targetHeight + listView.delegateShadowGutter
|
||||
|
||||
Component.onCompleted: {
|
||||
Qt.callLater(() => {
|
||||
if (delegateRoot)
|
||||
if (delegateRoot) {
|
||||
delegateRoot.__delegateInitialized = true;
|
||||
listView.queueStableContentHeightUpdate(listView.isAnimatingExpansion);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -180,6 +183,7 @@ DankListView {
|
||||
onIsAnimatingChanged: {
|
||||
if (isAnimating) {
|
||||
listView.isAnimatingExpansion = true;
|
||||
listView.syncStableContentHeight(true);
|
||||
} else {
|
||||
Qt.callLater(() => {
|
||||
if (!notificationCard || !listView)
|
||||
@@ -197,6 +201,13 @@ DankListView {
|
||||
}
|
||||
}
|
||||
|
||||
onTargetHeightChanged: {
|
||||
if (isAnimating || listView.isAnimatingExpansion)
|
||||
listView.syncStableContentHeight(true);
|
||||
else
|
||||
listView.queueStableContentHeightUpdate(false);
|
||||
}
|
||||
|
||||
isGroupSelected: {
|
||||
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive)
|
||||
return false;
|
||||
|
||||
@@ -15,6 +15,13 @@ Rectangle {
|
||||
property bool userInitiatedExpansion: false
|
||||
property bool isAnimating: false
|
||||
property bool animateExpansion: true
|
||||
property bool isDescriptionToggleAnimation: false
|
||||
property bool _retainedExpandedContent: false
|
||||
property bool _clipAnimatedContent: false
|
||||
property real expandedContentOpacity: expanded ? 1 : 0
|
||||
property real collapsedContentOpacity: expanded ? 0 : 1
|
||||
readonly property bool renderExpandedContent: expanded || _retainedExpandedContent
|
||||
readonly property bool renderCollapsedContent: !expanded
|
||||
|
||||
property bool isGroupSelected: false
|
||||
property int selectedNotificationIndex: -1
|
||||
@@ -33,11 +40,12 @@ Rectangle {
|
||||
readonly property real actionButtonHeight: compactMode ? 20 : 24
|
||||
readonly property real collapsedContentHeight: Math.max(iconSize, Theme.fontSizeSmall * 1.2 + Theme.fontSizeMedium * 1.2 + Theme.fontSizeSmall * 1.2 * (compactMode ? 1 : 2))
|
||||
readonly property real baseCardHeight: cardPadding * 2 + collapsedContentHeight + actionButtonHeight + contentSpacing
|
||||
readonly property bool connectedFrameMode: SettingsData.connectedFrameModeActive
|
||||
|
||||
width: parent ? parent.width : 400
|
||||
height: expanded ? (expandedContent.height + cardPadding * 2) : (baseCardHeight + collapsedContent.extraHeight)
|
||||
readonly property real targetHeight: expanded ? (expandedContent.height + cardPadding * 2) : (baseCardHeight + collapsedContent.extraHeight)
|
||||
radius: Theme.cornerRadius
|
||||
radius: connectedFrameMode ? Theme.connectedSurfaceRadius : Theme.cornerRadius
|
||||
scale: (cardHoverHandler.hovered ? 1.004 : 1.0) * listLevelAdjacentScaleInfluence
|
||||
readonly property bool shadowsAllowed: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" && !BlurService.enabled
|
||||
readonly property var shadowElevation: Theme.elevationLevel1
|
||||
@@ -55,6 +63,16 @@ Rectangle {
|
||||
});
|
||||
}
|
||||
|
||||
function expansionMotionDuration() {
|
||||
if (isDescriptionToggleAnimation)
|
||||
return descriptionExpanded ? Theme.notificationInlineExpandDuration : Theme.notificationInlineCollapseDuration;
|
||||
return Theme.variantDuration(Theme.popoutAnimationDuration, root.expanded);
|
||||
}
|
||||
|
||||
function expansionMotionCurve() {
|
||||
return root.expanded ? Theme.variantPopoutEnterCurve : Theme.variantPopoutExitCurve;
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
enabled: listLevelScaleAnimationsEnabled
|
||||
NumberAnimation {
|
||||
@@ -64,6 +82,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
Behavior on shadowBlurPx {
|
||||
enabled: !root.connectedFrameMode
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
@@ -71,6 +90,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
Behavior on shadowOffsetXPx {
|
||||
enabled: !root.connectedFrameMode
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
@@ -78,6 +98,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
Behavior on shadowOffsetYPx {
|
||||
enabled: !root.connectedFrameMode
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
@@ -92,6 +113,24 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on expandedContentOpacity {
|
||||
enabled: root.__initialized && root.userInitiatedExpansion && root.animateExpansion
|
||||
NumberAnimation {
|
||||
duration: root.expansionMotionDuration()
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: root.expansionMotionCurve()
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on collapsedContentOpacity {
|
||||
enabled: root.__initialized && root.userInitiatedExpansion && root.animateExpansion
|
||||
NumberAnimation {
|
||||
duration: root.expansionMotionDuration()
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: root.expansionMotionCurve()
|
||||
}
|
||||
}
|
||||
|
||||
color: {
|
||||
if (isGroupSelected && keyboardNavigationActive) {
|
||||
return Theme.primaryPressed;
|
||||
@@ -125,7 +164,31 @@ Rectangle {
|
||||
}
|
||||
return Theme.layerOutlineWidth;
|
||||
}
|
||||
clip: false
|
||||
clip: _clipAnimatedContent
|
||||
|
||||
onExpandedChanged: {
|
||||
if (__initialized && userInitiatedExpansion && animateExpansion)
|
||||
_clipAnimatedContent = true;
|
||||
if (expanded) {
|
||||
_retainedExpandedContent = false;
|
||||
return;
|
||||
}
|
||||
if (__initialized && userInitiatedExpansion && animateExpansion)
|
||||
_retainedExpandedContent = true;
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
if (Math.abs(height - targetHeight) > 0.5)
|
||||
return;
|
||||
_clipAnimatedContent = false;
|
||||
if (!expanded && _retainedExpandedContent)
|
||||
_retainedExpandedContent = false;
|
||||
}
|
||||
|
||||
onExpandedContentOpacityChanged: {
|
||||
if (!expanded && _retainedExpandedContent && expandedContentOpacity <= 0.01)
|
||||
_retainedExpandedContent = false;
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: cardHoverHandler
|
||||
@@ -145,7 +208,7 @@ Rectangle {
|
||||
shadowOffsetX: root.shadowOffsetXPx
|
||||
shadowOffsetY: root.shadowOffsetYPx
|
||||
shadowColor: root.shadowElevation ? Theme.elevationShadowColor(root.shadowElevation) : "transparent"
|
||||
shadowEnabled: root.shadowsAllowed
|
||||
shadowEnabled: root.shadowsAllowed && !root.connectedFrameMode
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -185,7 +248,8 @@ Rectangle {
|
||||
anchors.leftMargin: Theme.spacingL
|
||||
anchors.rightMargin: Theme.spacingL + Theme.notificationHoverRevealMargin
|
||||
height: collapsedContentHeight + extraHeight
|
||||
visible: !expanded
|
||||
visible: renderCollapsedContent
|
||||
opacity: root.collapsedContentOpacity
|
||||
|
||||
DankCircularImage {
|
||||
id: iconContainer
|
||||
@@ -348,6 +412,7 @@ Rectangle {
|
||||
onClicked: mouse => {
|
||||
if (!parent.hoveredLink && (parent.hasMoreText || descriptionExpanded)) {
|
||||
root.userInitiatedExpansion = true;
|
||||
root.isDescriptionToggleAnimation = true;
|
||||
const messageId = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification && notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : "";
|
||||
NotificationService.toggleMessageExpansion(messageId);
|
||||
Qt.callLater(() => {
|
||||
@@ -357,7 +422,7 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
propagateComposedEvents: true
|
||||
propagateComposedEvents: false
|
||||
onPressed: mouse => {
|
||||
if (parent.hoveredLink)
|
||||
mouse.accepted = false;
|
||||
@@ -382,7 +447,8 @@ Rectangle {
|
||||
anchors.leftMargin: Theme.spacingL
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
spacing: compactMode ? Theme.spacingXS : Theme.spacingS
|
||||
visible: expanded
|
||||
visible: renderExpandedContent
|
||||
opacity: root.expandedContentOpacity
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
@@ -513,7 +579,12 @@ Rectangle {
|
||||
}
|
||||
|
||||
Behavior on height {
|
||||
enabled: false
|
||||
enabled: expandedDelegateWrapper.__delegateInitialized && root.animateExpansion && root.userInitiatedExpansion
|
||||
NumberAnimation {
|
||||
duration: root.expansionMotionDuration()
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: root.expansionMotionCurve()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
@@ -650,6 +721,7 @@ Rectangle {
|
||||
onClicked: mouse => {
|
||||
if (!parent.hoveredLink && (bodyText.hasMoreText || messageExpanded)) {
|
||||
root.userInitiatedExpansion = true;
|
||||
root.isDescriptionToggleAnimation = true;
|
||||
NotificationService.toggleMessageExpansion(modelData?.notification?.id || "");
|
||||
Qt.callLater(() => {
|
||||
if (root && !root.isAnimating)
|
||||
@@ -658,7 +730,7 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
propagateComposedEvents: true
|
||||
propagateComposedEvents: false
|
||||
onPressed: mouse => {
|
||||
if (parent.hoveredLink) {
|
||||
mouse.accepted = false;
|
||||
@@ -825,7 +897,8 @@ Rectangle {
|
||||
}
|
||||
|
||||
Row {
|
||||
visible: !expanded
|
||||
visible: renderCollapsedContent
|
||||
opacity: root.collapsedContentOpacity
|
||||
anchors.right: clearButton.visible ? clearButton.left : parent.right
|
||||
anchors.rightMargin: clearButton.visible ? contentSpacing : Theme.spacingL
|
||||
anchors.top: collapsedContent.bottom
|
||||
@@ -882,7 +955,8 @@ Rectangle {
|
||||
property bool isHovered: false
|
||||
readonly property int actionCount: (notificationGroup?.latestNotification?.actions || []).length
|
||||
|
||||
visible: !expanded && actionCount < 3
|
||||
visible: renderCollapsedContent && actionCount < 3
|
||||
opacity: root.collapsedContentOpacity
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
anchors.top: collapsedContent.bottom
|
||||
@@ -913,10 +987,11 @@ Rectangle {
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
visible: !expanded && (notificationGroup?.count || 0) > 1 && !descriptionExpanded
|
||||
visible: renderCollapsedContent && (notificationGroup?.count || 0) > 1 && !descriptionExpanded
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root.userInitiatedExpansion = true;
|
||||
root.isDescriptionToggleAnimation = false;
|
||||
NotificationService.toggleGroupExpansion(notificationGroup?.key || "");
|
||||
}
|
||||
z: -1
|
||||
@@ -940,6 +1015,7 @@ Rectangle {
|
||||
buttonSize: compactMode ? 24 : 28
|
||||
onClicked: {
|
||||
root.userInitiatedExpansion = true;
|
||||
root.isDescriptionToggleAnimation = false;
|
||||
NotificationService.toggleGroupExpansion(notificationGroup?.key || "");
|
||||
}
|
||||
}
|
||||
@@ -957,15 +1033,18 @@ Rectangle {
|
||||
Behavior on height {
|
||||
enabled: root.__initialized && root.userInitiatedExpansion && root.animateExpansion
|
||||
NumberAnimation {
|
||||
duration: root.expanded ? Theme.notificationExpandDuration : Theme.notificationCollapseDuration
|
||||
duration: root.expansionMotionDuration()
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Theme.expressiveCurves.emphasized
|
||||
easing.bezierCurve: root.expansionMotionCurve()
|
||||
onRunningChanged: {
|
||||
if (running) {
|
||||
root.isAnimating = true;
|
||||
} else {
|
||||
root.isAnimating = false;
|
||||
root.userInitiatedExpansion = false;
|
||||
root.isDescriptionToggleAnimation = false;
|
||||
root._retainedExpandedContent = false;
|
||||
root._clipAnimatedContent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ DankPopout {
|
||||
property real stablePopupHeight: 400
|
||||
property real _lastAlignedContentHeight: -1
|
||||
property bool _pendingSizedOpen: false
|
||||
property bool _heightUpdatePending: false
|
||||
|
||||
function updateStablePopupHeight() {
|
||||
const item = contentLoader.item;
|
||||
@@ -30,6 +31,16 @@ DankPopout {
|
||||
stablePopupHeight = target;
|
||||
}
|
||||
|
||||
function queueStablePopupHeightUpdate() {
|
||||
if (_heightUpdatePending)
|
||||
return;
|
||||
_heightUpdatePending = true;
|
||||
Qt.callLater(() => {
|
||||
_heightUpdatePending = false;
|
||||
updateStablePopupHeight();
|
||||
});
|
||||
}
|
||||
|
||||
NotificationKeyboardController {
|
||||
id: keyboardController
|
||||
listView: null
|
||||
@@ -39,11 +50,9 @@ DankPopout {
|
||||
}
|
||||
}
|
||||
|
||||
popupWidth: triggerScreen ? Math.min(500, Math.max(380, triggerScreen.width - 48)) : 400
|
||||
popupWidth: 400
|
||||
popupHeight: stablePopupHeight
|
||||
positioning: ""
|
||||
animationScaleCollapsed: 0.94
|
||||
animationOffset: 0
|
||||
suspendShadowWhileResizing: false
|
||||
|
||||
screen: triggerScreen
|
||||
@@ -130,7 +139,7 @@ DankPopout {
|
||||
Connections {
|
||||
target: contentLoader.item
|
||||
function onImplicitHeightChanged() {
|
||||
root.updateStablePopupHeight();
|
||||
root.queueStablePopupHeightUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,327 +123,327 @@ Rectangle {
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Notification Settings")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Bold
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(dndRow.implicitHeight, dndToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: dndRow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: SessionData.doNotDisturb ? "notifications_off" : "notifications"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SessionData.doNotDisturb ? Theme.error : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Do Not Disturb")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
StyledText {
|
||||
text: I18n.tr("Notification Settings")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Bold
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: dndToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SessionData.doNotDisturb
|
||||
onToggled: SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
||||
}
|
||||
}
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(dndRow.implicitHeight, dndToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||
}
|
||||
Row {
|
||||
id: dndRow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Notification Timeouts")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
text: I18n.tr("Low Priority")
|
||||
description: I18n.tr("Timeout for low priority notifications")
|
||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutLow)
|
||||
options: timeoutOptions.map(opt => opt.text)
|
||||
onValueChanged: value => {
|
||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||
if (timeoutOptions[i].text === value) {
|
||||
SettingsData.set("notificationTimeoutLow", timeoutOptions[i].value);
|
||||
break;
|
||||
DankIcon {
|
||||
name: SessionData.doNotDisturb ? "notifications_off" : "notifications"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SessionData.doNotDisturb ? Theme.error : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
text: I18n.tr("Normal Priority")
|
||||
description: I18n.tr("Timeout for normal priority notifications")
|
||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutNormal)
|
||||
options: timeoutOptions.map(opt => opt.text)
|
||||
onValueChanged: value => {
|
||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||
if (timeoutOptions[i].text === value) {
|
||||
SettingsData.set("notificationTimeoutNormal", timeoutOptions[i].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
text: I18n.tr("Critical Priority")
|
||||
description: I18n.tr("Timeout for critical priority notifications")
|
||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutCritical)
|
||||
options: timeoutOptions.map(opt => opt.text)
|
||||
onValueChanged: value => {
|
||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||
if (timeoutOptions[i].text === value) {
|
||||
SettingsData.set("notificationTimeoutCritical", timeoutOptions[i].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(overlayRow.implicitHeight, overlayToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: overlayRow
|
||||
anchors.left: parent.left
|
||||
anchors.right: overlayToggle.left
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "notifications_active"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationOverlayEnabled ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: overlayRow.width - Theme.iconSizeSmall - Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Notification Overlay")
|
||||
text: I18n.tr("Do Not Disturb")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
wrapMode: Text.Wrap
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Display all priorities over fullscreen apps")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.Wrap
|
||||
DankToggle {
|
||||
id: dndToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SessionData.doNotDisturb
|
||||
onToggled: SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Notification Timeouts")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
text: I18n.tr("Low Priority")
|
||||
description: I18n.tr("Timeout for low priority notifications")
|
||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutLow)
|
||||
options: timeoutOptions.map(opt => opt.text)
|
||||
onValueChanged: value => {
|
||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||
if (timeoutOptions[i].text === value) {
|
||||
SettingsData.set("notificationTimeoutLow", timeoutOptions[i].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: overlayToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationOverlayEnabled
|
||||
onToggled: toggled => SettingsData.set("notificationOverlayEnabled", toggled)
|
||||
DankDropdown {
|
||||
text: I18n.tr("Normal Priority")
|
||||
description: I18n.tr("Timeout for normal priority notifications")
|
||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutNormal)
|
||||
options: timeoutOptions.map(opt => opt.text)
|
||||
onValueChanged: value => {
|
||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||
if (timeoutOptions[i].text === value) {
|
||||
SettingsData.set("notificationTimeoutNormal", timeoutOptions[i].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(privacyRow.implicitHeight, privacyToggle.implicitHeight) + Theme.spacingS
|
||||
DankDropdown {
|
||||
text: I18n.tr("Critical Priority")
|
||||
description: I18n.tr("Timeout for critical priority notifications")
|
||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutCritical)
|
||||
options: timeoutOptions.map(opt => opt.text)
|
||||
onValueChanged: value => {
|
||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||
if (timeoutOptions[i].text === value) {
|
||||
SettingsData.set("notificationTimeoutCritical", timeoutOptions[i].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: privacyRow
|
||||
anchors.left: parent.left
|
||||
anchors.right: privacyToggle.left
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
name: "privacy_tip"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationPopupPrivacyMode ? Theme.primary : Theme.surfaceText
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(overlayRow.implicitHeight, overlayToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: overlayRow
|
||||
anchors.left: parent.left
|
||||
anchors.right: overlayToggle.left
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "notifications_active"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationOverlayEnabled ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: overlayRow.width - Theme.iconSizeSmall - Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Notification Overlay")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Display all priorities over fullscreen apps")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 2
|
||||
DankToggle {
|
||||
id: overlayToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: privacyRow.width - Theme.iconSizeSmall - Theme.spacingM
|
||||
checked: SettingsData.notificationOverlayEnabled
|
||||
onToggled: toggled => SettingsData.set("notificationOverlayEnabled", toggled)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(privacyRow.implicitHeight, privacyToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: privacyRow
|
||||
anchors.left: parent.left
|
||||
anchors.right: privacyToggle.left
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "privacy_tip"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationPopupPrivacyMode ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: privacyRow.width - Theme.iconSizeSmall - Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Privacy Mode")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Hide notification content until expanded")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: privacyToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationPopupPrivacyMode
|
||||
onToggled: toggled => SettingsData.set("notificationPopupPrivacyMode", toggled)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("History Settings")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(lowRow.implicitHeight, lowToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: lowRow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "low_priority"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationHistorySaveLow ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Privacy Mode")
|
||||
text: I18n.tr("Low Priority")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
wrapMode: Text.Wrap
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: lowToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationHistorySaveLow
|
||||
onToggled: toggled => SettingsData.set("notificationHistorySaveLow", toggled)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(normalRow.implicitHeight, normalToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: normalRow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "notifications"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationHistorySaveNormal ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Hide notification content until expanded")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.Wrap
|
||||
text: I18n.tr("Normal Priority")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: privacyToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationPopupPrivacyMode
|
||||
onToggled: toggled => SettingsData.set("notificationPopupPrivacyMode", toggled)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("History Settings")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(lowRow.implicitHeight, lowToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: lowRow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "low_priority"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationHistorySaveLow ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Low Priority")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
DankToggle {
|
||||
id: normalToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationHistorySaveNormal
|
||||
onToggled: toggled => SettingsData.set("notificationHistorySaveNormal", toggled)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: lowToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationHistorySaveLow
|
||||
onToggled: toggled => SettingsData.set("notificationHistorySaveLow", toggled)
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(criticalRow.implicitHeight, criticalToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: criticalRow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "priority_high"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationHistorySaveCritical ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Critical Priority")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: criticalToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationHistorySaveCritical
|
||||
onToggled: toggled => SettingsData.set("notificationHistorySaveCritical", toggled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(normalRow.implicitHeight, normalToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: normalRow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "notifications"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationHistorySaveNormal ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Normal Priority")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: normalToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationHistorySaveNormal
|
||||
onToggled: toggled => SettingsData.set("notificationHistorySaveNormal", toggled)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Math.max(criticalRow.implicitHeight, criticalToggle.implicitHeight) + Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: criticalRow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "priority_high"
|
||||
size: Theme.iconSizeSmall
|
||||
color: SettingsData.notificationHistorySaveCritical ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Critical Priority")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: criticalToggle
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.notificationHistorySaveCritical
|
||||
onToggled: toggled => SettingsData.set("notificationHistorySaveCritical", toggled)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user