commit 910e66bc7b6dd11fffcd9434df74320bb9fe09fb
parent 3c8891e3d4a5b49a393baf5e042a708f4db7ba55
Author: Michael Camilleri <[email protected]>
Date: Wed, 10 Jun 2026 02:56:40 +0900
Remove engagement menu option
Diffstat:
4 files changed, 5 insertions(+), 42 deletions(-)
diff --git a/Crossmate/CrossmateApp.swift b/Crossmate/CrossmateApp.swift
@@ -26,9 +26,6 @@ struct CrossmateApp: App {
.environment(services.eventLog)
.environment(\.syncEngine, services.syncEngine)
.environment(\.engagementStatus, services.engagementStatus)
- .environment(\.offerEngagement, { gameID in
- await services.offerEngagement(gameID: gameID)
- })
.environment(services.nytAuth)
.environment(\.nytPuzzleFetcher, services.nytFetcher)
.environment(\.resetDatabase, {
diff --git a/Crossmate/Services/AppServices.swift b/Crossmate/Services/AppServices.swift
@@ -1426,12 +1426,11 @@ final class AppServices {
/// hands the desired creds to the coordinator, which connects, migrates, or
/// tears down to match. `force` is the manual "start a room now" path,
/// which mints and connects without waiting to see a present peer.
- func reconcileEngagement(gameID: UUID, force: Bool = false) async {
+ func reconcileEngagement(gameID: UUID) async {
guard preferences.isICloudSyncEnabled else { return }
// A completed game is not a live session. Never connect (this is also
// the reopen-from-Completed path, which re-runs through
- // `startEngagementIfPossible`) and tear down anything still up — even
- // a `force` manual offer is refused once the puzzle is done.
+ // `startEngagementIfPossible`) and tear down anything still up.
guard !store.isCompleted(gameID: gameID) else {
cancelEngagementLeaseExpiry(gameID: gameID)
await engagementCoordinator.reconcile(gameID: gameID, creds: nil, hasPeer: false)
@@ -1458,7 +1457,7 @@ final class AppServices {
gameID: gameID,
localAuthorID: identity.currentID
)
- let hasPeer = force || soonestLease != nil
+ let hasPeer = soonestLease != nil
var creds = EngagementRoomCredentials.decode(store.engagement(for: gameID))
if creds == nil, hasPeer {
if let minted = try? EngagementRoomCredentials.fresh(),
@@ -1476,7 +1475,7 @@ final class AppServices {
// onto the new horizon if one did. That instant is the lease plus the
// presence grace, not the bare lease — a peer stays present through the
// grace, so tearing down at the raw lease would race it. The 30s
- // reconnect tick remains the coarse backstop. A force/no-peer reconcile
+ // reconnect tick remains the coarse backstop. A no-peer reconcile
// has no lease to watch, so this just clears any prior wake.
scheduleEngagementLeaseExpiry(
gameID: gameID,
@@ -1484,24 +1483,6 @@ final class AppServices {
)
}
- func offerEngagement(gameID: UUID) async {
- cancelScheduledEngagementEnd(gameID: gameID)
- guard preferences.isICloudSyncEnabled else {
- syncMonitor.note("engagement: manual offer skipped, iCloud sync is disabled")
- return
- }
- guard await ensureICloudSyncStarted() else {
- syncMonitor.note("engagement: manual offer skipped, iCloud sync is unavailable")
- return
- }
- syncMonitor.note(
- "engagement: manual offer requested for \(gameID.uuidString) " +
- "device=\(RecordSerializer.localDeviceID.prefix(8))"
- )
- await reconcileEngagement(gameID: gameID, force: true)
- startEngagementReconnectRetry(gameID: gameID)
- }
-
func startEngagementIfPossible(gameID: UUID) async {
cancelScheduledEngagementEnd(gameID: gameID)
guard preferences.isICloudSyncEnabled else { return }
@@ -1596,7 +1577,7 @@ final class AppServices {
/// peer's lease lapses — replacing any prior wake for this game. When it
/// fires, `reconcileEngagement` tears the channel down if no renewal landed
/// (so the bolt drops at expiry, not up to a tick later) or reschedules
- /// onto the renewed horizon. `nil` (force/no-peer) just clears the wake.
+ /// onto the renewed horizon. `nil` (no-peer) just clears the wake.
private func scheduleEngagementLeaseExpiry(gameID: UUID, at expiry: Date?) {
engagementLeaseExpiryTasks[gameID]?.cancel()
engagementLeaseExpiryTasks[gameID] = nil
diff --git a/Crossmate/Services/EngagementHostEnvironment.swift b/Crossmate/Services/EngagementHostEnvironment.swift
@@ -22,18 +22,9 @@ private struct EngagementStatusKey: EnvironmentKey {
static let defaultValue: EngagementStatus? = nil
}
-private struct OfferEngagementKey: EnvironmentKey {
- static let defaultValue: (@Sendable (UUID) async -> Void)? = nil
-}
-
extension EnvironmentValues {
var engagementStatus: EngagementStatus? {
get { self[EngagementStatusKey.self] }
set { self[EngagementStatusKey.self] = newValue }
}
-
- var offerEngagement: (@Sendable (UUID) async -> Void)? {
- get { self[OfferEngagementKey.self] }
- set { self[OfferEngagementKey.self] = newValue }
- }
}
diff --git a/Crossmate/Views/PuzzleView.swift b/Crossmate/Views/PuzzleView.swift
@@ -792,7 +792,6 @@ private struct PuzzleToolbarModifier: ViewModifier {
@Binding var pendingRevealScope: RevealScope
@Binding var isShowingShareSheet: Bool
@Environment(PlayerPreferences.self) private var preferences
- @Environment(\.offerEngagement) private var offerEngagement
@AppStorage("debugMode") private var debugMode = false
func body(content: Content) -> some View {
@@ -858,11 +857,6 @@ private struct PuzzleToolbarModifier: ViewModifier {
} label: {
Text("Diagnostics Log")
}
-
- Button("Force Engagement") {
- Task { await offerEngagement?(session.mutator.gameID) }
- }
- .disabled(offerEngagement == nil)
}
}