feat(ios): P1-B — W7 UI wave: deep links, timeline, quick-reply, diff, projects, session switcher, thumbnails, lock-screen push
T-iOS-22: DeepLinkRouter (full-field whitelist, cold-start stash, route(from:) for push-tap reuse), 21 tests T-iOS-24: TimelineSheet mirroring web render() order; disabled→empty-state; reuses AwayDigest onExpand T-iOS-25: QuickReply chips (built-ins mirror quick-reply.ts via KeyByteMap; visible iff live gate && !readOnly) T-iOS-27: read-only DiffScreen + App-layer DiffFetcher (RO no-Origin; APIClient fold-in noted for T-iOS-38 owner) T-iOS-26: Projects list/detail — grouping byte-identical to web group keys (prefs-shared collapse state), prefs-clobber defenses (no blind PUT on empty base; adopt server echo), claude\r bootstrap T-iOS-23: UnreadLedger + TitleSanitizer (SessionCore, +15 tests), lastOutputAt decode, list-boundary re-sanitize T-iOS-29: new-in-cwd (untrusted cwd, no bootstrap re-injection) + exited-session reopen; fixes stale-controller SwiftTerm view bug via .id(controller.id) T-iOS-28: offscreen SwiftTerm thumbnail pipeline (LRU 32, concurrency gate 2, 256KiB cap, grid clamp) T-iOS-21: PushRegistrar (WEBTERM_GATE category: Allow=.authenticationRequired, no .foreground) + NotificationActionHandler (whitelisted payload, token never persisted, bg-task-wrapped POST, 403 fallback) CRITICAL fix (verify-found boot crash): @Sendable literals on UN completion closures — MainActor-inherited closures trapped Swift 6 executor check on UN's background queue; boot re-verified (no new crash reports, permission prompt reached, privacy shade correctly covering during system alert) Verified: 261 pkg + 247 app + 10 integration tests green; 7/7 semantics checks; Owns audit clean
This commit is contained in:
@@ -3,13 +3,33 @@ import SwiftUI
|
||||
/// T-iOS-15 · App entry: assemble the production dependency graph once and
|
||||
/// hand it to the coordinator (Pairing → SessionList → Terminal). All wiring
|
||||
/// lives under `Wiring/`; this file stays a thin `@main`.
|
||||
///
|
||||
/// T-iOS-21(增量接线,任务允许的最小改动):
|
||||
/// - `@UIApplicationDelegateAdaptor` 挂 `PushAppDelegate`(remote-notification
|
||||
/// 回调只能走 UIApplicationDelegate);SwiftUI 生命周期保证本 `init` 先于
|
||||
/// `didFinishLaunching` 运行,coordinator 经一次性静态槽交接过去,在启动
|
||||
/// 完成前就把通知 delegate 设好(冷启动动作不丢)。
|
||||
/// - scenePhase 转 `.active`(含每次可见启动)→ 幂等 `activate()`(授权 +
|
||||
/// token 注册补账);后台拉起(锁屏 Allow/Deny)不激活场景,正好不注册。
|
||||
@main
|
||||
struct WebTermApp: App {
|
||||
@State private var coordinator = AppCoordinator(environment: .production())
|
||||
@UIApplicationDelegateAdaptor(PushAppDelegate.self) private var pushDelegate
|
||||
@Environment(\.scenePhase) private var scenePhase
|
||||
@State private var coordinator: AppCoordinator
|
||||
|
||||
init() {
|
||||
let coordinator = AppCoordinator(environment: .production())
|
||||
_coordinator = State(initialValue: coordinator)
|
||||
PushAppDelegate.bootstrap = coordinator // 消费点:didFinishLaunching
|
||||
}
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
RootView(coordinator: coordinator)
|
||||
.onChange(of: scenePhase) { _, phase in
|
||||
guard phase == .active else { return }
|
||||
pushDelegate.activatePush()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user