Files
sing-box-gnome-extension/prefs.js
T

112 lines
4.9 KiB
JavaScript

import Adw from 'gi://Adw';
import Gtk from 'gi://Gtk';
import Gio from 'gi://Gio';
import { ExtensionPreferences, gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
export default class SingBoxStatusPreferences extends ExtensionPreferences {
fillPreferencesWindow(window) {
const settings = this.getSettings();
const page = new Adw.PreferencesPage({
title: _('General'),
icon_name: 'network-vpn-symbolic',
});
window.add(page);
// --- Connection ------------------------------------------------
const connGroup = new Adw.PreferencesGroup({
title: _('Clash API'),
description: _('Matches experimental_clash_api in your sing-box config.'),
});
page.add(connGroup);
connGroup.add(this._entryRow(settings, 'api-url', _('API URL'),
_('e.g. http://127.0.0.1:9090')));
connGroup.add(this._passwordRow(settings, 'api-secret', _('Secret'),
_('Bearer token; leave empty if none.')));
connGroup.add(this._entryRow(settings, 'dashboard-url', _('Dashboard URL'),
_('Opened by “Open dashboard”.')));
// --- Display ---------------------------------------------------
const dispGroup = new Adw.PreferencesGroup({ title: _('Display') });
page.add(dispGroup);
dispGroup.add(this._switchRow(settings, 'show-outbound', _('Show active outbound'),
_('Show the current outbound name in the top bar.')));
dispGroup.add(this._switchRow(settings, 'show-speed', _('Show speed'),
_('Show upload/download speed in the top bar.')));
dispGroup.add(this._entryRow(settings, 'selector-group', _('Panel selector group'),
_('Selector group shown in the panel. Empty = first one found.')));
const intervalRow = new Adw.SpinRow({
title: _('Refresh interval'),
subtitle: _('Seconds between Clash API polls.'),
adjustment: new Gtk.Adjustment({ lower: 1, upper: 30, step_increment: 1 }),
});
settings.bind('refresh-interval', intervalRow, 'value', Gio.SettingsBindFlags.DEFAULT);
dispGroup.add(intervalRow);
// --- Connectivity ---------------------------------------------
const connCheckGroup = new Adw.PreferencesGroup({
title: _('Connectivity check'),
description: _('Actively probe the active outbound to tell “up but no internet” from “up and reachable”. Adds a third status-dot state.'),
});
page.add(connCheckGroup);
const checkRow = this._switchRow(settings, 'check-connectivity',
_('Probe active outbound'),
_('Periodically sends a background request through the current outbound to the Probe URL below (an external site by default). Off = no background traffic.'));
connCheckGroup.add(checkRow);
const connIntervalRow = new Adw.SpinRow({
title: _('Probe interval'),
subtitle: _('Seconds between outbound probes.'),
adjustment: new Gtk.Adjustment({ lower: 5, upper: 600, step_increment: 5 }),
});
settings.bind('connectivity-interval', connIntervalRow, 'value', Gio.SettingsBindFlags.DEFAULT);
settings.bind('check-connectivity', connIntervalRow, 'sensitive', Gio.SettingsBindFlags.GET);
connCheckGroup.add(connIntervalRow);
const connUrlRow = this._entryRow(settings, 'connectivity-url', _('Probe URL'),
_('Target URL for the latency probe (a 204/no-content endpoint is ideal).'));
settings.bind('check-connectivity', connUrlRow, 'sensitive', Gio.SettingsBindFlags.GET);
connCheckGroup.add(connUrlRow);
}
_entryRow(settings, key, title, subtitle) {
const row = new Adw.EntryRow({ title });
// Adw.EntryRow has no subtitle; surface the hint as a tooltip instead.
if (subtitle)
row.set_tooltip_text(subtitle);
row.text = settings.get_string(key);
row.connect('changed', () => settings.set_string(key, row.text));
settings.connect(`changed::${key}`, () => {
const v = settings.get_string(key);
if (row.text !== v)
row.text = v;
});
return row;
}
_passwordRow(settings, key, title, subtitle) {
const row = new Adw.PasswordEntryRow({ title });
if (subtitle)
row.set_tooltip_text(subtitle);
row.text = settings.get_string(key);
row.connect('changed', () => settings.set_string(key, row.text));
settings.connect(`changed::${key}`, () => {
const v = settings.get_string(key);
if (row.text !== v)
row.text = v;
});
return row;
}
_switchRow(settings, key, title, subtitle) {
const row = new Adw.SwitchRow({ title, subtitle });
settings.bind(key, row, 'active', Gio.SettingsBindFlags.DEFAULT);
return row;
}
}