crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit a516df0db69f0b9c01d5107c25f4be6d8e073405
parent a8216ec129dd0b1f614bd165d148d595cb474432
Author: Michael Camilleri <[email protected]>
Date:   Mon,  4 May 2026 07:58:23 +0900

Update author tints dynamically

This commit tweaks the way that author information is assigned to
squares so that tinting can happen dynamically during gameplay.

Co-Authored-By: Claude Opus 4.7 <[email protected]>

Diffstat:
MCrossmate/Models/Game.swift | 6+++++-
MCrossmate/Persistence/GameMutator.swift | 2+-
MCrossmate/Views/CellView.swift | 2+-
3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/Crossmate/Models/Game.swift b/Crossmate/Models/Game.swift @@ -31,13 +31,14 @@ final class Game { /// Writes `letter` into `(row, col)`. If `pencil` is true the cell is /// marked `.pencil(checkedWrong: false)`; otherwise the mark is cleared /// to `.none`. Revealed cells are locked — writes are silently ignored. - func setLetter(_ letter: String, atRow row: Int, atCol col: Int, pencil: Bool) { + func setLetter(_ letter: String, atRow row: Int, atCol col: Int, pencil: Bool, authorID: String? = nil) { let cell = puzzle.cells[row][col] guard !cell.isBlock else { return } guard !squares[row][col].mark.isRevealed else { return } let oldEntry = squares[row][col].entry squares[row][col].entry = letter.uppercased() squares[row][col].mark = pencil ? .pencil(checkedWrong: false) : .none + squares[row][col].letterAuthorID = authorID noteEntryChange(from: oldEntry, to: squares[row][col].entry, for: cell) } @@ -49,6 +50,7 @@ final class Game { let oldEntry = squares[row][col].entry squares[row][col].entry = "" squares[row][col].mark = .none + squares[row][col].letterAuthorID = nil noteEntryChange(from: oldEntry, to: "", for: cell) } @@ -96,6 +98,7 @@ final class Game { if oldEntry == expected { continue } squares[cell.row][cell.col].entry = expected squares[cell.row][cell.col].mark = .revealed + squares[cell.row][cell.col].letterAuthorID = nil noteEntryChange(from: oldEntry, to: expected, for: cell) } } @@ -114,6 +117,7 @@ final class Game { let oldEntry = squares[cell.row][cell.col].entry squares[cell.row][cell.col].entry = "" squares[cell.row][cell.col].mark = .none + squares[cell.row][cell.col].letterAuthorID = nil noteEntryChange(from: oldEntry, to: "", for: cell) } } diff --git a/Crossmate/Persistence/GameMutator.swift b/Crossmate/Persistence/GameMutator.swift @@ -50,7 +50,7 @@ final class GameMutator { // MARK: - Single-cell mutations func setLetter(_ letter: String, atRow row: Int, atCol col: Int, pencil: Bool) { - game.setLetter(letter, atRow: row, atCol: col, pencil: pencil) + game.setLetter(letter, atRow: row, atCol: col, pencil: pencil, authorID: authorIDProvider?()) emitMove(atRow: row, atCol: col) } diff --git a/Crossmate/Views/CellView.swift b/Crossmate/Views/CellView.swift @@ -105,7 +105,7 @@ struct CellView: View, Equatable { // in a shared game. Sits beneath transient highlights so peer // and local cursors still dominate. if let authorTint { - authorTint.opacity(0.18) + authorTint.opacity(0.10) } // Peer word tint sits beneath self highlight/selection so the // local cursor always reads as the dominant focus.