Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<data android:path="/streak" />

<data android:pathPattern="/broadcast/.*/.*/........" />
<data android:pathPattern="/broadcast/.*/.*/......../........" />

<!-- Either game or challenge -->
<data android:pathPattern="/........" />
Expand Down
13 changes: 10 additions & 3 deletions lib/src/app_links.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/widgets.dart';
import 'package:lichess_mobile/src/model/common/id.dart';
import 'package:lichess_mobile/src/model/puzzle/puzzle_angle.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_game_screen.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_round_screen.dart';
import 'package:lichess_mobile/src/view/game/archived_game_screen.dart';
import 'package:lichess_mobile/src/view/puzzle/puzzle_screen.dart';
Expand All @@ -22,9 +23,15 @@ Route<dynamic>? resolveAppLinkUri(BuildContext context, Uri appLinkUri) {
final id = appLinkUri.pathSegments[1];
return StudyScreen.buildRoute(context, StudyId(id));
case 'broadcast':
final id = appLinkUri.pathSegments[3];
final tab = BroadcastRoundTab.tabOrNullFromString(appLinkUri.fragment);
return BroadcastRoundScreenLoading.buildRoute(context, BroadcastRoundId(id), initialTab: tab);
final roundId = BroadcastRoundId(appLinkUri.pathSegments[3]);
if (appLinkUri.pathSegments.length > 4) {
final gameId = BroadcastGameId(appLinkUri.pathSegments[4]);
return BroadcastGameScreen.buildRoute(context, roundId: roundId, gameId: gameId);
} else {
final tab = BroadcastRoundTab.tabOrNullFromString(appLinkUri.fragment);
return BroadcastRoundScreenLoading.buildRoute(context, roundId, initialTab: tab);
}

case 'training':
final id = appLinkUri.pathSegments[1];
return PuzzleScreen.buildRoute(
Expand Down
34 changes: 21 additions & 13 deletions lib/src/view/broadcast/broadcast_game_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ import 'package:lichess_mobile/src/widgets/pgn.dart';
import 'package:lichess_mobile/src/widgets/platform_scaffold.dart';

class BroadcastGameScreen extends ConsumerStatefulWidget {
final BroadcastTournamentId tournamentId;
final BroadcastTournamentId? tournamentId;
final BroadcastRoundId roundId;
final BroadcastGameId gameId;
final String? tournamentSlug;
final String? roundSlug;
final String? title;

const BroadcastGameScreen({
required this.tournamentId,
this.tournamentId,
required this.roundId,
required this.gameId,
this.tournamentSlug,
Expand All @@ -47,7 +47,7 @@ class BroadcastGameScreen extends ConsumerStatefulWidget {

static Route<dynamic> buildRoute(
BuildContext context, {
required BroadcastTournamentId tournamentId,
BroadcastTournamentId? tournamentId,
required BroadcastRoundId roundId,
required BroadcastGameId gameId,
String? tournamentSlug,
Expand Down Expand Up @@ -146,7 +146,7 @@ class _Body extends ConsumerWidget {
required this.tabController,
});

final BroadcastTournamentId tournamentId;
final BroadcastTournamentId? tournamentId;
final BroadcastRoundId roundId;
final BroadcastGameId gameId;
final String? tournamentSlug;
Expand Down Expand Up @@ -379,13 +379,13 @@ enum _PlayerWidgetPosition { bottom, top }

class _PlayerWidget extends ConsumerWidget {
const _PlayerWidget({
required this.tournamentId,
this.tournamentId,
required this.roundId,
required this.gameId,
required this.widgetPosition,
});

final BroadcastTournamentId tournamentId;
final BroadcastTournamentId? tournamentId;
final BroadcastRoundId roundId;
final BroadcastGameId gameId;
final _PlayerWidgetPosition widgetPosition;
Expand Down Expand Up @@ -415,13 +415,21 @@ class _PlayerWidget extends ConsumerWidget {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
BroadcastPlayerResultsScreen.buildRoute(
context,
tournamentId,
(player.fideId != null) ? player.fideId!.toString() : player.name,
playerTitle: player.title,
playerName: player.name,
),
(tournamentId != null)
? BroadcastPlayerResultsScreen.buildRoute(
context,
tournamentId!,
(player.fideId != null) ? player.fideId!.toString() : player.name,
playerTitle: player.title,
playerName: player.name,
)
: BroadcastPlayerResultsScreenLoading.buildRoute(
context,
roundId,
(player.fideId != null) ? player.fideId!.toString() : player.name,
playerTitle: player.title,
playerName: player.name,
),
);
},
child: Container(
Expand Down
55 changes: 55 additions & 0 deletions lib/src/view/broadcast/broadcast_player_results_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,66 @@ import 'package:lichess_mobile/src/styles/styles.dart';
import 'package:lichess_mobile/src/utils/l10n_context.dart';
import 'package:lichess_mobile/src/utils/navigation.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_game_screen.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_player_screen_providers.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_player_widget.dart';
import 'package:lichess_mobile/src/widgets/platform_scaffold.dart';
import 'package:lichess_mobile/src/widgets/progression_widget.dart';
import 'package:lichess_mobile/src/widgets/stat_card.dart';

class BroadcastPlayerResultsScreenLoading extends ConsumerWidget {
final BroadcastRoundId roundId;
final String playerId;
final String? playerTitle;
final String playerName;

const BroadcastPlayerResultsScreenLoading(
this.roundId,
this.playerId, {
required this.playerName,
this.playerTitle,
});

static Route<dynamic> buildRoute(
BuildContext context,
BroadcastRoundId roundId,
String playerId, {
String? playerTitle,
required String playerName,
}) {
return buildScreenRoute(
context,
screen: BroadcastPlayerResultsScreenLoading(
roundId,
playerId,
playerTitle: playerTitle,
playerName: playerName,
),
);
}

@override
Widget build(BuildContext context, WidgetRef ref) {
final tournamentId = ref.watch(broadcastTournamentIdProvider(roundId));

return switch (tournamentId) {
AsyncData(:final value) => BroadcastPlayerResultsScreen(
value,
playerId,
playerTitle: playerTitle,
playerName: playerName,
),
AsyncError(:final error) => PlatformScaffold(
appBarTitle: const Text(''),
body: Center(child: Text('Cannot load round data: $error')),
),
_ => const PlatformScaffold(
appBarTitle: Text(''),
body: Center(child: CircularProgressIndicator.adaptive()),
),
};
}
}

class BroadcastPlayerResultsScreen extends StatelessWidget {
final BroadcastTournamentId tournamentId;
final String playerId;
Expand Down
11 changes: 11 additions & 0 deletions lib/src/view/broadcast/broadcast_player_screen_providers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lichess_mobile/src/model/broadcast/broadcast_providers.dart';
import 'package:lichess_mobile/src/model/common/id.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'broadcast_player_screen_providers.g.dart';

@riverpod
Future<BroadcastTournamentId> broadcastTournamentId(Ref ref, BroadcastRoundId roundId) {
return ref.watch(broadcastRoundProvider(roundId).selectAsync((round) => round.tournament.id));
}