mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-11-08 22:14:51 +00:00
53 lines
1.5 KiB
Swift
53 lines
1.5 KiB
Swift
import Foundation
|
|
import Observation
|
|
|
|
/// 结果身份和完成时间来自命令;业务内容留在各自的呈现入口。
|
|
protocol DetailFeedbackResult: Identifiable where ID == UUID {
|
|
var completedAt: Date { get }
|
|
var isSuccess: Bool { get }
|
|
}
|
|
|
|
extension ActivationFeedbackState.Completion: DetailFeedbackResult {
|
|
var isSuccess: Bool { feedback.isSuccess }
|
|
}
|
|
|
|
extension SubscriptionRefreshCompletion: DetailFeedbackResult {
|
|
var isSuccess: Bool { failure == nil }
|
|
}
|
|
|
|
/// 详情会话持有展示寿命;命令结果仍由原工作流保留。
|
|
@Observable
|
|
@MainActor
|
|
final class DetailFeedbackState<Result: DetailFeedbackResult> {
|
|
private(set) var completion: Result?
|
|
private var generation = 0
|
|
private let now: () -> Date
|
|
private let sleep: (TimeInterval) async throws -> Void
|
|
|
|
init(
|
|
now: @escaping () -> Date = Date.init,
|
|
sleep: @escaping (TimeInterval) async throws -> Void = {
|
|
try await Task.sleep(for: .seconds($0))
|
|
}
|
|
) {
|
|
self.now = now
|
|
self.sleep = sleep
|
|
}
|
|
|
|
func present(_ result: Result?) async {
|
|
guard !Task.isCancelled else { return }
|
|
generation += 1
|
|
let currentGeneration = generation
|
|
completion = nil
|
|
guard let result else { return }
|
|
let remaining = result.completedAt.addingTimeInterval(result.isSuccess ? 3 : 10)
|
|
.timeIntervalSince(now())
|
|
guard remaining > 0 else { return }
|
|
completion = result
|
|
defer {
|
|
if generation == currentGeneration { completion = nil }
|
|
}
|
|
try? await sleep(remaining)
|
|
}
|
|
}
|