diff --git a/frontend/src/env.d.ts b/frontend/src/env.d.ts index 2dbc5aa13..6aff7f8be 100644 --- a/frontend/src/env.d.ts +++ b/frontend/src/env.d.ts @@ -15,6 +15,8 @@ interface SubPageData { subJsonUrl?: string; subClashUrl?: string; subTitle?: string; + subSupportUrl?: string; + subUpdates?: number; links?: string[]; emails?: string[]; datepicker?: 'gregorian' | 'jalalian'; diff --git a/frontend/src/pages/inbounds/qr/QrPanel.css b/frontend/src/pages/inbounds/qr/QrPanel.css index b2e2c1d8b..d7d3955c8 100644 --- a/frontend/src/pages/inbounds/qr/QrPanel.css +++ b/frontend/src/pages/inbounds/qr/QrPanel.css @@ -28,7 +28,7 @@ .qr-panel-canvas .qr-code { cursor: pointer; background: #fff; - border-radius: 4px; + border-radius: 8px; line-height: 0; } diff --git a/frontend/src/pages/inbounds/qr/QrPanel.tsx b/frontend/src/pages/inbounds/qr/QrPanel.tsx index a035a7175..482b77935 100644 --- a/frontend/src/pages/inbounds/qr/QrPanel.tsx +++ b/frontend/src/pages/inbounds/qr/QrPanel.tsx @@ -141,7 +141,7 @@ export default function QrPanel({ value={value} size={size} errorLevel="L" - marginSize={4} + marginSize={2} type="svg" bordered={false} color="#000000" diff --git a/frontend/src/pages/sub/SubAppsTab.tsx b/frontend/src/pages/sub/SubAppsTab.tsx new file mode 100644 index 000000000..3ada0bfee --- /dev/null +++ b/frontend/src/pages/sub/SubAppsTab.tsx @@ -0,0 +1,60 @@ +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Button, Segmented } from 'antd'; +import { AndroidOutlined, AppleOutlined } from '@ant-design/icons'; + +import { APP_ICONS } from './appIcons'; +import type { AppPlatform, SubApp } from './subPageModel'; + +interface SubAppsTabProps { + apps: Record; + initialPlatform: AppPlatform; + onOpen: (url: string) => void; +} + +const PLATFORM_OPTIONS = [ + { value: 'android' as const, label: 'Android', icon: }, + { value: 'ios' as const, label: 'iOS', icon: }, +]; + +function AppIcon({ name }: { name: string }) { + const icon = APP_ICONS[name]; + if (!icon) { + return ( + + ); + } + if (icon.tinted) { + const mask = `url("${icon.src}")`; + return ( +