🐛 fix(config): SubLink

This commit is contained in:
web@ppanel 2024-12-09 14:08:38 +07:00
parent 2cc18cf559
commit 1c619669a6
3 changed files with 50 additions and 24 deletions

View File

@ -32,6 +32,7 @@ import { useState } from 'react';
import useGlobalStore from '@/config/use-global'; import useGlobalStore from '@/config/use-global';
import { getStat } from '@/services/common/common'; import { getStat } from '@/services/common/common';
import { getPlatform } from '@/utils/common';
import CopyToClipboard from 'react-copy-to-clipboard'; import CopyToClipboard from 'react-copy-to-clipboard';
import Renewal from '../order/renewal'; import Renewal from '../order/renewal';
import ResetTraffic from '../order/reset-traffic'; import ResetTraffic from '../order/reset-traffic';
@ -58,16 +59,7 @@ export default function Page() {
return data.data as API.ApplicationResponse; return data.data as API.ApplicationResponse;
}, },
}); });
const [platform, setPlatform] = useState<keyof API.ApplicationResponse>('windows'); const [platform, setPlatform] = useState<keyof API.ApplicationResponse>(getPlatform());
const handleCopy = async (text: string) => {
try {
await navigator.clipboard.writeText(text);
toast.success(t('copySuccess'));
} catch {
toast.error(t('copyFailure'));
}
};
const { data } = useQuery({ const { data } = useQuery({
queryKey: ['getStat'], queryKey: ['getStat'],
@ -235,21 +227,26 @@ export default function Page() {
<Button size='sm' variant='secondary' className='px-1.5' asChild> <Button size='sm' variant='secondary' className='px-1.5' asChild>
<Link href={app.url!}>{t('download')}</Link> <Link href={app.url!}>{t('download')}</Link>
</Button> </Button>
<Button <CopyToClipboard
size='sm' text={url}
onClick={() => { onCopy={(text, result) => {
handleCopy(url);
const href = getAppSubLink(app.subscribe_type, url); const href = getAppSubLink(app.subscribe_type, url);
if (isBrowser() && href) { if (isBrowser() && href) {
window.location.href = href; window.location.href = href;
} else { } else if (result) {
toast.info(t('manualImportMessage')); toast.success(
<>
<p>{t('copySuccess')}</p>
<p>{t('manualImportMessage')}</p>
</>,
);
} }
}} }}
className='p-2'
> >
{t('import')} <Button size='sm' className='p-2'>
</Button> {t('import')}
</Button>
</CopyToClipboard>
</div> </div>
</div> </div>
))} ))}

View File

@ -95,12 +95,12 @@ export const useGlobalStore = create<GlobalStore>((set, get) => ({
getAppSubLink: (type: string, url: string) => { getAppSubLink: (type: string, url: string) => {
const name = get().common.site.site_name || ''; const name = get().common.site.site_name || '';
switch (type) { switch (type) {
// case 'Clash': case 'Clash':
// return `clash://install-config?url=${url}&name=${name}`; return `clash://install-config?url=${url}&name=${name}`;
case 'Hiddify': case 'Hiddify':
return `hiddify://import/${url}#${name}`; return `hiddify://import/${url}#${name}`;
case 'Loon': case 'Loon':
return `loon://import?sub=${encodeURI(url)}${name}`; return `loon://import?sub=${encodeURI(url)}`;
case 'NekoBox': case 'NekoBox':
return `sn://subscription?url=${url}&name=${name}`; return `sn://subscription?url=${url}&name=${name}`;
case 'NekoRay': case 'NekoRay':
@ -108,7 +108,11 @@ export const useGlobalStore = create<GlobalStore>((set, get) => ({
// case 'Netch': // case 'Netch':
// return ``; // return ``;
case 'Quantumult X': case 'Quantumult X':
return `quantumult-x://add-resource?remote-resource=${url}`; return `quantumult-x://add-resource?remote-resource=${encodeURIComponent(
JSON.stringify({
server_remote: [`${url}, tag=${name}`],
}),
)}`;
case 'Shadowrocket': case 'Shadowrocket':
return `shadowrocket://add/sub://${window.btoa(url)}?remark=${encodeURI(name)}`; return `shadowrocket://add/sub://${window.btoa(url)}?remark=${encodeURI(name)}`;
case 'Singbox': case 'Singbox':
@ -124,7 +128,7 @@ export const useGlobalStore = create<GlobalStore>((set, get) => ({
case 'V2rayNg': case 'V2rayNg':
return `v2rayng://install-sub?url=${encodeURI(url)}&name=${name}`; return `v2rayng://install-sub?url=${encodeURI(url)}&name=${name}`;
default: default:
return `clash://install-config?url=${encodeURI(url)}&name=${name}`; return '';
} }
}, },
})); }));

View File

@ -49,3 +49,28 @@ export function Logout() {
location.href = `/`; location.href = `/`;
} }
} }
export function getPlatform(): 'windows' | 'mac' | 'linux' | 'android' | 'ios' {
if (typeof navigator === 'undefined') {
console.log('This function can only run in a browser environment.');
return 'windows';
}
const userAgent = navigator.userAgent;
const platformPatterns: Record<string, RegExp> = {
windows: /Windows NT/,
mac: /Mac OS X/,
linux: /Linux/,
android: /Android/,
ios: /iPhone OS|iPad; CPU OS/,
};
for (const [platform, regex] of Object.entries(platformPatterns)) {
if (regex.test(userAgent)) {
return platform as 'windows' | 'mac' | 'linux' | 'android' | 'ios';
}
}
return 'windows';
}