Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
269 changes: 142 additions & 127 deletions systemUptime@KopfDesDaemons/files/systemUptime@KopfDesDaemons/desklet.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,140 +14,155 @@ const UUID = "systemUptime@KopfDesDaemons";
Gettext.bindtextdomain(UUID, GLib.get_home_dir() + "/.local/share/locale");

function _(str) {
return Gettext.dgettext(UUID, str);
return Gettext.dgettext(UUID, str);
}

class MyDesklet extends Desklet.Desklet {
constructor(metadata, deskletId) {
super(metadata, deskletId);

this.settings = new Settings.DeskletSettings(this, metadata["uuid"], deskletId);

// Bind settings properties
this.settings.bindProperty(Settings.BindingDirection.IN, "fontSize", "fontSize", this.onSettingsChanged.bind(this));
this.settings.bindProperty(Settings.BindingDirection.IN, "colorLabel", "colorLabel", this.onSettingsChanged.bind(this));

this.fontSize = this.settings.getValue("fontSize") || 20;
this.colorLabel = this.settings.getValue("colorLabel") || "rgb(51, 209, 122)";
this._timeout = null;

this.setHeader(_("System Uptime"));
this.setupLayout();
this.getStartupTime();
this.updateUptime();
}

setupLayout() {
// Create labels for uptime
this.uptimeLabel = this.createLabel(_("Uptime:") + " ", this.colorLabel);
this.uptimeValue = this.createLabel(_("Loading..."));

const uptimeRow = this.createRow([this.uptimeLabel, this.uptimeValue]);

// Create labels for startup time
this.startTimeLabel = this.createLabel(_("System start time:") + " ", this.colorLabel);
this.startupValue = this.createLabel(_("Loading..."));

const startupRow = this.createRow([this.startTimeLabel, this.startupValue]);

// Combine all into the main container
const contentBox = new St.BoxLayout({ vertical: true });
contentBox.set_style("margin-left: 0.5em;");
contentBox.add_child(startupRow);
contentBox.add_child(uptimeRow);

this.container = new St.BoxLayout();
this.container.add_child(contentBox);

Mainloop.idle_add(() => {
let computedHeight = contentBox.get_height();

const clockIcon = this.getImageAtScale(
`${this.metadata.path}/clock.svg`,
computedHeight,
computedHeight,
);

this.container.insert_child_below(clockIcon, contentBox);
clockIcon.queue_relayout();

return false;
});

this.setContent(this.container);
}

createLabel(text, color = "inherit") {
return new St.Label({
text,
y_align: St.Align.START,
style: `font-size: ${this.fontSize}px; color: ${color};`
});
}

createRow(children) {
const row = new St.BoxLayout();
children.forEach(child => row.add_child(child));
return row;
}

updateUptime() {
try {
const [result, out] = GLib.spawn_command_line_sync("awk '{print $1}' /proc/uptime");
if (!result || !out) throw new Error("Could not get system uptime.");

const uptimeInSeconds = parseFloat(out.toString().trim());
const hours = Math.floor(uptimeInSeconds / 3600);
const minutes = Math.floor((uptimeInSeconds % 3600) / 60);

this.uptimeValue.set_text(`${hours} ${_("hours")} ${minutes} ${_("minutes")}`);
} catch (error) {
this.uptimeValue.set_text("Error");
global.logError(`${UUID}: ${error.message}`);
}

if (this._timeout) Mainloop.source_remove(this._timeout);
this._timeout = Mainloop.timeout_add_seconds(60, () => this.updateUptime());
}

getStartupTime() {
try {
const [result, out] = GLib.spawn_command_line_sync("uptime -s");
if (!result || !out) throw new Error("Could not get system startup time.");

this.startupValue.set_text(out.toString().split(" ")[1].trim());
} catch (error) {
this.startupValue.set_text("Error");
global.logError(`${UUID}: ${error.message}`);
}
}

onSettingsChanged() {
this.setupLayout();
this.updateUptime();
this.getStartupTime();
}

on_desklet_removed() {
if (this._timeout) Mainloop.source_remove(this._timeout);
constructor(metadata, deskletId) {
super(metadata, deskletId);

this.settings = new Settings.DeskletSettings(this, metadata["uuid"], deskletId);

// Bind settings properties
this.settings.bindProperty(Settings.BindingDirection.IN, "fontSize", "fontSize", this.onSettingsChanged.bind(this));
this.settings.bindProperty(Settings.BindingDirection.IN, "colorLabel", "colorLabel", this.onSettingsChanged.bind(this));
this.settings.bindProperty(Settings.BindingDirection.IN, "showStartDate", "showStartDate", this.onSettingsChanged.bind(this));
this.settings.bindProperty(Settings.BindingDirection.IN, "showUptimeInDays", "showUptimeInDays", this.onSettingsChanged.bind(this));

this.fontSize = this.settings.getValue("fontSize") || 20;
this.colorLabel = this.settings.getValue("colorLabel") || "rgb(51, 209, 122)";
this._timeout = null;

this.setHeader(_("System Uptime"));
this.setupLayout();
this.getStartupTime();
this.updateUptime();
}

setupLayout() {
// Create labels for uptime
this.uptimeLabel = this.createLabel(_("Uptime:") + " ", this.colorLabel);
this.uptimeValue = this.createLabel(_("Loading..."));

const uptimeRow = this.createRow([this.uptimeLabel, this.uptimeValue]);

// Create labels for startup time
this.startTimeLabel = this.createLabel(_("Start time:") + " ", this.colorLabel);
this.startupValue = this.createLabel(_("Loading..."));

const startupRow = this.createRow([this.startTimeLabel, this.startupValue]);

// Combine all into the main container
const contentBox = new St.BoxLayout({ vertical: true });
contentBox.set_style("margin-left: 0.5em;");
contentBox.add_child(startupRow);
contentBox.add_child(uptimeRow);

this.container = new St.BoxLayout();
this.container.add_child(contentBox);

Mainloop.idle_add(() => {
let computedHeight = contentBox.get_height();

const clockIcon = this.getImageAtScale(`${this.metadata.path}/clock.svg`, computedHeight, computedHeight);

this.container.insert_child_below(clockIcon, contentBox);
clockIcon.queue_relayout();

return false;
});

this.setContent(this.container);
}

createLabel(text, color = "inherit") {
return new St.Label({
text,
y_align: St.Align.START,
style: `font-size: ${this.fontSize}px; color: ${color};`,
});
}

createRow(children) {
const row = new St.BoxLayout();
children.forEach((child) => row.add_child(child));
return row;
}

updateUptime() {
let uptimeInSeconds = 0;
try {
const [result, out] = GLib.spawn_command_line_sync("awk '{print $1}' /proc/uptime");
if (!result || !out) throw new Error("Could not get system uptime.");
uptimeInSeconds = parseFloat(out.toString().trim());

if (this.showUptimeInDays) {
const days = Math.floor(uptimeInSeconds / 86400);
const hours = Math.floor((uptimeInSeconds % 86400) / 3600);
const minutes = Math.floor(((uptimeInSeconds % 86400) % 3600) / 60);

this.uptimeValue.set_text(`${days} ${_("days")} ${hours} ${_("hrs")} ${minutes} ${_("min")}`);
} else {
const hours = Math.floor(uptimeInSeconds / 3600);
const minutes = Math.floor((uptimeInSeconds % 3600) / 60);

this.uptimeValue.set_text(`${hours} ${_("hours")} ${minutes} ${_("minutes")}`);
}
} catch (error) {
this.uptimeValue.set_text("Error");
global.logError(`${UUID}: ${error.message}`);
}

getImageAtScale(imageFileName, width, height) {
const pixBuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imageFileName, width, height);
const image = new Clutter.Image();
image.set_data(
pixBuf.get_pixels(),
pixBuf.get_has_alpha() ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGBA_888,
width, height,
pixBuf.get_rowstride()
);

const actor = new Clutter.Actor({ width, height });
actor.set_content(image);
return actor;
if (this._timeout) Mainloop.source_remove(this._timeout);
this._timeout = Mainloop.timeout_add_seconds(60, () => this.updateUptime());
}

getStartupTime() {
try {
const [result, out] = GLib.spawn_command_line_sync("uptime -s");
if (!result || !out) throw new Error("Could not get system startup time.");

const dateTime = out.toString().split(" ");
const date = dateTime[0].split("-");

if (this.showStartDate) {
this.startupValue.set_text(date[2] + "." + date[1] + "." + date[0] + ", " + dateTime[1].trim());
} else {
this.startupValue.set_text(dateTime[1].trim());
}
} catch (error) {
this.startupValue.set_text("Error");
global.logError(`${UUID}: ${error.message}`);
}
}

onSettingsChanged() {
this.setupLayout();
this.updateUptime();
this.getStartupTime();
}

on_desklet_removed() {
if (this._timeout) Mainloop.source_remove(this._timeout);
}

getImageAtScale(imageFileName, width, height) {
const pixBuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imageFileName, width, height);
const image = new Clutter.Image();
image.set_data(
pixBuf.get_pixels(),
pixBuf.get_has_alpha() ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGBA_888,
width,
height,
pixBuf.get_rowstride()
);

const actor = new Clutter.Actor({ width, height });
actor.set_content(image);
return actor;
}
}

function main(metadata, deskletId) {
return new MyDesklet(metadata, deskletId);
return new MyDesklet(metadata, deskletId);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"uuid": "systemUptime@KopfDesDaemons",
"name": "System Uptime",
"description": "Displays the current system uptime.",
"version": "1.0",
"max-instances": "50"
}
"uuid": "systemUptime@KopfDesDaemons",
"name": "System Uptime",
"description": "Displays the current system uptime.",
"version": "1.0",
"max-instances": "50",
"author": "KopfdesDaemons"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: systemUptime@KopfDesDaemons 1.0\n"
"Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-desklets/"
"issues\n"
"POT-Creation-Date: 2024-12-18 21:26+0100\n"
"POT-Creation-Date: 2025-07-31 22:57+0200\n"
"PO-Revision-Date: \n"
"Last-Translator: Dan <d3vf4n-linux (at) tutanota (dot) com>\n"
"Language-Team: \n"
Expand All @@ -19,30 +19,42 @@ msgstr ""
"X-Generator: Poedit 3.0.1\n"

#. metadata.json->name
#. desklet.js:34
#. desklet.js:61
msgid "System Uptime"
msgstr "Temps d'ús del sistema"

#. desklet.js:42
#. desklet.js:69
msgid "Uptime:"
msgstr "Temps d'ús:"

#. desklet.js:43 desklet.js:49
#. desklet.js:70 desklet.js:79
msgid "Loading..."
msgstr "S'està carregant..."

#. desklet.js:48
msgid "System start time:"
msgstr "Hora d'inici del sistema:"
#. desklet.js:76
msgid "Start time:"
msgstr "Hora d'inici:"

#. desklet.js:91
msgid "hours"
#. desklet.js:139
msgid "days"
msgstr "dies"

#. desklet.js:139
msgid "hrs"
msgstr "hores"

#. desklet.js:91
msgid "minutes"
#. desklet.js:139
msgid "min"
msgstr "minuts"

#. desklet.js:146
msgid "hours"
msgstr ""

#. desklet.js:146
msgid "minutes"
msgstr ""

#. metadata.json->description
msgid "Displays the current system uptime."
msgstr "Mostra el temps de funcionament del sistema."
Expand All @@ -58,3 +70,12 @@ msgstr "Mida de la lletra"
#. settings-schema.json->colorLabel->description
msgid "Label color"
msgstr "Color de les etiquetes"

#. settings-schema.json->showStartDate->description
#, fuzzy
msgid "Show start date"
msgstr "Hora d'inici:"

#. settings-schema.json->showUptimeInDays->description
msgid "Show uptime in days"
msgstr ""
Loading