use-render-list.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import useSWR from "swr";
  2. import { getProxies } from "@/services/api";
  3. import { useEffect, useMemo } from "react";
  4. import { filterSort } from "./use-filter-sort";
  5. import {
  6. useHeadStateNew,
  7. DEFAULT_STATE,
  8. type HeadState,
  9. } from "./use-head-state";
  10. export interface IRenderItem {
  11. type: 0 | 1 | 2 | 3; // 组 | head | item | empty
  12. key: string;
  13. group: IProxyGroupItem;
  14. proxy?: IProxyItem;
  15. headState?: HeadState;
  16. }
  17. export const useRenderList = (mode: string) => {
  18. const { data: proxiesData, mutate: mutateProxies } = useSWR(
  19. "getProxies",
  20. getProxies,
  21. { refreshInterval: 45000 }
  22. );
  23. const [headStates, setHeadState] = useHeadStateNew();
  24. // make sure that fetch the proxies successfully
  25. useEffect(() => {
  26. if (!proxiesData) return;
  27. const { groups, proxies } = proxiesData;
  28. if (
  29. (mode === "rule" && !groups.length) ||
  30. (mode === "global" && proxies.length < 2)
  31. ) {
  32. setTimeout(() => mutateProxies(), 500);
  33. }
  34. }, [proxiesData, mode]);
  35. const renderList: IRenderItem[] = useMemo(() => {
  36. if (!proxiesData) return [];
  37. // global 和 direct 使用展开的样式
  38. const useRule = mode === "rule" || mode === "script";
  39. const renderGroups =
  40. (useRule ? proxiesData?.groups : [proxiesData?.global!]) || [];
  41. const retList = renderGroups.flatMap((group) => {
  42. const headState = headStates[group.name] || DEFAULT_STATE;
  43. const ret: IRenderItem[] = [
  44. { type: 0, key: group.name, group, headState },
  45. ];
  46. if (headState?.open || !useRule) {
  47. const proxies = filterSort(
  48. group.all,
  49. group.name,
  50. headState.filterText,
  51. headState.sortType
  52. );
  53. ret.push({ type: 1, key: `head${group.name}`, group, headState });
  54. if (!proxies.length) {
  55. ret.push({ type: 3, key: `empty${group.name}`, group, headState });
  56. }
  57. return ret.concat(
  58. proxies.map((proxy) => ({
  59. type: 2,
  60. key: `${group.name}-${proxy!.name}`,
  61. group,
  62. proxy,
  63. headState,
  64. }))
  65. );
  66. }
  67. return ret;
  68. });
  69. if (!useRule) return retList.slice(1);
  70. return retList;
  71. }, [headStates, proxiesData, mode]);
  72. return {
  73. renderList,
  74. onProxies: mutateProxies,
  75. onHeadState: setHeadState,
  76. };
  77. };