mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 04:04:21 +02:00
Merge main into family-comfort; a session state without 'started' can't crash status
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
1203ec0a9e
180 files changed
+62069
-234
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import Citadel
|
||||
import CryptoKit
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
@@ -33,6 +34,11 @@ final class AppModel: ObservableObject {
|
||||
}
|
||||
|
||||
var deviceName: String { UIDevice.current.userInterfaceIdiom == .pad ? "iPad" : "iPhone" }
|
||||
/// Stable per install: a hash of this device's SSH key, which is made once and kept in the Keychain.
|
||||
var clientID: String {
|
||||
let digest = SHA256.hash(data: Data(authorizedKeysLine.utf8))
|
||||
return deviceName.lowercased() + "-" + digest.prefix(6).map { String(format: "%02x", $0) }.joined()
|
||||
}
|
||||
private var hostKey: String? { UserDefaults.standard.string(forKey: Self.hostKeyKey) }
|
||||
|
||||
// MARK: pairing
|
||||
@@ -167,7 +173,7 @@ final class AppModel: ObservableObject {
|
||||
guard current() else { throw CancellationError() }
|
||||
step("Starting Frame Control on the headset")
|
||||
let key = Self.randomKey()
|
||||
let server = try await HeadsetServer.start(in: dir, over: l, key: key, device: deviceName)
|
||||
let server = try await HeadsetServer.start(in: dir, over: l, key: key, device: deviceName, client: clientID)
|
||||
guard current() else { throw CancellationError() }
|
||||
let f = try await PortForwarder.start(over: l, to: server.port)
|
||||
forwarder = f
|
||||
|
||||
@@ -80,8 +80,10 @@ final class HeadsetServer: @unchecked Sendable {
|
||||
}
|
||||
|
||||
/// Starts the server in dir and waits for it to say which port it took.
|
||||
static func start(in dir: String, over link: FrameLink, key: String, device: String) async throws -> HeadsetServer {
|
||||
/// client is a stable id for this install (keyboard-and-trackpad pairing is kept per client).
|
||||
static func start(in dir: String, over link: FrameLink, key: String, device: String, client: String) async throws -> HeadsetServer {
|
||||
let command = "cd \(dir) && FRAME_LOCAL=1 FRAME_UI_KEY=\(key) FRAME_DEVICE=\(shellQuote(device)) "
|
||||
+ "FRAME_CLIENT=\(shellQuote(client)) "
|
||||
+ "exec python3 -I -u -B \"$PWD/ui/server.py\" --port 0 --exit-on-eof 2>&1"
|
||||
let stream = try await link.client.executeCommandStream(command)
|
||||
let box = PortWaiter()
|
||||
|
||||
Reference in new issue
Block a user