Skip to content

Sync origin#88

Closed
q231950 wants to merge 6 commits into
lightphone:mainfrom
q231950:main
Closed

Sync origin#88
q231950 wants to merge 6 commits into
lightphone:mainfrom
q231950:main

Conversation

@q231950

@q231950 q231950 commented Jul 11, 2026

Copy link
Copy Markdown

No description provided.

q231950 and others added 6 commits July 4, 2026 21:51
Replaces the sample Light SDK tool with a Flamingo-branded chess
client that lists games from the Flamingo API and shows move history
and board state for a selected game.

Co-authored-by: Claude Sonnet 5 <[email protected]>
Full chess engine library (bitboard move generation, castling, en
passant, check/checkmate/draw detection) and FEN/SAN/PGN/engine-LAN
parsers, ported from https://github.com/chesskit-app/chesskit-swift
(MIT licensed) with API kept as close to the Swift original as Kotlin
allows. Includes the full ported test suite.

Co-authored-by: Claude Sonnet 5 <[email protected]>
Wires the tool module up to chesskit and adds a GameView screen with
a ChessBoard composable, reachable via a new-game button on the games list.

Co-authored-by: Claude Sonnet 5 <[email protected]>
Every move on the board is now POSTed to the backend as it's made
(createGame for the first move, recordMove after), instead of GameView
being a fully local pass-and-play board. White/black player identity is
generated once per tool install and persisted via DataStore, replacing
the GamesListScreen HARDCODED_PLAYER_ID. Tapping an active game now
resumes it in GameView (replaying its recorded moves), while finished
games still open the read-only GameDetailScreen.

Also fixes the FEN submitted with a move to be the pre-move position
(matching what the backend and iOS client actually expect), which had
been sent as the post-move position.
* feat: share a game invite link and collapse identity to a single playerID

GameView now identifies its installation with a single persisted playerID
instead of a white/black pair, since a real second player (via a shared
invite link) can now become black rather than this device simulating both
sides locally. Local taps only move white; the board shows "Waiting for
opponent..." otherwise.

Adds a Share button to GameView's top bar that copies the game's invite
link (matching the iOS client's GameURL shape) to the clipboard. QR-code
rendering was dropped in favor of this since com.google.zxing isn't on the
light-sdk plugin's dependency allowlist.

* fix: share the pre-move fen + lan of the last move, not the post-move fen

The invite URL was sending the board's current (post-move) fen with no
lan, so iOS had nothing to apply — it just rendered whatever position was
in the fen verbatim. Every other message in this protocol sends the fen a
move was played *from* plus that move's lan, and the receiving client
applies the move to reach the current position (see
ChessBoardModel.preMovePosition on iOS). The invite URL now follows the
same convention, tracking the last submitted/replayed move's pre-move fen
and lan for the Share button to use.

Also gates showing Share on having a move to share at all, since sharing
before white's first move produced an invite with nothing for black to
reply to. blackPlayerID is now nullable to match games that haven't been
accepted yet.

* feat: live-move WebSocket transport for the chess tool (#6)

Add a LiveTransport interface (KtorLiveTransport adapter) so the game screen
sends and receives moves over a live WebSocket instead of a separate HTTP
request. Connects to wss://neoneon.dev/flamingo/games/<gameId>/socket?pid=<id>
and exchanges a minimal { intent, player, lan, fen, n } envelope.

Wire it into GameViewViewModel: white's moves are sent over the socket (the
server records them, creating the game lazily on move 1) and the opponent's
moves apply live to the board. The socket is dropped on onAppPause and
re-established on onScreenShow, re-syncing from the server first when we were
waiting for the opponent; divergence or a dropped socket triggers an HTTP
re-sync then reconnect.

Add io.ktor:ktor-client-websockets to the Light SDK dependency allow-list
(LightSdkPlugin) and the version catalog so the tool may use WebSockets.

Also keeps the board on screen while waiting for the opponent instead of
swapping it for text.

Co-authored-by: Claude Opus 4.8 <[email protected]>

---------

Co-authored-by: Claude Opus 4.8 <[email protected]>
The "Waiting for opponent…" label lived inside the vertically-centered
column with the board, so surfacing or clearing it re-centered the column
and shifted the board. Move the message into a fixed-height status strip
directly beneath the nav bar that always reserves its space, so the board
region stays constant regardless of status.

Co-authored-by: Claude Opus 4.8 <[email protected]>
@q231950 q231950 closed this Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant