fix: dashboard test button layout, outbounds latency fix, and WDTT/OlcRTC component update cards
This commit is contained in:
@@ -7,6 +7,8 @@ export function renderLoaderCircleIcon24() {
|
|||||||
{
|
{
|
||||||
xmlns: NS,
|
xmlns: NS,
|
||||||
viewBox: '0 0 24 24',
|
viewBox: '0 0 24 24',
|
||||||
|
width: '24',
|
||||||
|
height: '24',
|
||||||
fill: 'none',
|
fill: 'none',
|
||||||
stroke: 'currentColor',
|
stroke: 'currentColor',
|
||||||
'stroke-width': '2',
|
'stroke-width': '2',
|
||||||
|
|||||||
@@ -1815,7 +1815,8 @@ async function renderSectionsWidget() {
|
|||||||
type: 'button',
|
type: 'button',
|
||||||
id: 'dashboard-test-all-sections-button',
|
id: 'dashboard-test-all-sections-button',
|
||||||
class: 'btn',
|
class: 'btn',
|
||||||
style: 'padding: 4px 14px; height: 32px; font-size: 13px;',
|
style:
|
||||||
|
'display: inline-flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap; padding: 4px 14px; height: 32px; font-size: 13px;',
|
||||||
disabled: isTestingAllSections ? true : undefined,
|
disabled: isTestingAllSections ? true : undefined,
|
||||||
click: () => {
|
click: () => {
|
||||||
void handleTestAllSections();
|
void handleTestAllSections();
|
||||||
@@ -1824,11 +1825,7 @@ async function renderSectionsWidget() {
|
|||||||
isTestingAllSections
|
isTestingAllSections
|
||||||
? [
|
? [
|
||||||
renderLoaderCircleIcon24(),
|
renderLoaderCircleIcon24(),
|
||||||
E(
|
E('span', {}, _('Testing all sections...')),
|
||||||
'span',
|
|
||||||
{ style: 'margin-left: 6px;' },
|
|
||||||
_('Testing all sections...'),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
: E('span', {}, _('Test all sections')),
|
: E('span', {}, _('Test all sections')),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -189,6 +189,27 @@ export const styles = `
|
|||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#dashboard-test-all-sections-button {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dashboard-test-all-sections-button svg {
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
display: block;
|
||||||
|
flex: 0 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dashboard-test-all-sections-button[disabled] {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.65;
|
||||||
|
}
|
||||||
|
|
||||||
.tachyon_dashboard-page__outbound-grid {
|
.tachyon_dashboard-page__outbound-grid {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -77,13 +77,27 @@ export async function runSectionsCheck() {
|
|||||||
section.latencyTestTimeout,
|
section.latencyTestTimeout,
|
||||||
);
|
);
|
||||||
const proxySuccess =
|
const proxySuccess =
|
||||||
latencyProxy.success && !latencyProxy.data.message;
|
latencyProxy.success && !latencyProxy.data?.message;
|
||||||
|
|
||||||
if (proxySuccess) {
|
if (proxySuccess) {
|
||||||
return {
|
const delay = latencyProxy.data?.delay;
|
||||||
state: 'success',
|
if (typeof delay === 'number') {
|
||||||
latency: `[${selectedOutbound.displayName ?? ''}] ${latencyProxy.data.delay}ms`,
|
return {
|
||||||
};
|
state: 'success',
|
||||||
|
latency: `[${selectedOutbound.displayName ?? ''}] ${delay}ms`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const groupDelays = Object.values(latencyProxy.data || {}).filter(
|
||||||
|
(v): v is number => typeof v === 'number' && v > 0,
|
||||||
|
);
|
||||||
|
if (groupDelays.length > 0) {
|
||||||
|
const minDelay = Math.min(...groupDelays);
|
||||||
|
return {
|
||||||
|
state: 'success',
|
||||||
|
latency: `[${selectedOutbound.displayName ?? ''}] ${minDelay}ms`,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -95,7 +109,7 @@ export async function runSectionsCheck() {
|
|||||||
const latencyGroup = await TachyonShellMethods.getClashApiGroupLatency(
|
const latencyGroup = await TachyonShellMethods.getClashApiGroupLatency(
|
||||||
section.code,
|
section.code,
|
||||||
);
|
);
|
||||||
const success = latencyGroup.success && !latencyGroup.data.message;
|
const success = latencyGroup.success && !latencyGroup.data?.message;
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
const latencyValues = Object.values(latencyGroup.data);
|
const latencyValues = Object.values(latencyGroup.data);
|
||||||
@@ -106,7 +120,7 @@ export async function runSectionsCheck() {
|
|||||||
const selectedProxyDelay =
|
const selectedProxyDelay =
|
||||||
latencyGroup.data?.[selectedOutbound?.code ?? ''];
|
latencyGroup.data?.[selectedOutbound?.code ?? ''];
|
||||||
|
|
||||||
if (selectedProxyDelay) {
|
if (typeof selectedProxyDelay === 'number') {
|
||||||
return {
|
return {
|
||||||
state: sectionState,
|
state: sectionState,
|
||||||
latency: `[${selectedOutbound?.displayName ?? ''}] ${selectedProxyDelay}ms`,
|
latency: `[${selectedOutbound?.displayName ?? ''}] ${selectedProxyDelay}ms`,
|
||||||
@@ -169,13 +183,26 @@ export async function runSectionsCheck() {
|
|||||||
section.latencyTestTimeout,
|
section.latencyTestTimeout,
|
||||||
);
|
);
|
||||||
|
|
||||||
const success = latencyProxy.success && !latencyProxy.data.message;
|
const success = latencyProxy.success && !latencyProxy.data?.message;
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
return {
|
const delay = latencyProxy.data?.delay;
|
||||||
state: 'success',
|
if (typeof delay === 'number') {
|
||||||
latency: `${latencyProxy.data.delay} ms`,
|
return {
|
||||||
};
|
state: 'success',
|
||||||
|
latency: `${delay} ms`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const groupDelays = Object.values(latencyProxy.data || {}).filter(
|
||||||
|
(v): v is number => typeof v === 'number' && v > 0,
|
||||||
|
);
|
||||||
|
if (groupDelays.length > 0) {
|
||||||
|
return {
|
||||||
|
state: 'success',
|
||||||
|
latency: `${Math.min(...groupDelays)} ms`,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section.action === 'vpn' && selectedOutbound?.runtimeAvailable) {
|
if (section.action === 'vpn' && selectedOutbound?.runtimeAvailable) {
|
||||||
|
|||||||
@@ -198,4 +198,90 @@ describe('runSectionsCheck', () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('extracts minimum delay from group latency map response without delay field', async () => {
|
||||||
|
mocks.getDashboardSections.mockResolvedValue({
|
||||||
|
success: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
withTagSelect: true,
|
||||||
|
code: 'main-out',
|
||||||
|
sectionName: 'main',
|
||||||
|
displayName: 'Main',
|
||||||
|
outbounds: [
|
||||||
|
{
|
||||||
|
code: 'main-softportal-out',
|
||||||
|
displayName: 'SoftPortal',
|
||||||
|
latency: 0,
|
||||||
|
type: 'URLTest',
|
||||||
|
selected: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
mocks.getClashApiProxyLatency.mockResolvedValue({
|
||||||
|
success: true,
|
||||||
|
data: { 'node-1': 140, 'node-2': 45 },
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(runSectionsCheck()).resolves.toBeUndefined();
|
||||||
|
|
||||||
|
expect(mocks.updateCheckStore).toHaveBeenLastCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
state: 'success',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
state: 'success',
|
||||||
|
key: 'Main',
|
||||||
|
value: '[SoftPortal] 45ms',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns Not responding instead of undefinedms when latency response has no valid delay', async () => {
|
||||||
|
mocks.getDashboardSections.mockResolvedValue({
|
||||||
|
success: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
withTagSelect: true,
|
||||||
|
code: 'main-out',
|
||||||
|
sectionName: 'main',
|
||||||
|
displayName: 'Main',
|
||||||
|
outbounds: [
|
||||||
|
{
|
||||||
|
code: 'main-softportal-out',
|
||||||
|
displayName: 'SoftPortal',
|
||||||
|
latency: 0,
|
||||||
|
type: 'URLTest',
|
||||||
|
selected: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
mocks.getClashApiProxyLatency.mockResolvedValue({
|
||||||
|
success: true,
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(runSectionsCheck()).rejects.toThrow(
|
||||||
|
'Rule outbounds checks failed',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mocks.updateCheckStore).toHaveBeenLastCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
state: 'error',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
state: 'error',
|
||||||
|
key: 'Main',
|
||||||
|
value: '[SoftPortal] Not responding',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -213,6 +213,8 @@ export const initialDiagnosticStore: Pick<
|
|||||||
zapret: { status: null, latest_version: '', release_url: '' },
|
zapret: { status: null, latest_version: '', release_url: '' },
|
||||||
zapret2: { status: null, latest_version: '', release_url: '' },
|
zapret2: { status: null, latest_version: '', release_url: '' },
|
||||||
byedpi: { status: null, latest_version: '', release_url: '' },
|
byedpi: { status: null, latest_version: '', release_url: '' },
|
||||||
|
wdtt: { status: null, latest_version: '', release_url: '' },
|
||||||
|
olcrtc: { status: null, latest_version: '', release_url: '' },
|
||||||
tailscale: { status: null, latest_version: '', release_url: '' },
|
tailscale: { status: null, latest_version: '', release_url: '' },
|
||||||
direct_bypass: { status: null, latest_version: '', release_url: '' },
|
direct_bypass: { status: null, latest_version: '', release_url: '' },
|
||||||
torrserver_direct: { status: null, latest_version: '', release_url: '' },
|
torrserver_direct: { status: null, latest_version: '', release_url: '' },
|
||||||
|
|||||||
@@ -70,6 +70,10 @@ function getComponentCardTitle(component: Tachyon.ComponentName): string {
|
|||||||
return 'Zapret2';
|
return 'Zapret2';
|
||||||
case 'byedpi':
|
case 'byedpi':
|
||||||
return 'ByeDPI';
|
return 'ByeDPI';
|
||||||
|
case 'wdtt':
|
||||||
|
return 'WDTT';
|
||||||
|
case 'olcrtc':
|
||||||
|
return 'OlcRTC';
|
||||||
case 'tailscale':
|
case 'tailscale':
|
||||||
return 'Tailscale';
|
return 'Tailscale';
|
||||||
default:
|
default:
|
||||||
@@ -92,6 +96,10 @@ function getComponentCurrentVersion(
|
|||||||
return sys.zapret2_version;
|
return sys.zapret2_version;
|
||||||
case 'byedpi':
|
case 'byedpi':
|
||||||
return sys.byedpi_version;
|
return sys.byedpi_version;
|
||||||
|
case 'wdtt':
|
||||||
|
return sys.wdtt_version;
|
||||||
|
case 'olcrtc':
|
||||||
|
return sys.olcrtc_version;
|
||||||
case 'tailscale':
|
case 'tailscale':
|
||||||
return sys.tailscale_version;
|
return sys.tailscale_version;
|
||||||
default:
|
default:
|
||||||
@@ -396,6 +404,8 @@ function notifyActionProvidersAvailabilityChanged(
|
|||||||
zapretInstalled: Boolean(systemInfo.zapret_installed),
|
zapretInstalled: Boolean(systemInfo.zapret_installed),
|
||||||
zapret2Installed: Boolean(systemInfo.zapret2_installed),
|
zapret2Installed: Boolean(systemInfo.zapret2_installed),
|
||||||
byedpiInstalled: Boolean(systemInfo.byedpi_installed),
|
byedpiInstalled: Boolean(systemInfo.byedpi_installed),
|
||||||
|
wdttInstalled: Boolean(systemInfo.wdtt_installed),
|
||||||
|
olcrtcInstalled: Boolean(systemInfo.olcrtc_installed),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -527,6 +537,30 @@ function patchSystemInfoAfterMutation(result: Tachyon.ComponentActionResult) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.component === 'wdtt') {
|
||||||
|
nextSystemInfo.providerInfoLoaded = true;
|
||||||
|
|
||||||
|
if (result.action === 'remove') {
|
||||||
|
nextSystemInfo.wdtt_installed = 0;
|
||||||
|
nextSystemInfo.wdtt_version = 'not installed';
|
||||||
|
} else {
|
||||||
|
nextSystemInfo.wdtt_installed = 1;
|
||||||
|
nextSystemInfo.wdtt_version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.component === 'olcrtc') {
|
||||||
|
nextSystemInfo.providerInfoLoaded = true;
|
||||||
|
|
||||||
|
if (result.action === 'remove') {
|
||||||
|
nextSystemInfo.olcrtc_installed = 0;
|
||||||
|
nextSystemInfo.olcrtc_version = 'not installed';
|
||||||
|
} else {
|
||||||
|
nextSystemInfo.olcrtc_installed = 1;
|
||||||
|
nextSystemInfo.olcrtc_version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (result.component === 'direct_bypass') {
|
if (result.component === 'direct_bypass') {
|
||||||
nextSystemInfo.direct_bypass_enabled = result.action === 'enable' ? 1 : 0;
|
nextSystemInfo.direct_bypass_enabled = result.action === 'enable' ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -546,7 +580,9 @@ function patchSystemInfoAfterMutation(result: Tachyon.ComponentActionResult) {
|
|||||||
if (
|
if (
|
||||||
result.component === 'zapret' ||
|
result.component === 'zapret' ||
|
||||||
result.component === 'zapret2' ||
|
result.component === 'zapret2' ||
|
||||||
result.component === 'byedpi'
|
result.component === 'byedpi' ||
|
||||||
|
result.component === 'wdtt' ||
|
||||||
|
result.component === 'olcrtc'
|
||||||
) {
|
) {
|
||||||
notifyActionProvidersAvailabilityChanged(normalizedSystemInfo);
|
notifyActionProvidersAvailabilityChanged(normalizedSystemInfo);
|
||||||
}
|
}
|
||||||
@@ -1043,6 +1079,10 @@ function getComponentInstallKey(
|
|||||||
return 'zapret2Install';
|
return 'zapret2Install';
|
||||||
case 'byedpi':
|
case 'byedpi':
|
||||||
return 'byedpiInstall';
|
return 'byedpiInstall';
|
||||||
|
case 'wdtt':
|
||||||
|
return 'wdttInstall';
|
||||||
|
case 'olcrtc':
|
||||||
|
return 'olcrtcInstall';
|
||||||
case 'tailscale':
|
case 'tailscale':
|
||||||
return 'tailscaleInstall';
|
return 'tailscaleInstall';
|
||||||
default:
|
default:
|
||||||
@@ -1086,6 +1126,10 @@ function getComponentBackupVersion(component: Tachyon.ComponentName): string {
|
|||||||
return sys.zapret2_backup_version || '';
|
return sys.zapret2_backup_version || '';
|
||||||
case 'byedpi':
|
case 'byedpi':
|
||||||
return sys.byedpi_backup_version || '';
|
return sys.byedpi_backup_version || '';
|
||||||
|
case 'wdtt':
|
||||||
|
return sys.wdtt_backup_version || '';
|
||||||
|
case 'olcrtc':
|
||||||
|
return sys.olcrtc_backup_version || '';
|
||||||
case 'tailscale':
|
case 'tailscale':
|
||||||
return sys.tailscale_backup_version || '';
|
return sys.tailscale_backup_version || '';
|
||||||
default:
|
default:
|
||||||
@@ -1115,7 +1159,7 @@ function getOptionalComponentActions({
|
|||||||
removeKey,
|
removeKey,
|
||||||
rollbackKey,
|
rollbackKey,
|
||||||
}: {
|
}: {
|
||||||
component: 'zapret' | 'zapret2' | 'byedpi' | 'tailscale';
|
component: 'zapret' | 'zapret2' | 'byedpi' | 'wdtt' | 'olcrtc' | 'tailscale';
|
||||||
installed: boolean;
|
installed: boolean;
|
||||||
checkKey: UpdatesActionKey;
|
checkKey: UpdatesActionKey;
|
||||||
installKey: UpdatesActionKey;
|
installKey: UpdatesActionKey;
|
||||||
@@ -1151,6 +1195,8 @@ const COMPONENT_REPO_URLS: Record<Tachyon.ComponentName, string> = {
|
|||||||
zapret: 'https://github.com/remittor/zapret-openwrt',
|
zapret: 'https://github.com/remittor/zapret-openwrt',
|
||||||
zapret2: 'https://github.com/Dushnilin/zapret2-openwrt',
|
zapret2: 'https://github.com/Dushnilin/zapret2-openwrt',
|
||||||
byedpi: 'https://github.com/DPITrickster/ByeDPI-OpenWrt',
|
byedpi: 'https://github.com/DPITrickster/ByeDPI-OpenWrt',
|
||||||
|
wdtt: 'https://github.com/SpaceNeuroX/qwdtt-openwrt',
|
||||||
|
olcrtc: 'https://github.com/alekvol/openwrt-olcrtc',
|
||||||
tailscale: 'https://openwrt.org/packages/pkgdata/tailscale',
|
tailscale: 'https://openwrt.org/packages/pkgdata/tailscale',
|
||||||
direct_bypass: '',
|
direct_bypass: '',
|
||||||
torrserver_direct: '',
|
torrserver_direct: '',
|
||||||
@@ -1164,6 +1210,8 @@ function getComponentCards(): ComponentCard[] {
|
|||||||
const zapretInstalled = Boolean(systemInfo.zapret_installed);
|
const zapretInstalled = Boolean(systemInfo.zapret_installed);
|
||||||
const zapret2Installed = Boolean(systemInfo.zapret2_installed);
|
const zapret2Installed = Boolean(systemInfo.zapret2_installed);
|
||||||
const byedpiInstalled = Boolean(systemInfo.byedpi_installed);
|
const byedpiInstalled = Boolean(systemInfo.byedpi_installed);
|
||||||
|
const wdttInstalled = Boolean(systemInfo.wdtt_installed);
|
||||||
|
const olcrtcInstalled = Boolean(systemInfo.olcrtc_installed);
|
||||||
const tailscaleInstalled = Boolean(systemInfo.tailscale_installed);
|
const tailscaleInstalled = Boolean(systemInfo.tailscale_installed);
|
||||||
const singBoxInstalled = !isNotInstalled(systemInfo.sing_box_version);
|
const singBoxInstalled = !isNotInstalled(systemInfo.sing_box_version);
|
||||||
const singBoxStable =
|
const singBoxStable =
|
||||||
@@ -1275,6 +1323,22 @@ function getComponentCards(): ComponentCard[] {
|
|||||||
removeKey: 'byedpiRemove',
|
removeKey: 'byedpiRemove',
|
||||||
rollbackKey: 'byedpiRollback',
|
rollbackKey: 'byedpiRollback',
|
||||||
});
|
});
|
||||||
|
const wdttActions = getOptionalComponentActions({
|
||||||
|
component: 'wdtt',
|
||||||
|
installed: wdttInstalled,
|
||||||
|
checkKey: 'wdttCheck',
|
||||||
|
installKey: 'wdttInstall',
|
||||||
|
removeKey: 'wdttRemove',
|
||||||
|
rollbackKey: 'wdttRollback',
|
||||||
|
});
|
||||||
|
const olcrtcActions = getOptionalComponentActions({
|
||||||
|
component: 'olcrtc',
|
||||||
|
installed: olcrtcInstalled,
|
||||||
|
checkKey: 'olcrtcCheck',
|
||||||
|
installKey: 'olcrtcInstall',
|
||||||
|
removeKey: 'olcrtcRemove',
|
||||||
|
rollbackKey: 'olcrtcRollback',
|
||||||
|
});
|
||||||
const tailscaleActions = getOptionalComponentActions({
|
const tailscaleActions = getOptionalComponentActions({
|
||||||
component: 'tailscale',
|
component: 'tailscale',
|
||||||
installed: tailscaleInstalled,
|
installed: tailscaleInstalled,
|
||||||
@@ -1443,6 +1507,36 @@ function getComponentCards(): ComponentCard[] {
|
|||||||
repoUrl: COMPONENT_REPO_URLS.byedpi,
|
repoUrl: COMPONENT_REPO_URLS.byedpi,
|
||||||
actions: byedpiActions,
|
actions: byedpiActions,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: 'wdtt',
|
||||||
|
column: 1,
|
||||||
|
title: 'WDTT',
|
||||||
|
version: systemInfoLoading
|
||||||
|
? _('Loading...')
|
||||||
|
: wdttInstalled
|
||||||
|
? systemInfo.wdtt_version
|
||||||
|
: _('Not installed'),
|
||||||
|
latestVersion: getLatestVersion('wdtt'),
|
||||||
|
releaseUrl: getGitHubReleaseUrl('wdtt'),
|
||||||
|
repoUrl: COMPONENT_REPO_URLS.wdtt,
|
||||||
|
actions: wdttActions,
|
||||||
|
supportsVersions: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'olcrtc',
|
||||||
|
column: 1,
|
||||||
|
title: 'OlcRTC',
|
||||||
|
version: systemInfoLoading
|
||||||
|
? _('Loading...')
|
||||||
|
: olcrtcInstalled
|
||||||
|
? systemInfo.olcrtc_version
|
||||||
|
: _('Not installed'),
|
||||||
|
latestVersion: getLatestVersion('olcrtc'),
|
||||||
|
releaseUrl: getGitHubReleaseUrl('olcrtc'),
|
||||||
|
repoUrl: COMPONENT_REPO_URLS.olcrtc,
|
||||||
|
actions: olcrtcActions,
|
||||||
|
supportsVersions: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: 'tailscale',
|
component: 'tailscale',
|
||||||
column: 1,
|
column: 1,
|
||||||
|
|||||||
@@ -738,6 +738,8 @@ export namespace Tachyon {
|
|||||||
| 'zapret'
|
| 'zapret'
|
||||||
| 'zapret2'
|
| 'zapret2'
|
||||||
| 'byedpi'
|
| 'byedpi'
|
||||||
|
| 'wdtt'
|
||||||
|
| 'olcrtc'
|
||||||
| 'tailscale'
|
| 'tailscale'
|
||||||
| 'direct_bypass'
|
| 'direct_bypass'
|
||||||
| 'torrserver_direct';
|
| 'torrserver_direct';
|
||||||
|
|||||||
@@ -1489,6 +1489,8 @@ function renderLoaderCircleIcon24() {
|
|||||||
{
|
{
|
||||||
xmlns: NS,
|
xmlns: NS,
|
||||||
viewBox: "0 0 24 24",
|
viewBox: "0 0 24 24",
|
||||||
|
width: "24",
|
||||||
|
height: "24",
|
||||||
fill: "none",
|
fill: "none",
|
||||||
stroke: "currentColor",
|
stroke: "currentColor",
|
||||||
"stroke-width": "2",
|
"stroke-width": "2",
|
||||||
@@ -6413,6 +6415,8 @@ var initialDiagnosticStore = {
|
|||||||
zapret: { status: null, latest_version: "", release_url: "" },
|
zapret: { status: null, latest_version: "", release_url: "" },
|
||||||
zapret2: { status: null, latest_version: "", release_url: "" },
|
zapret2: { status: null, latest_version: "", release_url: "" },
|
||||||
byedpi: { status: null, latest_version: "", release_url: "" },
|
byedpi: { status: null, latest_version: "", release_url: "" },
|
||||||
|
wdtt: { status: null, latest_version: "", release_url: "" },
|
||||||
|
olcrtc: { status: null, latest_version: "", release_url: "" },
|
||||||
tailscale: { status: null, latest_version: "", release_url: "" },
|
tailscale: { status: null, latest_version: "", release_url: "" },
|
||||||
direct_bypass: { status: null, latest_version: "", release_url: "" },
|
direct_bypass: { status: null, latest_version: "", release_url: "" },
|
||||||
torrserver_direct: { status: null, latest_version: "", release_url: "" }
|
torrserver_direct: { status: null, latest_version: "", release_url: "" }
|
||||||
@@ -9131,7 +9135,7 @@ async function renderSectionsWidget() {
|
|||||||
type: "button",
|
type: "button",
|
||||||
id: "dashboard-test-all-sections-button",
|
id: "dashboard-test-all-sections-button",
|
||||||
class: "btn",
|
class: "btn",
|
||||||
style: "padding: 4px 14px; height: 32px; font-size: 13px;",
|
style: "display: inline-flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap; padding: 4px 14px; height: 32px; font-size: 13px;",
|
||||||
disabled: isTestingAllSections ? true : void 0,
|
disabled: isTestingAllSections ? true : void 0,
|
||||||
click: () => {
|
click: () => {
|
||||||
void handleTestAllSections();
|
void handleTestAllSections();
|
||||||
@@ -9139,11 +9143,7 @@ async function renderSectionsWidget() {
|
|||||||
},
|
},
|
||||||
isTestingAllSections ? [
|
isTestingAllSections ? [
|
||||||
renderLoaderCircleIcon24(),
|
renderLoaderCircleIcon24(),
|
||||||
E(
|
E("span", {}, _("Testing all sections..."))
|
||||||
"span",
|
|
||||||
{ style: "margin-left: 6px;" },
|
|
||||||
_("Testing all sections...")
|
|
||||||
)
|
|
||||||
] : E("span", {}, _("Test all sections"))
|
] : E("span", {}, _("Test all sections"))
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@@ -9777,6 +9777,27 @@ var styles = `
|
|||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#dashboard-test-all-sections-button {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dashboard-test-all-sections-button svg {
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
display: block;
|
||||||
|
flex: 0 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dashboard-test-all-sections-button[disabled] {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.65;
|
||||||
|
}
|
||||||
|
|
||||||
.tachyon_dashboard-page__outbound-grid {
|
.tachyon_dashboard-page__outbound-grid {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -15605,12 +15626,25 @@ async function runSectionsCheck() {
|
|||||||
selectedOutbound2.code,
|
selectedOutbound2.code,
|
||||||
section.latencyTestTimeout
|
section.latencyTestTimeout
|
||||||
);
|
);
|
||||||
const proxySuccess = latencyProxy2.success && !latencyProxy2.data.message;
|
const proxySuccess = latencyProxy2.success && !latencyProxy2.data?.message;
|
||||||
if (proxySuccess) {
|
if (proxySuccess) {
|
||||||
return {
|
const delay = latencyProxy2.data?.delay;
|
||||||
state: "success",
|
if (typeof delay === "number") {
|
||||||
latency: `[${selectedOutbound2.displayName ?? ""}] ${latencyProxy2.data.delay}ms`
|
return {
|
||||||
};
|
state: "success",
|
||||||
|
latency: `[${selectedOutbound2.displayName ?? ""}] ${delay}ms`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const groupDelays = Object.values(latencyProxy2.data || {}).filter(
|
||||||
|
(v) => typeof v === "number" && v > 0
|
||||||
|
);
|
||||||
|
if (groupDelays.length > 0) {
|
||||||
|
const minDelay = Math.min(...groupDelays);
|
||||||
|
return {
|
||||||
|
state: "success",
|
||||||
|
latency: `[${selectedOutbound2.displayName ?? ""}] ${minDelay}ms`
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
state: "error",
|
state: "error",
|
||||||
@@ -15620,12 +15654,12 @@ async function runSectionsCheck() {
|
|||||||
const latencyGroup = await TachyonShellMethods.getClashApiGroupLatency(
|
const latencyGroup = await TachyonShellMethods.getClashApiGroupLatency(
|
||||||
section.code
|
section.code
|
||||||
);
|
);
|
||||||
const success2 = latencyGroup.success && !latencyGroup.data.message;
|
const success2 = latencyGroup.success && !latencyGroup.data?.message;
|
||||||
if (success2) {
|
if (success2) {
|
||||||
const latencyValues = Object.values(latencyGroup.data);
|
const latencyValues = Object.values(latencyGroup.data);
|
||||||
const sectionState = isSubscription ? getSubscriptionLatencyState(latencyValues) : "success";
|
const sectionState = isSubscription ? getSubscriptionLatencyState(latencyValues) : "success";
|
||||||
const selectedProxyDelay = latencyGroup.data?.[selectedOutbound2?.code ?? ""];
|
const selectedProxyDelay = latencyGroup.data?.[selectedOutbound2?.code ?? ""];
|
||||||
if (selectedProxyDelay) {
|
if (typeof selectedProxyDelay === "number") {
|
||||||
return {
|
return {
|
||||||
state: sectionState,
|
state: sectionState,
|
||||||
latency: `[${selectedOutbound2?.displayName ?? ""}] ${selectedProxyDelay}ms`
|
latency: `[${selectedOutbound2?.displayName ?? ""}] ${selectedProxyDelay}ms`
|
||||||
@@ -15678,12 +15712,24 @@ async function runSectionsCheck() {
|
|||||||
section.code,
|
section.code,
|
||||||
section.latencyTestTimeout
|
section.latencyTestTimeout
|
||||||
);
|
);
|
||||||
const success = latencyProxy.success && !latencyProxy.data.message;
|
const success = latencyProxy.success && !latencyProxy.data?.message;
|
||||||
if (success) {
|
if (success) {
|
||||||
return {
|
const delay = latencyProxy.data?.delay;
|
||||||
state: "success",
|
if (typeof delay === "number") {
|
||||||
latency: `${latencyProxy.data.delay} ms`
|
return {
|
||||||
};
|
state: "success",
|
||||||
|
latency: `${delay} ms`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const groupDelays = Object.values(latencyProxy.data || {}).filter(
|
||||||
|
(v) => typeof v === "number" && v > 0
|
||||||
|
);
|
||||||
|
if (groupDelays.length > 0) {
|
||||||
|
return {
|
||||||
|
state: "success",
|
||||||
|
latency: `${Math.min(...groupDelays)} ms`
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (section.action === "vpn" && selectedOutbound?.runtimeAvailable) {
|
if (section.action === "vpn" && selectedOutbound?.runtimeAvailable) {
|
||||||
return {
|
return {
|
||||||
@@ -20697,6 +20743,10 @@ function getComponentCardTitle(component) {
|
|||||||
return "Zapret2";
|
return "Zapret2";
|
||||||
case "byedpi":
|
case "byedpi":
|
||||||
return "ByeDPI";
|
return "ByeDPI";
|
||||||
|
case "wdtt":
|
||||||
|
return "WDTT";
|
||||||
|
case "olcrtc":
|
||||||
|
return "OlcRTC";
|
||||||
case "tailscale":
|
case "tailscale":
|
||||||
return "Tailscale";
|
return "Tailscale";
|
||||||
default:
|
default:
|
||||||
@@ -20716,6 +20766,10 @@ function getComponentCurrentVersion(component) {
|
|||||||
return sys.zapret2_version;
|
return sys.zapret2_version;
|
||||||
case "byedpi":
|
case "byedpi":
|
||||||
return sys.byedpi_version;
|
return sys.byedpi_version;
|
||||||
|
case "wdtt":
|
||||||
|
return sys.wdtt_version;
|
||||||
|
case "olcrtc":
|
||||||
|
return sys.olcrtc_version;
|
||||||
case "tailscale":
|
case "tailscale":
|
||||||
return sys.tailscale_version;
|
return sys.tailscale_version;
|
||||||
default:
|
default:
|
||||||
@@ -20908,7 +20962,9 @@ function notifyActionProvidersAvailabilityChanged(systemInfo) {
|
|||||||
detail: {
|
detail: {
|
||||||
zapretInstalled: Boolean(systemInfo.zapret_installed),
|
zapretInstalled: Boolean(systemInfo.zapret_installed),
|
||||||
zapret2Installed: Boolean(systemInfo.zapret2_installed),
|
zapret2Installed: Boolean(systemInfo.zapret2_installed),
|
||||||
byedpiInstalled: Boolean(systemInfo.byedpi_installed)
|
byedpiInstalled: Boolean(systemInfo.byedpi_installed),
|
||||||
|
wdttInstalled: Boolean(systemInfo.wdtt_installed),
|
||||||
|
olcrtcInstalled: Boolean(systemInfo.olcrtc_installed)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -21014,6 +21070,26 @@ function patchSystemInfoAfterMutation(result) {
|
|||||||
nextSystemInfo.byedpi_version = version;
|
nextSystemInfo.byedpi_version = version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result.component === "wdtt") {
|
||||||
|
nextSystemInfo.providerInfoLoaded = true;
|
||||||
|
if (result.action === "remove") {
|
||||||
|
nextSystemInfo.wdtt_installed = 0;
|
||||||
|
nextSystemInfo.wdtt_version = "not installed";
|
||||||
|
} else {
|
||||||
|
nextSystemInfo.wdtt_installed = 1;
|
||||||
|
nextSystemInfo.wdtt_version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result.component === "olcrtc") {
|
||||||
|
nextSystemInfo.providerInfoLoaded = true;
|
||||||
|
if (result.action === "remove") {
|
||||||
|
nextSystemInfo.olcrtc_installed = 0;
|
||||||
|
nextSystemInfo.olcrtc_version = "not installed";
|
||||||
|
} else {
|
||||||
|
nextSystemInfo.olcrtc_installed = 1;
|
||||||
|
nextSystemInfo.olcrtc_version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (result.component === "direct_bypass") {
|
if (result.component === "direct_bypass") {
|
||||||
nextSystemInfo.direct_bypass_enabled = result.action === "enable" ? 1 : 0;
|
nextSystemInfo.direct_bypass_enabled = result.action === "enable" ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -21025,7 +21101,7 @@ function patchSystemInfoAfterMutation(result) {
|
|||||||
store.set({
|
store.set({
|
||||||
diagnosticsSystemInfo: normalizedSystemInfo
|
diagnosticsSystemInfo: normalizedSystemInfo
|
||||||
});
|
});
|
||||||
if (result.component === "zapret" || result.component === "zapret2" || result.component === "byedpi") {
|
if (result.component === "zapret" || result.component === "zapret2" || result.component === "byedpi" || result.component === "wdtt" || result.component === "olcrtc") {
|
||||||
notifyActionProvidersAvailabilityChanged(normalizedSystemInfo);
|
notifyActionProvidersAvailabilityChanged(normalizedSystemInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21403,6 +21479,10 @@ function getComponentInstallKey(component) {
|
|||||||
return "zapret2Install";
|
return "zapret2Install";
|
||||||
case "byedpi":
|
case "byedpi":
|
||||||
return "byedpiInstall";
|
return "byedpiInstall";
|
||||||
|
case "wdtt":
|
||||||
|
return "wdttInstall";
|
||||||
|
case "olcrtc":
|
||||||
|
return "olcrtcInstall";
|
||||||
case "tailscale":
|
case "tailscale":
|
||||||
return "tailscaleInstall";
|
return "tailscaleInstall";
|
||||||
default:
|
default:
|
||||||
@@ -21435,6 +21515,10 @@ function getComponentBackupVersion(component) {
|
|||||||
return sys.zapret2_backup_version || "";
|
return sys.zapret2_backup_version || "";
|
||||||
case "byedpi":
|
case "byedpi":
|
||||||
return sys.byedpi_backup_version || "";
|
return sys.byedpi_backup_version || "";
|
||||||
|
case "wdtt":
|
||||||
|
return sys.wdtt_backup_version || "";
|
||||||
|
case "olcrtc":
|
||||||
|
return sys.olcrtc_backup_version || "";
|
||||||
case "tailscale":
|
case "tailscale":
|
||||||
return sys.tailscale_backup_version || "";
|
return sys.tailscale_backup_version || "";
|
||||||
default:
|
default:
|
||||||
@@ -21483,6 +21567,8 @@ var COMPONENT_REPO_URLS = {
|
|||||||
zapret: "https://github.com/remittor/zapret-openwrt",
|
zapret: "https://github.com/remittor/zapret-openwrt",
|
||||||
zapret2: "https://github.com/Dushnilin/zapret2-openwrt",
|
zapret2: "https://github.com/Dushnilin/zapret2-openwrt",
|
||||||
byedpi: "https://github.com/DPITrickster/ByeDPI-OpenWrt",
|
byedpi: "https://github.com/DPITrickster/ByeDPI-OpenWrt",
|
||||||
|
wdtt: "https://github.com/SpaceNeuroX/qwdtt-openwrt",
|
||||||
|
olcrtc: "https://github.com/alekvol/openwrt-olcrtc",
|
||||||
tailscale: "https://openwrt.org/packages/pkgdata/tailscale",
|
tailscale: "https://openwrt.org/packages/pkgdata/tailscale",
|
||||||
direct_bypass: "",
|
direct_bypass: "",
|
||||||
torrserver_direct: ""
|
torrserver_direct: ""
|
||||||
@@ -21495,6 +21581,8 @@ function getComponentCards() {
|
|||||||
const zapretInstalled = Boolean(systemInfo.zapret_installed);
|
const zapretInstalled = Boolean(systemInfo.zapret_installed);
|
||||||
const zapret2Installed = Boolean(systemInfo.zapret2_installed);
|
const zapret2Installed = Boolean(systemInfo.zapret2_installed);
|
||||||
const byedpiInstalled = Boolean(systemInfo.byedpi_installed);
|
const byedpiInstalled = Boolean(systemInfo.byedpi_installed);
|
||||||
|
const wdttInstalled = Boolean(systemInfo.wdtt_installed);
|
||||||
|
const olcrtcInstalled = Boolean(systemInfo.olcrtc_installed);
|
||||||
const tailscaleInstalled = Boolean(systemInfo.tailscale_installed);
|
const tailscaleInstalled = Boolean(systemInfo.tailscale_installed);
|
||||||
const singBoxInstalled = !isNotInstalled(systemInfo.sing_box_version);
|
const singBoxInstalled = !isNotInstalled(systemInfo.sing_box_version);
|
||||||
const singBoxStable = singBoxInstalled && !systemInfo.sing_box_extended && !systemInfo.sing_box_tiny;
|
const singBoxStable = singBoxInstalled && !systemInfo.sing_box_extended && !systemInfo.sing_box_tiny;
|
||||||
@@ -21593,6 +21681,22 @@ function getComponentCards() {
|
|||||||
removeKey: "byedpiRemove",
|
removeKey: "byedpiRemove",
|
||||||
rollbackKey: "byedpiRollback"
|
rollbackKey: "byedpiRollback"
|
||||||
});
|
});
|
||||||
|
const wdttActions = getOptionalComponentActions({
|
||||||
|
component: "wdtt",
|
||||||
|
installed: wdttInstalled,
|
||||||
|
checkKey: "wdttCheck",
|
||||||
|
installKey: "wdttInstall",
|
||||||
|
removeKey: "wdttRemove",
|
||||||
|
rollbackKey: "wdttRollback"
|
||||||
|
});
|
||||||
|
const olcrtcActions = getOptionalComponentActions({
|
||||||
|
component: "olcrtc",
|
||||||
|
installed: olcrtcInstalled,
|
||||||
|
checkKey: "olcrtcCheck",
|
||||||
|
installKey: "olcrtcInstall",
|
||||||
|
removeKey: "olcrtcRemove",
|
||||||
|
rollbackKey: "olcrtcRollback"
|
||||||
|
});
|
||||||
const tailscaleActions = getOptionalComponentActions({
|
const tailscaleActions = getOptionalComponentActions({
|
||||||
component: "tailscale",
|
component: "tailscale",
|
||||||
installed: tailscaleInstalled,
|
installed: tailscaleInstalled,
|
||||||
@@ -21714,6 +21818,28 @@ function getComponentCards() {
|
|||||||
repoUrl: COMPONENT_REPO_URLS.byedpi,
|
repoUrl: COMPONENT_REPO_URLS.byedpi,
|
||||||
actions: byedpiActions
|
actions: byedpiActions
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: "wdtt",
|
||||||
|
column: 1,
|
||||||
|
title: "WDTT",
|
||||||
|
version: systemInfoLoading ? _("Loading...") : wdttInstalled ? systemInfo.wdtt_version : _("Not installed"),
|
||||||
|
latestVersion: getLatestVersion("wdtt"),
|
||||||
|
releaseUrl: getGitHubReleaseUrl("wdtt"),
|
||||||
|
repoUrl: COMPONENT_REPO_URLS.wdtt,
|
||||||
|
actions: wdttActions,
|
||||||
|
supportsVersions: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: "olcrtc",
|
||||||
|
column: 1,
|
||||||
|
title: "OlcRTC",
|
||||||
|
version: systemInfoLoading ? _("Loading...") : olcrtcInstalled ? systemInfo.olcrtc_version : _("Not installed"),
|
||||||
|
latestVersion: getLatestVersion("olcrtc"),
|
||||||
|
releaseUrl: getGitHubReleaseUrl("olcrtc"),
|
||||||
|
repoUrl: COMPONENT_REPO_URLS.olcrtc,
|
||||||
|
actions: olcrtcActions,
|
||||||
|
supportsVersions: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: "tailscale",
|
component: "tailscale",
|
||||||
column: 1,
|
column: 1,
|
||||||
|
|||||||
@@ -1353,8 +1353,8 @@ function resolve_wdtt_release(arch, tag) {
|
|||||||
let asset_ext = is_apk() ? "apk" : "ipk";
|
let asset_ext = is_apk() ? "apk" : "ipk";
|
||||||
let release_series = trim(helper_output("openwrt-release-series", [ "/etc/openwrt_release" ]));
|
let release_series = trim(helper_output("openwrt-release-series", [ "/etc/openwrt_release" ]));
|
||||||
let releases_json = (tag != null && tag != "") ?
|
let releases_json = (tag != null && tag != "") ?
|
||||||
fetch_github_release_by_tag_json("ret_dev", "wdtt", tag) :
|
fetch_github_release_by_tag_json("SpaceNeuroX", "qwdtt-openwrt", tag) :
|
||||||
fetch_github_releases_json("ret_dev", "wdtt", "30");
|
fetch_github_releases_json("SpaceNeuroX", "qwdtt-openwrt", "30");
|
||||||
if (releases_json != "") {
|
if (releases_json != "") {
|
||||||
let resolved = trim(helper_output_input(releases_json, "wdtt-select-asset", [ release_series, asset_ext, arch.candidates ]));
|
let resolved = trim(helper_output_input(releases_json, "wdtt-select-asset", [ release_series, asset_ext, arch.candidates ]));
|
||||||
let fields = split(resolved, "\t");
|
let fields = split(resolved, "\t");
|
||||||
@@ -1375,8 +1375,8 @@ function resolve_wdtt_release(arch, tag) {
|
|||||||
return {
|
return {
|
||||||
arch: distrib_arch,
|
arch: distrib_arch,
|
||||||
package_name: pkg_name,
|
package_name: pkg_name,
|
||||||
package_url: "https://github.com/ret_dev/wdtt/releases/download/" + tag + "/" + pkg_name,
|
package_url: "https://github.com/SpaceNeuroX/qwdtt-openwrt/releases/download/" + tag + "/" + pkg_name,
|
||||||
release_url: "https://github.com/ret_dev/wdtt/releases/tag/" + tag,
|
release_url: "https://github.com/SpaceNeuroX/qwdtt-openwrt/releases/tag/" + tag,
|
||||||
version: tag
|
version: tag
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1387,8 +1387,8 @@ function resolve_olcrtc_release(arch, tag) {
|
|||||||
let asset_ext = is_apk() ? "apk" : "ipk";
|
let asset_ext = is_apk() ? "apk" : "ipk";
|
||||||
let release_series = trim(helper_output("openwrt-release-series", [ "/etc/openwrt_release" ]));
|
let release_series = trim(helper_output("openwrt-release-series", [ "/etc/openwrt_release" ]));
|
||||||
let releases_json = (tag != null && tag != "") ?
|
let releases_json = (tag != null && tag != "") ?
|
||||||
fetch_github_release_by_tag_json("ret_dev", "olcrtc", tag) :
|
fetch_github_release_by_tag_json("alekvol", "openwrt-olcrtc", tag) :
|
||||||
fetch_github_releases_json("ret_dev", "olcrtc", "30");
|
fetch_github_releases_json("alekvol", "openwrt-olcrtc", "30");
|
||||||
if (releases_json != "") {
|
if (releases_json != "") {
|
||||||
let resolved = trim(helper_output_input(releases_json, "olcrtc-select-asset", [ release_series, asset_ext, arch.candidates ]));
|
let resolved = trim(helper_output_input(releases_json, "olcrtc-select-asset", [ release_series, asset_ext, arch.candidates ]));
|
||||||
let fields = split(resolved, "\t");
|
let fields = split(resolved, "\t");
|
||||||
@@ -1409,8 +1409,8 @@ function resolve_olcrtc_release(arch, tag) {
|
|||||||
return {
|
return {
|
||||||
arch: distrib_arch,
|
arch: distrib_arch,
|
||||||
package_name: pkg_name,
|
package_name: pkg_name,
|
||||||
package_url: "https://github.com/ret_dev/olcrtc/releases/download/" + tag + "/" + pkg_name,
|
package_url: "https://github.com/alekvol/openwrt-olcrtc/releases/download/" + tag + "/" + pkg_name,
|
||||||
release_url: "https://github.com/ret_dev/olcrtc/releases/tag/" + tag,
|
release_url: "https://github.com/alekvol/openwrt-olcrtc/releases/tag/" + tag,
|
||||||
version: tag
|
version: tag
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -3358,6 +3358,10 @@ function list_component_releases(component, count) {
|
|||||||
owner = "Dushnilin"; repo = "zapret2-openwrt";
|
owner = "Dushnilin"; repo = "zapret2-openwrt";
|
||||||
} else if (component == "byedpi") {
|
} else if (component == "byedpi") {
|
||||||
owner = "DPITrickster"; repo = "ByeDPI-OpenWrt";
|
owner = "DPITrickster"; repo = "ByeDPI-OpenWrt";
|
||||||
|
} else if (component == "wdtt") {
|
||||||
|
owner = "SpaceNeuroX"; repo = "qwdtt-openwrt";
|
||||||
|
} else if (component == "olcrtc") {
|
||||||
|
owner = "alekvol"; repo = "openwrt-olcrtc";
|
||||||
} else {
|
} else {
|
||||||
print("[]\n"); return;
|
print("[]\n"); return;
|
||||||
}
|
}
|
||||||
@@ -3410,6 +3414,10 @@ function install_component_version(component, tag) {
|
|||||||
install_zapret2("install", tag);
|
install_zapret2("install", tag);
|
||||||
} else if (component == "byedpi") {
|
} else if (component == "byedpi") {
|
||||||
install_byedpi("install", tag);
|
install_byedpi("install", tag);
|
||||||
|
} else if (component == "wdtt") {
|
||||||
|
install_wdtt("install", tag);
|
||||||
|
} else if (component == "olcrtc") {
|
||||||
|
install_olcrtc("install", tag);
|
||||||
} else {
|
} else {
|
||||||
action_fail(component, "install_version", "Component " + component + " does not support version installation");
|
action_fail(component, "install_version", "Component " + component + " does not support version installation");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user