mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-18 16:17:16 +00:00
e26cf1d3ed
The info page was a long key/value table followed by every link and two app dropdowns, and it rendered left-to-right even for Persian and Arabic. It now leads with a usage ring, the remaining quota and a stats grid, and splits the rest into Subscription / Apps / Configs tabs. - Status tells expired, data-used-up and disabled apart instead of one "Inactive", replacing the hard-coded English expiry chip. - The Apps tab keeps every Android and iOS app with its existing deep link, preselects the visitor's platform and adds Windows: Hiddify and Clash Verge Rev import directly, v2rayN copies the link. - fa-IR and ar-EG render right-to-left; URLs, IDs and sizes stay LTR. - The footer shows the support link and the client refresh interval, so subPageContext now carries subUpdates (also in ?format=info). - Status, days-left and app deep-link logic lives in subPageModel.ts, with unit tests pinning the deep links the page already shipped.
29 lines
970 B
TypeScript
29 lines
970 B
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { APP_ICONS } from '@/pages/sub/appIcons';
|
|
import { buildSubApps } from '@/pages/sub/subPageModel';
|
|
|
|
describe('APP_ICONS', () => {
|
|
it('has an icon for every app the subscription page offers on every platform', () => {
|
|
const apps = buildSubApps({
|
|
subUrl: 'https://sub.example.com/sub/abc',
|
|
sId: 'abc',
|
|
subTitle: '',
|
|
});
|
|
const names = [...new Set(Object.values(apps).flatMap((list) => list.map((app) => app.name)))];
|
|
|
|
expect(names.filter((name) => !APP_ICONS[name]?.src)).toEqual([]);
|
|
});
|
|
|
|
it('carries no icon for an app the page no longer offers', () => {
|
|
const apps = buildSubApps({
|
|
subUrl: 'https://sub.example.com/sub/abc',
|
|
sId: 'abc',
|
|
subTitle: '',
|
|
});
|
|
const offered = new Set(Object.values(apps).flatMap((list) => list.map((app) => app.name)));
|
|
|
|
expect(Object.keys(APP_ICONS).filter((name) => !offered.has(name))).toEqual([]);
|
|
});
|
|
});
|