From 024db4358b4d5aab701301005396c4efd7466c67 Mon Sep 17 00:00:00 2001 From: GyDi <zzzgydi@gmail.com> Date: Wed, 14 Dec 2022 15:07:51 +0800 Subject: [PATCH] feat: auto proxy layout column --- src/components/proxy/proxy-groups.tsx | 1 + src/components/proxy/proxy-item-mini.tsx | 72 ++++++++++----------- src/components/proxy/proxy-render.tsx | 3 +- src/components/proxy/use-render-list.ts | 16 ++++- src/components/proxy/use-window-width.ts | 16 +++++ src/components/setting/mods/misc-viewer.tsx | 3 + 6 files changed, 70 insertions(+), 41 deletions(-) create mode 100644 src/components/proxy/use-window-width.ts diff --git a/src/components/proxy/proxy-groups.tsx b/src/components/proxy/proxy-groups.tsx index e852391..8386b53 100644 --- a/src/components/proxy/proxy-groups.tsx +++ b/src/components/proxy/proxy-groups.tsx @@ -118,6 +118,7 @@ export const ProxyGroups = (props: Props) => { ref={virtuosoRef} style={{ height: "100%" }} totalCount={renderList.length} + increaseViewportBy={256} itemContent={(index) => ( <ProxyRender key={renderList[index].key} diff --git a/src/components/proxy/proxy-item-mini.tsx b/src/components/proxy/proxy-item-mini.tsx index 3e82c9e..68fcb61 100644 --- a/src/components/proxy/proxy-item-mini.tsx +++ b/src/components/proxy/proxy-item-mini.tsx @@ -1,14 +1,7 @@ import { useEffect, useState } from "react"; import { useLockFn } from "ahooks"; import { CheckCircleOutlineRounded } from "@mui/icons-material"; -import { - alpha, - Box, - ListItemButton, - ListItemIcon, - ListItemText, - styled, -} from "@mui/material"; +import { alpha, Box, ListItemButton, styled, Typography } from "@mui/material"; import { BaseLoading } from "@/components/base"; import delayManager from "@/services/delay"; @@ -52,7 +45,7 @@ export const ProxyItemMini = (props: Props) => { selected={selected} onClick={() => onClick?.(proxy.name)} sx={[ - { borderRadius: 1, pl: 1.5, pr: 1 }, + { height: 56, borderRadius: 1, pl: 1.5, pr: 1 }, ({ palette: { mode, primary } }) => { const bgcolor = mode === "light" @@ -61,45 +54,48 @@ export const ProxyItemMini = (props: Props) => { const color = mode === "light" ? primary.main : primary.light; const showDelay = delay > 0; + const shadowColor = + mode === "light" ? "rgba(0,0,0,0.04)" : "rgba(255,255,255,0.08)"; + return { "&:hover .the-check": { display: !showDelay ? "block" : "none" }, "&:hover .the-delay": { display: showDelay ? "block" : "none" }, "&:hover .the-icon": { display: "none" }, - "&.Mui-selected": { bgcolor }, + "&.Mui-selected": { bgcolor, boxShadow: `0 0 0 1px ${bgcolor}` }, "&.Mui-selected .MuiListItemText-secondary": { color }, + boxShadow: `0 0 0 1px ${shadowColor}`, }; }, ]} > - <ListItemText - title={proxy.name} - secondary={ - <div> - <div - style={{ - textOverflow: "ellipsis", - wordBreak: "break-all", - overflow: "hidden", - whiteSpace: showType ? "nowrap" : "inherit", - }} - > - {proxy.name} - </div> - - {showType && ( - <> - {!!proxy.provider && ( - <TypeBox component="span">{proxy.provider}</TypeBox> - )} - <TypeBox component="span">{proxy.type}</TypeBox> - {proxy.udp && <TypeBox component="span">UDP</TypeBox>} - </> + <Box title={proxy.name} sx={{ overflow: "hidden" }}> + <Typography + variant="body2" + component="div" + color="text.secondary" + sx={{ + display: "block", + textOverflow: "ellipsis", + wordBreak: "break-all", + overflow: "hidden", + whiteSpace: "nowrap", + }} + > + {proxy.name} + </Typography> + + {showType && ( + <Box sx={{ display: "flex", flexWrap: "nowrap", flex: "none" }}> + {!!proxy.provider && ( + <TypeBox component="span">{proxy.provider}</TypeBox> )} - </div> - } - /> + <TypeBox component="span">{proxy.type}</TypeBox> + {proxy.udp && <TypeBox component="span">UDP</TypeBox>} + </Box> + )} + </Box> - <ListItemIcon sx={{ justifyContent: "flex-end", color: "primary.main" }}> + <Box sx={{ ml: 0.5, justifyContent: "flex-end", color: "primary.main" }}> {delay === -2 && ( <Widget> <BaseLoading /> @@ -158,7 +154,7 @@ export const ProxyItemMini = (props: Props) => { sx={{ fontSize: 16 }} /> )} - </ListItemIcon> + </Box> </ListItemButton> ); }; diff --git a/src/components/proxy/proxy-render.tsx b/src/components/proxy/proxy-render.tsx index b5f50d0..f0d197f 100644 --- a/src/components/proxy/proxy-render.tsx +++ b/src/components/proxy/proxy-render.tsx @@ -110,6 +110,7 @@ export const ProxyRender = (props: RenderProps) => { return ( <Box sx={{ + height: 56, display: "grid", gap: 1, pl: indent ? 4 : 2, @@ -123,7 +124,7 @@ export const ProxyRender = (props: RenderProps) => { key={item.key + proxy.name} groupName={group.name} proxy={proxy!} - selected={group.now === proxy?.name} + selected={group.now === proxy.name} showType={headState?.showType} onClick={() => onChangeProxy(group, proxy!)} /> diff --git a/src/components/proxy/use-render-list.ts b/src/components/proxy/use-render-list.ts index 22fc96d..1753b01 100644 --- a/src/components/proxy/use-render-list.ts +++ b/src/components/proxy/use-render-list.ts @@ -3,6 +3,7 @@ import { useEffect, useMemo } from "react"; import { getProxies } from "@/services/api"; import { useVerge } from "@/hooks/use-verge"; import { filterSort } from "./use-filter-sort"; +import { useWindowWidth } from "./use-window-width"; import { useHeadStateNew, DEFAULT_STATE, @@ -28,7 +29,18 @@ export const useRenderList = (mode: string) => { ); const { verge } = useVerge(); - const col = verge?.proxy_layout_column || 1; + const { width } = useWindowWidth(); + + let col = verge?.proxy_layout_column || 1; + + // 自适应 + if (col === 6) { + if (width > 1450) col = 5; + else if (width > 1024) col = 4; + else if (width > 900) col = 3; + else if (width >= 600) col = 2; + else col = 1; + } const [headStates, setHeadState] = useHeadStateNew(); @@ -80,7 +92,7 @@ export const useRenderList = (mode: string) => { return ret.concat( groupList(proxies, col).map((proxyCol) => ({ type: 4, - key: `col-${group.name}`, + key: `col-${group.name}-${proxyCol[0].name}`, group, headState, col, diff --git a/src/components/proxy/use-window-width.ts b/src/components/proxy/use-window-width.ts new file mode 100644 index 0000000..d1de3c3 --- /dev/null +++ b/src/components/proxy/use-window-width.ts @@ -0,0 +1,16 @@ +import { useEffect, useState } from "react"; + +export const useWindowWidth = () => { + const [width, setWidth] = useState(() => document.body.clientWidth); + + useEffect(() => { + const handleResize = () => setWidth(document.body.clientWidth); + + window.addEventListener("resize", handleResize); + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + + return { width }; +}; diff --git a/src/components/setting/mods/misc-viewer.tsx b/src/components/setting/mods/misc-viewer.tsx index 02a0692..d438537 100644 --- a/src/components/setting/mods/misc-viewer.tsx +++ b/src/components/setting/mods/misc-viewer.tsx @@ -99,6 +99,9 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => { })); }} > + <MenuItem value={6} key={6}> + Auto + </MenuItem> {[1, 2, 3, 4, 5].map((i) => ( <MenuItem value={i} key={i}> {i} -- GitLab