Improved proxy selector view

This commit is contained in:
coolcoala
2025-08-23 03:10:46 +03:00
parent 3ecd73f430
commit 967f21cc23

View File

@@ -41,12 +41,14 @@ interface IProxyGroup {
} }
// --- Вспомогательная функция для цвета задержки --- // --- Вспомогательная функция для цвета задержки ---
function getDelayBadgeVariant( function getDelayColorClasses(delayValue: number): string {
delayValue: number, if (delayValue < 0) {
): "default" | "secondary" | "destructive" | "outline" { return "text-muted-foreground border-border";
if (delayValue < 0) return "secondary"; }
if (delayValue >= 150) return "destructive"; if (delayValue >= 150) {
return "default"; return "text-destructive border-destructive/40";
}
return "text-green-600 border-green-500/40 dark:text-green-400 dark:border-green-400/30";
} }
// --- Дочерний компонент для элемента списка с "живым" обновлением пинга --- // --- Дочерний компонент для элемента списка с "живым" обновлением пинга ---
@@ -80,20 +82,21 @@ const ProxySelectItem = ({
}, [proxyName, groupName]); }, [proxyName, groupName]);
return ( return (
<SelectItem key={proxyName} value={proxyName}> <SelectItem key={proxyName} value={proxyName}>
<div className="flex items-center justify-between w-full"> <div className="flex items-center justify-between w-full">
<span className="truncate">{proxyName}</span> <Badge
<Badge variant="outline"
variant={getDelayBadgeVariant(delay)} className={cn(
className={cn( "mr-2 flex-shrink-0 px-2 h-5 w-8 justify-center transition-colors duration-300",
"ml-4 flex-shrink-0 px-2 h-5 justify-center transition-colors duration-300", getDelayColorClasses(delay),
isJustUpdated && "bg-primary/20 border-primary/50", isJustUpdated && "bg-primary/10 border-primary/50",
)} )}
> >
{delay < 0 || delay > 10000 ? "---" : delay} {delay < 0 || delay > 10000 ? "---" : delay}
</Badge> </Badge>
</div> <span className="truncate">{proxyName}</span>
</SelectItem> </div>
</SelectItem>
); );
}; };
@@ -259,11 +262,21 @@ export const ProxySelectors: React.FC = () => {
?.all; ?.all;
if (sourceList) { if (sourceList) {
options = sourceList const rawOptions = sourceList
.map((proxy: any) => ({ .map((proxy: any) => ({
name: typeof proxy === "string" ? proxy : proxy.name, name: typeof proxy === "string" ? proxy : proxy.name,
})) }))
.filter((p: { name: string }) => p.name); .filter((p: { name: string }) => p.name);
// Удаляем дубли по имени прокси
const uniqueNames = new Set<string>();
options = rawOptions.filter((proxy: any) => {
if (!uniqueNames.has(proxy.name)) {
uniqueNames.add(proxy.name);
return true;
}
return false;
});
} }
if (sortType === "name") if (sortType === "name")
@@ -345,44 +358,37 @@ export const ProxySelectors: React.FC = () => {
{sortType === "name" && <WholeWord className="h-4 w-4" />} {sortType === "name" && <WholeWord className="h-4 w-4" />}
</Button> </Button>
</span> </span>
</TooltipTrigger>
<TooltipContent>
{sortType === "default" && <p>{t("Sort by default")}</p>}
{sortType === "delay" && <p>{t("Sort by delay")}</p>}
{sortType === "name" && <p>{t("Sort by name")}</p>}
</TooltipContent>
</Tooltip>
</div>
<Select
value={selectedProxy}
onValueChange={handleProxyChange}
disabled={isDirectMode}
onOpenChange={handleProxyListOpen}
>
<SelectTrigger className="w-100">
<Tooltip>
<TooltipTrigger asChild>
<span className="truncate">
<SelectValue placeholder={t("Select a proxy...")} />
</span>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent> <TooltipContent>
<p>{selectedProxy}</p> {sortType === "default" && <p>{t("Sort by default")}</p>}
{sortType === "delay" && <p>{t("Sort by delay")}</p>}
{sortType === "name" && <p>{t("Sort by name")}</p>}
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</SelectTrigger> </div>
<SelectContent> <Select
{proxyOptions.map((proxy) => ( value={selectedProxy}
<ProxySelectItem onValueChange={handleProxyChange}
key={proxy.name} disabled={isDirectMode}
proxyName={proxy.name} onOpenChange={handleProxyListOpen}
groupName={selectedGroup} >
/> <SelectTrigger className="w-100">
))} <span className="truncate">
</SelectContent> <SelectValue placeholder={t("Select a proxy...")} />
</Select> </span>
</SelectTrigger>
<SelectContent>
{proxyOptions.map((proxy) => (
<ProxySelectItem
key={proxy.name}
proxyName={proxy.name}
groupName={selectedGroup}
/>
))}
</SelectContent>
</Select>
</div>
</div> </div>
</div> </TooltipProvider>
</TooltipProvider>
); );
}; };