|
1 | | -const Desklet = imports.ui.desklet; |
2 | | -const Lang = imports.lang; |
3 | | -const St = imports.gi.St; |
4 | | -const Mainloop = imports.mainloop; |
5 | | -const GLib = imports.gi.GLib; |
6 | | -const Settings = imports.ui.settings; |
7 | | -const Gettext = imports.gettext; |
8 | | - |
9 | | -const UUID = "daysCountdown@KopfDesDaemons"; |
10 | | - |
11 | | -Gettext.bindtextdomain(UUID, GLib.get_home_dir() + "/.local/share/locale"); |
12 | | - |
13 | | -function _(str) { |
14 | | - return Gettext.dgettext(UUID, str); |
15 | | -} |
16 | | - |
17 | | -function MyDesklet(metadata, deskletId) { |
18 | | - this._init(metadata, deskletId); |
19 | | -} |
20 | | - |
21 | | -MyDesklet.prototype = { |
22 | | - __proto__: Desklet.Desklet.prototype, |
23 | | - |
24 | | - _init: function (metadata, deskletId) { |
25 | | - Desklet.Desklet.prototype._init.call(this, metadata, deskletId); |
26 | | - |
27 | | - this.setHeader(_("Days Countdown")); |
28 | | - |
29 | | - // Initialize settings |
30 | | - this.settings = new Settings.DeskletSettings(this, this.metadata["uuid"], deskletId); |
31 | | - |
32 | | - // Get settings |
33 | | - this.labelText = this.settings.getValue("labelText") || "New Year 2025 Countdown"; |
34 | | - this.fontSizeLabel = this.settings.getValue("fontSizeLabel") || 12; |
35 | | - this.fontSizeCountdown = this.settings.getValue("fontSizeCountdown") || 36; |
36 | | - this.colorCountdown = this.settings.getValue("colorCountdown") || "rgb(255, 255, 255)"; |
37 | | - this.colorLabel = this.settings.getValue("colorLabel") || "rgb(98, 160, 234)"; |
38 | | - this.countdownDate = this.settings.getValue("countdownDate") || { d: 31, m: 12, y: 2025 }; |
39 | | - this.refreshInterval = this.settings.getValue("refreshInterval") || "only-after-starting"; |
40 | | - |
41 | | - // Bind settings properties |
42 | | - this.settings.bindProperty(Settings.BindingDirection.IN, "labelText", "labelText", this.updateUI, null); |
43 | | - this.settings.bindProperty(Settings.BindingDirection.IN, "countdownDate", "countdownDate", this.updateUI, null); |
44 | | - this.settings.bindProperty(Settings.BindingDirection.IN, "fontSizeLabel", "fontSizeLabel", this.updateUI, null); |
45 | | - this.settings.bindProperty(Settings.BindingDirection.IN, "fontSizeCountdown", "fontSizeCountdown", this.updateUI, null); |
46 | | - this.settings.bindProperty(Settings.BindingDirection.IN, "colorLabel", "colorLabel", this.updateUI, null); |
47 | | - this.settings.bindProperty(Settings.BindingDirection.IN, "colorCountdown", "colorCountdown", this.updateUI, null); |
48 | | - this.settings.bindProperty(Settings.BindingDirection.IN, "refreshInterval", "refreshInterval", this.refreshCountdown, null); |
49 | | - |
50 | | - this._setupLayout(); |
51 | | - |
52 | | - this.timeout = null; |
53 | | - |
54 | | - this.updateUI(); |
55 | | - this.refreshCountdown(); |
56 | | - }, |
57 | | - |
58 | | - _setupLayout() { |
59 | | - this.box = new St.BoxLayout({ vertical: true }); |
60 | | - this.textLabel = new St.Label(); |
61 | | - this.daysLabel = new St.Label(); |
62 | | - |
63 | | - this.box.add_child(this.textLabel); |
64 | | - this.box.add_child(this.daysLabel); |
65 | | - this.setContent(this.box); |
66 | | - }, |
67 | | - |
68 | | - calcDays() { |
69 | | - if (!this.countdownDate) return 0; |
70 | | - const now = new Date(); |
71 | | - const then = new Date(this.countdownDate.y, this.countdownDate.m - 1, this.countdownDate.d); |
72 | | - return Math.ceil((then - now) / (1000 * 60 * 60 * 24)); |
73 | | - }, |
74 | | - |
75 | | - getDaysString() { |
76 | | - return _("%f days").format(this.calcDays().toString()); |
77 | | - }, |
78 | | - |
79 | | - updateUI: function () { |
80 | | - if (this.textLabel) { |
81 | | - this.textLabel.set_text(this.labelText); |
82 | | - this.textLabel.set_style(`font-size: ${this.fontSizeLabel}px; color: ${this.colorLabel};`); |
83 | | - } |
84 | | - |
85 | | - if (this.daysLabel) { |
86 | | - this.daysLabel.set_text(this.getDaysString()); |
87 | | - this.daysLabel.set_style(`font-size: ${this.fontSizeCountdown}px; color: ${this.colorCountdown};`); |
88 | | - } |
89 | | - }, |
90 | | - |
91 | | - refreshCountdown: function () { |
92 | | - this.daysLabel.set_text(this.getDaysString()); |
93 | | - |
94 | | - if (this.timeout) Mainloop.source_remove(this.timeout); |
95 | | - if (this.refreshInterval === "only-after-starting") return; |
96 | | - |
97 | | - global.log(`${UUID}: ${this.labelText} refreshed. Next refresh in ${this.refreshInterval} seconds.`); |
98 | | - this.timeout = Mainloop.timeout_add_seconds(this.refreshInterval, () => this.refreshCountdown()); |
99 | | - }, |
100 | | - |
101 | | - on_desklet_removed: function () { |
102 | | - if (this.timeout) Mainloop.source_remove(this.timeout); |
103 | | - if (this.textLabel) this.box.remove_child(this.textLabel); |
104 | | - if (this.daysLabel) this.box.remove_child(this.daysLabel); |
105 | | - |
106 | | - this.timeout = this.textLabel = this.daysLabel = null; |
107 | | - } |
108 | | -}; |
109 | | - |
110 | | -function main(metadata, deskletId) { |
111 | | - return new MyDesklet(metadata, deskletId); |
112 | | -} |
| 1 | +const Desklet = imports.ui.desklet; |
| 2 | +const St = imports.gi.St; |
| 3 | +const Mainloop = imports.mainloop; |
| 4 | +const GLib = imports.gi.GLib; |
| 5 | +const Settings = imports.ui.settings; |
| 6 | +const Gettext = imports.gettext; |
| 7 | + |
| 8 | +const UUID = "daysCountdown@KopfDesDaemons"; |
| 9 | + |
| 10 | +Gettext.bindtextdomain(UUID, GLib.get_user_data_dir() + "/locale"); |
| 11 | + |
| 12 | +function _(str) { |
| 13 | + return Gettext.dgettext(UUID, str); |
| 14 | +} |
| 15 | + |
| 16 | +class MyDesklet extends Desklet.Desklet { |
| 17 | + constructor(metadata, deskletId) { |
| 18 | + super(metadata, deskletId); |
| 19 | + this.setHeader(_("Days Countdown")); |
| 20 | + |
| 21 | + this._mainContainer = null; |
| 22 | + this._textLabel = null; |
| 23 | + this._daysLabel = null; |
| 24 | + this._refreshTimeoutId = null; |
| 25 | + this._isReloading = false; |
| 26 | + |
| 27 | + // Default settings |
| 28 | + this.labelText = ""; |
| 29 | + this.fontSizeLabel = 12; |
| 30 | + this.fontSizeCountdown = 36; |
| 31 | + this.colorCountdown = "rgb(255, 255, 255)"; |
| 32 | + this.colorLabel = "rgb(98, 160, 234)"; |
| 33 | + this.countdownDate = { d: 1, m: 1, y: 1 }; |
| 34 | + this.refreshInterval = "only-after-starting"; |
| 35 | + this.scaleSize = 1; |
| 36 | + this.hideDecorations = false; |
| 37 | + |
| 38 | + // Bind settings properties |
| 39 | + this.settings = new Settings.DeskletSettings(this, this.metadata["uuid"], deskletId); |
| 40 | + this.settings.bindProperty(Settings.BindingDirection.IN, "label-text", "labelText", this._updateUI); |
| 41 | + this.settings.bindProperty(Settings.BindingDirection.IN, "countdown-date", "countdownDate", this._updateUI); |
| 42 | + this.settings.bindProperty(Settings.BindingDirection.IN, "font-size-label", "fontSizeLabel", this._updateUI); |
| 43 | + this.settings.bindProperty(Settings.BindingDirection.IN, "font-size-countdown", "fontSizeCountdown", this._updateUI); |
| 44 | + this.settings.bindProperty(Settings.BindingDirection.IN, "color-label", "colorLabel", this._updateUI); |
| 45 | + this.settings.bindProperty(Settings.BindingDirection.IN, "color-countdown", "colorCountdown", this._updateUI); |
| 46 | + this.settings.bindProperty(Settings.BindingDirection.IN, "refresh-interval", "refreshInterval", this._setRefreshCountdown); |
| 47 | + this.settings.bindProperty(Settings.BindingDirection.IN, "scale-size", "scaleSize", this._updateUI); |
| 48 | + this.settings.bindProperty(Settings.BindingDirection.IN, "hide-decorations", "hideDecorations", this._onDecorationChanged.bind(this)); |
| 49 | + } |
| 50 | + |
| 51 | + on_desklet_added_to_desktop() { |
| 52 | + this._onDecorationChanged(); |
| 53 | + this._setupLayout(); |
| 54 | + this._updateUI(); |
| 55 | + this._setRefreshCountdown(); |
| 56 | + } |
| 57 | + |
| 58 | + on_desklet_removed() { |
| 59 | + this._removeRefreshTimeout(); |
| 60 | + if (this.settings && !this._isReloading) { |
| 61 | + this.settings.finalize(); |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | + on_desklet_reloaded() { |
| 66 | + this._isReloading = true; |
| 67 | + } |
| 68 | + |
| 69 | + _onDecorationChanged() { |
| 70 | + this.metadata["prevent-decorations"] = this.hideDecorations; |
| 71 | + this._updateDecoration(); |
| 72 | + } |
| 73 | + |
| 74 | + _setDefaultCountdown() { |
| 75 | + if (this.countdownDate.d === 1 && this.countdownDate.m === 1 && this.countdownDate.y === 1) { |
| 76 | + this.countdownDate = { d: 1, m: 1, y: new Date().getFullYear() + 1 }; |
| 77 | + this.labelText = _("New Year %f Countdown").format(this.countdownDate.y.toString()); |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + _setupLayout() { |
| 82 | + this._mainContainer = new St.BoxLayout({ vertical: true }); |
| 83 | + |
| 84 | + this._textLabel = new St.Label(); |
| 85 | + this._daysLabel = new St.Label(); |
| 86 | + |
| 87 | + this._mainContainer.add_child(this._textLabel); |
| 88 | + this._mainContainer.add_child(this._daysLabel); |
| 89 | + |
| 90 | + this.setContent(this._mainContainer); |
| 91 | + } |
| 92 | + |
| 93 | + _calcDays() { |
| 94 | + if (!this.countdownDate) return 0; |
| 95 | + |
| 96 | + const countDownDate = new Date(this.countdownDate.y, this.countdownDate.m - 1, this.countdownDate.d); |
| 97 | + const millisecondsPerDay = 1000 * 60 * 60 * 24; |
| 98 | + return Math.ceil((countDownDate - new Date()) / millisecondsPerDay); |
| 99 | + } |
| 100 | + |
| 101 | + _getDaysString() { |
| 102 | + return _("%f days").format(this._calcDays().toString()); |
| 103 | + } |
| 104 | + |
| 105 | + _updateUI() { |
| 106 | + this._setDefaultCountdown(); |
| 107 | + |
| 108 | + // Update labels |
| 109 | + this._textLabel.set_text(this.labelText); |
| 110 | + this._daysLabel.set_text(this._getDaysString()); |
| 111 | + |
| 112 | + // Update styles |
| 113 | + const fontSize = size => (size * this.scaleSize) / 10 + "em"; |
| 114 | + this._textLabel.set_style(`font-size: ${fontSize(this.fontSizeLabel)}; color: ${this.colorLabel};`); |
| 115 | + this._daysLabel.set_style(`font-size: ${fontSize(this.fontSizeCountdown)}; color: ${this.colorCountdown};`); |
| 116 | + } |
| 117 | + |
| 118 | + _setRefreshCountdown() { |
| 119 | + this._removeRefreshTimeout(); |
| 120 | + |
| 121 | + if (this.refreshInterval === "only-after-starting") return; |
| 122 | + |
| 123 | + this._refreshTimeoutId = Mainloop.timeout_add_seconds(this.refreshInterval, () => { |
| 124 | + this._daysLabel.set_text(this._getDaysString()); |
| 125 | + return true; |
| 126 | + }); |
| 127 | + } |
| 128 | + |
| 129 | + _removeRefreshTimeout() { |
| 130 | + if (this._refreshTimeoutId) { |
| 131 | + Mainloop.source_remove(this._refreshTimeoutId); |
| 132 | + this._refreshTimeoutId = null; |
| 133 | + } |
| 134 | + } |
| 135 | +} |
| 136 | + |
| 137 | +function main(metadata, deskletId) { |
| 138 | + return new MyDesklet(metadata, deskletId); |
| 139 | +} |
0 commit comments