crossmate

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

commit 5401155b14fba730c8b6216bab2190d0d951c5ab
parent 5a248e38bc1e6c397a5f9a9aaa5826a127a6aeac
Author: Michael Camilleri <[email protected]>
Date:   Wed,  6 May 2026 10:20:46 +0900

Add keyboard swipe to set entry direction

This commit adds a swipe gesture on the keyboard view: a predominantly
horizontal swipe sets direction to .across, a predominantly vertical swipe sets
it to .down. The gesture is attached as a simultaneousGesture on top of a
DragGesture with a 20pt minimum distance, so it coexists with the existing key
button taps without intercepting them, and a stray finger movement during a tap
will not trip it.

PlayerSession gains setDirection(_:), a sibling to toggleDirection that applies
the same guard (the new direction is only adopted if a word exists in that
direction at the current cell) and no-ops if the requested direction already
matches the current one.

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

Diffstat:
MCrossmate/Models/PlayerSession.swift | 7+++++++
MCrossmate/Views/KeyboardView.swift | 9+++++++++
2 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/Crossmate/Models/PlayerSession.swift b/Crossmate/Models/PlayerSession.swift @@ -120,6 +120,13 @@ final class PlayerSession { } } + func setDirection(_ newDirection: Puzzle.Direction) { + guard newDirection != direction else { return } + if hasWord(at: selectedRow, col: selectedCol, direction: newDirection) { + direction = newDirection + } + } + func selectClue(direction: Puzzle.Direction, number: Int) { guard let cell = puzzle.cell(numbered: number) else { return } self.direction = direction diff --git a/Crossmate/Views/KeyboardView.swift b/Crossmate/Views/KeyboardView.swift @@ -84,6 +84,15 @@ struct KeyboardView: View { .padding(.horizontal, 4) .padding(.top, 12) .padding(.bottom, 8) + .simultaneousGesture( + DragGesture(minimumDistance: 20) + .onEnded { value in + let dx = value.translation.width + let dy = value.translation.height + guard dx * dx + dy * dy >= 400 else { return } + session.setDirection(abs(dx) >= abs(dy) ? .across : .down) + } + ) } private func letterKey(_ letter: String) -> some View {