Compare commits

..

2 Commits

Author SHA1 Message Date
YoVinchen d8e8d5f095 Merge branch 'main' into fix/endpoint-auto-select-persist 2026-01-12 17:47:25 +08:00
YoVinchen e14e3ec141 fix(provider): persist endpoint auto-select state
- Add endpointAutoSelect field to ProviderMeta for persistence
- Lift autoSelect state from EndpointSpeedTest to ProviderForm
- Save auto-select preference when provider is saved
- Restore preference when editing existing provider

Fixes https://github.com/farion1231/cc-switch/issues/589
2026-01-12 15:34:32 +08:00
+6 -30
View File
@@ -1,4 +1,4 @@
import { useMemo, useState, useEffect, useRef } from "react"; import { useMemo, useState, useEffect } from "react";
import { GripVertical, ChevronDown, ChevronUp } from "lucide-react"; import { GripVertical, ChevronDown, ChevronUp } from "lucide-react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import type { import type {
@@ -149,10 +149,6 @@ export function ProviderCard({
// 多套餐默认展开 // 多套餐默认展开
const [isExpanded, setIsExpanded] = useState(false); const [isExpanded, setIsExpanded] = useState(false);
// 操作按钮容器 ref,用于动态计算宽度
const actionsRef = useRef<HTMLDivElement>(null);
const [actionsWidth, setActionsWidth] = useState(0);
// 当检测到多套餐时自动展开 // 当检测到多套餐时自动展开
useEffect(() => { useEffect(() => {
if (hasMultiplePlans) { if (hasMultiplePlans) {
@@ -160,20 +156,6 @@ export function ProviderCard({
} }
}, [hasMultiplePlans]); }, [hasMultiplePlans]);
// 动态获取操作按钮宽度
useEffect(() => {
if (actionsRef.current) {
const updateWidth = () => {
const width = actionsRef.current?.offsetWidth || 0;
setActionsWidth(width);
};
updateWidth();
// 监听窗口大小变化
window.addEventListener("resize", updateWidth);
return () => window.removeEventListener("resize", updateWidth);
}
}, [onTest, onOpenTerminal]); // 按钮数量可能变化时重新计算
const handleOpenWebsite = () => { const handleOpenWebsite = () => {
if (!isClickableUrl) { if (!isClickableUrl) {
return; return;
@@ -299,13 +281,10 @@ export function ProviderCard({
</div> </div>
</div> </div>
<div <div className="relative flex items-center ml-auto min-w-0">
className="relative flex items-center ml-auto min-w-0 gap-3"
style={{ "--actions-width": `${actionsWidth || 320}px` } as React.CSSProperties}
>
{/* 用量信息区域 - hover 时向左移动,为操作按钮腾出空间 */} {/* 用量信息区域 - hover 时向左移动,为操作按钮腾出空间 */}
<div className="ml-auto"> <div className="ml-auto transition-transform duration-200 group-hover:-translate-x-[14.5rem] group-focus-within:-translate-x-[14.5rem] sm:group-hover:-translate-x-[16rem] sm:group-focus-within:-translate-x-[16rem]">
<div className="flex items-center gap-1 transition-transform duration-200 group-hover:-translate-x-[var(--actions-width)] group-focus-within:-translate-x-[var(--actions-width)]"> <div className="flex items-center gap-1">
{/* 多套餐时显示套餐数量,单套餐时显示详细信息 */} {/* 多套餐时显示套餐数量,单套餐时显示详细信息 */}
{hasMultiplePlans ? ( {hasMultiplePlans ? (
<div className="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400"> <div className="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400">
@@ -350,11 +329,8 @@ export function ProviderCard({
</div> </div>
</div> </div>
{/* 操作按钮区域 - 绝对定位在右侧,hover 时滑入,与用量信息保持间距 */} {/* 操作按钮区域 - 绝对定位在右侧,hover 时滑入 */}
<div <div className="absolute right-0 top-1/2 -translate-y-1/2 flex items-center gap-1.5 opacity-0 pointer-events-none group-hover:opacity-100 group-focus-within:opacity-100 group-hover:pointer-events-auto group-focus-within:pointer-events-auto transition-all duration-200 translate-x-2 group-hover:translate-x-0 group-focus-within:translate-x-0">
ref={actionsRef}
className="absolute right-0 top-1/2 -translate-y-1/2 flex items-center gap-1.5 pl-3 opacity-0 pointer-events-none group-hover:opacity-100 group-focus-within:opacity-100 group-hover:pointer-events-auto group-focus-within:pointer-events-auto transition-all duration-200 translate-x-2 group-hover:translate-x-0 group-focus-within:translate-x-0"
>
<ProviderActions <ProviderActions
isCurrent={isCurrent} isCurrent={isCurrent}
isTesting={isTesting} isTesting={isTesting}