2022-11-20 19:46:16 +08:00
|
|
|
|
import useSWR from "swr";
|
|
|
|
|
|
import { useEffect, useMemo } from "react";
|
2022-12-13 17:34:39 +08:00
|
|
|
|
import { getProxies } from "@/services/api";
|
|
|
|
|
|
import { useVerge } from "@/hooks/use-verge";
|
2022-11-20 19:46:16 +08:00
|
|
|
|
import { filterSort } from "./use-filter-sort";
|
2022-12-14 15:07:51 +08:00
|
|
|
|
import { useWindowWidth } from "./use-window-width";
|
2022-11-21 22:10:24 +08:00
|
|
|
|
import {
|
|
|
|
|
|
useHeadStateNew,
|
|
|
|
|
|
DEFAULT_STATE,
|
|
|
|
|
|
type HeadState,
|
|
|
|
|
|
} from "./use-head-state";
|
2022-11-20 19:46:16 +08:00
|
|
|
|
|
|
|
|
|
|
export interface IRenderItem {
|
2022-12-13 17:34:39 +08:00
|
|
|
|
// 组 | head | item | empty | item col
|
|
|
|
|
|
type: 0 | 1 | 2 | 3 | 4;
|
2022-11-20 19:46:16 +08:00
|
|
|
|
key: string;
|
|
|
|
|
|
group: IProxyGroupItem;
|
|
|
|
|
|
proxy?: IProxyItem;
|
2022-12-13 17:34:39 +08:00
|
|
|
|
col?: number;
|
|
|
|
|
|
proxyCol?: IProxyItem[];
|
2022-11-20 19:46:16 +08:00
|
|
|
|
headState?: HeadState;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const useRenderList = (mode: string) => {
|
|
|
|
|
|
const { data: proxiesData, mutate: mutateProxies } = useSWR(
|
|
|
|
|
|
"getProxies",
|
|
|
|
|
|
getProxies,
|
2024-11-24 00:14:46 +08:00
|
|
|
|
{ refreshInterval: 45000 },
|
2022-11-20 19:46:16 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
2022-12-13 17:34:39 +08:00
|
|
|
|
const { verge } = useVerge();
|
2022-12-14 15:07:51 +08:00
|
|
|
|
const { width } = useWindowWidth();
|
|
|
|
|
|
|
2022-12-14 16:56:33 +08:00
|
|
|
|
let col = Math.floor(verge?.proxy_layout_column || 6);
|
2022-12-14 15:07:51 +08:00
|
|
|
|
|
|
|
|
|
|
// 自适应
|
2022-12-14 16:56:33 +08:00
|
|
|
|
if (col >= 6 || col <= 0) {
|
2023-11-28 07:49:44 +08:00
|
|
|
|
if (width > 1450) col = 4;
|
|
|
|
|
|
else if (width > 1024) col = 3;
|
|
|
|
|
|
else if (width > 900) col = 2;
|
2022-12-14 15:07:51 +08:00
|
|
|
|
else if (width >= 600) col = 2;
|
|
|
|
|
|
else col = 1;
|
|
|
|
|
|
}
|
2022-12-13 17:34:39 +08:00
|
|
|
|
|
2022-11-20 19:46:16 +08:00
|
|
|
|
const [headStates, setHeadState] = useHeadStateNew();
|
|
|
|
|
|
|
|
|
|
|
|
// make sure that fetch the proxies successfully
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (!proxiesData) return;
|
|
|
|
|
|
const { groups, proxies } = proxiesData;
|
|
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
(mode === "rule" && !groups.length) ||
|
|
|
|
|
|
(mode === "global" && proxies.length < 2)
|
|
|
|
|
|
) {
|
|
|
|
|
|
setTimeout(() => mutateProxies(), 500);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [proxiesData, mode]);
|
|
|
|
|
|
|
|
|
|
|
|
const renderList: IRenderItem[] = useMemo(() => {
|
2022-11-20 22:03:55 +08:00
|
|
|
|
if (!proxiesData) return [];
|
2022-11-21 22:10:24 +08:00
|
|
|
|
|
|
|
|
|
|
// global 和 direct 使用展开的样式
|
2022-11-20 19:46:16 +08:00
|
|
|
|
const useRule = mode === "rule" || mode === "script";
|
|
|
|
|
|
const renderGroups =
|
2022-11-21 23:06:32 +08:00
|
|
|
|
(useRule && proxiesData.groups.length
|
|
|
|
|
|
? proxiesData.groups
|
|
|
|
|
|
: [proxiesData.global!]) || [];
|
2022-11-20 19:46:16 +08:00
|
|
|
|
|
|
|
|
|
|
const retList = renderGroups.flatMap((group) => {
|
2022-11-21 22:10:24 +08:00
|
|
|
|
const headState = headStates[group.name] || DEFAULT_STATE;
|
2022-11-20 19:46:16 +08:00
|
|
|
|
const ret: IRenderItem[] = [
|
|
|
|
|
|
{ type: 0, key: group.name, group, headState },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
2022-11-21 22:10:24 +08:00
|
|
|
|
if (headState?.open || !useRule) {
|
2022-11-20 19:46:16 +08:00
|
|
|
|
const proxies = filterSort(
|
|
|
|
|
|
group.all,
|
|
|
|
|
|
group.name,
|
|
|
|
|
|
headState.filterText,
|
2024-11-24 00:14:46 +08:00
|
|
|
|
headState.sortType,
|
2022-11-20 19:46:16 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
2022-12-13 17:34:39 +08:00
|
|
|
|
ret.push({ type: 1, key: `head-${group.name}`, group, headState });
|
2022-11-20 19:46:16 +08:00
|
|
|
|
|
|
|
|
|
|
if (!proxies.length) {
|
2022-12-13 17:34:39 +08:00
|
|
|
|
ret.push({ type: 3, key: `empty-${group.name}`, group, headState });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 支持多列布局
|
|
|
|
|
|
if (col > 1) {
|
|
|
|
|
|
return ret.concat(
|
|
|
|
|
|
groupList(proxies, col).map((proxyCol) => ({
|
|
|
|
|
|
type: 4,
|
2022-12-14 15:07:51 +08:00
|
|
|
|
key: `col-${group.name}-${proxyCol[0].name}`,
|
2022-12-13 17:34:39 +08:00
|
|
|
|
group,
|
|
|
|
|
|
headState,
|
|
|
|
|
|
col,
|
|
|
|
|
|
proxyCol,
|
2024-11-24 00:14:46 +08:00
|
|
|
|
})),
|
2022-12-13 17:34:39 +08:00
|
|
|
|
);
|
2022-11-20 19:46:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret.concat(
|
|
|
|
|
|
proxies.map((proxy) => ({
|
|
|
|
|
|
type: 2,
|
|
|
|
|
|
key: `${group.name}-${proxy!.name}`,
|
|
|
|
|
|
group,
|
|
|
|
|
|
proxy,
|
|
|
|
|
|
headState,
|
2024-11-24 00:14:46 +08:00
|
|
|
|
})),
|
2022-11-20 19:46:16 +08:00
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!useRule) return retList.slice(1);
|
2024-10-24 06:54:27 +08:00
|
|
|
|
return retList.filter((item) => item.group.hidden === false);
|
2022-12-13 17:34:39 +08:00
|
|
|
|
}, [headStates, proxiesData, mode, col]);
|
2022-11-20 19:46:16 +08:00
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
renderList,
|
|
|
|
|
|
onProxies: mutateProxies,
|
|
|
|
|
|
onHeadState: setHeadState,
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
2022-12-13 17:34:39 +08:00
|
|
|
|
|
|
|
|
|
|
function groupList<T = any>(list: T[], size: number): T[][] {
|
|
|
|
|
|
return list.reduce((p, n) => {
|
|
|
|
|
|
if (!p.length) return [[n]];
|
|
|
|
|
|
|
|
|
|
|
|
const i = p.length - 1;
|
|
|
|
|
|
if (p[i].length < size) {
|
|
|
|
|
|
p[i].push(n);
|
|
|
|
|
|
return p;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
p.push([n]);
|
|
|
|
|
|
return p;
|
|
|
|
|
|
}, [] as T[][]);
|
|
|
|
|
|
}
|