diff --git a/track-notify@mk_shaf/README.md b/track-notify@mk_shaf/README.md new file mode 100644 index 000000000..2c54b7468 --- /dev/null +++ b/track-notify@mk_shaf/README.md @@ -0,0 +1,14 @@ +# Track Notifier + +A lightweight popup overlay that shows the currently playing track, driven by +MPRIS (works with Spotify, VLC, browsers, and any other MPRIS-compliant +player). + +## Features + +- Shows artist, title and cover art whenever the track changes +- Fully customizable appearance: background/text color and opacity, font + size, cover size, header text +- Configurable behavior: display duration, fade in/out time, opacity on + mouse hover, debounce delay (duplicate protection) +- Six screen positions: top/bottom, left/center/right diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/extension.js b/track-notify@mk_shaf/files/track-notify@mk_shaf/extension.js new file mode 100644 index 000000000..5024367d6 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/extension.js @@ -0,0 +1,405 @@ +const { St, GLib, Gio, Clutter, Pango } = imports.gi; +const Main = imports.ui.main; +const Settings = imports.ui.settings; +const Gettext = imports.gettext; + +let ext = null; +let uuid = null; + +function _(str) { + return Gettext.dgettext(uuid, str); +} + +function TrackNotify(metadata) { + this._init(metadata); +} + +TrackNotify.prototype = { + + _init: function (metadata) { + this.uuid = metadata.uuid; + this.settings = new Settings.ExtensionSettings(this, this.uuid); + + const keys = [ + ["duration", "duration"], + ["fade-time", "fadeTime"], + ["debounce", "debounceMs"], + ["bg-color", "bgColor"], + ["bg-opacity", "bgOpacity"], + ["text-color", "textColor"], + ["font-size", "fontSize"], + ["header-text", "headerText"], + ["hover-opacity", "hoverOpacity"], + ["show-cover", "showCover"], + ["cover-size", "coverSize"], + ["position", "position"], + ["margin", "margin"], + ["max-width", "maxWidth"], + ]; + for (const [key, prop] of keys) + this.settings.bind(key, prop, () => this._onSettingsChanged()); + + this._sub = null; + this._debounce = null; + this._holdTimer = null; + this._fadeTimer = null; + this._pointerTimer = null; + + this._lastKey = null; + this._pending = null; + this._state = "hidden"; // hidden | in | shown | out + this._coverSeq = 0; + this._coverStyle = ""; + this._coverFiles = []; + }, + + _build: function () { + this._box = new St.BoxLayout({ + vertical: false, + reactive: false, + track_hover: false, + can_focus: false, + }); + + this._cover = new St.Bin({ reactive: false }); + + this._textBox = new St.BoxLayout({ + vertical: true, + y_align: Clutter.ActorAlign.CENTER, + reactive: false, + }); + + this._head = new St.Label({ text: "", reactive: false }); + this._body = new St.Label({ text: "", reactive: false }); + this._body.clutter_text.ellipsize = Pango.EllipsizeMode.END; + + this._textBox.add_actor(this._head); + this._textBox.add_actor(this._body); + + this._box.add_actor(this._cover); + this._box.add_actor(this._textBox); + + this._box.opacity = 0; + this._box.hide(); + + Main.layoutManager.addChrome(this._box, { + visibleInFullscreen: true, + affectsInputRegion: false, + affectsStruts: false, + }); + + this._applyStyle(); + }, + + _rgba: function (rgbString, percent) { + const m = /(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(rgbString || ""); + const [r, g, b] = m ? [m[1], m[2], m[3]] : [0, 0, 0]; + return `rgba(${r},${g},${b},${(percent / 100).toFixed(2)})`; + }, + + _applyStyle: function () { + if (!this._box) return; + + this._box.style = + `background-color: ${this._rgba(this.bgColor, this.bgOpacity)};` + + `border-radius: 12px; padding: 12px 18px 12px 12px;`; + + this._textBox.style = "spacing: 2px;"; + + this._head.text = this.headerText || ""; + this._head.visible = !!this.headerText; + this._head.style = + `color: ${this.textColor}; font-size: ${Math.round(this.fontSize * 0.85)}px;`; + this._head.opacity = 190; + + this._body.style = + `color: ${this.textColor}; font-size: ${this.fontSize}px;` + + `font-weight: bold; max-width: ${Math.round(this.maxWidth)}px;`; + + if (this.showCover) { + this._cover.show(); + this._cover.set_size(this.coverSize, this.coverSize); + this._cover.style = + (this._coverStyle || "") + + `border-radius: 6px; margin-right: 12px;` + + `background-size: cover; background-position: center;` + + `background-color: rgba(255,255,255,0.12);`; + } else { + this._cover.hide(); + } + }, + + _onSettingsChanged: function () { + this._applyStyle(); + if (this._state !== "hidden") this._place(); + }, + + _place: function () { + const mon = Main.layoutManager.primaryMonitor; + const [, w] = this._box.get_preferred_width(-1); + const [, h] = this._box.get_preferred_height(w); + const m = this.margin; + + const x = this.position.endsWith("center") + ? mon.x + Math.round((mon.width - w) / 2) + : this.position.endsWith("right") + ? mon.x + mon.width - w - m + : mon.x + m; + const y = this.position.startsWith("bottom") + ? mon.y + mon.height - h - m + : mon.y + m; + + this._box.set_position(Math.round(x), Math.round(y)); + }, + + _setCover: function (artUrl) { + this._coverStyle = ""; + + if (!this.showCover || !artUrl) { + this._applyStyle(); + return; + } + + if (artUrl.startsWith("file://")) { + try { + const [path] = GLib.filename_from_uri(artUrl); + this._coverStyle = `background-image: url("${path}");`; + } catch (e) {} + this._applyStyle(); + return; + } + + if (artUrl.startsWith("http")) { + const seq = ++this._coverSeq; + const dest = GLib.build_filenamev([ + GLib.get_tmp_dir(), `track-notify-cover-${seq}` + ]); + Gio.File.new_for_uri(artUrl).load_contents_async(null, (f, res) => { + try { + const [ok, data] = f.load_contents_finish(res); + if (!ok || seq !== this._coverSeq) return; + GLib.file_set_contents(dest, data); + this._coverFiles.push(dest); + this._coverStyle = `background-image: url("${dest}");`; + this._applyStyle(); + if (this._state !== "hidden") this._place(); + } catch (e) {} + }); + return; + } + + this._applyStyle(); + }, + + _cleanupCovers: function () { + for (const p of this._coverFiles) { + try { GLib.unlink(p); } catch (e) {} + } + this._coverFiles = []; + }, + + _clearTimer: function (name) { + if (this[name] !== null && this[name] !== undefined) { + GLib.source_remove(this[name]); + this[name] = null; + } + }, + + _fadeTo: function (opacity, duration) { + this._box.save_easing_state(); + this._box.set_easing_duration(duration); + this._box.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD); + this._box.opacity = opacity; + this._box.restore_easing_state(); + }, + + _show: function (artist, title) { + this._clearTimer("_holdTimer"); + this._clearTimer("_fadeTimer"); + + this._body.text = artist ? `${artist} — ${title}` : title; + this._place(); + + const fade = Math.round(this.fadeTime); + + if (this._state === "hidden") { + this._box.opacity = 0; + this._box.show(); + } + + this._state = "in"; + this._fadeTo(255, fade); + this._startPointerWatch(); + + this._fadeTimer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, fade, () => { + this._fadeTimer = null; + this._state = "shown"; + + this._holdTimer = GLib.timeout_add( + GLib.PRIORITY_DEFAULT, + Math.round(this.duration * 1000), + () => { + this._holdTimer = null; + this._hide(); + return GLib.SOURCE_REMOVE; + } + ); + return GLib.SOURCE_REMOVE; + }); + }, + + _hide: function () { + const fade = Math.round(this.fadeTime); + this._state = "out"; + this._fadeTo(0, fade); + + this._clearTimer("_fadeTimer"); + this._fadeTimer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, fade, () => { + this._fadeTimer = null; + if (this._box) this._box.hide(); + this._state = "hidden"; + this._stopPointerWatch(); + return GLib.SOURCE_REMOVE; + }); + }, + + _startPointerWatch: function () { + if (this._pointerTimer !== null) return; + + this._pointerTimer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 120, () => { + if (this._state !== "shown") return GLib.SOURCE_CONTINUE; + + const [px, py] = global.get_pointer(); + const [bx, by] = this._box.get_transformed_position(); + const [bw, bh] = this._box.get_size(); + const inside = px >= bx && px <= bx + bw && py >= by && py <= by + bh; + + const target = inside + ? Math.round(255 * this.hoverOpacity / 100) + : 255; + + if (Math.abs(this._box.opacity - target) > 2) + this._fadeTo(target, 200); + + return GLib.SOURCE_CONTINUE; + }); + }, + + _stopPointerWatch: function () { + this._clearTimer("_pointerTimer"); + }, + + previewNotification: function () { + if (!this._box) this._build(); + this._setCover(null); + this._show(_("Test artist"), _("Test track title")); + }, + + _handleMetadata: function (meta) { + const title = meta["xesam:title"] ?? ""; + if (!title) return; // signal without a title = end of track, ignore + + const artist = (meta["xesam:artist"] ?? []).join(", "); + const trackId = meta["mpris:trackid"] ?? ""; + const artUrl = meta["mpris:artUrl"] ?? null; + const key = `${trackId}::${artist}::${title}`; + + this._pending = { key, title, artist, artUrl }; + + this._clearTimer("_debounce"); + this._debounce = GLib.timeout_add( + GLib.PRIORITY_DEFAULT, + Math.round(this.debounceMs), + () => { + this._debounce = null; + const p = this._pending; + if (!p || p.key === this._lastKey) return GLib.SOURCE_REMOVE; + + this._lastKey = p.key; + this._setCover(p.artUrl); + this._show(p.artist, p.title); + return GLib.SOURCE_REMOVE; + } + ); + }, + + enable: function () { + this._build(); + + this._sub = Gio.DBus.session.signal_subscribe( + null, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + "/org/mpris/MediaPlayer2", + null, + Gio.DBusSignalFlags.NONE, + (conn, sender, path, iface, signal, params) => { + let changed, invalidated; + try { + changed = params.get_child_value(1).recursiveUnpack(); + invalidated = params.get_child_value(2).deep_unpack(); + } catch (e) { return; } + + if (changed.Metadata) { + this._handleMetadata(changed.Metadata); + return; + } + + // Some players, on Next/Previous (including via hotkeys), don't include + // Metadata in the signal itself, only mark it as invalidated — in that + // case the current value needs to be requested via a separate Get call. + if (invalidated && invalidated.includes("Metadata")) { + conn.call( + sender, path, "org.freedesktop.DBus.Properties", "Get", + new GLib.Variant("(ss)", ["org.mpris.MediaPlayer2.Player", "Metadata"]), + null, Gio.DBusCallFlags.NONE, -1, null, + (c, res) => { + try { + const reply = c.call_finish(res); + const meta = reply.get_child_value(0).get_variant().recursiveUnpack(); + this._handleMetadata(meta); + } catch (e) {} + } + ); + } + } + ); + }, + + disable: function () { + for (const t of ["_debounce", "_holdTimer", "_fadeTimer", "_pointerTimer"]) + this._clearTimer(t); + + if (this._sub !== null) { + Gio.DBus.session.signal_unsubscribe(this._sub); + this._sub = null; + } + + if (this._box) { + Main.layoutManager.removeChrome(this._box); + this._box.destroy(); + this._box = null; + } + + this._cleanupCovers(); + this.settings.finalize(); + + this._lastKey = null; + this._pending = null; + this._state = "hidden"; + }, +}; + +function init(metadata) { + uuid = metadata.uuid; + Gettext.bindtextdomain(uuid, GLib.get_user_data_dir() + "/locale"); + ext = new TrackNotify(metadata); +} +function disable() { ext.disable(); } + +function enable() { + ext.enable(); + // Cinnamon calls button callbacks from settings-schema.json via the object + // returned by enable() — the regular this._box is not accessible here + return { previewNotification: () => ext.previewNotification() }; +} diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/metadata.json b/track-notify@mk_shaf/files/track-notify@mk_shaf/metadata.json new file mode 100644 index 000000000..dfedcb517 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/metadata.json @@ -0,0 +1,7 @@ +{ + "uuid": "track-notify@mk_shaf", + "name": "Track Notifier", + "description": "Popup overlay with the current track (MPRIS)", + "version": "2.1", + "cinnamon-version": ["5.0", "5.2", "5.4", "5.6", "5.8", "6.0", "6.2", "6.4"] +} diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/de.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/de.po new file mode 100644 index 000000000..33232466e --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/de.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Popup-Overlay mit dem aktuellen Titel (MPRIS)" + +msgid "Preview" +msgstr "Vorschau" + +msgid "Show notification" +msgstr "Benachrichtigung anzeigen" + +msgid "Appearance" +msgstr "Erscheinungsbild" + +msgid "Background color" +msgstr "Hintergrundfarbe" + +msgid "Background opacity (%)" +msgstr "Hintergrundtransparenz (%)" + +msgid "Text color" +msgstr "Textfarbe" + +msgid "Font size (px)" +msgstr "Schriftgröße (px)" + +msgid "Header text" +msgstr "Kopftext" + +msgid "Show cover art" +msgstr "Cover anzeigen" + +msgid "Cover size (px)" +msgstr "Covergröße (px)" + +msgid "Behavior" +msgstr "Verhalten" + +msgid "Display time (sec)" +msgstr "Anzeigedauer (Sek.)" + +msgid "Fade in/out duration (ms)" +msgstr "Ein-/Ausblenddauer (ms)" + +msgid "Opacity on hover (%)" +msgstr "Deckkraft bei Mauszeiger (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Verzögerung vor Anzeige, ms (Duplikatschutz)" + +msgid "Position" +msgstr "Position" + +msgid "Screen position" +msgstr "Bildschirmposition" + +msgid "Top left" +msgstr "Oben links" + +msgid "Top center" +msgstr "Oben mittig" + +msgid "Top right" +msgstr "Oben rechts" + +msgid "Bottom left" +msgstr "Unten links" + +msgid "Bottom center" +msgstr "Unten mittig" + +msgid "Bottom right" +msgstr "Unten rechts" + +msgid "Screen edge margin (px)" +msgstr "Abstand zum Bildschirmrand (px)" + +msgid "Maximum text width (px)" +msgstr "Maximale Textbreite (px)" + +msgid "Test artist" +msgstr "Testkünstler" + +msgid "Test track title" +msgstr "Testtitel" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/es.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/es.po new file mode 100644 index 000000000..65338377e --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/es.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Superposición emergente con la pista actual (MPRIS)" + +msgid "Preview" +msgstr "Vista previa" + +msgid "Show notification" +msgstr "Mostrar notificación" + +msgid "Appearance" +msgstr "Apariencia" + +msgid "Background color" +msgstr "Color de fondo" + +msgid "Background opacity (%)" +msgstr "Opacidad del fondo (%)" + +msgid "Text color" +msgstr "Color del texto" + +msgid "Font size (px)" +msgstr "Tamaño de fuente (px)" + +msgid "Header text" +msgstr "Texto de encabezado" + +msgid "Show cover art" +msgstr "Mostrar carátula" + +msgid "Cover size (px)" +msgstr "Tamaño de la carátula (px)" + +msgid "Behavior" +msgstr "Comportamiento" + +msgid "Display time (sec)" +msgstr "Tiempo de visualización (seg)" + +msgid "Fade in/out duration (ms)" +msgstr "Duración de aparición/desaparición (ms)" + +msgid "Opacity on hover (%)" +msgstr "Opacidad al pasar el cursor (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Retraso antes de mostrar, ms (protección contra duplicados)" + +msgid "Position" +msgstr "Posición" + +msgid "Screen position" +msgstr "Posición en pantalla" + +msgid "Top left" +msgstr "Arriba izquierda" + +msgid "Top center" +msgstr "Arriba centro" + +msgid "Top right" +msgstr "Arriba derecha" + +msgid "Bottom left" +msgstr "Abajo izquierda" + +msgid "Bottom center" +msgstr "Abajo centro" + +msgid "Bottom right" +msgstr "Abajo derecha" + +msgid "Screen edge margin (px)" +msgstr "Margen desde el borde de la pantalla (px)" + +msgid "Maximum text width (px)" +msgstr "Ancho máximo del texto (px)" + +msgid "Test artist" +msgstr "Artista de prueba" + +msgid "Test track title" +msgstr "Título de pista de prueba" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/fr.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/fr.po new file mode 100644 index 000000000..ba447136f --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/fr.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Superposition contextuelle avec la piste en cours (MPRIS)" + +msgid "Preview" +msgstr "Aperçu" + +msgid "Show notification" +msgstr "Afficher la notification" + +msgid "Appearance" +msgstr "Apparence" + +msgid "Background color" +msgstr "Couleur de fond" + +msgid "Background opacity (%)" +msgstr "Opacité du fond (%)" + +msgid "Text color" +msgstr "Couleur du texte" + +msgid "Font size (px)" +msgstr "Taille de police (px)" + +msgid "Header text" +msgstr "Texte d'en-tête" + +msgid "Show cover art" +msgstr "Afficher la pochette" + +msgid "Cover size (px)" +msgstr "Taille de la pochette (px)" + +msgid "Behavior" +msgstr "Comportement" + +msgid "Display time (sec)" +msgstr "Durée d'affichage (s)" + +msgid "Fade in/out duration (ms)" +msgstr "Durée du fondu (ms)" + +msgid "Opacity on hover (%)" +msgstr "Opacité au survol (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Délai avant affichage, ms (anti-doublon)" + +msgid "Position" +msgstr "Position" + +msgid "Screen position" +msgstr "Position à l'écran" + +msgid "Top left" +msgstr "Haut gauche" + +msgid "Top center" +msgstr "Haut centre" + +msgid "Top right" +msgstr "Haut droite" + +msgid "Bottom left" +msgstr "Bas gauche" + +msgid "Bottom center" +msgstr "Bas centre" + +msgid "Bottom right" +msgstr "Bas droite" + +msgid "Screen edge margin (px)" +msgstr "Marge par rapport au bord de l'écran (px)" + +msgid "Maximum text width (px)" +msgstr "Largeur maximale du texte (px)" + +msgid "Test artist" +msgstr "Artiste de test" + +msgid "Test track title" +msgstr "Titre de piste de test" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/it.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/it.po new file mode 100644 index 000000000..c5c653694 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/it.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Overlay popup con la traccia corrente (MPRIS)" + +msgid "Preview" +msgstr "Anteprima" + +msgid "Show notification" +msgstr "Mostra notifica" + +msgid "Appearance" +msgstr "Aspetto" + +msgid "Background color" +msgstr "Colore di sfondo" + +msgid "Background opacity (%)" +msgstr "Opacità sfondo (%)" + +msgid "Text color" +msgstr "Colore del testo" + +msgid "Font size (px)" +msgstr "Dimensione carattere (px)" + +msgid "Header text" +msgstr "Testo di intestazione" + +msgid "Show cover art" +msgstr "Mostra copertina" + +msgid "Cover size (px)" +msgstr "Dimensione copertina (px)" + +msgid "Behavior" +msgstr "Comportamento" + +msgid "Display time (sec)" +msgstr "Tempo di visualizzazione (sec)" + +msgid "Fade in/out duration (ms)" +msgstr "Durata dissolvenza (ms)" + +msgid "Opacity on hover (%)" +msgstr "Opacità al passaggio del mouse (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Ritardo prima della visualizzazione, ms (protezione duplicati)" + +msgid "Position" +msgstr "Posizione" + +msgid "Screen position" +msgstr "Posizione sullo schermo" + +msgid "Top left" +msgstr "In alto a sinistra" + +msgid "Top center" +msgstr "In alto al centro" + +msgid "Top right" +msgstr "In alto a destra" + +msgid "Bottom left" +msgstr "In basso a sinistra" + +msgid "Bottom center" +msgstr "In basso al centro" + +msgid "Bottom right" +msgstr "In basso a destra" + +msgid "Screen edge margin (px)" +msgstr "Margine dal bordo schermo (px)" + +msgid "Maximum text width (px)" +msgstr "Larghezza massima del testo (px)" + +msgid "Test artist" +msgstr "Artista di prova" + +msgid "Test track title" +msgstr "Titolo di prova" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/pl.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/pl.po new file mode 100644 index 000000000..cb9e05691 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/pl.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Nakładka z aktualnie odtwarzanym utworem (MPRIS)" + +msgid "Preview" +msgstr "Podgląd" + +msgid "Show notification" +msgstr "Pokaż powiadomienie" + +msgid "Appearance" +msgstr "Wygląd" + +msgid "Background color" +msgstr "Kolor tła" + +msgid "Background opacity (%)" +msgstr "Nieprzezroczystość tła (%)" + +msgid "Text color" +msgstr "Kolor tekstu" + +msgid "Font size (px)" +msgstr "Rozmiar czcionki (px)" + +msgid "Header text" +msgstr "Tekst nagłówka" + +msgid "Show cover art" +msgstr "Pokaż okładkę" + +msgid "Cover size (px)" +msgstr "Rozmiar okładki (px)" + +msgid "Behavior" +msgstr "Zachowanie" + +msgid "Display time (sec)" +msgstr "Czas wyświetlania (sek)" + +msgid "Fade in/out duration (ms)" +msgstr "Czas pojawiania/znikania (ms)" + +msgid "Opacity on hover (%)" +msgstr "Nieprzezroczystość po najechaniu (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Opóźnienie przed wyświetleniem, ms (ochrona przed duplikatami)" + +msgid "Position" +msgstr "Położenie" + +msgid "Screen position" +msgstr "Położenie na ekranie" + +msgid "Top left" +msgstr "Góra lewo" + +msgid "Top center" +msgstr "Góra środek" + +msgid "Top right" +msgstr "Góra prawo" + +msgid "Bottom left" +msgstr "Dół lewo" + +msgid "Bottom center" +msgstr "Dół środek" + +msgid "Bottom right" +msgstr "Dół prawo" + +msgid "Screen edge margin (px)" +msgstr "Margines od krawędzi ekranu (px)" + +msgid "Maximum text width (px)" +msgstr "Maksymalna szerokość tekstu (px)" + +msgid "Test artist" +msgstr "Testowy wykonawca" + +msgid "Test track title" +msgstr "Testowy tytuł utworu" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/pt.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/pt.po new file mode 100644 index 000000000..5da6046c5 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/pt.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Sobreposição pop-up com a faixa atual (MPRIS)" + +msgid "Preview" +msgstr "Pré-visualização" + +msgid "Show notification" +msgstr "Mostrar notificação" + +msgid "Appearance" +msgstr "Aparência" + +msgid "Background color" +msgstr "Cor de fundo" + +msgid "Background opacity (%)" +msgstr "Opacidade do fundo (%)" + +msgid "Text color" +msgstr "Cor do texto" + +msgid "Font size (px)" +msgstr "Tamanho da fonte (px)" + +msgid "Header text" +msgstr "Texto do cabeçalho" + +msgid "Show cover art" +msgstr "Mostrar capa" + +msgid "Cover size (px)" +msgstr "Tamanho da capa (px)" + +msgid "Behavior" +msgstr "Comportamento" + +msgid "Display time (sec)" +msgstr "Tempo de exibição (seg)" + +msgid "Fade in/out duration (ms)" +msgstr "Duração do fade in/out (ms)" + +msgid "Opacity on hover (%)" +msgstr "Opacidade ao passar o rato (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Atraso antes de mostrar, ms (proteção contra duplicados)" + +msgid "Position" +msgstr "Posição" + +msgid "Screen position" +msgstr "Posição no ecrã" + +msgid "Top left" +msgstr "Superior esquerdo" + +msgid "Top center" +msgstr "Superior centro" + +msgid "Top right" +msgstr "Superior direito" + +msgid "Bottom left" +msgstr "Inferior esquerdo" + +msgid "Bottom center" +msgstr "Inferior centro" + +msgid "Bottom right" +msgstr "Inferior direito" + +msgid "Screen edge margin (px)" +msgstr "Margem da borda do ecrã (px)" + +msgid "Maximum text width (px)" +msgstr "Largura máxima do texto (px)" + +msgid "Test artist" +msgstr "Artista de teste" + +msgid "Test track title" +msgstr "Título de faixa de teste" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/ru.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/ru.po new file mode 100644 index 000000000..2ed011c35 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/ru.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-26 00:00+0300\n" +"PO-Revision-Date: 2026-07-26 00:00+0300\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Всплывающий оверлей с текущим треком (MPRIS)" + +msgid "Preview" +msgstr "Предпросмотр" + +msgid "Show notification" +msgstr "Показать уведомление" + +msgid "Appearance" +msgstr "Внешний вид" + +msgid "Background color" +msgstr "Цвет фона" + +msgid "Background opacity (%)" +msgstr "Непрозрачность фона (%)" + +msgid "Text color" +msgstr "Цвет текста" + +msgid "Font size (px)" +msgstr "Размер шрифта (px)" + +msgid "Header text" +msgstr "Текст заголовка" + +msgid "Show cover art" +msgstr "Показывать обложку" + +msgid "Cover size (px)" +msgstr "Размер обложки (px)" + +msgid "Behavior" +msgstr "Поведение" + +msgid "Display time (sec)" +msgstr "Время показа (сек)" + +msgid "Fade in/out duration (ms)" +msgstr "Длительность появления/исчезания (мс)" + +msgid "Opacity on hover (%)" +msgstr "Непрозрачность при наведении мыши (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Задержка перед показом, мс (защита от дублей)" + +msgid "Position" +msgstr "Положение" + +msgid "Screen position" +msgstr "Положение на экране" + +msgid "Top left" +msgstr "Сверху слева" + +msgid "Top center" +msgstr "Сверху по центру" + +msgid "Top right" +msgstr "Сверху справа" + +msgid "Bottom left" +msgstr "Снизу слева" + +msgid "Bottom center" +msgstr "Снизу по центру" + +msgid "Bottom right" +msgstr "Снизу справа" + +msgid "Screen edge margin (px)" +msgstr "Отступ от края экрана (px)" + +msgid "Maximum text width (px)" +msgstr "Максимальная ширина текста (px)" + +msgid "Test artist" +msgstr "Тестовый исполнитель" + +msgid "Test track title" +msgstr "Тестовое название трека" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/tr.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/tr.po new file mode 100644 index 000000000..93d329d2b --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/tr.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Geçerli parça için açılır kaplama (MPRIS)" + +msgid "Preview" +msgstr "Önizleme" + +msgid "Show notification" +msgstr "Bildirimi göster" + +msgid "Appearance" +msgstr "Görünüm" + +msgid "Background color" +msgstr "Arka plan rengi" + +msgid "Background opacity (%)" +msgstr "Arka plan opaklığı (%)" + +msgid "Text color" +msgstr "Metin rengi" + +msgid "Font size (px)" +msgstr "Yazı tipi boyutu (px)" + +msgid "Header text" +msgstr "Başlık metni" + +msgid "Show cover art" +msgstr "Kapağı göster" + +msgid "Cover size (px)" +msgstr "Kapak boyutu (px)" + +msgid "Behavior" +msgstr "Davranış" + +msgid "Display time (sec)" +msgstr "Gösterim süresi (sn)" + +msgid "Fade in/out duration (ms)" +msgstr "Belirme/kaybolma süresi (ms)" + +msgid "Opacity on hover (%)" +msgstr "Fare üzerindeyken opaklık (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Göstermeden önce gecikme, ms (yinelenmeye karşı koruma)" + +msgid "Position" +msgstr "Konum" + +msgid "Screen position" +msgstr "Ekrandaki konum" + +msgid "Top left" +msgstr "Sol üst" + +msgid "Top center" +msgstr "Üst orta" + +msgid "Top right" +msgstr "Sağ üst" + +msgid "Bottom left" +msgstr "Sol alt" + +msgid "Bottom center" +msgstr "Alt orta" + +msgid "Bottom right" +msgstr "Sağ alt" + +msgid "Screen edge margin (px)" +msgstr "Ekran kenarından boşluk (px)" + +msgid "Maximum text width (px)" +msgstr "Maksimum metin genişliği (px)" + +msgid "Test artist" +msgstr "Test sanatçısı" + +msgid "Test track title" +msgstr "Test parça adı" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/track-notify@mk_shaf.pot b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/track-notify@mk_shaf.pot new file mode 100644 index 000000000..c27c30019 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/track-notify@mk_shaf.pot @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-26 00:00+0300\n" +"PO-Revision-Date: 2026-07-26 00:00+0300\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "" + +msgid "Preview" +msgstr "" + +msgid "Show notification" +msgstr "" + +msgid "Appearance" +msgstr "" + +msgid "Background color" +msgstr "" + +msgid "Background opacity (%)" +msgstr "" + +msgid "Text color" +msgstr "" + +msgid "Font size (px)" +msgstr "" + +msgid "Header text" +msgstr "" + +msgid "Show cover art" +msgstr "" + +msgid "Cover size (px)" +msgstr "" + +msgid "Behavior" +msgstr "" + +msgid "Display time (sec)" +msgstr "" + +msgid "Fade in/out duration (ms)" +msgstr "" + +msgid "Opacity on hover (%)" +msgstr "" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "" + +msgid "Position" +msgstr "" + +msgid "Screen position" +msgstr "" + +msgid "Top left" +msgstr "" + +msgid "Top center" +msgstr "" + +msgid "Top right" +msgstr "" + +msgid "Bottom left" +msgstr "" + +msgid "Bottom center" +msgstr "" + +msgid "Bottom right" +msgstr "" + +msgid "Screen edge margin (px)" +msgstr "" + +msgid "Maximum text width (px)" +msgstr "" + +msgid "Test artist" +msgstr "" + +msgid "Test track title" +msgstr "" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/uk.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/uk.po new file mode 100644 index 000000000..9c9bc1f32 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/uk.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "Спливаюче накладення з поточним треком (MPRIS)" + +msgid "Preview" +msgstr "Попередній перегляд" + +msgid "Show notification" +msgstr "Показати сповіщення" + +msgid "Appearance" +msgstr "Зовнішній вигляд" + +msgid "Background color" +msgstr "Колір фону" + +msgid "Background opacity (%)" +msgstr "Непрозорість фону (%)" + +msgid "Text color" +msgstr "Колір тексту" + +msgid "Font size (px)" +msgstr "Розмір шрифту (px)" + +msgid "Header text" +msgstr "Текст заголовка" + +msgid "Show cover art" +msgstr "Показувати обкладинку" + +msgid "Cover size (px)" +msgstr "Розмір обкладинки (px)" + +msgid "Behavior" +msgstr "Поведінка" + +msgid "Display time (sec)" +msgstr "Час показу (сек)" + +msgid "Fade in/out duration (ms)" +msgstr "Тривалість появи/зникнення (мс)" + +msgid "Opacity on hover (%)" +msgstr "Непрозорість при наведенні миші (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "Затримка перед показом, мс (захист від дублів)" + +msgid "Position" +msgstr "Розташування" + +msgid "Screen position" +msgstr "Розташування на екрані" + +msgid "Top left" +msgstr "Зверху зліва" + +msgid "Top center" +msgstr "Зверху по центру" + +msgid "Top right" +msgstr "Зверху справа" + +msgid "Bottom left" +msgstr "Знизу зліва" + +msgid "Bottom center" +msgstr "Знизу по центру" + +msgid "Bottom right" +msgstr "Знизу справа" + +msgid "Screen edge margin (px)" +msgstr "Відступ від краю екрана (px)" + +msgid "Maximum text width (px)" +msgstr "Максимальна ширина тексту (px)" + +msgid "Test artist" +msgstr "Тестовий виконавець" + +msgid "Test track title" +msgstr "Тестова назва треку" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/po/zh_CN.po b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/zh_CN.po new file mode 100644 index 000000000..dcd6cc09d --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/po/zh_CN.po @@ -0,0 +1,94 @@ +msgid "" +msgstr "" +"Project-Id-Version: track-notify@mk_shaf\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-25 00:00+0300\n" +"PO-Revision-Date: 2026-07-25 00:00+0300\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Popup overlay with the current track (MPRIS)" +msgstr "显示当前曲目的弹出层 (MPRIS)" + +msgid "Preview" +msgstr "预览" + +msgid "Show notification" +msgstr "显示通知" + +msgid "Appearance" +msgstr "外观" + +msgid "Background color" +msgstr "背景颜色" + +msgid "Background opacity (%)" +msgstr "背景不透明度 (%)" + +msgid "Text color" +msgstr "文字颜色" + +msgid "Font size (px)" +msgstr "字体大小 (px)" + +msgid "Header text" +msgstr "标题文字" + +msgid "Show cover art" +msgstr "显示封面" + +msgid "Cover size (px)" +msgstr "封面大小 (px)" + +msgid "Behavior" +msgstr "行为" + +msgid "Display time (sec)" +msgstr "显示时间 (秒)" + +msgid "Fade in/out duration (ms)" +msgstr "淡入/淡出时长 (毫秒)" + +msgid "Opacity on hover (%)" +msgstr "鼠标悬停时的不透明度 (%)" + +msgid "Delay before showing, ms (duplicate protection)" +msgstr "显示前的延迟,毫秒(防重复)" + +msgid "Position" +msgstr "位置" + +msgid "Screen position" +msgstr "屏幕位置" + +msgid "Top left" +msgstr "左上" + +msgid "Top center" +msgstr "顶部居中" + +msgid "Top right" +msgstr "右上" + +msgid "Bottom left" +msgstr "左下" + +msgid "Bottom center" +msgstr "底部居中" + +msgid "Bottom right" +msgstr "右下" + +msgid "Screen edge margin (px)" +msgstr "距屏幕边缘的间距 (px)" + +msgid "Maximum text width (px)" +msgstr "最大文本宽度 (px)" + +msgid "Test artist" +msgstr "测试艺术家" + +msgid "Test track title" +msgstr "测试曲目标题" diff --git a/track-notify@mk_shaf/files/track-notify@mk_shaf/settings-schema.json b/track-notify@mk_shaf/files/track-notify@mk_shaf/settings-schema.json new file mode 100644 index 000000000..9e0778326 --- /dev/null +++ b/track-notify@mk_shaf/files/track-notify@mk_shaf/settings-schema.json @@ -0,0 +1,168 @@ +{ + "layout": { + "type": "layout", + "pages": ["page-appearance", "page-behavior", "page-position"], + + "page-appearance": { + "type": "page", + "title": "Appearance", + "sections": ["section-preview-appearance", "section-appearance"] + }, + "section-preview-appearance": { + "type": "section", + "title": "Preview", + "keys": ["preview-button"] + }, + "section-appearance": { + "type": "section", + "title": "Appearance", + "keys": ["bg-color", "bg-opacity", "text-color", "font-size", "header-text", "show-cover", "cover-size"] + }, + + "page-behavior": { + "type": "page", + "title": "Behavior", + "sections": ["section-preview-behavior", "section-behavior"] + }, + "section-preview-behavior": { + "type": "section", + "title": "Preview", + "keys": ["preview-button"] + }, + "section-behavior": { + "type": "section", + "title": "Behavior", + "keys": ["duration", "fade-time", "hover-opacity", "debounce"] + }, + + "page-position": { + "type": "page", + "title": "Position", + "sections": ["section-preview-position", "section-position"] + }, + "section-preview-position": { + "type": "section", + "title": "Preview", + "keys": ["preview-button"] + }, + "section-position": { + "type": "section", + "title": "Position", + "keys": ["position", "margin", "max-width"] + } + }, + + "preview-button": { + "type": "button", + "description": "Show notification", + "callback": "previewNotification" + }, + + "bg-color": { + "type": "colorchooser", + "default": "rgb(0,0,0)", + "description": "Background color" + }, + "bg-opacity": { + "type": "scale", + "default": 75, + "min": 0, + "max": 100, + "step": 5, + "description": "Background opacity (%)" + }, + "text-color": { + "type": "colorchooser", + "default": "rgb(255,255,255)", + "description": "Text color" + }, + "font-size": { + "type": "scale", + "default": 14, + "min": 8, + "max": 32, + "step": 1, + "description": "Font size (px)" + }, + "header-text": { + "type": "entry", + "default": "Now playing:", + "description": "Header text" + }, + "show-cover": { + "type": "checkbox", + "default": true, + "description": "Show cover art" + }, + "cover-size": { + "type": "scale", + "default": 56, + "min": 24, + "max": 128, + "step": 4, + "description": "Cover size (px)" + }, + + "duration": { + "type": "scale", + "default": 3, + "min": 1, + "max": 15, + "step": 0.5, + "description": "Display time (sec)" + }, + "fade-time": { + "type": "scale", + "default": 400, + "min": 50, + "max": 2000, + "step": 50, + "description": "Fade in/out duration (ms)" + }, + "hover-opacity": { + "type": "scale", + "default": 10, + "min": 0, + "max": 100, + "step": 5, + "description": "Opacity on hover (%)" + }, + "debounce": { + "type": "scale", + "default": 400, + "min": 100, + "max": 2000, + "step": 50, + "description": "Delay before showing, ms (duplicate protection)" + }, + + "position": { + "type": "combobox", + "default": "top-right", + "options": { + "Top left": "top-left", + "Top center": "top-center", + "Top right": "top-right", + "Bottom left": "bottom-left", + "Bottom center": "bottom-center", + "Bottom right": "bottom-right" + }, + "description": "Screen position" + }, + "margin": { + "type": "scale", + "default": 24, + "min": 0, + "max": 200, + "step": 4, + "description": "Screen edge margin (px)" + }, + "max-width": { + "type": "scale", + "default": 460, + "min": 200, + "max": 900, + "step": 20, + "description": "Maximum text width (px)" + } +} diff --git a/track-notify@mk_shaf/info.json b/track-notify@mk_shaf/info.json new file mode 100644 index 000000000..027878929 --- /dev/null +++ b/track-notify@mk_shaf/info.json @@ -0,0 +1,3 @@ +{ + "author": "mk_shaf" +} diff --git a/track-notify@mk_shaf/screenshot.png b/track-notify@mk_shaf/screenshot.png new file mode 100644 index 000000000..76c645256 Binary files /dev/null and b/track-notify@mk_shaf/screenshot.png differ