From af5b4f9df2ef960df32bba411303ce51955302d7 Mon Sep 17 00:00:00 2001 From: Jaap Aarts Date: Wed, 13 Nov 2024 20:10:36 +0100 Subject: [PATCH] Change how the thabloids work (#523) --- lib/api/api_repository.dart | 5 ++ lib/api/concrexit_api_repository.dart | 14 +++++ lib/blocs/thabloid_cubit.dart | 22 ++++++++ lib/blocs/thabloid_list_cubit.dart | 4 +- lib/main.dart | 4 +- lib/ui/screens/thabloids_screen.dart | 29 ++++------ lib/ui/widgets/thabloid_tile.dart | 78 +++++++++++++++------------ 7 files changed, 98 insertions(+), 58 deletions(-) create mode 100644 lib/blocs/thabloid_cubit.dart diff --git a/lib/api/api_repository.dart b/lib/api/api_repository.dart index d0d180670..0da9edf2f 100644 --- a/lib/api/api_repository.dart +++ b/lib/api/api_repository.dart @@ -292,6 +292,11 @@ abstract class ApiRepository { int? offset, }); + /// Get a [Thabloid]. + Future getThabloid({ + required int pk, + }); + /// Get a list of [Slide]s. /// /// Use `limit` and `offset` for pagination. [ListResponse.count] is the diff --git a/lib/api/concrexit_api_repository.dart b/lib/api/concrexit_api_repository.dart index 3a5afcbc5..85e33ecc5 100644 --- a/lib/api/concrexit_api_repository.dart +++ b/lib/api/concrexit_api_repository.dart @@ -1074,6 +1074,20 @@ class ConcrexitApiRepository implements ApiRepository { ); } + @override + Future getThabloid({ + required int pk, + }) async { + return sandbox(() async { + final uri = _uri( + path: '/thabloid/thabloids/$pk', + ); + + final response = await _handleExceptions(() => _client.get(uri)); + return Thabloid.fromJson(_jsonDecode(response)); + }); + } + @override Future> getSlides({ int? limit, diff --git a/lib/blocs/thabloid_cubit.dart b/lib/blocs/thabloid_cubit.dart new file mode 100644 index 000000000..9f09f9148 --- /dev/null +++ b/lib/blocs/thabloid_cubit.dart @@ -0,0 +1,22 @@ +import 'dart:async'; + +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:reaxit/api/api_repository.dart'; +import 'package:reaxit/models/thabliod.dart'; + +class ThabloidCubit extends Cubit { + final ApiRepository api; + Thabloid thabloid; + Timer _debounceTimer = Timer(const Duration(hours: 1), () => {}); + + ThabloidCubit(this.api, this.thabloid) : super(thabloid); + + Future getTitle() async { + if (!_debounceTimer.isActive) { + Thabloid thabloid = await api.getThabloid(pk: this.thabloid.pk); + emit(thabloid); + _debounceTimer = Timer(const Duration(hours: 1), () => {}); + } + return thabloid.file; + } +} diff --git a/lib/blocs/thabloid_list_cubit.dart b/lib/blocs/thabloid_list_cubit.dart index 984bbc113..e7307fac4 100644 --- a/lib/blocs/thabloid_list_cubit.dart +++ b/lib/blocs/thabloid_list_cubit.dart @@ -7,8 +7,8 @@ import 'package:reaxit/models/thabliod.dart'; typedef ThabloidListState = ListState; -class ThabloidCubit extends SingleListCubit { - ThabloidCubit(super.api); +class ThabloidListCubit extends SingleListCubit { + ThabloidListCubit(super.api); static const int firstPageSize = 30; diff --git a/lib/main.dart b/lib/main.dart index a8ee5a28e..246f3ab34 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -331,8 +331,8 @@ class _ThaliAppState extends State { lazy: false, ), BlocProvider( - create: (_) => - ThabloidCubit(apiRepository)..cachedLoad(), + create: (_) => ThabloidListCubit(apiRepository) + ..cachedLoad(), lazy: false, ), BlocProvider( diff --git a/lib/ui/screens/thabloids_screen.dart b/lib/ui/screens/thabloids_screen.dart index 95191e46e..070c85f08 100644 --- a/lib/ui/screens/thabloids_screen.dart +++ b/lib/ui/screens/thabloids_screen.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; +import 'package:reaxit/api/api_repository.dart'; import 'package:reaxit/blocs.dart'; import 'package:reaxit/blocs/thabloid_list_cubit.dart'; import 'package:reaxit/models/thabliod.dart'; @@ -17,8 +18,6 @@ class ThabloidScreen extends StatefulWidget { class _ThabloidScreenState extends State { late ScrollController _controller; late CalendarCubit _cubit; - GlobalKey todayKey = GlobalKey(); - GlobalKey thisMonthKey = GlobalKey(); @override void initState() { @@ -47,22 +46,18 @@ class _ThabloidScreenState extends State { title: const Text('THABLOIDS'), ), drawer: MenuDrawer(), - body: BlocBuilder( - builder: (context, calendarState) { - if (calendarState.hasException) { - return ErrorScrollView(calendarState.message!); - } else if (calendarState.isLoading) { + body: BlocBuilder( + builder: (context, thabloidsState) { + if (thabloidsState.hasException) { + return ErrorScrollView(thabloidsState.message!); + } else if (thabloidsState.isLoading) { return const Center(child: CircularProgressIndicator()); } else { - todayKey = GlobalKey(); - thisMonthKey = GlobalKey(); return ThabloidsScrollView( key: const PageStorageKey('thabloids'), controller: _controller, - thabloidState: calendarState, - todayKey: todayKey, - thisMonthKey: thisMonthKey, - thabloids: calendarState.results, + thabloidState: thabloidsState, + thabloids: thabloidsState.results, ); } }, @@ -81,9 +76,6 @@ class ThabloidsScrollView extends StatelessWidget { static final monthFormatter = DateFormat('MMMM'); static final monthYearFormatter = DateFormat('MMMM yyyy'); - final GlobalKey? todayKey; - final GlobalKey? thisMonthKey; - final Key centerkey = UniqueKey(); final ScrollController controller; final ThabloidListState thabloidState; @@ -93,12 +85,11 @@ class ThabloidsScrollView extends StatelessWidget { {super.key, required this.controller, required this.thabloidState, - this.todayKey, - this.thisMonthKey, required this.thabloids}); @override Widget build(BuildContext context) { + ApiRepository api = context.read(); return Column( children: [ Expanded( @@ -119,7 +110,7 @@ class ThabloidsScrollView extends StatelessWidget { childAspectRatio: 1 / sqrt(2), ), delegate: SliverChildBuilderDelegate( - (_, index) => ThabloidDetailCard(thabloids[index]), + (_, index) => ThabloidDetailCard(thabloids[index], api), childCount: thabloids.length, ), ), diff --git a/lib/ui/widgets/thabloid_tile.dart b/lib/ui/widgets/thabloid_tile.dart index 0aaf8b83c..0360deeaa 100644 --- a/lib/ui/widgets/thabloid_tile.dart +++ b/lib/ui/widgets/thabloid_tile.dart @@ -1,53 +1,61 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:reaxit/api/api_repository.dart'; +import 'package:reaxit/blocs/thabloid_cubit.dart'; import 'package:reaxit/models/thabliod.dart'; import 'package:reaxit/ui/widgets/cached_image.dart'; import 'package:url_launcher/url_launcher.dart'; class ThabloidDetailCard extends StatelessWidget { - final Thabloid thabloid; + final ThabloidCubit cubit; + ThabloidDetailCard(Thabloid thabloid, ApiRepository api) + : cubit = ThabloidCubit(api, thabloid); - const ThabloidDetailCard(this.thabloid); - - void _openThabloid() { - launchUrl(Uri.parse(thabloid.file), mode: LaunchMode.externalApplication); + void _openThabloid() async { + launchUrl(Uri.parse(await cubit.getTitle()), + mode: LaunchMode.externalApplication); } @override Widget build(BuildContext context) { final textTheme = Theme.of(context).textTheme; - return Stack( - children: [ - CachedImage( - placeholder: 'assets/img/thabloid_placeholder.png', - imageUrl: thabloid.cover, - ), - Align( - alignment: Alignment.bottomRight, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - '${thabloid.year}-${thabloid.year + 1} nr. ${thabloid.issue}', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: textTheme.titleMedium?.copyWith(shadows: [ - const Shadow( - offset: Offset(0.0, 0.0), - blurRadius: 10.0, - color: Color.fromARGB(255, 0, 0, 0), - ), - ]), + return BlocBuilder( + builder: (context, thabloidsState) { + Thabloid thabloid = thabloidsState; + return Stack( + children: [ + CachedImage( + placeholder: 'assets/img/thabloid_placeholder.png', + imageUrl: thabloid.cover, + ), + Align( + alignment: Alignment.bottomRight, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + '${thabloid.year}-${thabloid.year + 1} nr. ${thabloid.issue}', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: textTheme.titleMedium?.copyWith(shadows: [ + const Shadow( + offset: Offset(0.0, 0.0), + blurRadius: 10.0, + color: Color.fromARGB(255, 0, 0, 0), + ), + ]), + ), ), ), - ), - Positioned.fill( - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: _openThabloid, + Positioned.fill( + child: Material( + color: Colors.transparent, + child: InkWell( + onTap: _openThabloid, + ), ), ), - ), - ], - ); + ], + ); + }); } }