feat: auto proxy layout column

This commit is contained in:
GyDi 2022-12-14 15:07:51 +08:00
parent 173f35487e
commit 024db4358b
No known key found for this signature in database
GPG Key ID: 9C3AD40F1F99880A
6 changed files with 69 additions and 40 deletions

View File

@ -118,6 +118,7 @@ export const ProxyGroups = (props: Props) => {
ref={virtuosoRef} ref={virtuosoRef}
style={{ height: "100%" }} style={{ height: "100%" }}
totalCount={renderList.length} totalCount={renderList.length}
increaseViewportBy={256}
itemContent={(index) => ( itemContent={(index) => (
<ProxyRender <ProxyRender
key={renderList[index].key} key={renderList[index].key}

View File

@ -1,14 +1,7 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useLockFn } from "ahooks"; import { useLockFn } from "ahooks";
import { CheckCircleOutlineRounded } from "@mui/icons-material"; import { CheckCircleOutlineRounded } from "@mui/icons-material";
import { import { alpha, Box, ListItemButton, styled, Typography } from "@mui/material";
alpha,
Box,
ListItemButton,
ListItemIcon,
ListItemText,
styled,
} from "@mui/material";
import { BaseLoading } from "@/components/base"; import { BaseLoading } from "@/components/base";
import delayManager from "@/services/delay"; import delayManager from "@/services/delay";
@ -52,7 +45,7 @@ export const ProxyItemMini = (props: Props) => {
selected={selected} selected={selected}
onClick={() => onClick?.(proxy.name)} onClick={() => onClick?.(proxy.name)}
sx={[ sx={[
{ borderRadius: 1, pl: 1.5, pr: 1 }, { height: 56, borderRadius: 1, pl: 1.5, pr: 1 },
({ palette: { mode, primary } }) => { ({ palette: { mode, primary } }) => {
const bgcolor = const bgcolor =
mode === "light" mode === "light"
@ -61,45 +54,48 @@ export const ProxyItemMini = (props: Props) => {
const color = mode === "light" ? primary.main : primary.light; const color = mode === "light" ? primary.main : primary.light;
const showDelay = delay > 0; const showDelay = delay > 0;
const shadowColor =
mode === "light" ? "rgba(0,0,0,0.04)" : "rgba(255,255,255,0.08)";
return { return {
"&:hover .the-check": { display: !showDelay ? "block" : "none" }, "&:hover .the-check": { display: !showDelay ? "block" : "none" },
"&:hover .the-delay": { display: showDelay ? "block" : "none" }, "&:hover .the-delay": { display: showDelay ? "block" : "none" },
"&:hover .the-icon": { display: "none" }, "&:hover .the-icon": { display: "none" },
"&.Mui-selected": { bgcolor }, "&.Mui-selected": { bgcolor, boxShadow: `0 0 0 1px ${bgcolor}` },
"&.Mui-selected .MuiListItemText-secondary": { color }, "&.Mui-selected .MuiListItemText-secondary": { color },
boxShadow: `0 0 0 1px ${shadowColor}`,
}; };
}, },
]} ]}
> >
<ListItemText <Box title={proxy.name} sx={{ overflow: "hidden" }}>
title={proxy.name} <Typography
secondary={ variant="body2"
<div> component="div"
<div color="text.secondary"
style={{ sx={{
display: "block",
textOverflow: "ellipsis", textOverflow: "ellipsis",
wordBreak: "break-all", wordBreak: "break-all",
overflow: "hidden", overflow: "hidden",
whiteSpace: showType ? "nowrap" : "inherit", whiteSpace: "nowrap",
}} }}
> >
{proxy.name} {proxy.name}
</div> </Typography>
{showType && ( {showType && (
<> <Box sx={{ display: "flex", flexWrap: "nowrap", flex: "none" }}>
{!!proxy.provider && ( {!!proxy.provider && (
<TypeBox component="span">{proxy.provider}</TypeBox> <TypeBox component="span">{proxy.provider}</TypeBox>
)} )}
<TypeBox component="span">{proxy.type}</TypeBox> <TypeBox component="span">{proxy.type}</TypeBox>
{proxy.udp && <TypeBox component="span">UDP</TypeBox>} {proxy.udp && <TypeBox component="span">UDP</TypeBox>}
</> </Box>
)} )}
</div> </Box>
}
/>
<ListItemIcon sx={{ justifyContent: "flex-end", color: "primary.main" }}> <Box sx={{ ml: 0.5, justifyContent: "flex-end", color: "primary.main" }}>
{delay === -2 && ( {delay === -2 && (
<Widget> <Widget>
<BaseLoading /> <BaseLoading />
@ -158,7 +154,7 @@ export const ProxyItemMini = (props: Props) => {
sx={{ fontSize: 16 }} sx={{ fontSize: 16 }}
/> />
)} )}
</ListItemIcon> </Box>
</ListItemButton> </ListItemButton>
); );
}; };

View File

@ -110,6 +110,7 @@ export const ProxyRender = (props: RenderProps) => {
return ( return (
<Box <Box
sx={{ sx={{
height: 56,
display: "grid", display: "grid",
gap: 1, gap: 1,
pl: indent ? 4 : 2, pl: indent ? 4 : 2,
@ -123,7 +124,7 @@ export const ProxyRender = (props: RenderProps) => {
key={item.key + proxy.name} key={item.key + proxy.name}
groupName={group.name} groupName={group.name}
proxy={proxy!} proxy={proxy!}
selected={group.now === proxy?.name} selected={group.now === proxy.name}
showType={headState?.showType} showType={headState?.showType}
onClick={() => onChangeProxy(group, proxy!)} onClick={() => onChangeProxy(group, proxy!)}
/> />

View File

@ -3,6 +3,7 @@ import { useEffect, useMemo } from "react";
import { getProxies } from "@/services/api"; import { getProxies } from "@/services/api";
import { useVerge } from "@/hooks/use-verge"; import { useVerge } from "@/hooks/use-verge";
import { filterSort } from "./use-filter-sort"; import { filterSort } from "./use-filter-sort";
import { useWindowWidth } from "./use-window-width";
import { import {
useHeadStateNew, useHeadStateNew,
DEFAULT_STATE, DEFAULT_STATE,
@ -28,7 +29,18 @@ export const useRenderList = (mode: string) => {
); );
const { verge } = useVerge(); 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(); const [headStates, setHeadState] = useHeadStateNew();
@ -80,7 +92,7 @@ export const useRenderList = (mode: string) => {
return ret.concat( return ret.concat(
groupList(proxies, col).map((proxyCol) => ({ groupList(proxies, col).map((proxyCol) => ({
type: 4, type: 4,
key: `col-${group.name}`, key: `col-${group.name}-${proxyCol[0].name}`,
group, group,
headState, headState,
col, col,

View File

@ -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 };
};

View File

@ -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) => ( {[1, 2, 3, 4, 5].map((i) => (
<MenuItem value={i} key={i}> <MenuItem value={i} key={i}>
{i} {i}