mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-11-14 10:13:54 +00:00
72 lines
2.5 KiB
Swift
72 lines
2.5 KiB
Swift
import Foundation
|
|
|
|
/// 展示排序不改写目录顺序;未知时间在两个方向都排在最后。
|
|
struct ServerTableSort: SortComparator {
|
|
enum Field: CaseIterable {
|
|
case name, createdAt, updatedAt
|
|
}
|
|
|
|
let field: Field
|
|
var order: SortOrder
|
|
|
|
init(_ field: Field, order: SortOrder = .forward) {
|
|
self.field = field
|
|
self.order = order
|
|
}
|
|
|
|
func compare(_ lhs: CatalogTreeNode, _ rhs: CatalogTreeNode) -> ComparisonResult {
|
|
let result: ComparisonResult
|
|
switch field {
|
|
case .name:
|
|
result = lhs.name.localizedStandardCompare(rhs.name)
|
|
case .createdAt, .updatedAt:
|
|
let left = field == .createdAt ? lhs.createdAt : lhs.updatedAt
|
|
let right = field == .createdAt ? rhs.createdAt : rhs.updatedAt
|
|
switch (left, right) {
|
|
case (nil, nil): return .orderedSame
|
|
case (nil, _): return .orderedDescending
|
|
case (_, nil): return .orderedAscending
|
|
case (.some(let left), .some(let right)): result = left.compare(right)
|
|
}
|
|
}
|
|
guard order == .reverse else { return result }
|
|
switch result {
|
|
case .orderedAscending: return .orderedDescending
|
|
case .orderedDescending: return .orderedAscending
|
|
case .orderedSame: return .orderedSame
|
|
}
|
|
}
|
|
|
|
static func sorted(_ nodes: [CatalogTreeNode], by sortOrder: [Self]) -> [CatalogTreeNode] {
|
|
guard let comparator = sortOrder.first else { return nodes }
|
|
return nodes.enumerated().sorted { lhs, rhs in
|
|
let result = comparator.compare(lhs.element, rhs.element)
|
|
return result == .orderedSame ? lhs.offset < rhs.offset : result == .orderedAscending
|
|
}.map(\.element)
|
|
}
|
|
}
|
|
|
|
extension CatalogTreeSnapshot {
|
|
/// 来源不跨越子树,因此根层筛选保留完整层级。
|
|
func roots(for source: NodeSource, sortedBy sortOrder: [ServerTableSort]) -> [CatalogTreeNode] {
|
|
ServerTableSort.sorted(roots.filter { $0.source == source }, by: sortOrder)
|
|
}
|
|
|
|
/// 每层单独排序,再按展开状态生成 Table 行;不改变子树归属。
|
|
func visibleRows(
|
|
source: NodeSource, sortedBy sortOrder: [ServerTableSort], collapsed: Set<NodeID>
|
|
) -> [CatalogTreeRow] {
|
|
var rows: [CatalogTreeRow] = []
|
|
func append(_ nodes: [CatalogTreeNode], depth: Int) {
|
|
for node in ServerTableSort.sorted(nodes, by: sortOrder) {
|
|
rows.append(CatalogTreeRow(node: node, depth: depth))
|
|
if !collapsed.contains(node.id) {
|
|
append(node.childNodes, depth: depth + 1)
|
|
}
|
|
}
|
|
}
|
|
append(roots.filter { $0.source == source }, depth: 0)
|
|
return rows
|
|
}
|
|
}
|