Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
julien4215 committed Dec 10, 2024
1 parent e00ba00 commit 5e66206
Show file tree
Hide file tree
Showing 11 changed files with 483 additions and 140 deletions.
19 changes: 15 additions & 4 deletions lib/src/model/broadcast/broadcast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ typedef BroadcastTournamentGroup = ({

@freezed
class BroadcastRound with _$BroadcastRound {
const BroadcastRound._();

const factory BroadcastRound({
required BroadcastRoundId id,
required String name,
Expand Down Expand Up @@ -117,17 +115,30 @@ class BroadcastGame with _$BroadcastGame {

@freezed
class BroadcastPlayer with _$BroadcastPlayer {
const BroadcastPlayer._();

const factory BroadcastPlayer({
required String name,
required String? title,
required int? rating,
required Duration? clock,
required String? federation,
required FideId? fideId,
}) = _BroadcastPlayer;
}

@freezed
class BroadcastPlayerExtended with _$BroadcastPlayerExtended {
const factory BroadcastPlayerExtended({
required String name,
required String? title,
required int? rating,
required String? federation,
required FideId? fideId,
required int played,
required double? score,
required int? ratingDiff,
}) = _BroadcastPlayerExtended;
}

enum RoundStatus {
live,
finished,
Expand Down
45 changes: 45 additions & 0 deletions lib/src/model/broadcast/broadcast_providers.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lichess_mobile/src/model/broadcast/broadcast.dart';
import 'package:lichess_mobile/src/model/broadcast/broadcast_repository.dart';
Expand Down Expand Up @@ -54,6 +55,50 @@ Future<BroadcastTournament> broadcastTournament(
);
}

enum BroadcastPlayersSortingTypes { player, elo, score }

@riverpod
class BroadcastPlayers extends _$BroadcastPlayers {
@override
Future<IList<BroadcastPlayerExtended>> build(
BroadcastTournamentId tournamentId,
) async {
final players = ref.withClient(
(client) => BroadcastRepository(client).getPlayers(tournamentId),
);

return players;
}

void sort(BroadcastPlayersSortingTypes sortingType, [bool reverse = false]) {
if (!state.hasValue) return;

final compare = switch (sortingType) {
BroadcastPlayersSortingTypes.player =>
(BroadcastPlayerExtended a, BroadcastPlayerExtended b) =>
a.name.compareTo(b.name),
BroadcastPlayersSortingTypes.elo =>
(BroadcastPlayerExtended a, BroadcastPlayerExtended b) {
if (a.rating == null) return -1;
if (b.rating == null) return 1;
return b.rating!.compareTo(a.rating!);
},
BroadcastPlayersSortingTypes.score =>
(BroadcastPlayerExtended a, BroadcastPlayerExtended b) {
if (a.score == null) return -1;
if (b.score == null) return 1;
return b.score!.compareTo(a.score!);
}
};

state = AsyncData(
reverse
? state.requireValue.sortReversed(compare)
: state.requireValue.sort(compare),
);
}
}

@Riverpod(keepAlive: true)
BroadcastImageWorkerFactory broadcastImageWorkerFactory(Ref ref) {
return const BroadcastImageWorkerFactory();
Expand Down
30 changes: 27 additions & 3 deletions lib/src/model/broadcast/broadcast_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class BroadcastRepository {
path: '/api/broadcast/top',
queryParameters: {'page': page.toString()},
),
headers: {'Accept': 'application/json'},
mapper: _makeBroadcastResponseFromJson,
);
}
Expand All @@ -28,7 +27,6 @@ class BroadcastRepository {
) {
return client.readJson(
Uri(path: 'api/broadcast/$broadcastTournamentId'),
headers: {'Accept': 'application/json'},
mapper: _makeTournamentFromJson,
);
}
Expand All @@ -40,7 +38,6 @@ class BroadcastRepository {
Uri(path: 'api/broadcast/-/-/$broadcastRoundId'),
// The path parameters with - are the broadcast tournament and round slugs
// They are only used for SEO, so we can safely use - for these parameters
headers: {'Accept': 'application/x-ndjson'},
mapper: _makeRoundWithGamesFromJson,
);
}
Expand All @@ -51,6 +48,15 @@ class BroadcastRepository {
) {
return client.read(Uri(path: 'api/study/$roundId/$gameId.pgn'));
}

Future<IList<BroadcastPlayerExtended>> getPlayers(
BroadcastTournamentId tournamentId,
) {
return client.readJsonList(
Uri(path: '/broadcast/$tournamentId/players'),
mapper: _makePlayerFromJson,
);
}
}

BroadcastList _makeBroadcastResponseFromJson(
Expand Down Expand Up @@ -195,5 +201,23 @@ BroadcastPlayer _playerFromPick(RequiredPick pick) {
rating: pick('rating').asIntOrNull(),
clock: pick('clock').asDurationFromCentiSecondsOrNull(),
federation: pick('fed').asStringOrNull(),
fideId: pick('fideId').asFideIdOrNull(),
);
}

BroadcastPlayerExtended _makePlayerFromJson(Map<String, dynamic> json) {
return _playerExtendedFromPick(pick(json).required());
}

BroadcastPlayerExtended _playerExtendedFromPick(RequiredPick pick) {
return BroadcastPlayerExtended(
name: pick('name').asStringOrThrow(),
title: pick('title').asStringOrNull(),
rating: pick('rating').asIntOrNull(),
federation: pick('fed').asStringOrNull(),
fideId: pick('fideId').asFideIdOrNull(),
played: pick('played').asIntOrThrow(),
score: pick('score').asDoubleOrNull(),
ratingDiff: pick('ratingDiff').asIntOrNull(),
);
}
21 changes: 21 additions & 0 deletions lib/src/model/common/id.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ extension type const StudyChapterId(String value) implements StringId {
StudyChapterId.fromJson(dynamic json) : this(json as String);
}

extension type const FideId(String value) implements StringId {}

extension IDPick on Pick {
UserId asUserIdOrThrow() {
final value = required().value;
Expand Down Expand Up @@ -227,4 +229,23 @@ extension IDPick on Pick {
"value $value at $debugParsingExit can't be casted to StudyId",
);
}

FideId asFideIdOrThrow() {
final value = required().value;
if (value is String) {
return FideId(value);
}
throw PickException(
"value $value at $debugParsingExit can't be casted to FideId",
);
}

FideId? asFideIdOrNull() {
if (value == null) return null;
try {
return asFideIdOrThrow();
} catch (_) {
return null;
}
}
}
43 changes: 6 additions & 37 deletions lib/src/view/broadcast/broadcast_boards_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ import 'package:dartchess/dartchess.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:lichess_mobile/src/model/broadcast/broadcast.dart';
import 'package:lichess_mobile/src/model/broadcast/broadcast_round_controller.dart';
import 'package:lichess_mobile/src/model/common/id.dart';
import 'package:lichess_mobile/src/network/http.dart';
import 'package:lichess_mobile/src/styles/styles.dart';
import 'package:lichess_mobile/src/utils/duration.dart';
import 'package:lichess_mobile/src/utils/l10n_context.dart';
import 'package:lichess_mobile/src/utils/lichess_assets.dart';
import 'package:lichess_mobile/src/utils/navigation.dart';
import 'package:lichess_mobile/src/utils/screen.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_game_screen.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_player_widget.dart';
import 'package:lichess_mobile/src/widgets/board_thumbnail.dart';
import 'package:lichess_mobile/src/widgets/clock.dart';
import 'package:lichess_mobile/src/widgets/shimmer.dart';
Expand Down Expand Up @@ -210,40 +208,11 @@ class _PlayerWidget extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (player.federation != null) ...[
Consumer(
builder: (context, widgetRef, _) {
return SvgPicture.network(
lichessFideFedSrc(player.federation!),
height: 12,
httpClient: widgetRef.read(defaultClientProvider),
);
},
),
],
const SizedBox(width: 5),
if (player.title != null) ...[
Text(
player.title!,
style: const TextStyle().copyWith(
color: context.lichessColors.brag,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
],
Flexible(
child: Text(
player.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
Expanded(
child: BroadcastPlayerWidget(
federation: player.federation,
title: player.title,
name: player.name,
),
),
const SizedBox(width: 5),
Expand Down
44 changes: 9 additions & 35 deletions lib/src/view/broadcast/broadcast_game_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:dartchess/dartchess.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:lichess_mobile/src/constants.dart';
import 'package:lichess_mobile/src/model/analysis/analysis_preferences.dart';
import 'package:lichess_mobile/src/model/broadcast/broadcast.dart';
Expand All @@ -14,16 +13,15 @@ import 'package:lichess_mobile/src/model/common/eval.dart';
import 'package:lichess_mobile/src/model/common/id.dart';
import 'package:lichess_mobile/src/model/engine/evaluation_service.dart';
import 'package:lichess_mobile/src/model/settings/board_preferences.dart';
import 'package:lichess_mobile/src/network/http.dart';
import 'package:lichess_mobile/src/styles/styles.dart';
import 'package:lichess_mobile/src/utils/duration.dart';
import 'package:lichess_mobile/src/utils/l10n_context.dart';
import 'package:lichess_mobile/src/utils/lichess_assets.dart';
import 'package:lichess_mobile/src/utils/navigation.dart';
import 'package:lichess_mobile/src/view/analysis/analysis_layout.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_game_bottom_bar.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_game_settings.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_game_tree_view.dart';
import 'package:lichess_mobile/src/view/broadcast/broadcast_player_widget.dart';
import 'package:lichess_mobile/src/view/engine/engine_gauge.dart';
import 'package:lichess_mobile/src/view/engine/engine_lines.dart';
import 'package:lichess_mobile/src/view/opening_explorer/opening_explorer_view.dart';
Expand Down Expand Up @@ -386,40 +384,16 @@ class _PlayerWidget extends ConsumerWidget {
),
const SizedBox(width: 16.0),
],
if (player.federation != null) ...[
SvgPicture.network(
lichessFideFedSrc(player.federation!),
height: 12,
httpClient: ref.read(defaultClientProvider),
Expanded(
child: BroadcastPlayerWidget(
federation: player.federation,
title: player.title,
name: player.name,
rating: player.rating,
textStyle:
const TextStyle().copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(width: 5),
],
if (player.title != null) ...[
Text(
player.title!,
style: const TextStyle().copyWith(
color: context.lichessColors.brag,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
],
Text(
player.name,
style: const TextStyle().copyWith(
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
),
if (player.rating != null) ...[
const SizedBox(width: 5),
Text(
player.rating.toString(),
style: const TextStyle(),
overflow: TextOverflow.ellipsis,
),
],
const Spacer(),
if (clock != null)
Container(
height: kAnalysisBoardHeaderOrFooterHeight,
Expand Down
63 changes: 63 additions & 0 deletions lib/src/view/broadcast/broadcast_player_widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:lichess_mobile/src/network/http.dart';
import 'package:lichess_mobile/src/styles/styles.dart';
import 'package:lichess_mobile/src/utils/lichess_assets.dart';

class BroadcastPlayerWidget extends ConsumerWidget {
const BroadcastPlayerWidget({
required this.federation,
required this.title,
required this.name,
this.rating,
this.textStyle,
});

final String? federation;
final String? title;
final int? rating;
final String name;
final TextStyle? textStyle;

@override
Widget build(BuildContext context, WidgetRef ref) {
return Row(
children: [
if (federation != null) ...[
SvgPicture.network(
lichessFideFedSrc(federation!),
height: 12,
httpClient: ref.read(defaultClientProvider),
),
const SizedBox(width: 5),
],
if (title != null) ...[
Text(
title!,
style: const TextStyle().copyWith(
color: context.lichessColors.brag,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
],
Flexible(
child: Text(
name,
style: textStyle,
overflow: TextOverflow.ellipsis,
),
),
if (rating != null) ...[
const SizedBox(width: 5),
Text(
rating.toString(),
style: const TextStyle(),
overflow: TextOverflow.ellipsis,
),
],
],
);
}
}
Loading

0 comments on commit 5e66206

Please sign in to comment.