199 lines
5.0 KiB
QML
199 lines
5.0 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Wayland
|
|
import qs.Commons
|
|
import qs.Ui
|
|
import "HistoryModel.js" as HistoryModel
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property var shell: null
|
|
property var manifest: null
|
|
property bool opened: false
|
|
|
|
readonly property string pluginId: (manifest && manifest.id) || "blob.notification-center"
|
|
readonly property string historyDir: Quickshell.env("HOME") + "/.local/state/blob/notifications/history"
|
|
|
|
property var entries: []
|
|
property bool doNotDisturb: false
|
|
readonly property bool empty: root.entries.length === 0
|
|
|
|
function open(payloadJson) {
|
|
root.opened = true
|
|
root.refresh()
|
|
}
|
|
|
|
function close() {
|
|
root.opened = false
|
|
}
|
|
|
|
function dismiss() {
|
|
root.opened = false
|
|
if (root.shell && typeof root.shell.hide === "function")
|
|
root.shell.hide(root.pluginId)
|
|
}
|
|
|
|
function refresh() {
|
|
if (!historyProbe.running) historyProbe.running = true
|
|
if (!dndProbe.running) dndProbe.running = true
|
|
}
|
|
|
|
function run(command) {
|
|
Quickshell.execDetached(["bash", "-c", command])
|
|
}
|
|
|
|
function clearAll() {
|
|
root.run("blob-shell notifications clearHistory")
|
|
root.entries = []
|
|
}
|
|
|
|
function toggleSilence() {
|
|
root.run("blob-shell notifications toggleDnd")
|
|
refreshTimer.restart()
|
|
}
|
|
|
|
function dismissEntry(index) {
|
|
var entry = root.entries[index]
|
|
if (!entry) return
|
|
root.run("blob-notify-dismiss " + entry.id)
|
|
var next = []
|
|
for (var i = 0; i < root.entries.length; i++)
|
|
if (i !== index) next.push(root.entries[i])
|
|
root.entries = next
|
|
}
|
|
|
|
Process {
|
|
id: historyProbe
|
|
command: ["bash", "-c", "cat " + root.historyDir + "/*.json 2>/dev/null || true"]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: root.entries = HistoryModel.parseHistory(text)
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: dndProbe
|
|
command: ["bash", "-c", "blob-shell notifications dndState 2>/dev/null"]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: root.doNotDisturb = String(text).trim() === "on"
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: refreshTimer
|
|
interval: 250
|
|
onTriggered: root.refresh()
|
|
}
|
|
|
|
Timer {
|
|
interval: 5000
|
|
running: root.opened
|
|
repeat: true
|
|
onTriggered: root.refresh()
|
|
}
|
|
|
|
PanelWindow {
|
|
visible: root.opened
|
|
anchors { top: true; bottom: true; left: true; right: true }
|
|
color: "transparent"
|
|
WlrLayershell.namespace: "blob-notification-center"
|
|
WlrLayershell.layer: WlrLayer.Overlay
|
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
|
exclusionMode: ExclusionMode.Ignore
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: root.dismiss()
|
|
}
|
|
|
|
Card {
|
|
anchors.top: parent.top
|
|
anchors.right: parent.right
|
|
anchors.topMargin: Style.spaceReal(10)
|
|
anchors.rightMargin: Style.spaceReal(10)
|
|
implicitWidth: Style.spaceReal(440)
|
|
implicitHeight: Style.spaceReal(420)
|
|
fillColor: Util.alpha(Color.background, Style.panelFillAlpha)
|
|
spacing: Style.spaceReal(10)
|
|
|
|
Item {
|
|
width: parent.width
|
|
implicitHeight: titleText.implicitHeight
|
|
|
|
Text {
|
|
id: titleText
|
|
anchors.left: parent.left
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: "Notifications"
|
|
textFormat: Text.PlainText
|
|
color: Color.foreground
|
|
font.family: Style.font.family
|
|
font.pixelSize: Style.font.body
|
|
font.bold: true
|
|
}
|
|
|
|
Row {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: Style.spaceReal(4)
|
|
|
|
CardIconButton {
|
|
icon: root.doNotDisturb ? "" : ""
|
|
active: root.doNotDisturb
|
|
onActivated: root.toggleSilence()
|
|
}
|
|
|
|
CardIconButton {
|
|
icon: ""
|
|
onActivated: root.clearAll()
|
|
}
|
|
}
|
|
}
|
|
|
|
ListView {
|
|
width: parent.width
|
|
height: Style.spaceReal(340)
|
|
clip: true
|
|
spacing: Style.spaceReal(8)
|
|
visible: !root.empty
|
|
model: root.entries
|
|
|
|
delegate: NotificationItem {
|
|
required property var modelData
|
|
required property int index
|
|
width: ListView.view.width
|
|
app: modelData.app
|
|
summary: modelData.summary
|
|
body: modelData.body
|
|
onDismissRequested: root.dismissEntry(index)
|
|
}
|
|
}
|
|
|
|
Column {
|
|
width: parent.width
|
|
visible: root.empty
|
|
spacing: Style.spaceReal(8)
|
|
|
|
Text {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: ""
|
|
textFormat: Text.PlainText
|
|
color: Util.alpha(Color.blue, 0.6)
|
|
font.family: Style.font.family
|
|
font.pixelSize: Style.font.heading
|
|
}
|
|
|
|
Text {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: "No notifications"
|
|
textFormat: Text.PlainText
|
|
color: Util.alpha(Color.foreground, 0.6)
|
|
font.family: Style.font.family
|
|
font.pixelSize: Style.font.bodySmall
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|