mirror of
https://github.com/clash-verge-rev/clash-verge-rev
synced 2025-05-05 05:13:44 +08:00
refactor: auto-truncate long text on home profile card
fix: sync system proxy and TUN mode status indicators on home proxy mode card
This commit is contained in:
parent
a28887be8e
commit
f739836891
38
UPDATELOG.md
38
UPDATELOG.md
@ -2,21 +2,22 @@
|
||||
|
||||
**发行代号:拓**
|
||||
|
||||
感谢 Tunglies 对 Verge 后端重构,性能优化做出的重大贡献!
|
||||
|
||||
代号释义: 本次发布在功能上的大幅扩展。新首页设计为用户带来全新交互体验,DNS 覆写功能增强网络控制能力,解锁测试页面助力内容访问自由度提升,轻量模式提供灵活使用选择。此外,macOS 应用菜单集成、sidecar 模式、诊断信息导出等新特性进一步丰富了软件的适用场景。这些新增功能显著拓宽了 Clash Verge 的功能边界,为用户提供了更强大的工具和可能性。
|
||||
|
||||
#### 修复
|
||||
2.2.1 相对于 2.2.0(已下架不在提供) 修复了:
|
||||
1. **首页**
|
||||
- 修复 Direct 模式首页无法渲染。
|
||||
- 修复 首页启用轻量模式导致 ClashVergeRev 从托盘退出。
|
||||
- 增加 首页文本过长自动截断
|
||||
- 修复 系统代理标识判断不准的问题
|
||||
2. **系统**
|
||||
- 修复 MacOS 无法使用快捷键粘贴/选择/复制订阅地址。
|
||||
|
||||
---
|
||||
|
||||
## v2.2.0
|
||||
|
||||
**发行代号:拓**
|
||||
|
||||
代号释义: 本次发布在功能上的大幅扩展。新首页设计为用户带来全新交互体验,DNS 覆写功能增强网络控制能力,解锁测试页面助力内容访问自由度提升,轻量模式提供灵活使用选择。此外,macOS 应用菜单集成、sidecar 模式、诊断信息导出等新特性进一步丰富了软件的适用场景。这些新增功能显著拓宽了 Clash Verge 的功能边界,为用户提供了更强大的工具和可能性。
|
||||
## v2.2.0(已下架不在提供)
|
||||
|
||||
#### 新增功能
|
||||
1. **首页**
|
||||
@ -27,8 +28,8 @@
|
||||
- 限制首页配置文件卡片URL长度。
|
||||
|
||||
2. **DNS 设置与覆写**
|
||||
- 默认启用 DNS 设置。
|
||||
- 新增 DNS 覆写功能。
|
||||
- 默认启用 DNS 覆写。
|
||||
|
||||
3. **解锁测试**
|
||||
- 新增解锁测试页面。
|
||||
@ -38,10 +39,11 @@
|
||||
- 添加自动轻量模式定时器。
|
||||
|
||||
5. **系统支持**
|
||||
- Mihomo(meta)内核升级 1.19.3
|
||||
- macOS 支持 CMD+W 关闭窗口。
|
||||
- 新增 macOS 应用菜单。
|
||||
- 添加管理员权限提示。
|
||||
- 新增 sidecar 模式。
|
||||
- 添加 macOS 安装服务时候的管理员权限提示。
|
||||
- 新增 sidecar(用户空间启动内核) 模式。
|
||||
|
||||
6. **其他**
|
||||
- 增强延迟测试日志和错误处理。
|
||||
@ -53,28 +55,28 @@
|
||||
- 修复 Windows 热键崩溃。
|
||||
- 修复 macOS 无框标题。
|
||||
- 修复 macOS 静默启动崩溃。
|
||||
- 修复 macOS tray图标错位到左上角的问题。
|
||||
- 修复 Windows/Linux 运行时崩溃。
|
||||
- 修复 Netflix 检测错误。
|
||||
- 修复服务模式检测失败。
|
||||
- 修复 Win10 阴影和边框问题。
|
||||
|
||||
2. **性能**
|
||||
- 优化小数值速度更新。
|
||||
- 增加请求超时至 60 秒。
|
||||
- 修复代理节点选择同步。
|
||||
- 优化修改verge配置性能。
|
||||
|
||||
3. **构建**
|
||||
2. **构建**
|
||||
- 修复构建失败问题。
|
||||
|
||||
#### 优化
|
||||
1. **性能**
|
||||
- 重构后端,巨幅性能优化。
|
||||
- 优化首页组件性能。
|
||||
- 优化流量图表资源使用。
|
||||
- 提升代理组列表滚动性能。
|
||||
- 加快应用退出速度。
|
||||
- 加快进入轻量模式速度。
|
||||
- 优化小数值速度更新。
|
||||
- 增加请求超时至 60 秒。
|
||||
- 修复代理节点选择同步。
|
||||
- 优化修改verge配置性能。
|
||||
|
||||
2. **重构**
|
||||
- 重构后端,巨幅性能优化。
|
||||
- 优化定时器管理。
|
||||
- 重构 MihomoManager 处理流量。
|
||||
- 优化 WebSocket 连接。
|
||||
|
@ -31,6 +31,16 @@ export const EnhancedCard = ({
|
||||
const theme = useTheme();
|
||||
const isDark = theme.palette.mode === "dark";
|
||||
|
||||
// 统一的标题截断样式
|
||||
const titleTruncateStyle = {
|
||||
minWidth: 0,
|
||||
maxWidth: "100%",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
display: "block"
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@ -52,7 +62,13 @@ export const EnhancedCard = ({
|
||||
borderColor: "divider",
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Box sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
minWidth: 0,
|
||||
flex: 1,
|
||||
overflow: "hidden"
|
||||
}}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@ -62,21 +78,32 @@ export const EnhancedCard = ({
|
||||
width: 38,
|
||||
height: 38,
|
||||
mr: 1.5,
|
||||
flexShrink: 0,
|
||||
backgroundColor: alpha(theme.palette[iconColor].main, 0.12),
|
||||
color: theme.palette[iconColor].main,
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
</Box>
|
||||
{typeof title === "string" ? (
|
||||
<Typography variant="h6" fontWeight="medium" fontSize={18}>
|
||||
{title}
|
||||
</Typography>
|
||||
) : (
|
||||
title
|
||||
)}
|
||||
<Box sx={{ minWidth: 0, flex: 1 }}>
|
||||
{typeof title === "string" ? (
|
||||
<Typography
|
||||
variant="h6"
|
||||
fontWeight="medium"
|
||||
fontSize={18}
|
||||
sx={titleTruncateStyle}
|
||||
title={title}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
) : (
|
||||
<Box sx={titleTruncateStyle}>
|
||||
{title}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
{action}
|
||||
{action && <Box sx={{ ml: 2, flexShrink: 0 }}>{action}</Box>}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
|
@ -35,19 +35,10 @@ const round = keyframes`
|
||||
`;
|
||||
|
||||
// 辅助函数解析URL和过期时间
|
||||
const parseUrl = (url?: string, maxLength: number = 25) => {
|
||||
const parseUrl = (url?: string) => {
|
||||
if (!url) return "-";
|
||||
let parsedUrl = "";
|
||||
if (url.startsWith("http")) {
|
||||
parsedUrl = new URL(url).host;
|
||||
} else {
|
||||
parsedUrl = "local";
|
||||
}
|
||||
|
||||
if (parsedUrl.length > maxLength) {
|
||||
return parsedUrl.substring(0, maxLength - 3) + "...";
|
||||
}
|
||||
return parsedUrl;
|
||||
if (url.startsWith("http")) return new URL(url).host;
|
||||
return "local";
|
||||
};
|
||||
|
||||
const parseExpire = (expire?: number) => {
|
||||
@ -81,6 +72,14 @@ export interface HomeProfileCardProps {
|
||||
onProfileUpdated?: () => void;
|
||||
}
|
||||
|
||||
// 添加一个通用的截断样式
|
||||
const truncateStyle = {
|
||||
maxWidth: "calc(100% - 28px)",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap"
|
||||
};
|
||||
|
||||
// 提取独立组件减少主组件复杂度
|
||||
const ProfileDetails = ({ current, onUpdateProfile, updating }: {
|
||||
current: ProfileItem;
|
||||
@ -109,31 +108,55 @@ const ProfileDetails = ({ current, onUpdateProfile, updating }: {
|
||||
{current.url && (
|
||||
<Stack direction="row" alignItems="center" spacing={1}>
|
||||
<DnsOutlined fontSize="small" color="action" />
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{t("From")}:{" "}
|
||||
<Typography variant="body2" color="text.secondary" noWrap sx={{ display: "flex", alignItems: "center" }}>
|
||||
<span style={{ flexShrink: 0 }}>{t("From")}: </span>
|
||||
{current.home ? (
|
||||
<Link
|
||||
component="button"
|
||||
fontWeight="medium"
|
||||
onClick={() => current.home && openWebUrl(current.home)}
|
||||
sx={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center"
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
minWidth: 0,
|
||||
maxWidth: "calc(100% - 40px)",
|
||||
ml: 0.5
|
||||
}}
|
||||
title={parseUrl(current.url)}
|
||||
>
|
||||
{parseUrl(current.url)}
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
minWidth: 0,
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
{parseUrl(current.url)}
|
||||
</Typography>
|
||||
<LaunchOutlined
|
||||
fontSize="inherit"
|
||||
sx={{ ml: 0.5, fontSize: "0.8rem", opacity: 0.7, flexShrink: 0 }}
|
||||
/>
|
||||
</Link>
|
||||
) : (
|
||||
<Box
|
||||
component="span"
|
||||
<Typography
|
||||
component="span"
|
||||
fontWeight="medium"
|
||||
sx={{
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
minWidth: 0,
|
||||
flex: 1,
|
||||
ml: 0.5
|
||||
}}
|
||||
title={parseUrl(current.url)}
|
||||
>
|
||||
{parseUrl(current.url)}
|
||||
</Box>
|
||||
</Typography>
|
||||
)}
|
||||
</Typography>
|
||||
</Stack>
|
||||
@ -285,16 +308,30 @@ export const HomeProfileCard = ({ current, onProfileUpdated }: HomeProfileCardPr
|
||||
fontSize={18}
|
||||
onClick={() => current.home && openWebUrl(current.home)}
|
||||
sx={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
color: "inherit",
|
||||
textDecoration: "none",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
minWidth: 0,
|
||||
maxWidth: "100%",
|
||||
"& > span": {
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
flex: 1
|
||||
}
|
||||
}}
|
||||
title={current.name}
|
||||
>
|
||||
{current.name}
|
||||
<span>{current.name}</span>
|
||||
<LaunchOutlined
|
||||
fontSize="inherit"
|
||||
sx={{ ml: 0.5, fontSize: "0.8rem", opacity: 0.7 }}
|
||||
sx={{
|
||||
ml: 0.5,
|
||||
fontSize: "0.8rem",
|
||||
opacity: 0.7,
|
||||
flexShrink: 0
|
||||
}}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
|
@ -24,6 +24,7 @@ import {
|
||||
getAutotemProxy,
|
||||
getRunningMode,
|
||||
} from "@/services/cmds";
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
|
||||
const LOCAL_STORAGE_TAB_KEY = "clash-verge-proxy-active-tab";
|
||||
|
||||
@ -151,6 +152,10 @@ export const ProxyTunCard: FC = () => {
|
||||
// 获取代理状态信息
|
||||
const { data: sysproxy } = useSWR("getSystemProxy", getSystemProxy);
|
||||
const { data: runningMode } = useSWR("getRunningMode", getRunningMode);
|
||||
const { verge } = useVerge();
|
||||
|
||||
// 从verge配置中获取开关状态
|
||||
const { enable_system_proxy, enable_tun_mode } = verge ?? {};
|
||||
|
||||
// 是否以sidecar模式运行
|
||||
const isSidecarMode = runningMode === "sidecar";
|
||||
@ -170,7 +175,7 @@ export const ProxyTunCard: FC = () => {
|
||||
const tabDescription = useMemo(() => {
|
||||
if (activeTab === "system") {
|
||||
return {
|
||||
text: sysproxy?.enable
|
||||
text: enable_system_proxy
|
||||
? t("System Proxy Enabled")
|
||||
: t("System Proxy Disabled"),
|
||||
tooltip: t("System Proxy Info")
|
||||
@ -179,11 +184,13 @@ export const ProxyTunCard: FC = () => {
|
||||
return {
|
||||
text: isSidecarMode
|
||||
? t("TUN Mode Service Required")
|
||||
: t("TUN Mode Intercept Info"),
|
||||
: enable_tun_mode
|
||||
? t("TUN Mode Enabled")
|
||||
: t("TUN Mode Disabled"),
|
||||
tooltip: t("Tun Mode Info")
|
||||
};
|
||||
}
|
||||
}, [activeTab, sysproxy?.enable, isSidecarMode, t]);
|
||||
}, [activeTab, enable_system_proxy, enable_tun_mode, isSidecarMode, t]);
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
||||
@ -203,13 +210,14 @@ export const ProxyTunCard: FC = () => {
|
||||
onClick={() => handleTabChange("system")}
|
||||
icon={ComputerRounded}
|
||||
label={t("System Proxy")}
|
||||
hasIndicator={sysproxy?.enable}
|
||||
hasIndicator={enable_system_proxy}
|
||||
/>
|
||||
<TabButton
|
||||
isActive={activeTab === "tun"}
|
||||
onClick={() => handleTabChange("tun")}
|
||||
icon={TroubleshootRounded}
|
||||
label={t("Tun Mode")}
|
||||
hasIndicator={enable_tun_mode && !isSidecarMode}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
|
@ -120,17 +120,7 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
{proxy_auto_config ? (
|
||||
autoproxy?.enable ? (
|
||||
<PlayCircleOutlineRounded
|
||||
sx={{ color: "success.main", mr: 1.5, fontSize: 28 }}
|
||||
/>
|
||||
) : (
|
||||
<PauseCircleOutlineRounded
|
||||
sx={{ color: "text.disabled", mr: 1.5, fontSize: 28 }}
|
||||
/>
|
||||
)
|
||||
) : sysproxy?.enable ? (
|
||||
{enable_system_proxy ? (
|
||||
<PlayCircleOutlineRounded
|
||||
sx={{ color: "success.main", mr: 1.5, fontSize: 28 }}
|
||||
/>
|
||||
|
@ -570,7 +570,6 @@
|
||||
"No": "No",
|
||||
"Failed": "Failed",
|
||||
"Completed": "Completed",
|
||||
"Bahamut Anime": "Bahamut Anime",
|
||||
"Disallowed ISP": "Disallowed ISP",
|
||||
"Originals Only": "Originals Only",
|
||||
"No (IP Banned By Disney+)": "No (IP Banned By Disney+)",
|
||||
|
@ -570,7 +570,6 @@
|
||||
"No": "不支持",
|
||||
"Failed": "测试失败",
|
||||
"Completed": "检测完成",
|
||||
"Bahamut Anime": "动画疯",
|
||||
"Disallowed ISP": "不允许的 ISP",
|
||||
"Originals Only": "仅限原创",
|
||||
"No (IP Banned By Disney+)": "不支持(IP被Disney+禁止)",
|
||||
|
Loading…
x
Reference in New Issue
Block a user