Personal noctalia plugins collection
at e3b992797f980a0baa0b96fd16cb195df126f1da 149 lines 4.4 kB view raw
1import QtQuick 2import Quickshell 3import qs.Commons 4import qs.Widgets 5import qs.Modules.Bar.Extras 6import qs.Services.UI 7 8Item { 9 id: root 10 11 property QtObject pluginApi: null 12 readonly property QtObject pluginCore: pluginApi?.mainInstance 13 14 property ShellScreen screen 15 property string widgetId: "" 16 property string section: "" 17 property int sectionWidgetIndex: -1 18 property int sectionWidgetsCount: 0 19 20 property string tooltipContent: "" 21 22 Timer { 23 id: updateTimer 24 interval: 1000 25 running: true 26 repeat: true 27 onTriggered: updateTooltip() 28 } 29 30 function updateTooltip() { 31 if (!pluginCore || !pluginCore.eventsModel) { 32 tooltipContent = ""; 33 return; 34 } 35 36 var events = pluginCore.eventsModel; 37 var now = new Date(); 38 39 // Get start and end of today 40 var todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()); 41 var todayEnd = new Date(todayStart); 42 todayEnd.setDate(todayEnd.getDate() + 1); 43 44 var currentEv = null; 45 var nextEv = null; 46 var hasEventsToday = false; 47 48 for (var i = 0; i < events.count; i++) { 49 var event = events.get(i); 50 var eventStart = event.startTime; 51 var eventEnd = event.endTime; 52 53 // Only consider events that occur today 54 var occursToday = (eventStart >= todayStart && eventStart < todayEnd) || 55 (eventEnd > todayStart && eventEnd <= todayEnd) || 56 (eventStart < todayStart && eventEnd > todayEnd); 57 58 if (!occursToday) { 59 continue; 60 } 61 62 hasEventsToday = true; 63 64 // Check if event is currently happening 65 if (now >= eventStart && now <= eventEnd) { 66 currentEv = event; 67 } 68 69 // Check for next event (starting later today) 70 if (!nextEv && eventStart > now && eventStart < todayEnd) { 71 nextEv = event; 72 } 73 74 if (currentEv && nextEv) break; 75 } 76 77 var tip = ""; 78 79 if (currentEv) { 80 tip = pluginApi.tr("bar_widget.now") + ": " + currentEv.title + "\n" + 81 pluginCore.formatTimeRangeForDisplay(currentEv); 82 83 // If there's a current event and a next event 84 if (nextEv) { 85 tip += "\n\n" + pluginApi.tr("bar_widget.next") + ": " + nextEv.title + "\n" + 86 pluginCore.formatTimeRangeForDisplay(nextEv); 87 } 88 } 89 90 if (nextEv && !currentEv) { 91 // If no current event but there's a next event today 92 tip = pluginApi.tr("bar_widget.next") + ": " + nextEv.title + "\n" + 93 pluginCore.formatTimeRangeForDisplay(nextEv); 94 } 95 96 // If all events have passed today 97 if (!tip && hasEventsToday) { 98 tip = pluginApi.tr("bar_widget.no_more_events_today"); 99 } 100 101 tooltipContent = tip; 102 } 103 104 Connections { 105 target: pluginCore 106 function onEventsModelChanged() { updateTooltip(); } 107 function onCurrentDateChanged() { updateTooltip(); } 108 } 109 110 implicitWidth: pill.width 111 implicitHeight: pill.height 112 113 BarPill { 114 id: pill 115 screen: root.screen 116 oppositeDirection: BarService.getPillDirection(root) 117 forceClose: true 118 119 icon: "calendar" 120 tooltipText: tooltipContent 121 122 onClicked: root.pluginApi?.openPanel(root.screen) 123 124 onRightClicked: { 125 PanelService.showContextMenu(contextMenu, pill, root.screen); 126 } 127 } 128 129 NPopupContextMenu { 130 id: contextMenu 131 model: [ 132 { 133 "label": pluginApi.tr("bar_widget.settings"), 134 "action": "widget-settings", 135 "icon": "settings", 136 "enabled": true 137 } 138 ] 139 140 onTriggered: action => { 141 contextMenu.close(); 142 PanelService.closeContextMenu(root.screen); 143 144 if (action === "widget-settings") { 145 BarService.openPluginSettings(screen, pluginApi.manifest); 146 } 147 } 148 } 149}