commit 77ddc8c530c8137a3fbce5ee83ae20b89362ff38
parent 6a360059c435bee2c8e8d21589aec43072fbacfb
Author: Michael Camilleri <[email protected]>
Date: Thu, 23 Jul 2026 22:08:35 +0900
Skip foreground grid refreshes for Chronicles
Foregrounding an open Chronicle still treated its local projection as an
active live-game target, issuing an empty CloudKit Game, Moves and
Player fetch.
This commit gives GameStore an explicit archived-game classification and
excludes Chronicles from foreground puzzle-grid refreshes while
retaining their archived replay routing.
Co-Authored-By: Codex GPT 5.6 Sol <[email protected]>
Diffstat:
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/Crossmate/Persistence/GameStore.swift b/Crossmate/Persistence/GameStore.swift
@@ -2226,10 +2226,8 @@ final class GameStore {
return entity.ckShareRecordName != nil || entity.databaseScope == 1
}
- /// A materialised Chronicle carries its replay as cached Journal rows,
- /// regardless of whether the original game was shared. It must use the
- /// merged replay loader rather than the live game's local-journal shortcut.
- func usesArchivedReplay(gameID: UUID) -> Bool {
+ /// Whether `gameID` is the local read-only projection of a Chronicle.
+ func isGameArchived(gameID: UUID) -> Bool {
let request = NSFetchRequest<GameEntity>(entityName: "GameEntity")
request.predicate = NSPredicate(format: "id == %@", gameID as CVarArg)
request.fetchLimit = 1
@@ -2237,6 +2235,13 @@ final class GameStore {
return isMaterializedArchive(entity)
}
+ /// A materialised Chronicle carries its replay as cached Journal rows,
+ /// regardless of whether the original game was shared. It must use the
+ /// merged replay loader rather than the live game's local-journal shortcut.
+ func usesArchivedReplay(gameID: UUID) -> Bool {
+ isGameArchived(gameID: gameID)
+ }
+
/// Reads, mutates, and re-persists the local author's `Player.timeLog`,
/// creating a stub `PlayerEntity` if none exists (works for solo games — no
/// `isShared` gate). `updatedAt` is left untouched on an existing row: the
diff --git a/Crossmate/Services/AppServices.swift b/Crossmate/Services/AppServices.swift
@@ -2113,7 +2113,8 @@ final class AppServices {
private func activePuzzleGridTarget() -> (UUID, CKDatabase.Scope)? {
guard let entity = store.currentEntity,
- let gameID = entity.id
+ let gameID = entity.id,
+ !store.isGameArchived(gameID: gameID)
else { return nil }
switch entity.databaseScope {
case 0:
diff --git a/Tests/Unit/ArchiveTests.swift b/Tests/Unit/ArchiveTests.swift
@@ -620,6 +620,7 @@ struct ArchiveTests {
#expect(Set(players.compactMap(\.authorID)) == ["alice", "bob"])
#expect(players.allSatisfy { ($0.name ?? "").isEmpty })
#expect(GameSummary(entity: game)?.isShared == true)
+ #expect(store.isGameArchived(gameID: game.id!))
#expect(store.usesArchivedReplay(gameID: game.id!))
#expect(await store.cachedRemoteJournals(forGameID: game.id!)?.count == 2)
}