mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-11-12 08:25:07 +00:00
45 lines
1.5 KiB
Swift
45 lines
1.5 KiB
Swift
import Combine
|
|
|
|
/// 目录树折叠状态(纯窗口呈现状态):组合根持有的长寿命对象。destination 切换
|
|
/// 会销毁分区子树里的 `@State`,折叠状态因此必须活在视图层级之外;服务器管理分区
|
|
/// 侧栏专用,首页另行持久化自己的状态。语义=收起的分组身份集合,
|
|
/// 缺省全部展开;不落盘,进程重启回全展开基线。
|
|
@MainActor
|
|
final class CatalogExpansionState: ObservableObject {
|
|
@Published private(set) var collapsedGroupIDs: Set<NodeID> = []
|
|
|
|
func isCollapsed(_ id: NodeID) -> Bool {
|
|
collapsedGroupIDs.contains(id)
|
|
}
|
|
|
|
func toggleCollapsed(_ id: NodeID) {
|
|
if collapsedGroupIDs.contains(id) {
|
|
collapsedGroupIDs.remove(id)
|
|
} else {
|
|
collapsedGroupIDs.insert(id)
|
|
}
|
|
}
|
|
|
|
/// 收起包含选中节点的组时,选择该组,避免详情指向隐藏的后代。
|
|
func setExpanded(_ expanded: Bool, for group: CatalogTreeNode, selection: NodeID?) -> NodeID? {
|
|
if expanded {
|
|
collapsedGroupIDs.remove(group.id)
|
|
} else {
|
|
collapsedGroupIDs.insert(group.id)
|
|
if let selection, selection != group.id, group.find(selection) != nil {
|
|
return group.id
|
|
}
|
|
}
|
|
return selection
|
|
}
|
|
|
|
/// 创建成功后仅展开祖先,保留其他分组的折叠状态。
|
|
func reveal(_ id: NodeID, in tree: CatalogTreeSnapshot) {
|
|
var parent = tree.node(withID: id)?.parentID
|
|
while let current = parent {
|
|
collapsedGroupIDs.remove(current)
|
|
parent = tree.node(withID: current)?.parentID
|
|
}
|
|
}
|
|
}
|