mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-17 19:22:04 -04:00
notifications: add configurable durations for do not disturb
fixes #1481
This commit is contained in:
@@ -188,6 +188,9 @@ Item {
|
||||
case "battery":
|
||||
coreDetailLoader.sourceComponent = batteryDetailComponent;
|
||||
break;
|
||||
case "doNotDisturb":
|
||||
coreDetailLoader.sourceComponent = doNotDisturbDetailComponent;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -230,6 +233,11 @@ Item {
|
||||
BatteryDetail {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: doNotDisturbDetailComponent
|
||||
DoNotDisturbDetail {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: diskUsageDetailComponent
|
||||
DiskUsageDetail {
|
||||
|
||||
@@ -163,6 +163,8 @@ Column {
|
||||
return widgetWidth <= 25 ? smallDiskUsageComponent : diskUsagePillComponent;
|
||||
} else if (id === "colorPicker") {
|
||||
return colorPickerPillComponent;
|
||||
} else if (id === "doNotDisturb") {
|
||||
return widgetWidth <= 25 ? smallToggleComponent : dndPillComponent;
|
||||
} else {
|
||||
return widgetWidth <= 25 ? smallToggleComponent : toggleButtonComponent;
|
||||
}
|
||||
@@ -573,6 +575,22 @@ Column {
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: dndPillComponent
|
||||
DndPill {
|
||||
property var widgetData: parent.widgetData || {}
|
||||
property int widgetIndex: parent.widgetIndex || 0
|
||||
width: parent.width
|
||||
height: 60
|
||||
|
||||
onExpandClicked: {
|
||||
if (!root.editMode) {
|
||||
root.expandClicked(widgetData, widgetIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: smallBatteryComponent
|
||||
SmallBatteryButton {
|
||||
@@ -603,8 +621,6 @@ Column {
|
||||
return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode";
|
||||
case "darkMode":
|
||||
return "contrast";
|
||||
case "doNotDisturb":
|
||||
return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off";
|
||||
case "idleInhibitor":
|
||||
return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle";
|
||||
default:
|
||||
@@ -618,8 +634,6 @@ Column {
|
||||
return I18n.tr("Night Mode");
|
||||
case "darkMode":
|
||||
return I18n.tr("Dark Mode");
|
||||
case "doNotDisturb":
|
||||
return I18n.tr("Do Not Disturb");
|
||||
case "idleInhibitor":
|
||||
return SessionService.idleInhibited ? I18n.tr("Keeping Awake") : I18n.tr("Keep Awake");
|
||||
default:
|
||||
@@ -642,8 +656,6 @@ Column {
|
||||
return DisplayService.nightModeEnabled || false;
|
||||
case "darkMode":
|
||||
return !SessionData.isLightMode;
|
||||
case "doNotDisturb":
|
||||
return SessionData.doNotDisturb || false;
|
||||
case "idleInhibitor":
|
||||
return SessionService.idleInhibited || false;
|
||||
default:
|
||||
@@ -670,11 +682,6 @@ Column {
|
||||
Theme.setLightMode(newMode);
|
||||
break;
|
||||
}
|
||||
case "doNotDisturb":
|
||||
{
|
||||
SessionData.setDoNotDisturb(!SessionData.doNotDisturb);
|
||||
break;
|
||||
}
|
||||
case "idleInhibitor":
|
||||
{
|
||||
SessionService.toggleIdleInhibit();
|
||||
|
||||
258
quickshell/Modules/ControlCenter/Details/DoNotDisturbDetail.qml
Normal file
258
quickshell/Modules/ControlCenter/Details/DoNotDisturbDetail.qml
Normal file
@@ -0,0 +1,258 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Widgets
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
LayoutMirroring.enabled: I18n.isRtl
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
implicitHeight: contentColumn.implicitHeight + Theme.spacingL * 2
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||
border.width: 0
|
||||
|
||||
property real nowMs: Date.now()
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
repeat: true
|
||||
running: root.visible && SessionData.doNotDisturb && SessionData.doNotDisturbUntil > 0
|
||||
onTriggered: root.nowMs = Date.now()
|
||||
}
|
||||
|
||||
function _pad2(n) {
|
||||
return n < 10 ? "0" + n : "" + n;
|
||||
}
|
||||
|
||||
function formatUntil(ts) {
|
||||
if (!ts)
|
||||
return "";
|
||||
const d = new Date(ts);
|
||||
const use24h = (typeof SettingsData !== "undefined") ? SettingsData.use24HourClock : true;
|
||||
if (use24h)
|
||||
return _pad2(d.getHours()) + ":" + _pad2(d.getMinutes());
|
||||
const suffix = d.getHours() >= 12 ? "PM" : "AM";
|
||||
const h12 = ((d.getHours() + 11) % 12) + 1;
|
||||
return h12 + ":" + _pad2(d.getMinutes()) + " " + suffix;
|
||||
}
|
||||
|
||||
function formatRemaining(ms) {
|
||||
if (ms <= 0)
|
||||
return "";
|
||||
const totalMinutes = Math.ceil(ms / 60000);
|
||||
if (totalMinutes < 60)
|
||||
return I18n.tr("%1 min left").arg(totalMinutes);
|
||||
const hours = Math.floor(totalMinutes / 60);
|
||||
const mins = totalMinutes - hours * 60;
|
||||
if (mins === 0)
|
||||
return I18n.tr("%1 h left").arg(hours);
|
||||
return I18n.tr("%1 h %2 m left").arg(hours).arg(mins);
|
||||
}
|
||||
|
||||
function minutesUntilTomorrowMorning() {
|
||||
const now = new Date();
|
||||
const target = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 8, 0, 0, 0);
|
||||
return Math.max(1, Math.round((target.getTime() - now.getTime()) / 60000));
|
||||
}
|
||||
|
||||
readonly property var presets: [
|
||||
{
|
||||
"label": I18n.tr("15 min"),
|
||||
"minutes": 15
|
||||
},
|
||||
{
|
||||
"label": I18n.tr("30 min"),
|
||||
"minutes": 30
|
||||
},
|
||||
{
|
||||
"label": I18n.tr("1 hour"),
|
||||
"minutes": 60
|
||||
},
|
||||
{
|
||||
"label": I18n.tr("3 hours"),
|
||||
"minutes": 180
|
||||
},
|
||||
{
|
||||
"label": I18n.tr("8 hours"),
|
||||
"minutes": 480
|
||||
},
|
||||
{
|
||||
"label": I18n.tr("Until 8 AM"),
|
||||
"minutesFn": true
|
||||
}
|
||||
]
|
||||
|
||||
Column {
|
||||
id: contentColumn
|
||||
width: parent.width - Theme.spacingL * 2
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: SessionData.doNotDisturb ? "do_not_disturb_on" : "notifications_paused"
|
||||
size: Theme.iconSizeLarge
|
||||
color: SessionData.doNotDisturb ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width - Theme.iconSizeLarge - Theme.spacingM
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Silence notifications")
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
if (!SessionData.doNotDisturb)
|
||||
return I18n.tr("Pick how long to pause notifications");
|
||||
if (SessionData.doNotDisturbUntil <= 0)
|
||||
return I18n.tr("On indefinitely");
|
||||
const remaining = Math.max(0, SessionData.doNotDisturbUntil - root.nowMs);
|
||||
return root.formatRemaining(remaining) + " · " + I18n.tr("until %1").arg(root.formatUntil(SessionData.doNotDisturbUntil));
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Grid {
|
||||
width: parent.width
|
||||
columns: 3
|
||||
columnSpacing: Theme.spacingS
|
||||
rowSpacing: Theme.spacingS
|
||||
|
||||
Repeater {
|
||||
model: root.presets
|
||||
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
width: (contentColumn.width - Theme.spacingS * 2) / 3
|
||||
height: 36
|
||||
radius: Theme.cornerRadius
|
||||
color: presetArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) : Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||
border.width: 1
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
text: modelData.label
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: presetArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const minutes = modelData.minutesFn ? root.minutesUntilTomorrowMorning() : modelData.minutes;
|
||||
SessionData.setDoNotDisturb(true, minutes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Rectangle {
|
||||
width: (contentColumn.width - Theme.spacingS) / 2
|
||||
height: 36
|
||||
radius: Theme.cornerRadius
|
||||
color: foreverArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) : Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||
border.width: 1
|
||||
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
DankIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: "block"
|
||||
size: Theme.iconSizeSmall
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: I18n.tr("Until I turn it off")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: foreverArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: SessionData.setDoNotDisturb(true, 0)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: (contentColumn.width - Theme.spacingS) / 2
|
||||
height: 36
|
||||
radius: Theme.cornerRadius
|
||||
visible: SessionData.doNotDisturb
|
||||
color: offArea.containsMouse ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.18) : Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||
border.width: 1
|
||||
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
DankIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: "notifications_active"
|
||||
size: Theme.iconSizeSmall
|
||||
color: offArea.containsMouse ? Theme.error : Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: I18n.tr("Turn off")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: offArea.containsMouse ? Theme.error : Theme.surfaceText
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: offArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: SessionData.setDoNotDisturb(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
quickshell/Modules/ControlCenter/Widgets/DndPill.qml
Normal file
29
quickshell/Modules/ControlCenter/Widgets/DndPill.qml
Normal file
@@ -0,0 +1,29 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Modules.ControlCenter.Widgets
|
||||
|
||||
CompoundPill {
|
||||
id: root
|
||||
|
||||
iconName: SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off"
|
||||
iconColor: SessionData.doNotDisturb ? Theme.primary : Theme.surfaceText
|
||||
primaryText: I18n.tr("Do Not Disturb")
|
||||
isActive: SessionData.doNotDisturb
|
||||
|
||||
secondaryText: {
|
||||
if (!SessionData.doNotDisturb)
|
||||
return I18n.tr("Off");
|
||||
if (SessionData.doNotDisturbUntil <= 0)
|
||||
return I18n.tr("On");
|
||||
const d = new Date(SessionData.doNotDisturbUntil);
|
||||
const use24h = (typeof SettingsData !== "undefined") ? SettingsData.use24HourClock : true;
|
||||
const pad = n => n < 10 ? "0" + n : "" + n;
|
||||
if (use24h)
|
||||
return I18n.tr("Until %1").arg(pad(d.getHours()) + ":" + pad(d.getMinutes()));
|
||||
const suffix = d.getHours() >= 12 ? "PM" : "AM";
|
||||
const h12 = ((d.getHours() + 11) % 12) + 1;
|
||||
return I18n.tr("Until %1").arg(h12 + ":" + pad(d.getMinutes()) + " " + suffix);
|
||||
}
|
||||
|
||||
onToggled: SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
||||
}
|
||||
Reference in New Issue
Block a user