the alphabetical index has been removed, and additional information about proxies is now hidden by default
This commit is contained in:
@@ -23,14 +23,8 @@ import { ProxyRender } from "./proxy-render";
|
|||||||
import delayManager from "@/services/delay";
|
import delayManager from "@/services/delay";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { ScrollTopButton } from "../layout/scroll-top-button";
|
import { ScrollTopButton } from "../layout/scroll-top-button";
|
||||||
import {
|
|
||||||
Tooltip,
|
|
||||||
TooltipContent,
|
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger,
|
|
||||||
} from "@/components/ui/tooltip";
|
|
||||||
|
|
||||||
// Вспомогательная функция для плавного скролла (взята из вашего оригинального файла)
|
|
||||||
function throttle<T extends (...args: any[]) => any>(
|
function throttle<T extends (...args: any[]) => any>(
|
||||||
func: T,
|
func: T,
|
||||||
wait: number,
|
wait: number,
|
||||||
@@ -59,36 +53,6 @@ function throttle<T extends (...args: any[]) => any>(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Компонент для одной буквы в навигаторе, переписанный на Tailwind и shadcn/ui
|
|
||||||
const LetterItem = memo(
|
|
||||||
({
|
|
||||||
name,
|
|
||||||
onClick,
|
|
||||||
getFirstChar,
|
|
||||||
}: {
|
|
||||||
name: string;
|
|
||||||
onClick: (name: string) => void;
|
|
||||||
getFirstChar: (str: string) => string;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<TooltipProvider delayDuration={100}>
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<div
|
|
||||||
className="flex items-center justify-center w-6 h-6 text-xs rounded-md border shadow-sm cursor-pointer text-muted-foreground transition-transform hover:bg-accent hover:text-accent-foreground hover:scale-125"
|
|
||||||
onClick={() => onClick(name)}
|
|
||||||
>
|
|
||||||
{getFirstChar(name)}
|
|
||||||
</div>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent side="left">
|
|
||||||
<p>{name}</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
mode: string;
|
mode: string;
|
||||||
@@ -108,33 +72,6 @@ export const ProxyGroups = memo((props: Props) => {
|
|||||||
const scrollerRef = useRef<Element | null>(null);
|
const scrollerRef = useRef<Element | null>(null);
|
||||||
const [showScrollTop, setShowScrollTop] = useState(false);
|
const [showScrollTop, setShowScrollTop] = useState(false);
|
||||||
|
|
||||||
// Мемоизация вычисления букв и индексов для навигатора
|
|
||||||
const { groupFirstLetters, letterIndexMap } = useMemo(() => {
|
|
||||||
const letters = new Set<string>();
|
|
||||||
const indexMap: Record<string, number> = {};
|
|
||||||
renderList.forEach((item, index) => {
|
|
||||||
if (item.type === 0) {
|
|
||||||
// type 0 - это заголовок группы
|
|
||||||
const fullName = item.group.name;
|
|
||||||
letters.add(fullName);
|
|
||||||
if (!(fullName in indexMap)) {
|
|
||||||
indexMap[fullName] = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
groupFirstLetters: Array.from(letters),
|
|
||||||
letterIndexMap: indexMap,
|
|
||||||
};
|
|
||||||
}, [renderList]);
|
|
||||||
|
|
||||||
// Мемоизация функции для получения первой буквы (поддерживает эмодзи)
|
|
||||||
const getFirstChar = useCallback((str: string) => {
|
|
||||||
const match = str.match(
|
|
||||||
/\p{Regional_Indicator}{2}|\p{Extended_Pictographic}|\p{L}|\p{N}|./u,
|
|
||||||
);
|
|
||||||
return match ? match[0] : str.charAt(0);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Обработчик скролла для показа/скрытия кнопки "Наверх"
|
// Обработчик скролла для показа/скрытия кнопки "Наверх"
|
||||||
const handleScroll = useCallback(
|
const handleScroll = useCallback(
|
||||||
@@ -161,20 +98,6 @@ export const ProxyGroups = memo((props: Props) => {
|
|||||||
virtuosoRef.current?.scrollTo({ top: 0, behavior: "smooth" });
|
virtuosoRef.current?.scrollTo({ top: 0, behavior: "smooth" });
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleLetterClick = useCallback(
|
|
||||||
(name: string) => {
|
|
||||||
const index = letterIndexMap[name];
|
|
||||||
if (index !== undefined) {
|
|
||||||
virtuosoRef.current?.scrollToIndex({
|
|
||||||
index,
|
|
||||||
align: "start",
|
|
||||||
behavior: "smooth",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[letterIndexMap],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Вся бизнес-логика из оригинального файла
|
// Вся бизнес-логика из оригинального файла
|
||||||
const handleChangeProxy = useLockFn(
|
const handleChangeProxy = useLockFn(
|
||||||
async (group: IProxyGroupItem, proxy: IProxyItem) => {
|
async (group: IProxyGroupItem, proxy: IProxyItem) => {
|
||||||
@@ -288,18 +211,6 @@ export const ProxyGroups = memo((props: Props) => {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<ScrollTopButton show={showScrollTop} onClick={scrollToTop} />
|
<ScrollTopButton show={showScrollTop} onClick={scrollToTop} />
|
||||||
|
|
||||||
{/* Алфавитный указатель */}
|
|
||||||
<div className="fixed top-1/2 right-4 z-50 flex -translate-y-1/2 flex-col gap-1 rounded-md bg-background/50 p-1 backdrop-blur-sm">
|
|
||||||
{groupFirstLetters.map((name) => (
|
|
||||||
<LetterItem
|
|
||||||
key={name}
|
|
||||||
name={name}
|
|
||||||
onClick={handleLetterClick}
|
|
||||||
getFirstChar={getFirstChar}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type HeadStateStorage = Record<string, Record<string, HeadState>>;
|
|||||||
const HEAD_STATE_KEY = "proxy-head-state";
|
const HEAD_STATE_KEY = "proxy-head-state";
|
||||||
export const DEFAULT_STATE: HeadState = {
|
export const DEFAULT_STATE: HeadState = {
|
||||||
open: false,
|
open: false,
|
||||||
showType: true,
|
showType: false,
|
||||||
sortType: 0,
|
sortType: 0,
|
||||||
filterText: "",
|
filterText: "",
|
||||||
textState: null,
|
textState: null,
|
||||||
|
|||||||
Reference in New Issue
Block a user