From cb71e053a8067beb260bec3feceaa001fd330781 Mon Sep 17 00:00:00 2001 From: claudiux <33965039+claudiux@users.noreply.github.com> Date: Mon, 13 Jan 2025 02:14:22 +0100 Subject: [PATCH] Radio3.0 v2.7.2: Now uses mainloopTools to manage loops. (#6757) --- .../files/Radio3.0@claudiux/CHANGELOG.md | 4 + .../files/Radio3.0@claudiux/applet.js | 77 +++---- .../desklet/AlbumArt3.0@claudiux/desklet.js | 29 ++- .../AlbumArt3.0@claudiux/mainloopTools.js | 191 ++++++++++++++++++ .../Radio3.0@claudiux/lib/mainloopTools.js | 191 ++++++++++++++++++ .../Radio3.0@claudiux/lib/sourceExists.js | 17 -- .../files/Radio3.0@claudiux/metadata.json | 2 +- .../radiodb/server-list.json | 6 +- 8 files changed, 452 insertions(+), 65 deletions(-) create mode 100644 Radio3.0@claudiux/files/Radio3.0@claudiux/desklet/AlbumArt3.0@claudiux/mainloopTools.js create mode 100644 Radio3.0@claudiux/files/Radio3.0@claudiux/lib/mainloopTools.js delete mode 100644 Radio3.0@claudiux/files/Radio3.0@claudiux/lib/sourceExists.js diff --git a/Radio3.0@claudiux/files/Radio3.0@claudiux/CHANGELOG.md b/Radio3.0@claudiux/files/Radio3.0@claudiux/CHANGELOG.md index 6bcc50e7e6f..df7240fb126 100644 --- a/Radio3.0@claudiux/files/Radio3.0@claudiux/CHANGELOG.md +++ b/Radio3.0@claudiux/files/Radio3.0@claudiux/CHANGELOG.md @@ -1,3 +1,7 @@ +### v2.7.2~20250112 + * Now the desklet uses the mainloopTools library. + * Minor bugfixes. + ### v2.7.1~20250111 * Improved management of loops. * Improved management of desklet. diff --git a/Radio3.0@claudiux/files/Radio3.0@claudiux/applet.js b/Radio3.0@claudiux/files/Radio3.0@claudiux/applet.js index f89cedf2374..45c60d9fac7 100644 --- a/Radio3.0@claudiux/files/Radio3.0@claudiux/applet.js +++ b/Radio3.0@claudiux/files/Radio3.0@claudiux/applet.js @@ -13,7 +13,7 @@ const { PopupMenu, PopupMenuManager, PopupMenuItem, PopupSeparatorMenuItem, Popu // Settings: const { AppletSettings } = imports.ui.settings; // ./lib/util: -const { spawnCommandLineAsyncIO, spawnCommandLineAsync, spawnCommandLine, spawn_async, trySpawnCommandLine, setTimeout, clearTimeout } = require("./lib/util"); +const { spawnCommandLineAsyncIO, spawnCommandLineAsync, spawnCommandLine, spawn_async, trySpawnCommandLine } = require("./lib/util"); //Clutter: const { ScrollDirection, Image, Actor, Color, RotateAxis } = imports.gi.Clutter; //Gettext: @@ -39,8 +39,6 @@ const { Urgency, MessageTray, SystemNotificationSource, Notification } = imports var RADIO_NOTIFICATION_TIMEOUT = 2; const RADIO_NOTIFICATION_CRITICAL_TIMEOUT_WITH_APPLET = 10; -//Mainloop: -//~ const { timeout_add_seconds, source_remove } = imports.mainloop; //Pango const { parse_markup, WrapMode, EllipsizeMode } = imports.gi.Pango; //Extension: @@ -59,40 +57,52 @@ const Atk = imports.gi.Atk; const Cvc = imports.gi.Cvc; //Signals: const Signals = imports.signals; -// checkDependencies: +//checkDependencies: const { Dependencies, criticalNotify } = require("./lib/checkDependencies"); -// htmlEncodeDecode: +//htmlEncodeDecode: let HtmlEncodeDecode = require('./lib/htmlEncodeDecode'); -// xml2json.min: +//xml2json.min: const { xml2json } = require('./lib/xml2json.min'); -// filesCsv: +//filesCsv: const FilesCsv = require("./lib/filesCsv"); -// filesPls: +//filesPls: const FilesPls = require("./lib/filesPls"); -// filesM3u: +//filesM3u: const FilesM3u = require("./lib/filesM3u"); -// filesXspf: +//filesXspf: const FilesXspf = require("./lib/filesXspf"); -// filesJson: +//filesJson: const FilesJson = require("./lib/filesJson"); -// files: +//files: const Files = require("./lib/files"); -// volumeslider: +//volumeslider: const VolumeSlider = require("./lib/volumeslider"); -// screensaverInhibitor: +//screensaverInhibitor: const ScreensaverInhibitor = require("./lib/screensaverInhibitor"); -// to-string: +//to-string: const {to_string} = require("./lib/to-string"); -// text-wrap: +//text-wrap: const {formatTextWrap} = require("./lib/text-wrap"); -// httpLib: -const {HttpLib} = require("./lib/httpLib"); -// fixedEncodeURIComponent: +//httpLib: +const{HttpLib} = require("./lib/httpLib"); +//fixedEncodeURIComponent: const { fixedEncodeURIComponent } = require("./lib/fixedEncodeURIComponent"); -// checkTranslations: +//checkTranslations: const { are_translations_installed, install_translations } = require("./lib/checkTranslations"); -const { source_exists } = require("./lib/sourceExists"); +//mainloopTools: +const { + _sourceIds, + timeout_add_seconds, + timeout_add, + setTimeout, + clearTimeout, + setInterval, + clearInterval, + source_exists, + source_remove, + remove_all_sources +} = require("./lib/mainloopTools"); //~ const { //~ Shoutcast @@ -1466,7 +1476,7 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { if (this.database_favorite !== "random") { //~ this.database_url = ""+this.database_favorite; - let id_to = setTimeout( Lang.bind(this, () => { + let id_to = setTimeout( () => { //~ var fav = ""+this.settings.getValue("database-favorite"); //~ this.settings.setValue("database-url", ""+fav); //~ this.settings.getValue("database-url"); @@ -1475,7 +1485,7 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { //~ this.settings.emit("settings-changed"); this.get_random_server_name(); clearTimeout(id_to); - }), 1000); + }, 1000); } else { this.get_random_server_name(); } @@ -1863,10 +1873,10 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { let songTitle = this.songTitle; this.stop_mpv_radio(false); this.songTitle = songTitle; - let idtemp = setTimeout (Lang.bind(this, () => { + let idtemp = setTimeout (() => { this.start_mpv_radio(this.last_radio_listened_to); clearTimeout(idtemp); - }), (this.network_quality === "high") ? 5000 : 12000); // 5 or 12 seconds + }, (this.network_quality === "high") ? 5000 : 12000); // 5 or 12 seconds } else { this.stop_mpv_radio(); } @@ -2104,7 +2114,7 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { unmonitor_jobs_dir() { //log("unmonitor_jobs_dir"); - if (this.jobsMonitor == null || thisjobsMonitorId == null || this.jobsMonitor.is_cancelled()) return; + if (this.jobsMonitor == null || this.jobsMonitorId == null || this.jobsMonitor.is_cancelled()) return; try { this.jobsMonitor.disconnect(this.jobsMonitorId); @@ -3509,7 +3519,7 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { this.icon_or_favicon(_id); this.progress = 10/REFRESH_INTERVAL; - this.interval = setInterval(() => this.on_progress_change(), 100); // 100 ms. + this.interval = setInterval(() => { this.on_progress_change(); }, 100); // 100 ms. this.monitor_mpv_title(); this.monitor_r30stop(); @@ -4072,7 +4082,7 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { // Some dependencies are missing. Suggest to the user to install them. this.appletRunning = false; if (!this.dont_check_dependencies) { - this.checkDepInterval = setInterval(() => this.dependencies.check_dependencies(), 10000); + this.checkDepInterval = setInterval(() => { this.dependencies.check_dependencies(); }, 10000); } } @@ -4192,8 +4202,7 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { if (this._control) this._control.close(); - // Finalize settings: - //~ this.settings.finalize(); + remove_all_sources(); } _clean_str(str) { @@ -4511,8 +4520,8 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { this._applet_context_menu.close(); let to = setTimeout( () => { // Reload this applet - reloadExtension(UUID, Type.APPLET); clearTimeout(to); + reloadExtension(UUID, Type.APPLET); }, 600 ); @@ -4728,7 +4737,7 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { if (this.do_rotation) { this.icon_rotate() } else { - clearInterval(); + clearInterval(this.rot_interval); this.rot_interval = 0 } }, 50); @@ -5950,10 +5959,10 @@ class WebRadioReceiverAndRecorder extends TextIconApplet { this.settings.setValue("search-list-page-label", ""+(this.settings.getValue("search-page")-1)); } - let _idto = setTimeout(Lang.bind(this, () => { + let _idto = setTimeout(() => { file_set_contents(UPDATE_OPTIONS_FILE, ""+uuid_string_random()); clearTimeout(_idto); - }), 300); + }, 300); //if (this.settingsWindow != undefined) { diff --git a/Radio3.0@claudiux/files/Radio3.0@claudiux/desklet/AlbumArt3.0@claudiux/desklet.js b/Radio3.0@claudiux/files/Radio3.0@claudiux/desklet/AlbumArt3.0@claudiux/desklet.js index c87092a2e4f..1be4183ee66 100644 --- a/Radio3.0@claudiux/files/Radio3.0@claudiux/desklet/AlbumArt3.0@claudiux/desklet.js +++ b/Radio3.0@claudiux/files/Radio3.0@claudiux/desklet/AlbumArt3.0@claudiux/desklet.js @@ -5,13 +5,16 @@ const PopupMenu = imports.ui.popupMenu; const St = imports.gi.St; const Desklet = imports.ui.desklet; const Lang = imports.lang; -const Mainloop = imports.mainloop; +//~ const Mainloop = imports.mainloop; const Clutter = imports.gi.Clutter; const GLib = imports.gi.GLib; const Tweener = imports.ui.tweener; const Util = imports.misc.util; const Settings = imports.ui.settings; const Gettext = imports.gettext; +//Mainloop: +const { timeout_add_seconds, timeout_add, setTimeout, clearTimeout, setInterval, clearInterval, source_exists, source_remove, remove_all_sources } = require("mainloopTools"); + const APPLET_UUID = "Radio3.0@claudiux"; const DESKLET_UUID = "AlbumArt3.0@claudiux"; @@ -121,11 +124,14 @@ class AlbumArtRadio30 extends Desklet.Desklet { this.dir_monitor_loop_is_active = false; if (this._bin != null) { - Tweener.removeTweens(this._bin); + if (Tweener.getTweenCount(this._bin) > 0) + Tweener.removeTweens(this._bin); this._bin.destroy_all_children(); this._bin.destroy(); this._bin = null; } + + remove_all_sources(); } _scan_dir(dir) { @@ -160,12 +166,12 @@ class AlbumArtRadio30 extends Desklet.Desklet { this._bin.set_size(this.width, this.height); this._images = []; - if (this._photoFrame) { + if (this._photoFrame && (this._bin != null)) { this._photoFrame.set_child(this._bin); this.setContent(this._photoFrame); } - if (this.dir_file.query_exists(null)) { + if (this.dir_file != null && this.dir_file.query_exists(null)) { this._scan_dir(this.dir); this.updateInProgress = false; @@ -180,7 +186,8 @@ class AlbumArtRadio30 extends Desklet.Desklet { if (!this.isLooping) return false; this._update(); if (this.isLooping) - this.update_id = Mainloop.timeout_add_seconds(this.delay, Lang.bind(this, this._update_loop)); + //~ this.update_id = Mainloop.timeout_add_seconds(this.delay, Lang.bind(this, this._update_loop)); + this.update_id = timeout_add_seconds(this.delay, () => { this._update_loop() }); else return false; } @@ -243,13 +250,13 @@ class AlbumArtRadio30 extends Desklet.Desklet { let _transition = "easeNone"; if (this.fade_effect != "None") _transition = "easeOut"+this.fade_effect; - if (this._bin) { + if (this._bin != null) { Tweener.addTween(this._bin, { opacity: 255, time: 0, transition: _transition, onComplete: () => { - if (this._bin) { + if (this._bin != null) { this._bin.set_child(this.currentPicture); Tweener.addTween(this._bin, { opacity: 0, @@ -261,7 +268,7 @@ class AlbumArtRadio30 extends Desklet.Desklet { }); } } else { - if (this._bin) this._bin.set_child(this.currentPicture); + if (this._bin != null) this._bin.set_child(this.currentPicture); } //~ if (old_pic) { //~ old_pic.destroy(); @@ -275,7 +282,8 @@ class AlbumArtRadio30 extends Desklet.Desklet { if (event.get_button() == 1) { this.on_setting_changed(); } else if (event.get_button() == 2) { - Util.spawn(['xdg-open', this.currentPicture.path]); + if (this.currentPicture != null) + Util.spawn(['xdg-open', this.currentPicture.path]); } } catch (e) { global.logError(e); @@ -291,7 +299,8 @@ class AlbumArtRadio30 extends Desklet.Desklet { // Set "Display Album Art at full size" menu item, in top position: let displayCoverArtInRealSize = new PopupMenu.PopupIconMenuItem(_("Display Album Art at full size"), "image-x-generic-symbolic", St.IconType.SYMBOLIC); displayCoverArtInRealSize.connect("activate", (event) => { - GLib.spawn_command_line_async("xdg-open "+this.currentPicture.path); + if (this.currentPicture != null) + GLib.spawn_command_line_async("xdg-open "+this.currentPicture.path); }); this._menu.addMenuItem(displayCoverArtInRealSize, 0); // 0 for top position. } diff --git a/Radio3.0@claudiux/files/Radio3.0@claudiux/desklet/AlbumArt3.0@claudiux/mainloopTools.js b/Radio3.0@claudiux/files/Radio3.0@claudiux/desklet/AlbumArt3.0@claudiux/mainloopTools.js new file mode 100644 index 00000000000..ccebf2e2e37 --- /dev/null +++ b/Radio3.0@claudiux/files/Radio3.0@claudiux/desklet/AlbumArt3.0@claudiux/mainloopTools.js @@ -0,0 +1,191 @@ +const GLib = imports.gi.GLib; +const Mainloop = imports.mainloop; + +/** + * _sourceIds + * Array containing IDs of all looping loops. + */ +var _sourceIds = []; + +/** + * timeout_add_seconds + * + * @callback (function) is executed every @sec (number) seconds + * with @params (dictionnary as {'key1': value1, 'key2': value2, ...}). + * + * @params is often null. + * + */ +function timeout_add_seconds(sec, callback, params=null) { + let id = Mainloop.timeout_add_seconds(sec, callback, params); + if (id && (_sourceIds.indexOf(id) === -1)) _sourceIds.push(id); + return id; +} + +/** + * timeout_add_seconds + * + * @callback (function) is executed every @ms (number) milliseconds + * with @params (dictionnary as {'key1': value1, 'key2': value2, ...}). + * + * @params is often null. + * + */ +function timeout_add(ms, callback, params=null) { + let id = Mainloop.timeout_add_seconds(ms, callback, params); + if (id && (_sourceIds.indexOf(id) === -1)) _sourceIds.push(id); + return id; +} + +/** + * setTimeout: + * @callback (function): Function to call at the end of the timeout. + * @ms (number): Milliseconds until the timeout expires. + * + * Convenience wrapper for a Mainloop.timeout_add loop that + * returns false. + * + * Returns (number): The ID of the loop. + */ +function setTimeout(callback, ms) { + let args = []; + if (arguments.length > 2) { + args = args.slice.call(arguments, 2); + } + + let id = Mainloop.timeout_add(ms, () => { + callback.call(null, ...args); + return false; // Stop repeating + }, null); + + if (id && (_sourceIds.indexOf(id) === -1)) _sourceIds.push(id); + + return id; +} + +/** + * clearTimeout: + * @id (number): The ID of the loop to remove. + * + * Convenience wrapper for Mainloop.source_remove. + */ +function clearTimeout(id) { + if (id) { + Mainloop.source_remove(id); + const pos = _sourceIds.indexOf(id); + if (pos > -1) _sourceIds.splice(pos, 1); + } +} + + +/** + * setInterval: + * @callback (function): Function to call on every interval. + * @ms (number): Milliseconds between invocations. + * + * Convenience wrapper for a Mainloop.timeout_add loop that + * returns true. + * + * Returns (number): The ID of the loop. + */ +function setInterval(callback, ms) { + let args = []; + if (arguments.length > 2) { + args = args.slice.call(arguments, 2); + } + + let id = Mainloop.timeout_add(ms, () => { + callback.call(null, ...args); + return true; // Repeat + }, null); + + if (id && (_sourceIds.indexOf(id) === -1)) _sourceIds.push(id); + + return id; +} + +/** + * clearInterval: + * @id (number): The ID of the loop to remove. + * + * Convenience wrapper for Mainloop.source_remove. + */ +function clearInterval(id) { + if (id) { + Mainloop.source_remove(id); + const pos = _sourceIds.indexOf(id); + if (pos > -1) _sourceIds.splice(pos, 1); + } +}; + +/** + * source_exists + * + * @id (number, or null) + * + * Checks if @id is well the ID of a loop. + * + */ +function source_exists(id) { + let _id = id; + if (!_id) return false; + return (GLib.MainContext.default().find_source_by_id(_id) != null); +} + +//~ function timeout_exists(id) { + //~ if (!id) return false; + //~ if (!id.source_id) return false; + //~ return (GLib.MainContext.default().find_source_by_id(id.source_id) != null); +//~ } + +//~ function interval_exists(id) { + //~ return timeout_exists(id); +//~ } + +/** + * source_remove + * + * @id (number): The ID of the loop to stop. + * @remove_from_sourceIds (boolean): *true* (by default) when we want to + * remove @id from _sourceIds. May be *false* for internal functionning. + * + * Convenience wrapper for a Mainloop.source_remove(id) that returns a + * boolean. + */ +function source_remove(id, remove_from_sourceIds=true) { + if (source_exists(id)) { + Mainloop.source_remove(id); + if (remove_from_sourceIds) { + const pos = _sourceIds.indexOf(id); + if (pos > -1) _sourceIds.splice(pos, 1); + } + return true; + } + return false; +} + +/** + * remove_all_sources + * + * Execute it when removing the spice. + * Tries to delete all remaining sources, in order to remove all loops. + */ +function remove_all_sources() { + while (_sourceIds.length > 0) { + let id = _sourceIds.pop(); + source_remove(id, false); + } +} + +module.exports = { + _sourceIds, + timeout_add_seconds, + timeout_add, + setTimeout, + clearTimeout, + setInterval, + clearInterval, + source_exists, + source_remove, + remove_all_sources +} diff --git a/Radio3.0@claudiux/files/Radio3.0@claudiux/lib/mainloopTools.js b/Radio3.0@claudiux/files/Radio3.0@claudiux/lib/mainloopTools.js new file mode 100644 index 00000000000..ccebf2e2e37 --- /dev/null +++ b/Radio3.0@claudiux/files/Radio3.0@claudiux/lib/mainloopTools.js @@ -0,0 +1,191 @@ +const GLib = imports.gi.GLib; +const Mainloop = imports.mainloop; + +/** + * _sourceIds + * Array containing IDs of all looping loops. + */ +var _sourceIds = []; + +/** + * timeout_add_seconds + * + * @callback (function) is executed every @sec (number) seconds + * with @params (dictionnary as {'key1': value1, 'key2': value2, ...}). + * + * @params is often null. + * + */ +function timeout_add_seconds(sec, callback, params=null) { + let id = Mainloop.timeout_add_seconds(sec, callback, params); + if (id && (_sourceIds.indexOf(id) === -1)) _sourceIds.push(id); + return id; +} + +/** + * timeout_add_seconds + * + * @callback (function) is executed every @ms (number) milliseconds + * with @params (dictionnary as {'key1': value1, 'key2': value2, ...}). + * + * @params is often null. + * + */ +function timeout_add(ms, callback, params=null) { + let id = Mainloop.timeout_add_seconds(ms, callback, params); + if (id && (_sourceIds.indexOf(id) === -1)) _sourceIds.push(id); + return id; +} + +/** + * setTimeout: + * @callback (function): Function to call at the end of the timeout. + * @ms (number): Milliseconds until the timeout expires. + * + * Convenience wrapper for a Mainloop.timeout_add loop that + * returns false. + * + * Returns (number): The ID of the loop. + */ +function setTimeout(callback, ms) { + let args = []; + if (arguments.length > 2) { + args = args.slice.call(arguments, 2); + } + + let id = Mainloop.timeout_add(ms, () => { + callback.call(null, ...args); + return false; // Stop repeating + }, null); + + if (id && (_sourceIds.indexOf(id) === -1)) _sourceIds.push(id); + + return id; +} + +/** + * clearTimeout: + * @id (number): The ID of the loop to remove. + * + * Convenience wrapper for Mainloop.source_remove. + */ +function clearTimeout(id) { + if (id) { + Mainloop.source_remove(id); + const pos = _sourceIds.indexOf(id); + if (pos > -1) _sourceIds.splice(pos, 1); + } +} + + +/** + * setInterval: + * @callback (function): Function to call on every interval. + * @ms (number): Milliseconds between invocations. + * + * Convenience wrapper for a Mainloop.timeout_add loop that + * returns true. + * + * Returns (number): The ID of the loop. + */ +function setInterval(callback, ms) { + let args = []; + if (arguments.length > 2) { + args = args.slice.call(arguments, 2); + } + + let id = Mainloop.timeout_add(ms, () => { + callback.call(null, ...args); + return true; // Repeat + }, null); + + if (id && (_sourceIds.indexOf(id) === -1)) _sourceIds.push(id); + + return id; +} + +/** + * clearInterval: + * @id (number): The ID of the loop to remove. + * + * Convenience wrapper for Mainloop.source_remove. + */ +function clearInterval(id) { + if (id) { + Mainloop.source_remove(id); + const pos = _sourceIds.indexOf(id); + if (pos > -1) _sourceIds.splice(pos, 1); + } +}; + +/** + * source_exists + * + * @id (number, or null) + * + * Checks if @id is well the ID of a loop. + * + */ +function source_exists(id) { + let _id = id; + if (!_id) return false; + return (GLib.MainContext.default().find_source_by_id(_id) != null); +} + +//~ function timeout_exists(id) { + //~ if (!id) return false; + //~ if (!id.source_id) return false; + //~ return (GLib.MainContext.default().find_source_by_id(id.source_id) != null); +//~ } + +//~ function interval_exists(id) { + //~ return timeout_exists(id); +//~ } + +/** + * source_remove + * + * @id (number): The ID of the loop to stop. + * @remove_from_sourceIds (boolean): *true* (by default) when we want to + * remove @id from _sourceIds. May be *false* for internal functionning. + * + * Convenience wrapper for a Mainloop.source_remove(id) that returns a + * boolean. + */ +function source_remove(id, remove_from_sourceIds=true) { + if (source_exists(id)) { + Mainloop.source_remove(id); + if (remove_from_sourceIds) { + const pos = _sourceIds.indexOf(id); + if (pos > -1) _sourceIds.splice(pos, 1); + } + return true; + } + return false; +} + +/** + * remove_all_sources + * + * Execute it when removing the spice. + * Tries to delete all remaining sources, in order to remove all loops. + */ +function remove_all_sources() { + while (_sourceIds.length > 0) { + let id = _sourceIds.pop(); + source_remove(id, false); + } +} + +module.exports = { + _sourceIds, + timeout_add_seconds, + timeout_add, + setTimeout, + clearTimeout, + setInterval, + clearInterval, + source_exists, + source_remove, + remove_all_sources +} diff --git a/Radio3.0@claudiux/files/Radio3.0@claudiux/lib/sourceExists.js b/Radio3.0@claudiux/files/Radio3.0@claudiux/lib/sourceExists.js deleted file mode 100644 index e12bfb87ae3..00000000000 --- a/Radio3.0@claudiux/files/Radio3.0@claudiux/lib/sourceExists.js +++ /dev/null @@ -1,17 +0,0 @@ -const GLib = imports.gi.GLib; - -function source_exists(id) { - let _id = id; - if (!_id) return false; - return (GLib.MainContext.default().find_source_by_id(_id) != null); -} - -function timeout_exists(id) { - if (!id) return false; - if (!id.source_id) return false; - return (GLib.MainContext.default().find_source_by_id(id.source_id) != null); -} - -function interval_exists(id) { - return timeout_exists(id); -} diff --git a/Radio3.0@claudiux/files/Radio3.0@claudiux/metadata.json b/Radio3.0@claudiux/files/Radio3.0@claudiux/metadata.json index de985a59120..9a1267b229b 100644 --- a/Radio3.0@claudiux/files/Radio3.0@claudiux/metadata.json +++ b/Radio3.0@claudiux/files/Radio3.0@claudiux/metadata.json @@ -1,7 +1,7 @@ { "description": "The Ultimate Internet Radio Receiver & Recorder for Cinnamon", "max-instances": 1, - "version": "2.7.1", + "version": "2.7.2", "uuid": "Radio3.0@claudiux", "name": "Radio3.0", "author": "claudiux", diff --git a/Radio3.0@claudiux/files/Radio3.0@claudiux/radiodb/server-list.json b/Radio3.0@claudiux/files/Radio3.0@claudiux/radiodb/server-list.json index bfc7e8d0f22..c23864b0a50 100644 --- a/Radio3.0@claudiux/files/Radio3.0@claudiux/radiodb/server-list.json +++ b/Radio3.0@claudiux/files/Radio3.0@claudiux/radiodb/server-list.json @@ -2,13 +2,13 @@ { "server": "https://api.radiodb.fr" }, - { - "server": "https://at1.api.radio-browser.info" - }, { "server": "https://de1.api.radio-browser.info" }, { "server": "https://nl1.api.radio-browser.info" + }, + { + "server": "https://at1.api.radio-browser.info" } ]