feat: auto proxy layout column
This commit is contained in:
parent
173f35487e
commit
024db4358b
@ -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}
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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!)}
|
||||||
/>
|
/>
|
||||||
|
@ -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,
|
||||||
|
16
src/components/proxy/use-window-width.ts
Normal file
16
src/components/proxy/use-window-width.ts
Normal 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 };
|
||||||
|
};
|
@ -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}
|
||||||
|
Loading…
Reference in New Issue
Block a user