112 lines
4.8 KiB
JavaScript
112 lines
4.8 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 measure latency through the current outbound.'));
|
|
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;
|
|
}
|
|
}
|