[gnome] Updating extensions, back to Forge
This commit is contained in:
@ -14,21 +14,30 @@ function jsonRpc(method, params = {}) {
|
||||
return JSON.stringify({ jsonrpc: "2.0", id: 1, method, params });
|
||||
}
|
||||
|
||||
// Soup 3: callback-based async -> Promise wrapper
|
||||
async function postJson(session, url, bodyStr) {
|
||||
const msg = Soup.Message.new("POST", url);
|
||||
msg.request_headers.append("Content-Type", "application/json");
|
||||
|
||||
// Soup 3: request body as GLib.Bytes
|
||||
msg.set_request_body_from_bytes(
|
||||
"application/json",
|
||||
new GLib.Bytes(bodyStr),
|
||||
);
|
||||
|
||||
const bytes = await session.send_and_read_async(
|
||||
msg,
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
null,
|
||||
);
|
||||
const bytes = await new Promise((resolve, reject) => {
|
||||
session.send_and_read_async(
|
||||
msg,
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
null,
|
||||
(sess, res) => {
|
||||
try {
|
||||
resolve(sess.send_and_read_finish(res));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const text = new TextDecoder().decode(bytes.get_data());
|
||||
return JSON.parse(text);
|
||||
}
|
||||
@ -75,7 +84,13 @@ const SnapcastSlider = GObject.registerClass(
|
||||
|
||||
this._ext = extension;
|
||||
this._settings = extension.getSettings();
|
||||
this._session = new Soup.Session();
|
||||
|
||||
// --- Soup session with timeouts (seconds) ---
|
||||
this._session = new Soup.Session({
|
||||
timeout: 5, // total request timeout
|
||||
idle_timeout: 5, // idle timeout
|
||||
user_agent: "Snapshell/1",
|
||||
});
|
||||
|
||||
this._pollId = 0;
|
||||
this._debounceId = 0;
|
||||
@ -85,37 +100,28 @@ const SnapcastSlider = GObject.registerClass(
|
||||
this._isUpdatingFromServer = false;
|
||||
this._groupClientIds = [];
|
||||
|
||||
// Load settings
|
||||
this._reloadSettings();
|
||||
|
||||
// React to settings changes (server-url, group-id, poll-seconds)
|
||||
this._settingsChangedId = this._settings.connect("changed", () => {
|
||||
this._reloadSettings();
|
||||
this._restartPolling();
|
||||
this._pollOnce().catch(logError);
|
||||
});
|
||||
|
||||
// Slider change -> debounce -> set group volume
|
||||
this._sliderChangedId = this.slider.connect("notify::value", () => {
|
||||
if (this._isUpdatingFromServer) return;
|
||||
this._debouncedSetVolume();
|
||||
});
|
||||
|
||||
// Start polling + initial sync
|
||||
this._restartPolling();
|
||||
this._pollOnce().catch(logError);
|
||||
}
|
||||
|
||||
_reloadSettings() {
|
||||
// You’ll define these keys in your gschema:
|
||||
// - server-url (string)
|
||||
// - group-id (string)
|
||||
// - poll-seconds (uint)
|
||||
this._url = this._settings.get_string("server-url");
|
||||
this._groupId = this._settings.get_string("group-id");
|
||||
this._url = this._settings.get_string("server-url").trim();
|
||||
this._groupId = this._settings.get_string("group-id").trim();
|
||||
this._pollSeconds = this._settings.get_uint("poll-seconds");
|
||||
|
||||
// Sensible guards
|
||||
if (!this._pollSeconds || this._pollSeconds < 2)
|
||||
this._pollSeconds = 5;
|
||||
}
|
||||
@ -142,7 +148,6 @@ const SnapcastSlider = GObject.registerClass(
|
||||
this._debounceId = 0;
|
||||
}
|
||||
|
||||
// Wait a beat so dragging doesn’t fire 100 requests/sec
|
||||
this._debounceId = GLib.timeout_add(
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
150,
|
||||
@ -155,7 +160,6 @@ const SnapcastSlider = GObject.registerClass(
|
||||
}
|
||||
|
||||
async _pollOnce() {
|
||||
// If not configured yet
|
||||
if (!this._url) {
|
||||
this.title = "Snapcast — set server URL";
|
||||
this._groupClientIds = [];
|
||||
@ -167,7 +171,6 @@ const SnapcastSlider = GObject.registerClass(
|
||||
return;
|
||||
}
|
||||
|
||||
// Pull all status in one request
|
||||
const resp = await postJson(
|
||||
this._session,
|
||||
this._url,
|
||||
@ -182,13 +185,9 @@ const SnapcastSlider = GObject.registerClass(
|
||||
return;
|
||||
}
|
||||
|
||||
// Only connected clients
|
||||
this._groupClientIds = connectedClientIds(group);
|
||||
|
||||
// Update title with something human-readable
|
||||
this.title = `Snapcast — ${groupLabel(group)}`;
|
||||
|
||||
// Slider position = average of connected clients’ volumes
|
||||
const avg = avgConnectedVolumePercent(group);
|
||||
if (typeof avg === "number") {
|
||||
const v = clamp01(avg / 100);
|
||||
@ -208,7 +207,6 @@ const SnapcastSlider = GObject.registerClass(
|
||||
|
||||
const percent = Math.round(clamp01(this.slider.value) * 100);
|
||||
|
||||
// Fan out: set volume for each connected client in the group
|
||||
await Promise.allSettled(
|
||||
this._groupClientIds.map((id) => {
|
||||
const body = jsonRpc("Client.SetVolume", {
|
||||
@ -227,7 +225,6 @@ const SnapcastSlider = GObject.registerClass(
|
||||
this.slider.disconnect(this._sliderChangedId);
|
||||
if (this._settingsChangedId)
|
||||
this._settings.disconnect(this._settingsChangedId);
|
||||
|
||||
super.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user