@@ -4,8 +4,11 @@ import 'package:flutter/material.dart';
44import 'package:flutter/services.dart' ;
55import 'package:flutter_riverpod/flutter_riverpod.dart' ;
66import 'package:lichess_mobile/src/constants.dart' ;
7+ import 'package:lichess_mobile/src/model/auth/auth_controller.dart' ;
78import 'package:lichess_mobile/src/model/challenge/challenge.dart' ;
9+ import 'package:lichess_mobile/src/model/challenge/challenge_repository.dart' ;
810import 'package:lichess_mobile/src/model/common/chess.dart' ;
11+ import 'package:lichess_mobile/src/model/common/id.dart' ;
912import 'package:lichess_mobile/src/model/game/game_board_params.dart' ;
1013import 'package:lichess_mobile/src/model/lobby/game_seek.dart' ;
1114import 'package:lichess_mobile/src/model/lobby/lobby_numbers.dart' ;
@@ -15,6 +18,9 @@ import 'package:lichess_mobile/src/utils/share.dart';
1518import 'package:lichess_mobile/src/utils/string.dart' ;
1619import 'package:lichess_mobile/src/view/account/rating_pref_aware.dart' ;
1720import 'package:lichess_mobile/src/view/game/game_body.dart' ;
21+ import 'package:lichess_mobile/src/view/game/game_screen.dart' ;
22+ import 'package:lichess_mobile/src/view/game/game_screen_providers.dart' ;
23+ import 'package:lichess_mobile/src/view/user/pick_player_screen.dart' ;
1824import 'package:lichess_mobile/src/widgets/bottom_bar.dart' ;
1925import 'package:lichess_mobile/src/widgets/feedback.dart' ;
2026import 'package:lichess_mobile/src/widgets/game_layout.dart' ;
@@ -211,9 +217,14 @@ class _UserChallengeLoadingContentState extends State<UserChallengeLoadingConten
211217}
212218
213219class OpenChallengeLoadingContent extends ConsumerStatefulWidget {
214- const OpenChallengeLoadingContent (this .challenge, this .cancelChallenge);
215-
216- final Challenge challenge;
220+ const OpenChallengeLoadingContent ({
221+ required this .id,
222+ required this .challengeRequest,
223+ required this .cancelChallenge,
224+ });
225+
226+ final ChallengeId id;
227+ final ChallengeRequest challengeRequest;
217228 final Future <void > Function () cancelChallenge;
218229
219230 @override
@@ -225,7 +236,8 @@ class _OpenChallengeLoadingContentState extends ConsumerState<OpenChallengeLoadi
225236
226237 @override
227238 Widget build (BuildContext context) {
228- final challengeLink = 'https://$kLichessHost /${widget .challenge .id }' ;
239+ final challengeLink = 'https://$kLichessHost /${widget .id }' ;
240+ final authUser = ref.watch (authControllerProvider);
229241
230242 final qrColor = ref.watch (currentBrightnessProvider) == Brightness .dark
231243 ? Colors .white
@@ -252,13 +264,13 @@ class _OpenChallengeLoadingContentState extends ConsumerState<OpenChallengeLoadi
252264 mainAxisSize: MainAxisSize .min,
253265 children: [
254266 Icon (
255- widget.challenge .perf.icon,
267+ widget.challengeRequest .perf.icon,
256268 color: DefaultTextStyle .of (context).style.color,
257269 ),
258270 const SizedBox (width: 8.0 ),
259271 Text (
260- widget.challenge .timeIncrement? .display ??
261- '${context .l10n .daysPerTurn }: ${widget .challenge .days }' ,
272+ widget.challengeRequest .timeIncrement? .display ??
273+ '${context .l10n .daysPerTurn }: ${widget .challengeRequest .days }' ,
262274 style: TextTheme .of (context).titleLarge,
263275 ),
264276 ],
@@ -295,6 +307,47 @@ class _OpenChallengeLoadingContentState extends ConsumerState<OpenChallengeLoadi
295307
296308 Text (context.l10n.theFirstPersonToComeOnThisUrlWillPlayWithYou),
297309
310+ if (authUser != null )
311+ FilledButton .tonalIcon (
312+ onPressed: () => Navigator .of (context).push (
313+ PickPlayerScreen .buildRoute (
314+ context,
315+ title: Text (context.l10n.challengeAFriend),
316+ onUserTap: (user) async {
317+ Navigator .of (context).pop ();
318+
319+ widget.cancelChallenge ();
320+
321+ final directedChallengeReq = widget.challengeRequest.copyWith (
322+ destUser: user,
323+ );
324+ await ref
325+ .read (challengeRepositoryProvider)
326+ .create (directedChallengeReq);
327+ if (! context.mounted) return ;
328+
329+ if (widget.challengeRequest.timeControl ==
330+ ChallengeTimeControlType .clock) {
331+ Navigator .of (context, rootNavigator: true ).pushReplacement (
332+ GameScreen .buildRoute (
333+ context,
334+ source: UserChallengeSource (directedChallengeReq),
335+ ),
336+ );
337+ } else {
338+ if (! context.mounted) return ;
339+ ScaffoldMessenger .of (context).showSnackBar (
340+ SnackBar (content: Text (context.l10n.mobileChallengeCreated)),
341+ );
342+ Navigator .of (context).pop ();
343+ }
344+ },
345+ ),
346+ ),
347+ label: Text (context.l10n.challengeInviteLichessUser.replaceFirst (':' , '' )),
348+ icon: const Icon (Icons .person_search),
349+ ),
350+
298351 Container (
299352 padding: const EdgeInsets .all (4.0 ),
300353 decoration: BoxDecoration (
0 commit comments