-
-
Notifications
You must be signed in to change notification settings - Fork 382
Description
As a user, I'd like to add a native widget with a daily (or random) puzzle to my iOS home screen so that I can solve puzzles without opening the app.
The Idea
MVP
- The widget calls the Get the daily puzzle endpoint and renders an image of the position. It also shows the side to move.
- Since iOS widgets are not interactive, the user can't solve the puzzle directly in the widget. Instead, tapping the widget uses a deep link to open the app and show the puzzle details.
- The widget uses the default chessboard style.
Nice to Have
- Authenticate the API call to get a random puzzle that fits the user's rating.
- Use the same chessboard style as the one used in the app.
- A widget setting to toggle showing the puzzle rating.
Known Problems
Current Backend Situation
The Get the daily puzzle endpoint does not currently include the FEN of the position. This makes implementing a puzzle-based iOS home widget problematic.
The iOS home widget process runs separately from the app and does not have access to the main app's chess engine logic to calculate the FEN from the PGN found in the response. Adding a chess engine to the widget process is not an option, as it must stay very lightweight. Furthermore, iOS widgets cannot use the Flutter framework.
The simplest solution would therefore be to extend the backend endpoint to include the FEN of the initial puzzle position, or to create a new endpoint for this purpose. A similar change was previously discussed and rejected in lichess-org/lila#16244 β however, there may now be a stronger case for it, as there appears to be no other practical way to implement this feature.
Backend API response illustrating the problem (FEN is missing):
Details
```json GET https://lichess.org/api/puzzle/daily { "game": { "id": "kQsFfCy4", "perf": { "key": "blitz", "name": "Blitz" }, "rated": true, "players": [ { "name": "mustanco", "id": "mustanco", "color": "white", "rating": 1807 }, { "name": "Ilnasogonfiabile", "id": "ilnasogonfiabile", "color": "black", "rating": 1834 } ], "pgn": "d4 e5 c3 exd4 cxd4 d5 Bf4 Nc6 Nc3 Be6 Nf3 Bb4 e3 Nge7 a3 Ba5 b4 Bb6 Bb5 O-O Bxc6 Nxc6 O-O Bg4 a4 a6 b5 Na5 h3 Bh5 g4 Bg6 Ne5 Qh4 Nxg6 fxg6 Kh2 Nc4 Nxd5 Rad8 Nxb6 Nxb6 Bxc7 Rd7 Bxb6 Rdf7 Qb3 Kh8 Ra2 Rf3 Rh1 Qxh3+ Kg1", "clock": "5+0" }, "puzzle": { "id": "VAfZj", "rating": 1821, "plays": 120267, "solution": [ "f3g3", "f2g3", "f8f1" ], "themes": [ "clearance", "mateIn2", "middlegame", "short", "sacrifice", "kingsideAttack", "killBoxMate" ], "initialPly": 52 } } ```My plan is to proceed with the implementation as drafted above. Any feedback is appreciated ππΎ