mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-06 19:46:52 +03:00
fix: correct dashboard displaying
This commit is contained in:
@@ -8,3 +8,4 @@ export * from './getProxyUrlName';
|
|||||||
export * from './onMount';
|
export * from './onMount';
|
||||||
export * from './getClashApiUrl';
|
export * from './getClashApiUrl';
|
||||||
export * from './splitProxyString';
|
export * from './splitProxyString';
|
||||||
|
export * from './preserveScrollForPage';
|
||||||
|
|||||||
9
fe-app-podkop/src/helpers/preserveScrollForPage.ts
Normal file
9
fe-app-podkop/src/helpers/preserveScrollForPage.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function preserveScrollForPage(renderFn: () => void) {
|
||||||
|
const scrollY = window.scrollY;
|
||||||
|
|
||||||
|
renderFn();
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
window.scrollTo({ top: scrollY });
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -62,9 +62,10 @@ export async function getDashboardSections(): Promise<IGetDashboardSectionsRespo
|
|||||||
);
|
);
|
||||||
|
|
||||||
const parsedOutbound = JSON.parse(section.outbound_json);
|
const parsedOutbound = JSON.parse(section.outbound_json);
|
||||||
const parsedTag = parsedOutbound?.tag ? decodeURIComponent(parsedOutbound?.tag) : undefined;
|
const parsedTag = parsedOutbound?.tag
|
||||||
const proxyDisplayName = parsedTag || outbound?.value?.name || ''
|
? decodeURIComponent(parsedOutbound?.tag)
|
||||||
|
: undefined;
|
||||||
|
const proxyDisplayName = parsedTag || outbound?.value?.name || '';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
withTagSelect: false,
|
withTagSelect: false,
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import {
|
|||||||
getPodkopStatus,
|
getPodkopStatus,
|
||||||
getSingboxStatus,
|
getSingboxStatus,
|
||||||
} from '../../methods';
|
} from '../../methods';
|
||||||
import { getClashWsUrl, onMount } from '../../../helpers';
|
import {
|
||||||
|
getClashWsUrl,
|
||||||
|
onMount,
|
||||||
|
preserveScrollForPage,
|
||||||
|
} from '../../../helpers';
|
||||||
import {
|
import {
|
||||||
triggerLatencyGroupTest,
|
triggerLatencyGroupTest,
|
||||||
triggerLatencyProxyTest,
|
triggerLatencyProxyTest,
|
||||||
@@ -31,6 +35,7 @@ async function fetchDashboardSections() {
|
|||||||
|
|
||||||
store.set({
|
store.set({
|
||||||
sectionsWidget: {
|
sectionsWidget: {
|
||||||
|
latencyFetching: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
failed: !success,
|
failed: !success,
|
||||||
data,
|
data,
|
||||||
@@ -130,25 +135,41 @@ async function handleChooseOutbound(selector: string, tag: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleTestGroupLatency(tag: string) {
|
async function handleTestGroupLatency(tag: string) {
|
||||||
|
store.set({
|
||||||
|
sectionsWidget: {
|
||||||
|
...store.get().sectionsWidget,
|
||||||
|
latencyFetching: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await triggerLatencyGroupTest(tag);
|
await triggerLatencyGroupTest(tag);
|
||||||
await fetchDashboardSections();
|
await fetchDashboardSections();
|
||||||
|
|
||||||
|
store.set({
|
||||||
|
sectionsWidget: {
|
||||||
|
...store.get().sectionsWidget,
|
||||||
|
latencyFetching: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleTestProxyLatency(tag: string) {
|
async function handleTestProxyLatency(tag: string) {
|
||||||
|
store.set({
|
||||||
|
sectionsWidget: {
|
||||||
|
...store.get().sectionsWidget,
|
||||||
|
latencyFetching: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await triggerLatencyProxyTest(tag);
|
await triggerLatencyProxyTest(tag);
|
||||||
await fetchDashboardSections();
|
await fetchDashboardSections();
|
||||||
}
|
|
||||||
|
|
||||||
function replaceTestLatencyButtonsWithSkeleton() {
|
store.set({
|
||||||
document
|
sectionsWidget: {
|
||||||
.querySelectorAll('.dashboard-sections-grid-item-test-latency')
|
...store.get().sectionsWidget,
|
||||||
.forEach((el) => {
|
latencyFetching: false,
|
||||||
const newDiv = document.createElement('div');
|
},
|
||||||
newDiv.className = 'skeleton';
|
});
|
||||||
newDiv.style.width = '99px';
|
|
||||||
newDiv.style.height = '28px';
|
|
||||||
el.replaceWith(newDiv);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
@@ -170,8 +191,12 @@ async function renderSectionsWidget() {
|
|||||||
},
|
},
|
||||||
onTestLatency: () => {},
|
onTestLatency: () => {},
|
||||||
onChooseOutbound: () => {},
|
onChooseOutbound: () => {},
|
||||||
|
latencyFetching: sectionsWidget.latencyFetching,
|
||||||
|
});
|
||||||
|
|
||||||
|
return preserveScrollForPage(() => {
|
||||||
|
container!.replaceChildren(renderedWidget);
|
||||||
});
|
});
|
||||||
return container!.replaceChildren(renderedWidget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderedWidgets = sectionsWidget.data.map((section) =>
|
const renderedWidgets = sectionsWidget.data.map((section) =>
|
||||||
@@ -179,9 +204,8 @@ async function renderSectionsWidget() {
|
|||||||
loading: sectionsWidget.loading,
|
loading: sectionsWidget.loading,
|
||||||
failed: sectionsWidget.failed,
|
failed: sectionsWidget.failed,
|
||||||
section,
|
section,
|
||||||
|
latencyFetching: sectionsWidget.latencyFetching,
|
||||||
onTestLatency: (tag) => {
|
onTestLatency: (tag) => {
|
||||||
replaceTestLatencyButtonsWithSkeleton();
|
|
||||||
|
|
||||||
if (section.withTagSelect) {
|
if (section.withTagSelect) {
|
||||||
return handleTestGroupLatency(tag);
|
return handleTestGroupLatency(tag);
|
||||||
}
|
}
|
||||||
@@ -194,7 +218,9 @@ async function renderSectionsWidget() {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return container!.replaceChildren(...renderedWidgets);
|
return preserveScrollForPage(() => {
|
||||||
|
container!.replaceChildren(...renderedWidgets);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderBandwidthWidget() {
|
async function renderBandwidthWidget() {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ interface IRenderSectionsProps {
|
|||||||
section: Podkop.OutboundGroup;
|
section: Podkop.OutboundGroup;
|
||||||
onTestLatency: (tag: string) => void;
|
onTestLatency: (tag: string) => void;
|
||||||
onChooseOutbound: (selector: string, tag: string) => void;
|
onChooseOutbound: (selector: string, tag: string) => void;
|
||||||
|
latencyFetching: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderFailedState() {
|
function renderFailedState() {
|
||||||
@@ -31,6 +32,7 @@ export function renderDefaultState({
|
|||||||
section,
|
section,
|
||||||
onChooseOutbound,
|
onChooseOutbound,
|
||||||
onTestLatency,
|
onTestLatency,
|
||||||
|
latencyFetching,
|
||||||
}: IRenderSectionsProps) {
|
}: IRenderSectionsProps) {
|
||||||
function testLatency() {
|
function testLatency() {
|
||||||
if (section.withTagSelect) {
|
if (section.withTagSelect) {
|
||||||
@@ -95,14 +97,16 @@ export function renderDefaultState({
|
|||||||
},
|
},
|
||||||
section.displayName,
|
section.displayName,
|
||||||
),
|
),
|
||||||
E(
|
latencyFetching
|
||||||
'button',
|
? E('div', { class: 'skeleton', style: 'width: 99px; height: 28px' })
|
||||||
{
|
: E(
|
||||||
class: 'btn dashboard-sections-grid-item-test-latency',
|
'button',
|
||||||
click: () => testLatency(),
|
{
|
||||||
},
|
class: 'btn dashboard-sections-grid-item-test-latency',
|
||||||
_('Test latency'),
|
click: () => testLatency(),
|
||||||
),
|
},
|
||||||
|
_('Test latency'),
|
||||||
|
),
|
||||||
]),
|
]),
|
||||||
E(
|
E(
|
||||||
'div',
|
'div',
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ export interface StoreType {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
failed: boolean;
|
failed: boolean;
|
||||||
data: Podkop.OutboundGroup[];
|
data: Podkop.OutboundGroup[];
|
||||||
|
latencyFetching: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +173,7 @@ const initialStore: StoreType = {
|
|||||||
sectionsWidget: {
|
sectionsWidget: {
|
||||||
loading: true,
|
loading: true,
|
||||||
failed: false,
|
failed: false,
|
||||||
|
latencyFetching: false,
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -776,6 +776,15 @@ function splitProxyString(str) {
|
|||||||
return str.split("\n").map((line) => line.trim()).filter((line) => !line.startsWith("//")).filter(Boolean);
|
return str.split("\n").map((line) => line.trim()).filter((line) => !line.startsWith("//")).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// src/helpers/preserveScrollForPage.ts
|
||||||
|
function preserveScrollForPage(renderFn) {
|
||||||
|
const scrollY = window.scrollY;
|
||||||
|
renderFn();
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
window.scrollTo({ top: scrollY });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// src/clash/methods/createBaseApiRequest.ts
|
// src/clash/methods/createBaseApiRequest.ts
|
||||||
async function createBaseApiRequest(fetchFn) {
|
async function createBaseApiRequest(fetchFn) {
|
||||||
try {
|
try {
|
||||||
@@ -1210,6 +1219,7 @@ var initialStore = {
|
|||||||
sectionsWidget: {
|
sectionsWidget: {
|
||||||
loading: true,
|
loading: true,
|
||||||
failed: false,
|
failed: false,
|
||||||
|
latencyFetching: false,
|
||||||
data: []
|
data: []
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1248,7 +1258,8 @@ function renderLoadingState() {
|
|||||||
function renderDefaultState({
|
function renderDefaultState({
|
||||||
section,
|
section,
|
||||||
onChooseOutbound,
|
onChooseOutbound,
|
||||||
onTestLatency
|
onTestLatency,
|
||||||
|
latencyFetching
|
||||||
}) {
|
}) {
|
||||||
function testLatency() {
|
function testLatency() {
|
||||||
if (section.withTagSelect) {
|
if (section.withTagSelect) {
|
||||||
@@ -1304,7 +1315,7 @@ function renderDefaultState({
|
|||||||
},
|
},
|
||||||
section.displayName
|
section.displayName
|
||||||
),
|
),
|
||||||
E(
|
latencyFetching ? E("div", { class: "skeleton", style: "width: 99px; height: 28px" }) : E(
|
||||||
"button",
|
"button",
|
||||||
{
|
{
|
||||||
class: "btn dashboard-sections-grid-item-test-latency",
|
class: "btn dashboard-sections-grid-item-test-latency",
|
||||||
@@ -1573,6 +1584,7 @@ async function fetchDashboardSections() {
|
|||||||
const { data, success } = await getDashboardSections();
|
const { data, success } = await getDashboardSections();
|
||||||
store.set({
|
store.set({
|
||||||
sectionsWidget: {
|
sectionsWidget: {
|
||||||
|
latencyFetching: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
failed: !success,
|
failed: !success,
|
||||||
data
|
data
|
||||||
@@ -1662,20 +1674,35 @@ async function handleChooseOutbound(selector, tag) {
|
|||||||
await fetchDashboardSections();
|
await fetchDashboardSections();
|
||||||
}
|
}
|
||||||
async function handleTestGroupLatency(tag) {
|
async function handleTestGroupLatency(tag) {
|
||||||
|
store.set({
|
||||||
|
sectionsWidget: {
|
||||||
|
...store.get().sectionsWidget,
|
||||||
|
latencyFetching: true
|
||||||
|
}
|
||||||
|
});
|
||||||
await triggerLatencyGroupTest(tag);
|
await triggerLatencyGroupTest(tag);
|
||||||
await fetchDashboardSections();
|
await fetchDashboardSections();
|
||||||
|
store.set({
|
||||||
|
sectionsWidget: {
|
||||||
|
...store.get().sectionsWidget,
|
||||||
|
latencyFetching: false
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
async function handleTestProxyLatency(tag) {
|
async function handleTestProxyLatency(tag) {
|
||||||
|
store.set({
|
||||||
|
sectionsWidget: {
|
||||||
|
...store.get().sectionsWidget,
|
||||||
|
latencyFetching: true
|
||||||
|
}
|
||||||
|
});
|
||||||
await triggerLatencyProxyTest(tag);
|
await triggerLatencyProxyTest(tag);
|
||||||
await fetchDashboardSections();
|
await fetchDashboardSections();
|
||||||
}
|
store.set({
|
||||||
function replaceTestLatencyButtonsWithSkeleton() {
|
sectionsWidget: {
|
||||||
document.querySelectorAll(".dashboard-sections-grid-item-test-latency").forEach((el) => {
|
...store.get().sectionsWidget,
|
||||||
const newDiv = document.createElement("div");
|
latencyFetching: false
|
||||||
newDiv.className = "skeleton";
|
}
|
||||||
newDiv.style.width = "99px";
|
|
||||||
newDiv.style.height = "28px";
|
|
||||||
el.replaceWith(newDiv);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function renderSectionsWidget() {
|
async function renderSectionsWidget() {
|
||||||
@@ -1695,17 +1722,20 @@ async function renderSectionsWidget() {
|
|||||||
onTestLatency: () => {
|
onTestLatency: () => {
|
||||||
},
|
},
|
||||||
onChooseOutbound: () => {
|
onChooseOutbound: () => {
|
||||||
}
|
},
|
||||||
|
latencyFetching: sectionsWidget.latencyFetching
|
||||||
|
});
|
||||||
|
return preserveScrollForPage(() => {
|
||||||
|
container.replaceChildren(renderedWidget);
|
||||||
});
|
});
|
||||||
return container.replaceChildren(renderedWidget);
|
|
||||||
}
|
}
|
||||||
const renderedWidgets = sectionsWidget.data.map(
|
const renderedWidgets = sectionsWidget.data.map(
|
||||||
(section) => renderSections({
|
(section) => renderSections({
|
||||||
loading: sectionsWidget.loading,
|
loading: sectionsWidget.loading,
|
||||||
failed: sectionsWidget.failed,
|
failed: sectionsWidget.failed,
|
||||||
section,
|
section,
|
||||||
|
latencyFetching: sectionsWidget.latencyFetching,
|
||||||
onTestLatency: (tag) => {
|
onTestLatency: (tag) => {
|
||||||
replaceTestLatencyButtonsWithSkeleton();
|
|
||||||
if (section.withTagSelect) {
|
if (section.withTagSelect) {
|
||||||
return handleTestGroupLatency(tag);
|
return handleTestGroupLatency(tag);
|
||||||
}
|
}
|
||||||
@@ -1716,7 +1746,9 @@ async function renderSectionsWidget() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
return container.replaceChildren(...renderedWidgets);
|
return preserveScrollForPage(() => {
|
||||||
|
container.replaceChildren(...renderedWidgets);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
async function renderBandwidthWidget() {
|
async function renderBandwidthWidget() {
|
||||||
console.log("renderBandwidthWidget");
|
console.log("renderBandwidthWidget");
|
||||||
@@ -1906,6 +1938,7 @@ return baseclass.extend({
|
|||||||
maskIP,
|
maskIP,
|
||||||
onMount,
|
onMount,
|
||||||
parseValueList,
|
parseValueList,
|
||||||
|
preserveScrollForPage,
|
||||||
renderDashboard,
|
renderDashboard,
|
||||||
splitProxyString,
|
splitProxyString,
|
||||||
triggerLatencyGroupTest,
|
triggerLatencyGroupTest,
|
||||||
|
|||||||
Reference in New Issue
Block a user