订阅列表可以调顺序

每行末尾两个箭头,鼠标划过那一行才显现。proxy-providers 是映射,顺序只
影响界面呈现,内核不看;交换的是两个用户订阅在映射里的位置,中间夹着的
链式副本留在原地——它们不在列表上,跟着挪只会把 diff 撑大。

顺序写在配置文件里,所以走保存链路,不是运行时动作。
This commit is contained in:
2026-08-14 14:06:11 +08:00
parent 23aa28fbea
commit 0f0ac3c4b7
4 changed files with 175 additions and 19 deletions
+30
View File
@@ -238,6 +238,36 @@ export function renameSubscription(
return next
}
/**
* 把一个订阅在列表里上移或下移一位。
*
* 顺序只是呈现顺序,内核不看 `proxy-providers` 里条目的先后。交换的是两个用户订阅在
* 映射里的位置,中间夹着的副本留在原地——它们不在列表上,跟着挪只会把 diff 撑大。
* 已经在头(尾)还要上(下)移时原样返回,调用方据此不发起保存。
*/
export function moveSubscription(
data: ConfigObject,
name: string,
delta: -1 | 1,
): ConfigObject {
const entries = Object.entries(providersOf(data))
const keys = entries.map(([key]) => key)
const mine = keys.filter((key) => !isGenerated(key))
const at = mine.indexOf(name)
const target = mine[at + delta]
if (at < 0 || target === undefined) return data
const from = keys.indexOf(name)
const onto = keys.indexOf(target)
const order = [...entries]
order[from] = entries[onto]!
order[onto] = entries[from]!
const next = { ...data }
next['proxy-providers'] = Object.fromEntries(order)
return next
}
/** 删除一个订阅。删到最后一个时把整个键去掉,不在文件里留空映射。 */
export function removeSubscription(data: ConfigObject, name: string): ConfigObject {
const providers = { ...providersOf(data) }