feat: use special color for non-proxy summary view dot item
This commit is contained in:
parent
c848d8414e
commit
babe27f9d2
4 changed files with 66 additions and 32 deletions
|
@ -4,7 +4,7 @@ import cx from 'clsx';
|
||||||
|
|
||||||
import { connect } from '../StateProvider';
|
import { connect } from '../StateProvider';
|
||||||
import { ProxyLatency } from './ProxyLatency';
|
import { ProxyLatency } from './ProxyLatency';
|
||||||
import { getProxies, getDelay } from '../../store/proxies';
|
import { NonProxyTypes, getProxies, getDelay } from '../../store/proxies';
|
||||||
|
|
||||||
import s0 from './Proxy.module.css';
|
import s0 from './Proxy.module.css';
|
||||||
|
|
||||||
|
@ -36,6 +36,18 @@ function getLabelColor({
|
||||||
return colorMap.na;
|
return colorMap.na;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getProxyDotBackgroundColor(
|
||||||
|
latency: {
|
||||||
|
number?: number;
|
||||||
|
},
|
||||||
|
proxyType: string
|
||||||
|
) {
|
||||||
|
if (NonProxyTypes.indexOf(proxyType) > -1) {
|
||||||
|
return 'linear-gradient(135deg, white 15%, #999 15% 30%, white 30% 45%, #999 45% 60%, white 60% 75%, #999 75% 90%, white 90% 100%)';
|
||||||
|
}
|
||||||
|
return getLabelColor(latency);
|
||||||
|
}
|
||||||
|
|
||||||
type ProxyProps = {
|
type ProxyProps = {
|
||||||
name: string;
|
name: string;
|
||||||
now?: boolean;
|
now?: boolean;
|
||||||
|
@ -48,11 +60,15 @@ type ProxyProps = {
|
||||||
function ProxySmallImpl({
|
function ProxySmallImpl({
|
||||||
now,
|
now,
|
||||||
name,
|
name,
|
||||||
|
proxy,
|
||||||
latency,
|
latency,
|
||||||
isSelectable,
|
isSelectable,
|
||||||
onClick,
|
onClick,
|
||||||
}: ProxyProps) {
|
}: ProxyProps) {
|
||||||
const color = useMemo(() => getLabelColor(latency), [latency]);
|
const color = useMemo(() => getProxyDotBackgroundColor(latency, proxy.type), [
|
||||||
|
latency,
|
||||||
|
proxy,
|
||||||
|
]);
|
||||||
const title = useMemo(() => {
|
const title = useMemo(() => {
|
||||||
let ret = name;
|
let ret = name;
|
||||||
if (latency && typeof latency.number === 'number') {
|
if (latency && typeof latency.number === 'number') {
|
||||||
|
@ -67,7 +83,7 @@ function ProxySmallImpl({
|
||||||
[s0.now]: now,
|
[s0.now]: now,
|
||||||
[s0.selectable]: isSelectable,
|
[s0.selectable]: isSelectable,
|
||||||
})}
|
})}
|
||||||
style={{ backgroundColor: color }}
|
style={{ background: color }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
isSelectable && onClick && onClick(name);
|
isSelectable && onClick && onClick(name);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -3,13 +3,18 @@ import memoizeOne from 'memoize-one';
|
||||||
import { Zap } from 'react-feather';
|
import { Zap } from 'react-feather';
|
||||||
|
|
||||||
import { connect, useStoreActions } from '../StateProvider';
|
import { connect, useStoreActions } from '../StateProvider';
|
||||||
import { getProxies } from '../../store/proxies';
|
import {
|
||||||
|
DelayMapping,
|
||||||
|
ProxiesMapping,
|
||||||
|
NonProxyTypes,
|
||||||
|
getProxies,
|
||||||
|
switchProxy,
|
||||||
|
} from '../../store/proxies';
|
||||||
import {
|
import {
|
||||||
getCollapsibleIsOpen,
|
getCollapsibleIsOpen,
|
||||||
getProxySortBy,
|
getProxySortBy,
|
||||||
getHideUnavailableProxies,
|
getHideUnavailableProxies,
|
||||||
} from '../../store/app';
|
} from '../../store/app';
|
||||||
import { switchProxy } from '../../store/proxies';
|
|
||||||
import CollapsibleSectionHeader from '../CollapsibleSectionHeader';
|
import CollapsibleSectionHeader from '../CollapsibleSectionHeader';
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
import { ProxyList, ProxyListSummaryView } from './ProxyList';
|
import { ProxyList, ProxyListSummaryView } from './ProxyList';
|
||||||
|
@ -83,11 +88,15 @@ function ProxyGroupImpl({ name, all, type, now, isOpen, apiConfig, dispatch }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSortDelay = (d, w) => {
|
const getSortDelay = (d, proxyInfo) => {
|
||||||
if (d && typeof d.number === 'number' && d.number > 0) {
|
if (d && typeof d.number === 'number' && d.number > 0) {
|
||||||
return d.number;
|
return d.number;
|
||||||
}
|
}
|
||||||
return w;
|
|
||||||
|
const type = proxyInfo && proxyInfo.type;
|
||||||
|
if (type && NonProxyTypes.indexOf(type) > -1) return 999998;
|
||||||
|
|
||||||
|
return 999999;
|
||||||
};
|
};
|
||||||
|
|
||||||
function filterAvailableProxies(list, delay) {
|
function filterAvailableProxies(list, delay) {
|
||||||
|
@ -105,27 +114,33 @@ function filterAvailableProxies(list, delay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProxySortingFns = {
|
const ProxySortingFns = {
|
||||||
Natural: (proxies, _delay) => {
|
Natural: (proxies: string[]) => proxies,
|
||||||
return proxies;
|
LatencyAsc: (
|
||||||
},
|
proxies: string[],
|
||||||
LatencyAsc: (proxies, delay) => {
|
delay: DelayMapping,
|
||||||
|
proxyMapping?: ProxiesMapping
|
||||||
|
) => {
|
||||||
return proxies.sort((a, b) => {
|
return proxies.sort((a, b) => {
|
||||||
const d1 = getSortDelay(delay[a], 999999);
|
const d1 = getSortDelay(delay[a], proxyMapping && proxyMapping[a]);
|
||||||
const d2 = getSortDelay(delay[b], 999999);
|
const d2 = getSortDelay(delay[b], proxyMapping && proxyMapping[b]);
|
||||||
return d1 - d2;
|
return d1 - d2;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
LatencyDesc: (proxies, delay) => {
|
LatencyDesc: (
|
||||||
|
proxies: string[],
|
||||||
|
delay: DelayMapping,
|
||||||
|
proxyMapping?: ProxiesMapping
|
||||||
|
) => {
|
||||||
return proxies.sort((a, b) => {
|
return proxies.sort((a, b) => {
|
||||||
const d1 = getSortDelay(delay[a], 999999);
|
const d1 = getSortDelay(delay[a], proxyMapping && proxyMapping[a]);
|
||||||
const d2 = getSortDelay(delay[b], 999999);
|
const d2 = getSortDelay(delay[b], proxyMapping && proxyMapping[b]);
|
||||||
return d2 - d1;
|
return d2 - d1;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NameAsc: (proxies) => {
|
NameAsc: (proxies: string[]) => {
|
||||||
return proxies.sort();
|
return proxies.sort();
|
||||||
},
|
},
|
||||||
NameDesc: (proxies) => {
|
NameDesc: (proxies: string[]) => {
|
||||||
return proxies.sort((a, b) => {
|
return proxies.sort((a, b) => {
|
||||||
if (a > b) return -1;
|
if (a > b) return -1;
|
||||||
if (a < b) return 1;
|
if (a < b) return 1;
|
||||||
|
@ -135,17 +150,18 @@ const ProxySortingFns = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function filterAvailableProxiesAndSortImpl(
|
function filterAvailableProxiesAndSortImpl(
|
||||||
all,
|
all: string[],
|
||||||
delay,
|
delay: DelayMapping,
|
||||||
hideUnavailableProxies,
|
hideUnavailableProxies: boolean,
|
||||||
proxySortBy
|
proxySortBy: string,
|
||||||
|
proxies?: ProxiesMapping
|
||||||
) {
|
) {
|
||||||
// all is freezed
|
// all is freezed
|
||||||
let filtered = [...all];
|
let filtered = [...all];
|
||||||
if (hideUnavailableProxies) {
|
if (hideUnavailableProxies) {
|
||||||
filtered = filterAvailableProxies(all, delay);
|
filtered = filterAvailableProxies(all, delay);
|
||||||
}
|
}
|
||||||
return ProxySortingFns[proxySortBy](filtered, delay);
|
return ProxySortingFns[proxySortBy](filtered, delay, proxies);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const filterAvailableProxiesAndSort = memoizeOne(
|
export const filterAvailableProxiesAndSort = memoizeOne(
|
||||||
|
@ -165,7 +181,8 @@ export const ProxyGroup = connect((s, { name, delay }) => {
|
||||||
all,
|
all,
|
||||||
delay,
|
delay,
|
||||||
hideUnavailableProxies,
|
hideUnavailableProxies,
|
||||||
proxySortBy
|
proxySortBy,
|
||||||
|
proxies
|
||||||
),
|
),
|
||||||
type,
|
type,
|
||||||
now,
|
now,
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
.list {
|
.list {
|
||||||
margin-top: 8px;
|
margin: 8px 0;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(auto, 280px));
|
grid-template-columns: repeat(auto-fill, minmax(auto, 280px));
|
||||||
grid-gap: 10px;
|
grid-gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.listSummaryView {
|
.listSummaryView {
|
||||||
margin-top: 8px;
|
margin: 8px 0;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, 13px);
|
grid-template-columns: repeat(auto-fill, 13px);
|
||||||
grid-gap: 10px;
|
grid-gap: 10px;
|
||||||
|
|
|
@ -6,7 +6,7 @@ type PrimitiveProxyType = 'Shadowsocks' | 'Snell' | 'Socks5' | 'Http' | 'Vmess';
|
||||||
|
|
||||||
type LatencyHistory = Array<{ time: string; delay: number }>;
|
type LatencyHistory = Array<{ time: string; delay: number }>;
|
||||||
|
|
||||||
type ProxyItem = {
|
export type ProxyItem = {
|
||||||
name: string;
|
name: string;
|
||||||
type: PrimitiveProxyType;
|
type: PrimitiveProxyType;
|
||||||
history: LatencyHistory;
|
history: LatencyHistory;
|
||||||
|
@ -26,11 +26,12 @@ type FormattedProxyProvider = Omit<ProxyProvider, 'proxies'> & {
|
||||||
proxies: string[];
|
proxies: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type ProxiesDict = { [name: string]: ProxyItem };
|
export type ProxiesMapping = Record<string, ProxyItem>;
|
||||||
|
export type DelayMapping = Record<string, { number?: number }>;
|
||||||
|
|
||||||
type ProxiesState = {
|
type ProxiesState = {
|
||||||
proxies: ProxiesDict;
|
proxies: ProxiesMapping;
|
||||||
delay: { [key: string]: { number: number } };
|
delay: DelayMapping;
|
||||||
groupNames: string[];
|
groupNames: string[];
|
||||||
proxyProviders?: FormattedProxyProvider[];
|
proxyProviders?: FormattedProxyProvider[];
|
||||||
dangleProxyNames?: string[];
|
dangleProxyNames?: string[];
|
||||||
|
@ -61,7 +62,7 @@ const noop = () => null;
|
||||||
// const ProxyGroupTypes = ['Fallback', 'URLTest', 'Selector', 'LoadBalance'];
|
// const ProxyGroupTypes = ['Fallback', 'URLTest', 'Selector', 'LoadBalance'];
|
||||||
// const ProxyTypes = ['Shadowsocks', 'Snell', 'Socks5', 'Http', 'Vmess'];
|
// const ProxyTypes = ['Shadowsocks', 'Snell', 'Socks5', 'Http', 'Vmess'];
|
||||||
|
|
||||||
const NonProxyTypes = [
|
export const NonProxyTypes = [
|
||||||
'Direct',
|
'Direct',
|
||||||
'Fallback',
|
'Fallback',
|
||||||
'Reject',
|
'Reject',
|
||||||
|
@ -189,7 +190,7 @@ async function closeGroupConns(
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveChain(
|
function resolveChain(
|
||||||
proxies: ProxiesDict,
|
proxies: ProxiesMapping,
|
||||||
groupName: string,
|
groupName: string,
|
||||||
itemName: string
|
itemName: string
|
||||||
) {
|
) {
|
||||||
|
|
Loading…
Reference in a new issue