feat(hosts): add drag-and-drop and global subscription ordering (#6895)

Hosts already had one saved order on the Hosts page, but subscriptions honoured
it only inside each inbound, so a host of a later inbound could never come before
one of an earlier inbound (#6894). A new opt-in setting makes raw/base64,
Clash/Mihomo and JSON subscriptions follow the Hosts page order across inbounds;
the default keeps today's inbound-first output unchanged. The Hosts table gains
drag-and-drop reordering next to the Up/Down buttons, on a pointer-reorder hook
the Routing Rules table now shares.
This commit is contained in:
Hamed
2026-10-24 08:57:47 +03:30
committed by GitHub
parent a69ae2b0ea
commit 136c1c4d50
51 changed files with 1643 additions and 149 deletions
@@ -11,7 +11,7 @@ import {
import { useTranslation } from 'react-i18next';
import { useNavigate, useSearchParams } from 'react-router';
import type { AllSetting } from '@/models/setting';
import type { SubProfileMode } from '@/schemas/setting';
import type { SubProfileMode, SubHostSortMode } from '@/schemas/setting';
import { onNumber } from '@/utils/onNumber';
import { DefaultSettingTag, SettingListItem } from '@/components/ui';
import { RemarkTemplateField } from '@/components/form';
@@ -95,6 +95,22 @@ export default function SubscriptionGeneralTab({
}
/>
)}
<SettingListItem
paddings="small"
title={t('pages.settings.subHostSortMode')}
description={t('pages.settings.subHostSortModeDesc')}
>
<Select
id="sub-host-sort-mode"
aria-label={t('pages.settings.subHostSortMode')}
value={allSetting.subHostSortMode}
onChange={(value: SubHostSortMode) => updateSetting({ subHostSortMode: value })}
options={[
{ value: 'inbound-first', label: t('pages.settings.subHostSortInbound') },
{ value: 'hosts-first', label: t('pages.settings.subHostSortHosts') },
]}
/>
</SettingListItem>
<SettingListItem
paddings="small"
title={t('pages.settings.subListen')}