fix: run prettier for luci app js assets

This commit is contained in:
divocat
2025-10-05 16:12:56 +03:00
parent d9a4f50f62
commit eb60e6edec
4 changed files with 2216 additions and 1484 deletions

View File

@@ -7,22 +7,46 @@
function createAdditionalSection(mainSection) { function createAdditionalSection(mainSection) {
let o = mainSection.tab('additional', _('Additional Settings')); let o = mainSection.tab('additional', _('Additional Settings'));
o = mainSection.taboption('additional', form.Flag, 'yacd', _('Yacd enable'), `<a href="${main.getBaseUrl()}:9090/ui" target="_blank">${main.getBaseUrl()}:9090/ui</a>`); o = mainSection.taboption(
'additional',
form.Flag,
'yacd',
_('Yacd enable'),
`<a href="${main.getBaseUrl()}:9090/ui" target="_blank">${main.getBaseUrl()}:9090/ui</a>`,
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('additional', form.Flag, 'exclude_ntp', _('Exclude NTP'), _('Allows you to exclude NTP protocol traffic from the tunnel')); o = mainSection.taboption(
'additional',
form.Flag,
'exclude_ntp',
_('Exclude NTP'),
_('Allows you to exclude NTP protocol traffic from the tunnel'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('additional', form.Flag, 'quic_disable', _('QUIC disable'), _('For issues with the video stream')); o = mainSection.taboption(
'additional',
form.Flag,
'quic_disable',
_('QUIC disable'),
_('For issues with the video stream'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('additional', form.ListValue, 'update_interval', _('List Update Frequency'), _('Select how often the lists will be updated')); o = mainSection.taboption(
'additional',
form.ListValue,
'update_interval',
_('List Update Frequency'),
_('Select how often the lists will be updated'),
);
Object.entries(main.UPDATE_INTERVAL_OPTIONS).forEach(([key, label]) => { Object.entries(main.UPDATE_INTERVAL_OPTIONS).forEach(([key, label]) => {
o.value(key, _(label)); o.value(key, _(label));
}); });
@@ -30,7 +54,13 @@ function createAdditionalSection(mainSection) {
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('additional', form.ListValue, 'dns_type', _('DNS Protocol Type'), _('Select DNS protocol to use')); o = mainSection.taboption(
'additional',
form.ListValue,
'dns_type',
_('DNS Protocol Type'),
_('Select DNS protocol to use'),
);
o.value('doh', _('DNS over HTTPS (DoH)')); o.value('doh', _('DNS over HTTPS (DoH)'));
o.value('dot', _('DNS over TLS (DoT)')); o.value('dot', _('DNS over TLS (DoT)'));
o.value('udp', _('UDP (Unprotected DNS)')); o.value('udp', _('UDP (Unprotected DNS)'));
@@ -38,7 +68,13 @@ function createAdditionalSection(mainSection) {
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('additional', form.Value, 'dns_server', _('DNS Server'), _('Select or enter DNS server address')); o = mainSection.taboption(
'additional',
form.Value,
'dns_server',
_('DNS Server'),
_('Select or enter DNS server address'),
);
Object.entries(main.DNS_SERVER_OPTIONS).forEach(([key, label]) => { Object.entries(main.DNS_SERVER_OPTIONS).forEach(([key, label]) => {
o.value(key, _(label)); o.value(key, _(label));
}); });
@@ -55,7 +91,15 @@ function createAdditionalSection(mainSection) {
return _(validation.message); return _(validation.message);
}; };
o = mainSection.taboption('additional', form.Value, 'bootstrap_dns_server', _('Bootstrap DNS server'), _('The DNS server used to look up the IP address of an upstream DNS server')); o = mainSection.taboption(
'additional',
form.Value,
'bootstrap_dns_server',
_('Bootstrap DNS server'),
_(
'The DNS server used to look up the IP address of an upstream DNS server',
),
);
Object.entries(main.BOOTSTRAP_DNS_SERVER_OPTIONS).forEach(([key, label]) => { Object.entries(main.BOOTSTRAP_DNS_SERVER_OPTIONS).forEach(([key, label]) => {
o.value(key, _(label)); o.value(key, _(label));
}); });
@@ -72,7 +116,13 @@ function createAdditionalSection(mainSection) {
return _(validation.message); return _(validation.message);
}; };
o = mainSection.taboption('additional', form.Value, 'dns_rewrite_ttl', _('DNS Rewrite TTL'), _('Time in seconds for DNS record caching (default: 60)')); o = mainSection.taboption(
'additional',
form.Value,
'dns_rewrite_ttl',
_('DNS Rewrite TTL'),
_('Time in seconds for DNS record caching (default: 60)'),
);
o.default = '60'; o.default = '60';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
@@ -89,16 +139,35 @@ function createAdditionalSection(mainSection) {
return true; return true;
}; };
o = mainSection.taboption('additional', form.ListValue, 'config_path', _('Config File Path'), _('Select path for sing-box config file. Change this ONLY if you know what you are doing')); o = mainSection.taboption(
'additional',
form.ListValue,
'config_path',
_('Config File Path'),
_(
'Select path for sing-box config file. Change this ONLY if you know what you are doing',
),
);
o.value('/etc/sing-box/config.json', 'Flash (/etc/sing-box/config.json)'); o.value('/etc/sing-box/config.json', 'Flash (/etc/sing-box/config.json)');
o.value('/tmp/sing-box/config.json', 'RAM (/tmp/sing-box/config.json)'); o.value('/tmp/sing-box/config.json', 'RAM (/tmp/sing-box/config.json)');
o.default = '/etc/sing-box/config.json'; o.default = '/etc/sing-box/config.json';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('additional', form.Value, 'cache_path', _('Cache File Path'), _('Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing')); o = mainSection.taboption(
'additional',
form.Value,
'cache_path',
_('Cache File Path'),
_(
'Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing',
),
);
o.value('/tmp/sing-box/cache.db', 'RAM (/tmp/sing-box/cache.db)'); o.value('/tmp/sing-box/cache.db', 'RAM (/tmp/sing-box/cache.db)');
o.value('/usr/share/sing-box/cache.db', 'Flash (/usr/share/sing-box/cache.db)'); o.value(
'/usr/share/sing-box/cache.db',
'Flash (/usr/share/sing-box/cache.db)',
);
o.default = '/tmp/sing-box/cache.db'; o.default = '/tmp/sing-box/cache.db';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
@@ -123,7 +192,13 @@ function createAdditionalSection(mainSection) {
return true; return true;
}; };
o = mainSection.taboption('additional', widgets.DeviceSelect, 'iface', _('Source Network Interface'), _('Select the network interface from which the traffic will originate')); o = mainSection.taboption(
'additional',
widgets.DeviceSelect,
'iface',
_('Source Network Interface'),
_('Select the network interface from which the traffic will originate'),
);
o.ucisection = 'main'; o.ucisection = 'main';
o.default = 'br-lan'; o.default = 'br-lan';
o.noaliases = true; o.noaliases = true;
@@ -138,7 +213,7 @@ function createAdditionalSection(mainSection) {
} }
// Try to find the device object by its name // Try to find the device object by its name
const device = this.devices.find(dev => dev.getName() === value); const device = this.devices.find((dev) => dev.getName() === value);
// If no device is found, allow the value // If no device is found, allow the value
if (!device) { if (!device) {
@@ -156,12 +231,24 @@ function createAdditionalSection(mainSection) {
return !isWireless; return !isWireless;
}; };
o = mainSection.taboption('additional', form.Flag, 'mon_restart_ifaces', _('Interface monitoring'), _('Interface monitoring for bad WAN')); o = mainSection.taboption(
'additional',
form.Flag,
'mon_restart_ifaces',
_('Interface monitoring'),
_('Interface monitoring for bad WAN'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('additional', widgets.NetworkSelect, 'restart_ifaces', _('Interface for monitoring'), _('Select the WAN interfaces to be monitored')); o = mainSection.taboption(
'additional',
widgets.NetworkSelect,
'restart_ifaces',
_('Interface for monitoring'),
_('Select the WAN interfaces to be monitored'),
);
o.ucisection = 'main'; o.ucisection = 'main';
o.depends('mon_restart_ifaces', '1'); o.depends('mon_restart_ifaces', '1');
o.multiple = true; o.multiple = true;
@@ -180,7 +267,13 @@ function createAdditionalSection(mainSection) {
return true; return true;
}; };
o = mainSection.taboption('additional', form.Value, 'procd_reload_delay', _('Interface Monitoring Delay'), _('Delay in milliseconds before reloading podkop after interface UP')); o = mainSection.taboption(
'additional',
form.Value,
'procd_reload_delay',
_('Interface Monitoring Delay'),
_('Delay in milliseconds before reloading podkop after interface UP'),
);
o.ucisection = 'main'; o.ucisection = 'main';
o.depends('mon_restart_ifaces', '1'); o.depends('mon_restart_ifaces', '1');
o.default = '2000'; o.default = '2000';
@@ -192,23 +285,47 @@ function createAdditionalSection(mainSection) {
return true; return true;
}; };
o = mainSection.taboption('additional', form.Flag, 'dont_touch_dhcp', _('Dont touch my DHCP!'), _('Podkop will not change the DHCP config')); o = mainSection.taboption(
'additional',
form.Flag,
'dont_touch_dhcp',
_('Dont touch my DHCP!'),
_('Podkop will not change the DHCP config'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('additional', form.Flag, 'detour', _('Proxy download of lists'), _('Downloading all lists via main Proxy/VPN')); o = mainSection.taboption(
'additional',
form.Flag,
'detour',
_('Proxy download of lists'),
_('Downloading all lists via main Proxy/VPN'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
// Extra IPs and exclusions (main section) // Extra IPs and exclusions (main section)
o = mainSection.taboption('basic', form.Flag, 'exclude_from_ip_enabled', _('IP for exclusion'), _('Specify local IP addresses that will never use the configured route')); o = mainSection.taboption(
'basic',
form.Flag,
'exclude_from_ip_enabled',
_('IP for exclusion'),
_('Specify local IP addresses that will never use the configured route'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
o = mainSection.taboption('basic', form.DynamicList, 'exclude_traffic_ip', _('Local IPs'), _('Enter valid IPv4 addresses')); o = mainSection.taboption(
'basic',
form.DynamicList,
'exclude_traffic_ip',
_('Local IPs'),
_('Enter valid IPv4 addresses'),
);
o.placeholder = 'IP'; o.placeholder = 'IP';
o.depends('exclude_from_ip_enabled', '1'); o.depends('exclude_from_ip_enabled', '1');
o.rmempty = false; o.rmempty = false;
@@ -216,7 +333,7 @@ function createAdditionalSection(mainSection) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validateIPV4(value); const validation = main.validateIPV4(value);
@@ -225,15 +342,21 @@ function createAdditionalSection(mainSection) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = mainSection.taboption('basic', form.Flag, 'socks5', _('Mixed enable'), _('Browser port: 2080')); o = mainSection.taboption(
'basic',
form.Flag,
'socks5',
_('Mixed enable'),
_('Browser port: 2080'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = 'main'; o.ucisection = 'main';
} }
return baseclass.extend({ return baseclass.extend({
createAdditionalSection createAdditionalSection,
}); });

View File

@@ -6,19 +6,30 @@
'require view.podkop.main as main'; 'require view.podkop.main as main';
'require tools.widgets as widgets'; 'require tools.widgets as widgets';
function createConfigSection(section) { function createConfigSection(section) {
const s = section; const s = section;
let o = s.tab('basic', _('Basic Settings')); let o = s.tab('basic', _('Basic Settings'));
o = s.taboption('basic', form.ListValue, 'mode', _('Connection Type'), _('Select between VPN and Proxy connection methods for traffic routing')); o = s.taboption(
o.value('proxy', ('Proxy')); 'basic',
o.value('vpn', ('VPN')); form.ListValue,
o.value('block', ('Block')); 'mode',
_('Connection Type'),
_('Select between VPN and Proxy connection methods for traffic routing'),
);
o.value('proxy', 'Proxy');
o.value('vpn', 'VPN');
o.value('block', 'Block');
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.ListValue, 'proxy_config_type', _('Configuration Type'), _('Select how to configure the proxy')); o = s.taboption(
'basic',
form.ListValue,
'proxy_config_type',
_('Configuration Type'),
_('Select how to configure the proxy'),
);
o.value('url', _('Connection URL')); o.value('url', _('Connection URL'));
o.value('outbound', _('Outbound Config')); o.value('outbound', _('Outbound Config'));
o.value('urltest', _('URLTest')); o.value('urltest', _('URLTest'));
@@ -26,7 +37,13 @@ function createConfigSection(section) {
o.depends('mode', 'proxy'); o.depends('mode', 'proxy');
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.TextValue, 'proxy_string', _('Proxy Configuration URL'), ''); o = s.taboption(
'basic',
form.TextValue,
'proxy_string',
_('Proxy Configuration URL'),
'',
);
o.depends('proxy_config_type', 'url'); o.depends('proxy_config_type', 'url');
o.rows = 5; o.rows = 5;
o.wrap = 'soft'; o.wrap = 'soft';
@@ -34,43 +51,70 @@ function createConfigSection(section) {
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o.sectionDescriptions = new Map(); o.sectionDescriptions = new Map();
o.placeholder = 'vless://uuid@server:port?type=tcp&security=tls#main\n// backup ss://method:pass@server:port\n// backup2 vless://uuid@server:port?type=grpc&security=reality#alt\n// backup3 trojan://04agAQapcl@127.0.0.1:33641?type=tcp&security=none#trojan-tcp-none'; o.placeholder =
'vless://uuid@server:port?type=tcp&security=tls#main\n// backup ss://method:pass@server:port\n// backup2 vless://uuid@server:port?type=grpc&security=reality#alt\n// backup3 trojan://04agAQapcl@127.0.0.1:33641?type=tcp&security=none#trojan-tcp-none';
o.renderWidget = function (section_id, option_index, cfgvalue) { o.renderWidget = function (section_id, option_index, cfgvalue) {
const original = form.TextValue.prototype.renderWidget.apply(this, [section_id, option_index, cfgvalue]); const original = form.TextValue.prototype.renderWidget.apply(this, [
section_id,
option_index,
cfgvalue,
]);
const container = E('div', {}); const container = E('div', {});
container.appendChild(original); container.appendChild(original);
if (cfgvalue) { if (cfgvalue) {
try { try {
const activeConfig = cfgvalue.split('\n') const activeConfig = cfgvalue
.map(line => line.trim()) .split('\n')
.find(line => line && !line.startsWith('//')); .map((line) => line.trim())
.find((line) => line && !line.startsWith('//'));
if (activeConfig) { if (activeConfig) {
if (activeConfig.includes('#')) { if (activeConfig.includes('#')) {
const label = activeConfig.split('#').pop(); const label = activeConfig.split('#').pop();
if (label && label.trim()) { if (label && label.trim()) {
const decodedLabel = decodeURIComponent(label); const decodedLabel = decodeURIComponent(label);
const descDiv = E('div', { 'class': 'cbi-value-description' }, _('Current config: ') + decodedLabel); const descDiv = E(
'div',
{ class: 'cbi-value-description' },
_('Current config: ') + decodedLabel,
);
container.appendChild(descDiv); container.appendChild(descDiv);
} else { } else {
const descDiv = E('div', { 'class': 'cbi-value-description' }, _('Config without description')); const descDiv = E(
'div',
{ class: 'cbi-value-description' },
_('Config without description'),
);
container.appendChild(descDiv); container.appendChild(descDiv);
} }
} else { } else {
const descDiv = E('div', { 'class': 'cbi-value-description' }, _('Config without description')); const descDiv = E(
'div',
{ class: 'cbi-value-description' },
_('Config without description'),
);
container.appendChild(descDiv); container.appendChild(descDiv);
} }
} }
} catch (e) { } catch (e) {
console.error('Error parsing config label:', e); console.error('Error parsing config label:', e);
const descDiv = E('div', { 'class': 'cbi-value-description' }, _('Config without description')); const descDiv = E(
'div',
{ class: 'cbi-value-description' },
_('Config without description'),
);
container.appendChild(descDiv); container.appendChild(descDiv);
} }
} else { } else {
const defaultDesc = E('div', { 'class': 'cbi-value-description' }, const defaultDesc = E(
_('Enter connection string starting with vless:// or ss:// for proxy configuration. Add comments with // for backup configs')); 'div',
{ class: 'cbi-value-description' },
_(
'Enter connection string starting with vless:// or ss:// for proxy configuration. Add comments with // for backup configs',
),
);
container.appendChild(defaultDesc); container.appendChild(defaultDesc);
} }
@@ -80,16 +124,19 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
try { try {
const activeConfig = value.split('\n') const activeConfig = value
.map(line => line.trim()) .split('\n')
.find(line => line && !line.startsWith('//')); .map((line) => line.trim())
.find((line) => line && !line.startsWith('//'));
if (!activeConfig) { if (!activeConfig) {
return _('No active configuration found. At least one non-commented line is required.'); return _(
'No active configuration found. At least one non-commented line is required.',
);
} }
const validation = main.validateProxyUrl(activeConfig); const validation = main.validateProxyUrl(activeConfig);
@@ -98,20 +145,26 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
} catch (e) { } catch (e) {
return `${_('Invalid URL format:')} ${e?.message}`; return `${_('Invalid URL format:')} ${e?.message}`;
} }
}; };
o = s.taboption('basic', form.TextValue, 'outbound_json', _('Outbound Configuration'), _('Enter complete outbound configuration in JSON format')); o = s.taboption(
'basic',
form.TextValue,
'outbound_json',
_('Outbound Configuration'),
_('Enter complete outbound configuration in JSON format'),
);
o.depends('proxy_config_type', 'outbound'); o.depends('proxy_config_type', 'outbound');
o.rows = 10; o.rows = 10;
o.ucisection = s.section; o.ucisection = s.section;
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validateOutboundJson(value); const validation = main.validateOutboundJson(value);
@@ -120,10 +173,15 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.DynamicList, 'urltest_proxy_links', _('URLTest Proxy Links')); o = s.taboption(
'basic',
form.DynamicList,
'urltest_proxy_links',
_('URLTest Proxy Links'),
);
o.depends('proxy_config_type', 'urltest'); o.depends('proxy_config_type', 'urltest');
o.placeholder = 'vless://, ss://, trojan:// links'; o.placeholder = 'vless://, ss://, trojan:// links';
o.rmempty = false; o.rmempty = false;
@@ -133,7 +191,7 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validateProxyUrl(value); const validation = main.validateProxyUrl(value);
@@ -142,16 +200,28 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.Flag, 'ss_uot', _('Shadowsocks UDP over TCP'), _('Apply for SS2022')); o = s.taboption(
'basic',
form.Flag,
'ss_uot',
_('Shadowsocks UDP over TCP'),
_('Apply for SS2022'),
);
o.default = '0'; o.default = '0';
o.depends('mode', 'proxy'); o.depends('mode', 'proxy');
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', widgets.DeviceSelect, 'interface', _('Network Interface'), _('Select network interface for VPN connection')); o = s.taboption(
'basic',
widgets.DeviceSelect,
'interface',
_('Network Interface'),
_('Select network interface for VPN connection'),
);
o.depends('mode', 'vpn'); o.depends('mode', 'vpn');
o.ucisection = s.section; o.ucisection = s.section;
o.noaliases = true; o.noaliases = true;
@@ -176,7 +246,7 @@ function createConfigSection(section) {
} }
// Try to find the device object with the given name // Try to find the device object with the given name
const device = this.devices.find(dev => dev.getName() === value); const device = this.devices.find((dev) => dev.getName() === value);
// If no device is found, allow the value // If no device is found, allow the value
if (!device) { if (!device) {
@@ -193,13 +263,25 @@ function createConfigSection(section) {
return !isWireless; return !isWireless;
}; };
o = s.taboption('basic', form.Flag, 'domain_resolver_enabled', _('Domain Resolver'), _('Enable built-in DNS resolver for domains handled by this section')); o = s.taboption(
'basic',
form.Flag,
'domain_resolver_enabled',
_('Domain Resolver'),
_('Enable built-in DNS resolver for domains handled by this section'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.depends('mode', 'vpn'); o.depends('mode', 'vpn');
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.ListValue, 'domain_resolver_dns_type', _('DNS Protocol Type'), _('Select the DNS protocol type for the domain resolver')); o = s.taboption(
'basic',
form.ListValue,
'domain_resolver_dns_type',
_('DNS Protocol Type'),
_('Select the DNS protocol type for the domain resolver'),
);
o.value('doh', _('DNS over HTTPS (DoH)')); o.value('doh', _('DNS over HTTPS (DoH)'));
o.value('dot', _('DNS over TLS (DoT)')); o.value('dot', _('DNS over TLS (DoT)'));
o.value('udp', _('UDP (Unprotected DNS)')); o.value('udp', _('UDP (Unprotected DNS)'));
@@ -208,7 +290,13 @@ function createConfigSection(section) {
o.depends('domain_resolver_enabled', '1'); o.depends('domain_resolver_enabled', '1');
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.Value, 'domain_resolver_dns_server', _('DNS Server'), _('Select or enter DNS server address')); o = s.taboption(
'basic',
form.Value,
'domain_resolver_dns_server',
_('DNS Server'),
_('Select or enter DNS server address'),
);
Object.entries(main.DNS_SERVER_OPTIONS).forEach(([key, label]) => { Object.entries(main.DNS_SERVER_OPTIONS).forEach(([key, label]) => {
o.value(key, _(label)); o.value(key, _(label));
}); });
@@ -223,15 +311,27 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.Flag, 'community_lists_enabled', _('Community Lists')); o = s.taboption(
'basic',
form.Flag,
'community_lists_enabled',
_('Community Lists'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.DynamicList, 'community_lists', _('Service List'), _('Select predefined service for routing') + ' <a href="https://github.com/itdoginfo/allow-domains" target="_blank">github.com/itdoginfo/allow-domains</a>'); o = s.taboption(
'basic',
form.DynamicList,
'community_lists',
_('Service List'),
_('Select predefined service for routing') +
' <a href="https://github.com/itdoginfo/allow-domains" target="_blank">github.com/itdoginfo/allow-domains</a>',
);
o.placeholder = 'Service list'; o.placeholder = 'Service list';
Object.entries(main.DOMAIN_LIST_OPTIONS).forEach(([key, label]) => { Object.entries(main.DOMAIN_LIST_OPTIONS).forEach(([key, label]) => {
o.value(key, _(label)); o.value(key, _(label));
@@ -252,31 +352,52 @@ function createConfigSection(section) {
let newValues = [...values]; let newValues = [...values];
let notifications = []; let notifications = [];
const selectedRegionalOptions = main.REGIONAL_OPTIONS.filter(opt => newValues.includes(opt)); const selectedRegionalOptions = main.REGIONAL_OPTIONS.filter((opt) =>
newValues.includes(opt),
);
if (selectedRegionalOptions.length > 1) { if (selectedRegionalOptions.length > 1) {
const lastSelected = selectedRegionalOptions[selectedRegionalOptions.length - 1]; const lastSelected =
selectedRegionalOptions[selectedRegionalOptions.length - 1];
const removedRegions = selectedRegionalOptions.slice(0, -1); const removedRegions = selectedRegionalOptions.slice(0, -1);
newValues = newValues.filter(v => v === lastSelected || !main.REGIONAL_OPTIONS.includes(v)); newValues = newValues.filter(
notifications.push(E('p', { class: 'alert-message warning' }, [ (v) => v === lastSelected || !main.REGIONAL_OPTIONS.includes(v),
E('strong', {}, _('Regional options cannot be used together')), E('br'), );
_('Warning: %s cannot be used together with %s. Previous selections have been removed.') notifications.push(
.format(removedRegions.join(', '), lastSelected) E('p', { class: 'alert-message warning' }, [
])); E('strong', {}, _('Regional options cannot be used together')),
E('br'),
_(
'Warning: %s cannot be used together with %s. Previous selections have been removed.',
).format(removedRegions.join(', '), lastSelected),
]),
);
} }
if (newValues.includes('russia_inside')) { if (newValues.includes('russia_inside')) {
const removedServices = newValues.filter(v => !main.ALLOWED_WITH_RUSSIA_INSIDE.includes(v)); const removedServices = newValues.filter(
(v) => !main.ALLOWED_WITH_RUSSIA_INSIDE.includes(v),
);
if (removedServices.length > 0) { if (removedServices.length > 0) {
newValues = newValues.filter(v => main.ALLOWED_WITH_RUSSIA_INSIDE.includes(v)); newValues = newValues.filter((v) =>
notifications.push(E('p', { class: 'alert-message warning' }, [ main.ALLOWED_WITH_RUSSIA_INSIDE.includes(v),
E('strong', {}, _('Russia inside restrictions')), E('br'), );
_('Warning: Russia inside can only be used with %s. %s already in Russia inside and have been removed from selection.') notifications.push(
.format( E('p', { class: 'alert-message warning' }, [
main.ALLOWED_WITH_RUSSIA_INSIDE.map(key => main.DOMAIN_LIST_OPTIONS[key]).filter(label => label !== 'Russia inside').join(', '), E('strong', {}, _('Russia inside restrictions')),
removedServices.join(', ') E('br'),
_(
'Warning: Russia inside can only be used with %s. %s already in Russia inside and have been removed from selection.',
).format(
main.ALLOWED_WITH_RUSSIA_INSIDE.map(
(key) => main.DOMAIN_LIST_OPTIONS[key],
) )
])); .filter((label) => label !== 'Russia inside')
.join(', '),
removedServices.join(', '),
),
]),
);
} }
} }
@@ -284,7 +405,9 @@ function createConfigSection(section) {
this.getUIElement(section_id).setValue(newValues); this.getUIElement(section_id).setValue(newValues);
} }
notifications.forEach(notification => ui.addNotification(null, notification)); notifications.forEach((notification) =>
ui.addNotification(null, notification),
);
lastValues = newValues; lastValues = newValues;
} catch (e) { } catch (e) {
console.error('Error in onchange handler:', e); console.error('Error in onchange handler:', e);
@@ -293,7 +416,13 @@ function createConfigSection(section) {
} }
}; };
o = s.taboption('basic', form.ListValue, 'user_domain_list_type', _('User Domain List Type'), _('Select how to add your custom domains')); o = s.taboption(
'basic',
form.ListValue,
'user_domain_list_type',
_('User Domain List Type'),
_('Select how to add your custom domains'),
);
o.value('disabled', _('Disabled')); o.value('disabled', _('Disabled'));
o.value('dynamic', _('Dynamic List')); o.value('dynamic', _('Dynamic List'));
o.value('text', _('Text List')); o.value('text', _('Text List'));
@@ -301,7 +430,15 @@ function createConfigSection(section) {
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.DynamicList, 'user_domains', _('User Domains'), _('Enter domain names without protocols (example: sub.example.com or example.com)')); o = s.taboption(
'basic',
form.DynamicList,
'user_domains',
_('User Domains'),
_(
'Enter domain names without protocols (example: sub.example.com or example.com)',
),
);
o.placeholder = 'Domains list'; o.placeholder = 'Domains list';
o.depends('user_domain_list_type', 'dynamic'); o.depends('user_domain_list_type', 'dynamic');
o.rmempty = false; o.rmempty = false;
@@ -309,7 +446,7 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validateDomain(value); const validation = main.validateDomain(value);
@@ -318,11 +455,20 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.TextValue, 'user_domains_text', _('User Domains List'), _('Enter domain names separated by comma, space or newline. You can add comments after //')); o = s.taboption(
o.placeholder = 'example.com, sub.example.com\n// Social networks\ndomain.com test.com // personal domains'; 'basic',
form.TextValue,
'user_domains_text',
_('User Domains List'),
_(
'Enter domain names separated by comma, space or newline. You can add comments after //',
),
);
o.placeholder =
'example.com, sub.example.com\n// Social networks\ndomain.com test.com // personal domains';
o.depends('user_domain_list_type', 'text'); o.depends('user_domain_list_type', 'text');
o.rows = 8; o.rows = 8;
o.rmempty = false; o.rmempty = false;
@@ -330,14 +476,14 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const domains = main.parseValueList(value); const domains = main.parseValueList(value);
if (!domains.length) { if (!domains.length) {
return _( return _(
'At least one valid domain must be specified. Comments-only content is not allowed.' 'At least one valid domain must be specified. Comments-only content is not allowed.',
); );
} }
@@ -345,8 +491,8 @@ function createConfigSection(section) {
if (!valid) { if (!valid) {
const errors = results const errors = results
.filter(validation => !validation.valid) // Leave only failed validations .filter((validation) => !validation.valid) // Leave only failed validations
.map((validation) => _(`${validation.value}: ${validation.message}`)) // Collect validation errors .map((validation) => _(`${validation.value}: ${validation.message}`)); // Collect validation errors
return [_('Validation errors:'), ...errors].join('\n'); return [_('Validation errors:'), ...errors].join('\n');
} }
@@ -354,12 +500,24 @@ function createConfigSection(section) {
return true; return true;
}; };
o = s.taboption('basic', form.Flag, 'local_domain_lists_enabled', _('Local Domain Lists'), _('Use the list from the router filesystem')); o = s.taboption(
'basic',
form.Flag,
'local_domain_lists_enabled',
_('Local Domain Lists'),
_('Use the list from the router filesystem'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.DynamicList, 'local_domain_lists', _('Local Domain List Paths'), _('Enter the list file path')); o = s.taboption(
'basic',
form.DynamicList,
'local_domain_lists',
_('Local Domain List Paths'),
_('Enter the list file path'),
);
o.placeholder = '/path/file.lst'; o.placeholder = '/path/file.lst';
o.depends('local_domain_lists_enabled', '1'); o.depends('local_domain_lists_enabled', '1');
o.rmempty = false; o.rmempty = false;
@@ -367,7 +525,7 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validatePath(value); const validation = main.validatePath(value);
@@ -376,15 +534,27 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.Flag, 'remote_domain_lists_enabled', _('Remote Domain Lists'), _('Download and use domain lists from remote URLs')); o = s.taboption(
'basic',
form.Flag,
'remote_domain_lists_enabled',
_('Remote Domain Lists'),
_('Download and use domain lists from remote URLs'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.DynamicList, 'remote_domain_lists', _('Remote Domain URLs'), _('Enter full URLs starting with http:// or https://')); o = s.taboption(
'basic',
form.DynamicList,
'remote_domain_lists',
_('Remote Domain URLs'),
_('Enter full URLs starting with http:// or https://'),
);
o.placeholder = 'URL'; o.placeholder = 'URL';
o.depends('remote_domain_lists_enabled', '1'); o.depends('remote_domain_lists_enabled', '1');
o.rmempty = false; o.rmempty = false;
@@ -392,7 +562,7 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validateUrl(value); const validation = main.validateUrl(value);
@@ -401,15 +571,27 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.Flag, 'local_subnet_lists_enabled', _('Local Subnet Lists'), _('Use the list from the router filesystem')); o = s.taboption(
'basic',
form.Flag,
'local_subnet_lists_enabled',
_('Local Subnet Lists'),
_('Use the list from the router filesystem'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.DynamicList, 'local_subnet_lists', _('Local Subnet List Paths'), _('Enter the list file path')); o = s.taboption(
'basic',
form.DynamicList,
'local_subnet_lists',
_('Local Subnet List Paths'),
_('Enter the list file path'),
);
o.placeholder = '/path/file.lst'; o.placeholder = '/path/file.lst';
o.depends('local_subnet_lists_enabled', '1'); o.depends('local_subnet_lists_enabled', '1');
o.rmempty = false; o.rmempty = false;
@@ -417,7 +599,7 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validatePath(value); const validation = main.validatePath(value);
@@ -426,10 +608,16 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.ListValue, 'user_subnet_list_type', _('User Subnet List Type'), _('Select how to add your custom subnets')); o = s.taboption(
'basic',
form.ListValue,
'user_subnet_list_type',
_('User Subnet List Type'),
_('Select how to add your custom subnets'),
);
o.value('disabled', _('Disabled')); o.value('disabled', _('Disabled'));
o.value('dynamic', _('Dynamic List')); o.value('dynamic', _('Dynamic List'));
o.value('text', _('Text List (comma/space/newline separated)')); o.value('text', _('Text List (comma/space/newline separated)'));
@@ -437,7 +625,15 @@ function createConfigSection(section) {
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.DynamicList, 'user_subnets', _('User Subnets'), _('Enter subnets in CIDR notation (example: 103.21.244.0/22) or single IP addresses')); o = s.taboption(
'basic',
form.DynamicList,
'user_subnets',
_('User Subnets'),
_(
'Enter subnets in CIDR notation (example: 103.21.244.0/22) or single IP addresses',
),
);
o.placeholder = 'IP or subnet'; o.placeholder = 'IP or subnet';
o.depends('user_subnet_list_type', 'dynamic'); o.depends('user_subnet_list_type', 'dynamic');
o.rmempty = false; o.rmempty = false;
@@ -445,7 +641,7 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validateSubnet(value); const validation = main.validateSubnet(value);
@@ -454,11 +650,20 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.TextValue, 'user_subnets_text', _('User Subnets List'), _('Enter subnets in CIDR notation or single IP addresses, separated by comma, space or newline. You can add comments after //')); o = s.taboption(
o.placeholder = '103.21.244.0/22\n// Google DNS\n8.8.8.8\n1.1.1.1/32, 9.9.9.9 // Cloudflare and Quad9'; 'basic',
form.TextValue,
'user_subnets_text',
_('User Subnets List'),
_(
'Enter subnets in CIDR notation or single IP addresses, separated by comma, space or newline. You can add comments after //',
),
);
o.placeholder =
'103.21.244.0/22\n// Google DNS\n8.8.8.8\n1.1.1.1/32, 9.9.9.9 // Cloudflare and Quad9';
o.depends('user_subnet_list_type', 'text'); o.depends('user_subnet_list_type', 'text');
o.rows = 10; o.rows = 10;
o.rmempty = false; o.rmempty = false;
@@ -466,14 +671,14 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const subnets = main.parseValueList(value); const subnets = main.parseValueList(value);
if (!subnets.length) { if (!subnets.length) {
return _( return _(
'At least one valid subnet or IP must be specified. Comments-only content is not allowed.' 'At least one valid subnet or IP must be specified. Comments-only content is not allowed.',
); );
} }
@@ -481,8 +686,8 @@ function createConfigSection(section) {
if (!valid) { if (!valid) {
const errors = results const errors = results
.filter(validation => !validation.valid) // Leave only failed validations .filter((validation) => !validation.valid) // Leave only failed validations
.map((validation) => _(`${validation.value}: ${validation.message}`)) // Collect validation errors .map((validation) => _(`${validation.value}: ${validation.message}`)); // Collect validation errors
return [_('Validation errors:'), ...errors].join('\n'); return [_('Validation errors:'), ...errors].join('\n');
} }
@@ -490,12 +695,24 @@ function createConfigSection(section) {
return true; return true;
}; };
o = s.taboption('basic', form.Flag, 'remote_subnet_lists_enabled', _('Remote Subnet Lists'), _('Download and use subnet lists from remote URLs')); o = s.taboption(
'basic',
form.Flag,
'remote_subnet_lists_enabled',
_('Remote Subnet Lists'),
_('Download and use subnet lists from remote URLs'),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.DynamicList, 'remote_subnet_lists', _('Remote Subnet URLs'), _('Enter full URLs starting with http:// or https://')); o = s.taboption(
'basic',
form.DynamicList,
'remote_subnet_lists',
_('Remote Subnet URLs'),
_('Enter full URLs starting with http:// or https://'),
);
o.placeholder = 'URL'; o.placeholder = 'URL';
o.depends('remote_subnet_lists_enabled', '1'); o.depends('remote_subnet_lists_enabled', '1');
o.rmempty = false; o.rmempty = false;
@@ -503,7 +720,7 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validateUrl(value); const validation = main.validateUrl(value);
@@ -512,15 +729,29 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
o = s.taboption('basic', form.Flag, 'all_traffic_from_ip_enabled', _('IP for full redirection'), _('Specify local IP addresses whose traffic will always use the configured route')); o = s.taboption(
'basic',
form.Flag,
'all_traffic_from_ip_enabled',
_('IP for full redirection'),
_(
'Specify local IP addresses whose traffic will always use the configured route',
),
);
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
o.ucisection = s.section; o.ucisection = s.section;
o = s.taboption('basic', form.DynamicList, 'all_traffic_ip', _('Local IPs'), _('Enter valid IPv4 addresses')); o = s.taboption(
'basic',
form.DynamicList,
'all_traffic_ip',
_('Local IPs'),
_('Enter valid IPv4 addresses'),
);
o.placeholder = 'IP'; o.placeholder = 'IP';
o.depends('all_traffic_from_ip_enabled', '1'); o.depends('all_traffic_from_ip_enabled', '1');
o.rmempty = false; o.rmempty = false;
@@ -528,7 +759,7 @@ function createConfigSection(section) {
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
return true return true;
} }
const validation = main.validateIPV4(value); const validation = main.validateIPV4(value);
@@ -537,10 +768,10 @@ function createConfigSection(section) {
return true; return true;
} }
return _(validation.message) return _(validation.message);
}; };
} }
return baseclass.extend({ return baseclass.extend({
createConfigSection createConfigSection,
}); });

View File

@@ -15,14 +15,12 @@ let errorPollTimer = null;
// Helper function to fetch errors from the podkop command // Helper function to fetch errors from the podkop command
async function getPodkopErrors() { async function getPodkopErrors() {
return new Promise(resolve => { return new Promise((resolve) => {
safeExec('/usr/bin/podkop', ['check_logs'], 'P0_PRIORITY', result => { safeExec('/usr/bin/podkop', ['check_logs'], 'P0_PRIORITY', (result) => {
if (!result || !result.stdout) return resolve([]); if (!result || !result.stdout) return resolve([]);
const logs = result.stdout.split('\n'); const logs = result.stdout.split('\n');
const errors = logs.filter(log => const errors = logs.filter((log) => log.includes('[critical]'));
log.includes('[critical]')
);
resolve(errors); resolve(errors);
}); });
@@ -31,20 +29,29 @@ async function getPodkopErrors() {
// Show error notification to the user // Show error notification to the user
function showErrorNotification(error, isMultiple = false) { function showErrorNotification(error, isMultiple = false) {
const notificationContent = E('div', { 'class': 'alert-message error' }, [ const notificationContent = E('div', { class: 'alert-message error' }, [
E('pre', { 'class': 'error-log' }, error) E('pre', { class: 'error-log' }, error),
]); ]);
ui.addNotification(null, notificationContent); ui.addNotification(null, notificationContent);
} }
// Helper function for command execution with prioritization // Helper function for command execution with prioritization
function safeExec(command, args, priority, callback, timeout = main.COMMAND_TIMEOUT) { function safeExec(
command,
args,
priority,
callback,
timeout = main.COMMAND_TIMEOUT,
) {
// Default to highest priority execution if priority is not provided or invalid // Default to highest priority execution if priority is not provided or invalid
let schedulingDelay = main.COMMAND_SCHEDULING.P0_PRIORITY; let schedulingDelay = main.COMMAND_SCHEDULING.P0_PRIORITY;
// If priority is a string, try to get the corresponding delay value // If priority is a string, try to get the corresponding delay value
if (typeof priority === 'string' && main.COMMAND_SCHEDULING[priority] !== undefined) { if (
typeof priority === 'string' &&
main.COMMAND_SCHEDULING[priority] !== undefined
) {
schedulingDelay = main.COMMAND_SCHEDULING[priority]; schedulingDelay = main.COMMAND_SCHEDULING[priority];
} }
@@ -59,7 +66,7 @@ function safeExec(command, args, priority, callback, timeout = main.COMMAND_TIME
controller.signal.addEventListener('abort', () => { controller.signal.addEventListener('abort', () => {
reject(new Error('Command execution timed out')); reject(new Error('Command execution timed out'));
}); });
}) }),
]); ]);
clearTimeout(timeoutId); clearTimeout(timeoutId);
@@ -70,7 +77,9 @@ function safeExec(command, args, priority, callback, timeout = main.COMMAND_TIME
return result; return result;
} catch (error) { } catch (error) {
console.warn(`Command execution failed or timed out: ${command} ${args.join(' ')}`); console.warn(
`Command execution failed or timed out: ${command} ${args.join(' ')}`,
);
const errorResult = { stdout: '', stderr: error.message, error: error }; const errorResult = { stdout: '', stderr: error.message, error: error };
if (callback && typeof callback === 'function') { if (callback && typeof callback === 'function') {
@@ -84,8 +93,7 @@ function safeExec(command, args, priority, callback, timeout = main.COMMAND_TIME
if (callback && typeof callback === 'function') { if (callback && typeof callback === 'function') {
setTimeout(executeCommand, schedulingDelay); setTimeout(executeCommand, schedulingDelay);
return; return;
} } else {
else {
return executeCommand(); return executeCommand();
} }
} }
@@ -97,19 +105,19 @@ async function checkForCriticalErrors() {
if (errors && errors.length > 0) { if (errors && errors.length > 0) {
// Filter out errors we've already seen // Filter out errors we've already seen
const newErrors = errors.filter(error => !lastErrorsSet.has(error)); const newErrors = errors.filter((error) => !lastErrorsSet.has(error));
if (newErrors.length > 0) { if (newErrors.length > 0) {
// On initial check, just store errors without showing notifications // On initial check, just store errors without showing notifications
if (!isInitialCheck) { if (!isInitialCheck) {
// Show each new error as a notification // Show each new error as a notification
newErrors.forEach(error => { newErrors.forEach((error) => {
showErrorNotification(error, newErrors.length > 1); showErrorNotification(error, newErrors.length > 1);
}); });
} }
// Add new errors to our set of seen errors // Add new errors to our set of seen errors
newErrors.forEach(error => lastErrorsSet.add(error)); newErrors.forEach((error) => lastErrorsSet.add(error));
} }
} }
@@ -133,7 +141,10 @@ function startErrorPolling() {
checkForCriticalErrors(); checkForCriticalErrors();
// Then set up periodic checks // Then set up periodic checks
errorPollTimer = setInterval(checkForCriticalErrors, main.ERROR_POLL_INTERVAL); errorPollTimer = setInterval(
checkForCriticalErrors,
main.ERROR_POLL_INTERVAL,
);
} }
// Stop polling for errors // Stop polling for errors
@@ -148,5 +159,5 @@ return baseclass.extend({
startErrorPolling, startErrorPolling,
stopErrorPolling, stopErrorPolling,
checkForCriticalErrors, checkForCriticalErrors,
safeExec safeExec,
}); });