Skip to content

Commit b812a53

Browse files
daysCountdown@KopfdesDaemons: Version 1.1.0 (#1780)
* refactor * default countdown * scaling setting, decoration toggle setting, settings cleanup * organize settings in tabs and sections * translation * refactor + comments * update version order in `CHANGELOG.md`
1 parent 199f77d commit b812a53

16 files changed

Lines changed: 820 additions & 428 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Changelog
2+
3+
## [1.1.0] 03.04.2026
4+
5+
- Features
6+
- Added scaling setting based on system font size
7+
- Added decoration toggle setting
8+
- Refactoring
9+
- Switched desklet to `class` syntax
10+
- Removed `getValue`function in constructor (use binding)
11+
- Switched desklet entry to `on_desklet_added_to_desktop`
12+
- Set default countdown to current New Year
13+
- Defined empty properties in constructor
14+
- Renamed functions and properties
15+
- Removed logs
16+
- Simplified cleanup
17+
- Removed hard-coded local path
18+
- Removed unused imports
19+
- Cleanup settings on desklet remove (`settings.finalize()`)
20+
- Kebab-case for setting names
21+
- Organized settings by tabs and sections
22+
23+
## [1.0.0] 24.11.2024
24+
25+
- Initial release
Lines changed: 139 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,139 @@
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+
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
{
2-
"uuid": "daysCountdown@KopfDesDaemons",
3-
"name": "Days Countdown",
4-
"description": "Countdown of the remaining days to a date.",
5-
"version": "1.0",
6-
"max-instances": "50"
7-
}
1+
{
2+
"uuid": "daysCountdown@KopfDesDaemons",
3+
"name": "Days Countdown",
4+
"description": "Countdown of the remaining days to a date.",
5+
"version": "1.1.0",
6+
"max-instances": "50"
7+
}

0 commit comments

Comments
 (0)