feat: add "or invite a lichess user" button to the "share challenge link" dialog#2881
Conversation
2a91a7c to
12a2d57
Compare
There was a problem hiding this comment.
Pull request overview
This PR enhances the challenge-sharing flow by adding a logged-in “invite a Lichess user” entry point and introducing a new player picker screen that surfaces online/offline friends immediately. It also adjusts challenge creation to fix the “open correspondence challenge” flow so it can reach the share-link UI.
Changes:
- Added
PickPlayerScreento quickly pick from following/online friends, with search navigation. - Updated open-challenge share-link UI to optionally offer “Or invite a Lichess user” when authenticated.
- Adjusted challenge creation/loading logic to support open correspondence/unlimited challenges reaching the share-link screen.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| test/view/game/game_screen_test.dart | Expands open-challenge share-link test to cover logged-in vs anonymous UI. |
| lib/src/view/user/search_screen.dart | Adds a mounted guard before saving search history in a debounced callback. |
| lib/src/view/user/pick_player_screen.dart | New screen to browse online/offline following and navigate to search. |
| lib/src/view/play/create_challenge_bottom_sheet.dart | Routes open correspondence/unlimited challenges into GameScreen (share-link flow). |
| lib/src/view/game/game_screen.dart | Updates open-challenge loading widget parameters and app bar title logic. |
| lib/src/view/game/game_screen_providers.dart | Creates “directed real-time or open” challenge and mounts guard before updating state. |
| lib/src/view/game/game_loading_board.dart | Adds authenticated “invite user” button to the open-challenge share-link UI. |
| lib/src/view/board_editor/board_editor_screen.dart | Uses PickPlayerScreen for “Challenge from position” user selection. |
| lib/src/model/lobby/create_game_service.dart | Renames/expands real-time challenge creation; adds (currently unused) correspondence option param. |
| lib/src/model/challenge/challenge.dart | Adds isOpenOrRealTime helper on Challenge and ChallengeRequest. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
12a2d57 to
3a98a80
Compare
3a98a80 to
35885a3
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Padding( | ||
| padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), | ||
| child: PlatformSearchBar( | ||
| hintText: context.l10n.searchSearch, | ||
| focusNode: _AlwaysDisabledFocusNode(), | ||
| onTap: () => Navigator.of(context).push( |
There was a problem hiding this comment.
PlatformSearchBar is given a new _AlwaysDisabledFocusNode() on every build, but _PlayersList is a StatelessWidget so the FocusNode is never disposed. This can leak focus nodes; prefer avoiding a custom focus node (e.g., use canRequestFocus: false / readOnly patterns) or manage/dispose a single node in a StatefulWidget.
There was a problem hiding this comment.
Copied from PlayerScreen 🤷
…enge It used to just show the "challenge created" snackbar, which of course is useless for an open challenge
35885a3 to
4c82562
Compare
There was a problem hiding this comment.
Great stuff!
Challenges are always more complicated that what we think...
One UI suggestion: I find that the "share link or invite user" card look a bit too cramped. Some more vertical space around elements would be nice.
Or perhaps just more padding around the "Invite user" button would do it.
| ScaffoldMessenger.of(context).showSnackBar( | ||
| SnackBar( | ||
| content: Text( | ||
| context.l10n.mobileChallengeCreated.replaceAll('\\n', '\n'), |
There was a problem hiding this comment.
I'm surprised you have to do that... it should not be necessary. And I saw an \n in the snackbar of the screen recording in the PR description.
There was a problem hiding this comment.
hmm i copied this from #2882, but yeah it looks like a bug with the translation generation.
I created the video before I cherry-picked that change, that's why it's still broken there
| padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), | ||
| child: PlatformSearchBar( | ||
| hintText: context.l10n.searchSearch, | ||
| focusNode: _AlwaysDisabledFocusNode(), |
There was a problem hiding this comment.
Copilot comment makes sense. We should convert the _PlayersList to a StatefulWidget and initialise the _AlwaysDisabledFocusNode() in a field of that class to be able to dispose it.
(and do the same in PlayerScreen)

This also adds a new
PickPlayerScreenthat immediately displays your online/offline friends, instead of having to use the search bar to find them. I also made use of that in "challenge from position".Demo:
inviteuser.webm
Also, fix a bug where creating an open correspondence challenge would not show the "share link" screen.