refactor: unify dynamic page structure

This commit is contained in:
divocat
2025-10-14 21:49:09 +03:00
parent 33dfb8c3f0
commit 67ec5f3090
22 changed files with 430 additions and 404 deletions

View File

@@ -1,2 +1,7 @@
export * from './renderDashboard';
export * from './initDashboardController';
import { render } from './render';
import { initController } from './initController';
export const DashboardTab = {
render,
initController,
};

View File

@@ -5,14 +5,13 @@ import {
preserveScrollForPage,
} from '../../../helpers';
import { prettyBytes } from '../../../helpers/prettyBytes';
import { renderSections } from './renderSections';
import { renderWidget } from './renderWidget';
import {
ClashMethods,
CustomPodkopMethods,
PodkopShellMethods,
} from '../../methods';
import { socket, store, StoreType } from '../../services';
import { renderSections, renderWidget } from './partials';
// Fetchers
@@ -420,7 +419,7 @@ async function onStoreUpdate(
}
}
export async function initDashboardController(): Promise<void> {
export async function initController(): Promise<void> {
onMount('dashboard-status').then(() => {
// Remove old listener
store.unsubscribe(onStoreUpdate);

View File

@@ -0,0 +1,2 @@
export * from './renderSections';
export * from './renderWidget';

View File

@@ -1,5 +1,5 @@
import { Podkop } from '../../types';
import { getClashApiUrl } from '../../../helpers';
import { Podkop } from '../../../types';
import { getClashApiUrl } from '../../../../helpers';
interface IRenderSectionsProps {
loading: boolean;

View File

@@ -1,7 +1,6 @@
import { renderSections } from './renderSections';
import { renderWidget } from './renderWidget';
import { renderSections, renderWidget } from './partials';
export function renderDashboard() {
export function render() {
return E(
'div',
{

View File

@@ -1,13 +1,13 @@
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
import { insertIf } from '../../../../helpers';
import { DIAGNOSTICS_CHECKS_MAP } from './contstants';
import { PodkopShellMethods } from '../../../methods';
import { IDiagnosticsChecksItem } from '../../../services';
import { updateCheckStore } from './updateCheckStore';
export async function runDnsCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.DNS;
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,
@@ -19,7 +19,7 @@ export async function runDnsCheck() {
const dnsChecks = await PodkopShellMethods.checkDNSAvailable();
if (!dnsChecks.success) {
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,
@@ -57,7 +57,7 @@ export async function runDnsCheck() {
return 'error';
}
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,

View File

@@ -1,13 +1,13 @@
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
import { insertIf } from '../../../../helpers';
import { DIAGNOSTICS_CHECKS_MAP } from './contstants';
import { PodkopShellMethods, RemoteFakeIPMethods } from '../../../methods';
import { IDiagnosticsChecksItem } from '../../../services';
import { updateCheckStore } from './updateCheckStore';
export async function runFakeIPCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.FAKEIP;
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,
@@ -68,7 +68,7 @@ export async function runFakeIPCheck() {
const { state, description } = getMeta();
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,

View File

@@ -1,11 +1,11 @@
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
import { DIAGNOSTICS_CHECKS_MAP } from './contstants';
import { RemoteFakeIPMethods, PodkopShellMethods } from '../../../methods';
import { updateCheckStore } from './updateCheckStore';
export async function runNftCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.NFT;
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,
@@ -20,7 +20,7 @@ export async function runNftCheck() {
const nftablesChecks = await PodkopShellMethods.checkNftRules();
if (!nftablesChecks.success) {
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,
@@ -68,7 +68,7 @@ export async function runNftCheck() {
return 'error';
}
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,

View File

@@ -1,11 +1,11 @@
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
import { DIAGNOSTICS_CHECKS_MAP } from './contstants';
import { PodkopShellMethods } from '../../../methods';
import { updateCheckStore } from './updateCheckStore';
export async function runSingBoxCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.SINGBOX;
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,
@@ -17,7 +17,7 @@ export async function runSingBoxCheck() {
const singBoxChecks = await PodkopShellMethods.checkSingBox();
if (!singBoxChecks.success) {
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,
@@ -61,7 +61,7 @@ export async function runSingBoxCheck() {
return 'error';
}
updateDiagnosticsCheck({
updateCheckStore({
order,
code,
title,

View File

@@ -1,6 +1,6 @@
import { IDiagnosticsChecksStoreItem, store } from '../../services';
import { IDiagnosticsChecksStoreItem, store } from '../../../services';
export function updateDiagnosticsCheck(
export function updateCheckStore(
check: IDiagnosticsChecksStoreItem,
minified?: boolean,
) {

View File

@@ -1,2 +1,7 @@
export * from './renderDiagnostic';
export * from './initDiagnosticController';
import { render } from './renderDiagnostic';
import { initController } from './initController';
export const DiagnosticTab = {
render,
initController,
};

View File

@@ -1,14 +1,16 @@
import { onMount, preserveScrollForPage } from '../../../helpers';
import { renderCheckSection } from './renderCheckSection';
import { runDnsCheck } from './checks/runDnsCheck';
import { runSingBoxCheck } from './checks/runSingBoxCheck';
import { runNftCheck } from './checks/runNftCheck';
import { runFakeIPCheck } from './checks/runFakeIPCheck';
import { renderDiagnosticRunAction } from './renderDiagnosticRunAction';
import { renderAvailableActions } from './renderAvailableActions';
import { renderSystemInfo } from './renderSystemInfo';
import { loadingDiagnosticsChecksStore } from './diagnostic.store';
import { store, StoreType } from '../../services';
import {
renderAvailableActions,
renderCheckSection,
renderRunAction,
renderSystemInfo,
} from './partials';
function renderDiagnosticsChecks() {
console.log('renderDiagnosticsChecks');
@@ -32,7 +34,7 @@ function renderDiagnosticRunActionWidget() {
const { loading } = store.get().diagnosticsRunAction;
const container = document.getElementById('pdk_diagnostic-page-run-check');
const renderedAction = renderDiagnosticRunAction({
const renderedAction = renderRunAction({
loading,
click: () => runChecks(),
});
@@ -124,7 +126,7 @@ async function runChecks() {
}
}
export async function initDiagnosticController(): Promise<void> {
export async function initController(): Promise<void> {
onMount('diagnostic-status').then(() => {
console.log('diagnostic controller initialized.');
// Remove old listener

View File

@@ -0,0 +1,4 @@
export * from './renderAvailableActions';
export * from './renderCheckSection';
export * from './renderRunAction';
export * from './renderSystemInfo';

View File

@@ -7,8 +7,8 @@ import {
renderLoaderCircleIcon24,
renderTriangleAlertIcon24,
renderXIcon24,
} from '../../../icons';
import { IDiagnosticsChecksStoreItem } from '../../services';
} from '../../../../icons';
import { IDiagnosticsChecksStoreItem } from '../../../services';
type IRenderCheckSectionProps = IDiagnosticsChecksStoreItem;

View File

@@ -3,7 +3,7 @@ interface IRenderDiagnosticRunActionProps {
click: () => void;
}
export function renderDiagnosticRunAction({
export function renderRunAction({
loading,
click,
}: IRenderDiagnosticRunActionProps) {

View File

@@ -1,4 +1,4 @@
export function renderDiagnostic() {
export function render() {
return E('div', { id: 'diagnostic-status', class: 'pdk_diagnostic-page' }, [
E('div', { class: 'pdk_diagnostic-page__left-bar' }, [
E('div', { id: 'pdk_diagnostic-page-run-check' }),

View File

@@ -10,8 +10,8 @@ function createDashboardContent(section) {
const o = section.option(form.DummyValue, '_mount_node');
o.rawhtml = true;
o.cfgvalue = () => {
main.initDashboardController();
return main.renderDashboard();
main.DashboardTab.initController();
return main.DashboardTab.render();
};
}

View File

@@ -10,8 +10,8 @@ function createDiagnosticContent(section) {
const o = section.option(form.DummyValue, '_mount_node');
o.rawhtml = true;
o.cfgvalue = () => {
main.initDiagnosticController();
return main.renderDiagnostic();
main.DiagnosticTab.initController();
return main.DiagnosticTab.render();
};
}

View File

@@ -1716,7 +1716,7 @@ var SocketManager = class _SocketManager {
};
var socket = SocketManager.getInstance();
// src/podkop/tabs/dashboard/renderSections.ts
// src/podkop/tabs/dashboard/partials/renderSections.ts
function renderFailedState() {
return E(
"div",
@@ -1823,7 +1823,7 @@ function renderSections(props) {
return renderDefaultState(props);
}
// src/podkop/tabs/dashboard/renderWidget.ts
// src/podkop/tabs/dashboard/partials/renderWidget.ts
function renderFailedState2() {
return E(
"div",
@@ -1885,8 +1885,8 @@ function renderWidget(props) {
return renderDefaultState2(props);
}
// src/podkop/tabs/dashboard/renderDashboard.ts
function renderDashboard() {
// src/podkop/tabs/dashboard/render.ts
function render() {
return E(
"div",
{
@@ -1953,7 +1953,7 @@ function prettyBytes(n) {
return n + " " + unit;
}
// src/podkop/tabs/dashboard/initDashboardController.ts
// src/podkop/tabs/dashboard/initController.ts
async function fetchDashboardSections() {
const prev = store.get().sectionsWidget;
store.set({
@@ -2290,7 +2290,7 @@ async function onStoreUpdate(next, prev, diff) {
renderServicesInfoWidget();
}
}
async function initDashboardController() {
async function initController() {
onMount("dashboard-status").then(() => {
store.unsubscribe(onStoreUpdate);
store.reset([
@@ -2307,8 +2307,14 @@ async function initDashboardController() {
});
}
// src/podkop/tabs/dashboard/index.ts
var DashboardTab = {
render,
initController
};
// src/podkop/tabs/diagnostic/renderDiagnostic.ts
function renderDiagnostic() {
function render2() {
return E("div", { id: "diagnostic-status", class: "pdk_diagnostic-page" }, [
E("div", { class: "pdk_diagnostic-page__left-bar" }, [
E("div", { id: "pdk_diagnostic-page-run-check" }),
@@ -2324,6 +2330,349 @@ function renderDiagnostic() {
]);
}
// src/podkop/tabs/diagnostic/checks/updateCheckStore.ts
function updateCheckStore(check, minified) {
const diagnosticsChecks = store.get().diagnosticsChecks;
const other = diagnosticsChecks.filter((item) => item.code !== check.code);
const smallCheck = {
...check,
items: check.items.filter((item) => item.state !== "success")
};
const targetCheck = minified ? smallCheck : check;
store.set({
diagnosticsChecks: [...other, targetCheck]
});
}
// src/podkop/tabs/diagnostic/checks/runDnsCheck.ts
async function runDnsCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.DNS;
updateCheckStore({
order,
code,
title,
description: _("Checking dns, please wait"),
state: "loading",
items: []
});
const dnsChecks = await PodkopShellMethods.checkDNSAvailable();
if (!dnsChecks.success) {
updateCheckStore({
order,
code,
title,
description: _("Cannot receive DNS checks result"),
state: "error",
items: []
});
throw new Error("DNS checks failed");
}
const data = dnsChecks.data;
const allGood = Boolean(data.local_dns_status) && Boolean(data.bootstrap_dns_status) && Boolean(data.dns_status);
const atLeastOneGood = Boolean(data.local_dns_status) || Boolean(data.bootstrap_dns_status) || Boolean(data.dns_status);
console.log("dnsChecks", dnsChecks);
function getStatus() {
if (allGood) {
return "success";
}
if (atLeastOneGood) {
return "warning";
}
return "error";
}
updateCheckStore({
order,
code,
title,
description: _("DNS checks passed"),
state: getStatus(),
items: [
...insertIf(
data.dns_type === "doh" || data.dns_type === "dot",
[
{
state: data.bootstrap_dns_status ? "success" : "error",
key: _("Bootsrap DNS"),
value: data.bootstrap_dns_server
}
]
),
{
state: data.dns_status ? "success" : "error",
key: _("Main DNS"),
value: `${data.dns_server} [${data.dns_type}]`
},
{
state: data.local_dns_status ? "success" : "error",
key: _("Local DNS"),
value: ""
}
]
});
if (!atLeastOneGood) {
throw new Error("DNS checks failed");
}
}
// src/podkop/tabs/diagnostic/checks/runSingBoxCheck.ts
async function runSingBoxCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.SINGBOX;
updateCheckStore({
order,
code,
title,
description: _("Checking sing-box, please wait"),
state: "loading",
items: []
});
const singBoxChecks = await PodkopShellMethods.checkSingBox();
if (!singBoxChecks.success) {
updateCheckStore({
order,
code,
title,
description: _("Cannot receive Sing-box checks result"),
state: "error",
items: []
});
throw new Error("Sing-box checks failed");
}
const data = singBoxChecks.data;
const allGood = Boolean(data.sing_box_installed) && Boolean(data.sing_box_version_ok) && Boolean(data.sing_box_service_exist) && Boolean(data.sing_box_autostart_disabled) && Boolean(data.sing_box_process_running) && Boolean(data.sing_box_ports_listening);
const atLeastOneGood = Boolean(data.sing_box_installed) || Boolean(data.sing_box_version_ok) || Boolean(data.sing_box_service_exist) || Boolean(data.sing_box_autostart_disabled) || Boolean(data.sing_box_process_running) || Boolean(data.sing_box_ports_listening);
console.log("singBoxChecks", singBoxChecks);
function getStatus() {
if (allGood) {
return "success";
}
if (atLeastOneGood) {
return "warning";
}
return "error";
}
updateCheckStore({
order,
code,
title,
description: _("Sing-box checks passed"),
state: getStatus(),
items: [
{
state: data.sing_box_installed ? "success" : "error",
key: _("Sing-box installed"),
value: ""
},
{
state: data.sing_box_version_ok ? "success" : "error",
key: _("Sing-box version >= 1.12.4"),
value: ""
},
{
state: data.sing_box_service_exist ? "success" : "error",
key: _("Sing-box service exist"),
value: ""
},
{
state: data.sing_box_autostart_disabled ? "success" : "error",
key: _("Sing-box autostart disabled"),
value: ""
},
{
state: data.sing_box_process_running ? "success" : "error",
key: _("Sing-box process running"),
value: ""
},
{
state: data.sing_box_ports_listening ? "success" : "error",
key: _("Sing-box listening ports"),
value: ""
}
]
});
if (!atLeastOneGood) {
throw new Error("Sing-box checks failed");
}
}
// src/podkop/tabs/diagnostic/checks/runNftCheck.ts
async function runNftCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.NFT;
updateCheckStore({
order,
code,
title,
description: _("Checking nftables, please wait"),
state: "loading",
items: []
});
await RemoteFakeIPMethods.getFakeIpCheck();
await RemoteFakeIPMethods.getIpCheck();
const nftablesChecks = await PodkopShellMethods.checkNftRules();
if (!nftablesChecks.success) {
updateCheckStore({
order,
code,
title,
description: _("Cannot receive nftables checks result"),
state: "error",
items: []
});
throw new Error("Nftables checks failed");
}
const data = nftablesChecks.data;
const allGood = Boolean(data.table_exist) && Boolean(data.rules_mangle_exist) && Boolean(data.rules_mangle_counters) && Boolean(data.rules_mangle_output_exist) && Boolean(data.rules_mangle_output_counters) && Boolean(data.rules_proxy_exist) && Boolean(data.rules_proxy_counters) && Boolean(data.rules_other_mark_exist);
const atLeastOneGood = Boolean(data.table_exist) || Boolean(data.rules_mangle_exist) || Boolean(data.rules_mangle_counters) || Boolean(data.rules_mangle_output_exist) || Boolean(data.rules_mangle_output_counters) || Boolean(data.rules_proxy_exist) || Boolean(data.rules_proxy_counters) || Boolean(data.rules_other_mark_exist);
console.log("nftablesChecks", nftablesChecks);
function getStatus() {
if (allGood) {
return "success";
}
if (atLeastOneGood) {
return "warning";
}
return "error";
}
updateCheckStore({
order,
code,
title,
description: allGood ? _("Nftables checks passed") : _("Nftables checks partially passed"),
state: getStatus(),
items: [
{
state: data.table_exist ? "success" : "error",
key: _("Table exist"),
value: ""
},
{
state: data.rules_mangle_exist ? "success" : "error",
key: _("Rules mangle exist"),
value: ""
},
{
state: data.rules_mangle_counters ? "success" : "error",
key: _("Rules mangle counters"),
value: ""
},
{
state: data.rules_mangle_output_exist ? "success" : "error",
key: _("Rules mangle output exist"),
value: ""
},
{
state: data.rules_mangle_output_counters ? "success" : "error",
key: _("Rules mangle output counters"),
value: ""
},
{
state: data.rules_proxy_exist ? "success" : "error",
key: _("Rules proxy exist"),
value: ""
},
{
state: data.rules_proxy_counters ? "success" : "error",
key: _("Rules proxy counters"),
value: ""
},
{
state: !data.rules_other_mark_exist ? "success" : "warning",
key: !data.rules_other_mark_exist ? _("No other marking rules found") : _("Additional marking rules found"),
value: ""
}
]
});
if (!atLeastOneGood) {
throw new Error("Nftables checks failed");
}
}
// src/podkop/tabs/diagnostic/checks/runFakeIPCheck.ts
async function runFakeIPCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.FAKEIP;
updateCheckStore({
order,
code,
title,
description: _("Checking FakeIP, please wait"),
state: "loading",
items: []
});
const routerFakeIPResponse = await PodkopShellMethods.checkFakeIP();
const checkFakeIPResponse = await RemoteFakeIPMethods.getFakeIpCheck();
const checkIPResponse = await RemoteFakeIPMethods.getIpCheck();
console.log("runFakeIPCheck", {
routerFakeIPResponse,
checkFakeIPResponse,
checkIPResponse
});
const checks = {
router: routerFakeIPResponse.success && routerFakeIPResponse.data.fakeip,
browserFakeIP: checkFakeIPResponse.success && checkFakeIPResponse.data.fakeip,
differentIP: checkFakeIPResponse.success && checkIPResponse.success && checkFakeIPResponse.data.IP !== checkIPResponse.data.IP
};
console.log("checks", checks);
const allGood = checks.router || checks.browserFakeIP || checks.differentIP;
const atLeastOneGood = checks.router && checks.browserFakeIP && checks.differentIP;
function getMeta() {
if (allGood) {
return {
state: "success",
description: _("FakeIP checks passed")
};
}
if (atLeastOneGood) {
return {
state: "warning",
description: _("FakeIP checks partially passed")
};
}
return {
state: "error",
description: _("FakeIP checks failed")
};
}
const { state, description } = getMeta();
updateCheckStore({
order,
code,
title,
description,
state,
items: [
{
state: checks.router ? "success" : "warning",
key: checks.router ? _("Router DNS is routed through sing-box") : _("Router DNS is not routed through sing-box"),
value: ""
},
{
state: checks.browserFakeIP ? "success" : "error",
key: checks.browserFakeIP ? _("Browser is using FakeIP correctly") : _("Browser is not using FakeIP"),
value: ""
},
...insertIf(checks.browserFakeIP, [
{
state: checks.differentIP ? "success" : "error",
key: checks.differentIP ? _("Proxy traffic is routed via FakeIP") : _("Proxy traffic is not routed via FakeIP"),
value: ""
}
])
]
});
}
// src/podkop/tabs/diagnostic/partials/renderAvailableActions.ts
function renderAvailableActions() {
return E("div", { class: "pdk_diagnostic-page__right-bar__actions" }, [
E("b", {}, "Available actions"),
E("button", { class: "btn" }, "Restart podkop"),
E("button", { class: "btn" }, "Stop podkop"),
E("button", { class: "btn" }, "Disable podkop"),
E("button", { class: "btn" }, "Get global check"),
E("button", { class: "btn" }, "View logs"),
E("button", { class: "btn" }, "Show sing-box config")
]);
}
// src/icons/renderLoaderCircleIcon24.ts
function renderLoaderCircleIcon24() {
const NS = "http://www.w3.org/2000/svg";
@@ -2560,7 +2909,7 @@ function renderTriangleAlertIcon24() {
);
}
// src/podkop/tabs/diagnostic/renderCheckSection.ts
// src/podkop/tabs/diagnostic/partials/renderCheckSection.ts
function renderCheckSummary(items) {
if (!items.length) {
return E("div", {}, "");
@@ -2715,338 +3064,8 @@ function renderCheckSection(props) {
return E("div", {}, "Not implement yet");
}
// src/podkop/tabs/diagnostic/updateDiagnosticsCheck.ts
function updateDiagnosticsCheck(check, minified) {
const diagnosticsChecks = store.get().diagnosticsChecks;
const other = diagnosticsChecks.filter((item) => item.code !== check.code);
const smallCheck = {
...check,
items: check.items.filter((item) => item.state !== "success")
};
const targetCheck = minified ? smallCheck : check;
store.set({
diagnosticsChecks: [...other, targetCheck]
});
}
// src/podkop/tabs/diagnostic/checks/runDnsCheck.ts
async function runDnsCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.DNS;
updateDiagnosticsCheck({
order,
code,
title,
description: _("Checking dns, please wait"),
state: "loading",
items: []
});
const dnsChecks = await PodkopShellMethods.checkDNSAvailable();
if (!dnsChecks.success) {
updateDiagnosticsCheck({
order,
code,
title,
description: _("Cannot receive DNS checks result"),
state: "error",
items: []
});
throw new Error("DNS checks failed");
}
const data = dnsChecks.data;
const allGood = Boolean(data.local_dns_status) && Boolean(data.bootstrap_dns_status) && Boolean(data.dns_status);
const atLeastOneGood = Boolean(data.local_dns_status) || Boolean(data.bootstrap_dns_status) || Boolean(data.dns_status);
console.log("dnsChecks", dnsChecks);
function getStatus() {
if (allGood) {
return "success";
}
if (atLeastOneGood) {
return "warning";
}
return "error";
}
updateDiagnosticsCheck({
order,
code,
title,
description: _("DNS checks passed"),
state: getStatus(),
items: [
...insertIf(
data.dns_type === "doh" || data.dns_type === "dot",
[
{
state: data.bootstrap_dns_status ? "success" : "error",
key: _("Bootsrap DNS"),
value: data.bootstrap_dns_server
}
]
),
{
state: data.dns_status ? "success" : "error",
key: _("Main DNS"),
value: `${data.dns_server} [${data.dns_type}]`
},
{
state: data.local_dns_status ? "success" : "error",
key: _("Local DNS"),
value: ""
}
]
});
if (!atLeastOneGood) {
throw new Error("DNS checks failed");
}
}
// src/podkop/tabs/diagnostic/checks/runSingBoxCheck.ts
async function runSingBoxCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.SINGBOX;
updateDiagnosticsCheck({
order,
code,
title,
description: _("Checking sing-box, please wait"),
state: "loading",
items: []
});
const singBoxChecks = await PodkopShellMethods.checkSingBox();
if (!singBoxChecks.success) {
updateDiagnosticsCheck({
order,
code,
title,
description: _("Cannot receive Sing-box checks result"),
state: "error",
items: []
});
throw new Error("Sing-box checks failed");
}
const data = singBoxChecks.data;
const allGood = Boolean(data.sing_box_installed) && Boolean(data.sing_box_version_ok) && Boolean(data.sing_box_service_exist) && Boolean(data.sing_box_autostart_disabled) && Boolean(data.sing_box_process_running) && Boolean(data.sing_box_ports_listening);
const atLeastOneGood = Boolean(data.sing_box_installed) || Boolean(data.sing_box_version_ok) || Boolean(data.sing_box_service_exist) || Boolean(data.sing_box_autostart_disabled) || Boolean(data.sing_box_process_running) || Boolean(data.sing_box_ports_listening);
console.log("singBoxChecks", singBoxChecks);
function getStatus() {
if (allGood) {
return "success";
}
if (atLeastOneGood) {
return "warning";
}
return "error";
}
updateDiagnosticsCheck({
order,
code,
title,
description: _("Sing-box checks passed"),
state: getStatus(),
items: [
{
state: data.sing_box_installed ? "success" : "error",
key: _("Sing-box installed"),
value: ""
},
{
state: data.sing_box_version_ok ? "success" : "error",
key: _("Sing-box version >= 1.12.4"),
value: ""
},
{
state: data.sing_box_service_exist ? "success" : "error",
key: _("Sing-box service exist"),
value: ""
},
{
state: data.sing_box_autostart_disabled ? "success" : "error",
key: _("Sing-box autostart disabled"),
value: ""
},
{
state: data.sing_box_process_running ? "success" : "error",
key: _("Sing-box process running"),
value: ""
},
{
state: data.sing_box_ports_listening ? "success" : "error",
key: _("Sing-box listening ports"),
value: ""
}
]
});
if (!atLeastOneGood) {
throw new Error("Sing-box checks failed");
}
}
// src/podkop/tabs/diagnostic/checks/runNftCheck.ts
async function runNftCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.NFT;
updateDiagnosticsCheck({
order,
code,
title,
description: _("Checking nftables, please wait"),
state: "loading",
items: []
});
await RemoteFakeIPMethods.getFakeIpCheck();
await RemoteFakeIPMethods.getIpCheck();
const nftablesChecks = await PodkopShellMethods.checkNftRules();
if (!nftablesChecks.success) {
updateDiagnosticsCheck({
order,
code,
title,
description: _("Cannot receive nftables checks result"),
state: "error",
items: []
});
throw new Error("Nftables checks failed");
}
const data = nftablesChecks.data;
const allGood = Boolean(data.table_exist) && Boolean(data.rules_mangle_exist) && Boolean(data.rules_mangle_counters) && Boolean(data.rules_mangle_output_exist) && Boolean(data.rules_mangle_output_counters) && Boolean(data.rules_proxy_exist) && Boolean(data.rules_proxy_counters) && Boolean(data.rules_other_mark_exist);
const atLeastOneGood = Boolean(data.table_exist) || Boolean(data.rules_mangle_exist) || Boolean(data.rules_mangle_counters) || Boolean(data.rules_mangle_output_exist) || Boolean(data.rules_mangle_output_counters) || Boolean(data.rules_proxy_exist) || Boolean(data.rules_proxy_counters) || Boolean(data.rules_other_mark_exist);
console.log("nftablesChecks", nftablesChecks);
function getStatus() {
if (allGood) {
return "success";
}
if (atLeastOneGood) {
return "warning";
}
return "error";
}
updateDiagnosticsCheck({
order,
code,
title,
description: allGood ? _("Nftables checks passed") : _("Nftables checks partially passed"),
state: getStatus(),
items: [
{
state: data.table_exist ? "success" : "error",
key: _("Table exist"),
value: ""
},
{
state: data.rules_mangle_exist ? "success" : "error",
key: _("Rules mangle exist"),
value: ""
},
{
state: data.rules_mangle_counters ? "success" : "error",
key: _("Rules mangle counters"),
value: ""
},
{
state: data.rules_mangle_output_exist ? "success" : "error",
key: _("Rules mangle output exist"),
value: ""
},
{
state: data.rules_mangle_output_counters ? "success" : "error",
key: _("Rules mangle output counters"),
value: ""
},
{
state: data.rules_proxy_exist ? "success" : "error",
key: _("Rules proxy exist"),
value: ""
},
{
state: data.rules_proxy_counters ? "success" : "error",
key: _("Rules proxy counters"),
value: ""
},
{
state: !data.rules_other_mark_exist ? "success" : "warning",
key: !data.rules_other_mark_exist ? _("No other marking rules found") : _("Additional marking rules found"),
value: ""
}
]
});
if (!atLeastOneGood) {
throw new Error("Nftables checks failed");
}
}
// src/podkop/tabs/diagnostic/checks/runFakeIPCheck.ts
async function runFakeIPCheck() {
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.FAKEIP;
updateDiagnosticsCheck({
order,
code,
title,
description: _("Checking FakeIP, please wait"),
state: "loading",
items: []
});
const routerFakeIPResponse = await PodkopShellMethods.checkFakeIP();
const checkFakeIPResponse = await RemoteFakeIPMethods.getFakeIpCheck();
const checkIPResponse = await RemoteFakeIPMethods.getIpCheck();
console.log("runFakeIPCheck", {
routerFakeIPResponse,
checkFakeIPResponse,
checkIPResponse
});
const checks = {
router: routerFakeIPResponse.success && routerFakeIPResponse.data.fakeip,
browserFakeIP: checkFakeIPResponse.success && checkFakeIPResponse.data.fakeip,
differentIP: checkFakeIPResponse.success && checkIPResponse.success && checkFakeIPResponse.data.IP !== checkIPResponse.data.IP
};
console.log("checks", checks);
const allGood = checks.router || checks.browserFakeIP || checks.differentIP;
const atLeastOneGood = checks.router && checks.browserFakeIP && checks.differentIP;
function getMeta() {
if (allGood) {
return {
state: "success",
description: _("FakeIP checks passed")
};
}
if (atLeastOneGood) {
return {
state: "warning",
description: _("FakeIP checks partially passed")
};
}
return {
state: "error",
description: _("FakeIP checks failed")
};
}
const { state, description } = getMeta();
updateDiagnosticsCheck({
order,
code,
title,
description,
state,
items: [
{
state: checks.router ? "success" : "warning",
key: checks.router ? _("Router DNS is routed through sing-box") : _("Router DNS is not routed through sing-box"),
value: ""
},
{
state: checks.browserFakeIP ? "success" : "error",
key: checks.browserFakeIP ? _("Browser is using FakeIP correctly") : _("Browser is not using FakeIP"),
value: ""
},
...insertIf(checks.browserFakeIP, [
{
state: checks.differentIP ? "success" : "error",
key: checks.differentIP ? _("Proxy traffic is routed via FakeIP") : _("Proxy traffic is not routed via FakeIP"),
value: ""
}
])
]
});
}
// src/podkop/tabs/diagnostic/renderDiagnosticRunAction.ts
function renderDiagnosticRunAction({
// src/podkop/tabs/diagnostic/partials/renderRunAction.ts
function renderRunAction({
loading,
click
}) {
@@ -3059,20 +3078,7 @@ function renderDiagnosticRunAction({
]);
}
// src/podkop/tabs/diagnostic/renderAvailableActions.ts
function renderAvailableActions() {
return E("div", { class: "pdk_diagnostic-page__right-bar__actions" }, [
E("b", {}, "Available actions"),
E("button", { class: "btn" }, "Restart podkop"),
E("button", { class: "btn" }, "Stop podkop"),
E("button", { class: "btn" }, "Disable podkop"),
E("button", { class: "btn" }, "Get global check"),
E("button", { class: "btn" }, "View logs"),
E("button", { class: "btn" }, "Show sing-box config")
]);
}
// src/podkop/tabs/diagnostic/renderSystemInfo.ts
// src/podkop/tabs/diagnostic/partials/renderSystemInfo.ts
function renderSystemInfo({ items }) {
return E("div", { class: "pdk_diagnostic-page__right-bar__system-info" }, [
E(
@@ -3089,7 +3095,7 @@ function renderSystemInfo({ items }) {
]);
}
// src/podkop/tabs/diagnostic/initDiagnosticController.ts
// src/podkop/tabs/diagnostic/initController.ts
function renderDiagnosticsChecks() {
console.log("renderDiagnosticsChecks");
const diagnosticsChecks = store.get().diagnosticsChecks.sort((a, b) => a.order - b.order);
@@ -3105,7 +3111,7 @@ function renderDiagnosticRunActionWidget() {
console.log("renderDiagnosticRunActionWidget");
const { loading } = store.get().diagnosticsRunAction;
const container = document.getElementById("pdk_diagnostic-page-run-check");
const renderedAction = renderDiagnosticRunAction({
const renderedAction = renderRunAction({
loading,
click: () => runChecks()
});
@@ -3176,7 +3182,7 @@ async function runChecks() {
store.set({ diagnosticsRunAction: { loading: false } });
}
}
async function initDiagnosticController() {
async function initController2() {
onMount("diagnostic-status").then(() => {
console.log("diagnostic controller initialized.");
store.unsubscribe(onStoreUpdate2);
@@ -3187,6 +3193,12 @@ async function initDiagnosticController() {
renderDiagnosticSystemInfoWidget();
});
}
// src/podkop/tabs/diagnostic/index.ts
var DiagnosticTab = {
render: render2,
initController: initController2
};
return baseclass.extend({
ALLOWED_WITH_RUSSIA_INSIDE,
BOOTSTRAP_DNS_SERVER_OPTIONS,
@@ -3200,6 +3212,8 @@ return baseclass.extend({
DIAGNOSTICS_UPDATE_INTERVAL,
DNS_SERVER_OPTIONS,
DOMAIN_LIST_OPTIONS,
DashboardTab,
DiagnosticTab,
ERROR_POLL_INTERVAL,
FAKEIP_CHECK_DOMAIN,
FETCH_TIMEOUT,
@@ -3220,8 +3234,6 @@ return baseclass.extend({
getClashUIUrl,
getClashWsUrl,
getProxyUrlName,
initDashboardController,
initDiagnosticController,
injectGlobalStyles,
insertIf,
insertIfObj,
@@ -3230,8 +3242,6 @@ return baseclass.extend({
parseQueryString,
parseValueList,
preserveScrollForPage,
renderDashboard,
renderDiagnostic,
socket,
splitProxyString,
store,