Skip to content

Commit a5831fb

Browse files
authored
feat: use a router for navigation (#185)
* [router] add home and article * [router] add more routes; make video and article reachable only from url! * [router] add drivers and teams * [router] add 404, circuit, free practice, settings without update function * [router] add results, support routes with bbbuttons * [router] fix * [router] improve circuit screen when coming from url * [router] make results available from url too * [router] add schedule and standings * [router] add racehub * [router] add all results routes * [router] forgot this one * [shared links] fix texts, improve handler * [router] translate 404 page * [router] review fixes
1 parent 6e688dd commit a5831fb

30 files changed

+1494
-868
lines changed

lib/Screens/404.dart

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* This file is part of BoxBox (https://github.com/BrightDV/BoxBox).
3+
*
4+
* BoxBox is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* BoxBox is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with BoxBox. If not, see <http://www.gnu.org/licenses/>.
16+
*
17+
* Copyright (c) 2022-2024, BrightDV
18+
*/
19+
20+
import 'package:flutter/material.dart';
21+
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
22+
import 'package:go_router/go_router.dart';
23+
24+
class ErrorNotFoundScreen extends StatelessWidget {
25+
final String? route;
26+
const ErrorNotFoundScreen({super.key, this.route});
27+
28+
@override
29+
Widget build(BuildContext context) {
30+
return Scaffold(
31+
appBar: AppBar(
32+
centerTitle: true,
33+
title: const Text(
34+
'Box, Box!',
35+
style: TextStyle(
36+
fontWeight: FontWeight.w700,
37+
),
38+
),
39+
backgroundColor: Theme.of(context).colorScheme.onPrimary,
40+
),
41+
body: Center(
42+
child: Column(
43+
mainAxisAlignment: MainAxisAlignment.center,
44+
children: [
45+
Padding(
46+
padding: EdgeInsets.only(bottom: 5),
47+
child: Text(
48+
AppLocalizations.of(context)!.offtrack,
49+
style: TextStyle(fontSize: 24),
50+
),
51+
),
52+
Padding(
53+
padding: EdgeInsets.only(bottom: 30),
54+
child: Text(
55+
route ?? '',
56+
style: TextStyle(fontSize: 14),
57+
),
58+
),
59+
ElevatedButton(
60+
onPressed: () => context.go("/"),
61+
child: Text(AppLocalizations.of(context)!.offtrackSub),
62+
),
63+
],
64+
),
65+
),
66+
);
67+
}
68+
}

lib/Screens/circuit.dart

Lines changed: 85 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
* Copyright (c) 2022-2024, BrightDV
1818
*/
1919

20-
import 'package:boxbox/Screens/article.dart';
21-
import 'package:boxbox/Screens/race_details.dart';
2220
import 'package:boxbox/api/event_tracker.dart';
2321
import 'package:boxbox/api/formula1.dart';
2422
import 'package:boxbox/api/formulae.dart';
@@ -36,6 +34,7 @@ import 'package:cached_network_image/cached_network_image.dart';
3634
import 'package:flutter/material.dart';
3735
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
3836
import 'package:flutter_markdown/flutter_markdown.dart';
37+
import 'package:go_router/go_router.dart';
3938
import 'package:hive_flutter/hive_flutter.dart';
4039
import 'package:url_launcher/url_launcher.dart';
4140

@@ -107,10 +106,12 @@ class CircuitScreen extends StatelessWidget {
107106
Icon(
108107
Icons.arrow_forward_rounded,
109108
),
110-
RaceDetailsScreen(
111-
race,
112-
false, // offline
113-
),
109+
route: 'results',
110+
pathParameters: {'meetingId': race.meetingId},
111+
extra: {
112+
'race': race,
113+
'hasSprint': false, // offline
114+
},
114115
)
115116
: snapshot.hasData
116117
? Column(
@@ -123,21 +124,23 @@ class CircuitScreen extends StatelessWidget {
123124
Icon(
124125
Icons.arrow_forward_rounded,
125126
),
126-
RaceDetailsScreen(
127-
scheduleLastSavedFormat == 'ergast'
127+
route: 'results',
128+
pathParameters: {'meetingId': race.meetingId},
129+
extra: {
130+
'race': scheduleLastSavedFormat == 'ergast'
128131
? race
129132
: snapshot
130133
.data!['raceCustomBBParameter'],
131-
championship == 'Formula E'
134+
'hasSprint': championship == 'Formula E'
132135
? false
133136
: snapshot.data!['meetingContext']
134137
['timetables'][2]['session'] ==
135138
's',
136-
sessions: championship == 'Formula E'
139+
'sessions': championship == 'Formula E'
137140
? snapshot.data![
138141
'sessionsIdsCustomBBParameter']
139142
: null,
140-
),
143+
},
141144
),
142145
snapshot.data!['links'] != null &&
143146
snapshot.data!['links'].isNotEmpty &&
@@ -148,8 +151,10 @@ class CircuitScreen extends StatelessWidget {
148151
Icon(
149152
Icons.arrow_forward_rounded,
150153
),
151-
ArticleScreen(
152-
snapshot.data!['links'].last['url']
154+
route: 'article',
155+
pathParameters: {
156+
'id': snapshot
157+
.data!['links'].last['url']
153158
.endsWith('.html')
154159
? snapshot
155160
.data!['links'].last['url']
@@ -158,9 +163,8 @@ class CircuitScreen extends StatelessWidget {
158163
.data!['links'].last['url']
159164
.split('.')
160165
.last,
161-
'',
162-
true,
163-
),
166+
},
167+
extra: {'isFromLink': true},
164168
)
165169
: Container(),
166170
championship == 'Formula 1'
@@ -170,7 +174,7 @@ class CircuitScreen extends StatelessWidget {
170174
Icon(
171175
Icons.map_outlined,
172176
),
173-
CircuitMapScreen(
177+
widget: CircuitMapScreen(
174178
scheduleLastSavedFormat == 'ergast'
175179
? race.circuitId
176180
: Convert()
@@ -220,10 +224,12 @@ class CircuitScreen extends StatelessWidget {
220224
Icon(
221225
Icons.arrow_forward_rounded,
222226
),
223-
RaceDetailsScreen(
224-
race,
225-
false, // offline
226-
),
227+
route: 'results',
228+
pathParameters: {'meetingId': race.meetingId},
229+
extra: {
230+
'race': race,
231+
'hasSprint': false, //offline
232+
},
227233
),
228234
),
229235
),
@@ -248,6 +254,9 @@ class CircuitScreen extends StatelessWidget {
248254
pinned: true,
249255
centerTitle: true,
250256
flexibleSpace: FlexibleSpaceBar(
257+
background: RaceImageProvider(
258+
snapshot.data!['raceCustomBBParameter'],
259+
),
251260
title: Text(
252261
snapshot.data!['raceCustomBBParameter']
253262
.raceName,
@@ -269,13 +278,19 @@ class CircuitScreen extends StatelessWidget {
269278
Icon(
270279
Icons.arrow_forward_rounded,
271280
),
272-
RaceDetailsScreen(
273-
snapshot.data!['raceCustomBBParameter'],
274-
snapshot.data!['meetingContext']
275-
['timetables'][2]['session'] ==
276-
's',
277-
isFromRaceHub: true,
278-
),
281+
route: 'results',
282+
pathParameters: {
283+
'meetingId': snapshot
284+
.data!['meetingContext']['meetingKey']
285+
},
286+
extra: {
287+
'race':
288+
snapshot.data!['raceCustomBBParameter'],
289+
'hasSprint':
290+
snapshot.data!['meetingContext']
291+
['timetables'][2]['session'] ==
292+
's',
293+
},
279294
),
280295
snapshot.data!['links'] != null &&
281296
snapshot.data!['links'].isNotEmpty &&
@@ -286,8 +301,10 @@ class CircuitScreen extends StatelessWidget {
286301
Icon(
287302
Icons.arrow_forward_rounded,
288303
),
289-
ArticleScreen(
290-
snapshot.data!['links'][1]['url']
304+
route: 'article',
305+
pathParameters: {
306+
'id': snapshot.data!['links'][1]
307+
['url']
291308
.endsWith('.html')
292309
? snapshot.data!['links'][1]
293310
['url']
@@ -296,9 +313,32 @@ class CircuitScreen extends StatelessWidget {
296313
['url']
297314
.split('.')
298315
.last,
299-
'',
300-
true,
316+
},
317+
extra: {'isFromLink': true},
318+
)
319+
: Container(),
320+
championship == 'Formula 1'
321+
? BoxBoxButton(
322+
AppLocalizations.of(context)!
323+
.grandPrixMap,
324+
Icon(
325+
Icons.map_outlined,
301326
),
327+
widget: CircuitMapScreen(
328+
scheduleLastSavedFormat == 'ergast'
329+
? snapshot
330+
.data![
331+
'raceCustomBBParameter']
332+
.circuitId
333+
: Convert()
334+
.circuitNameFromFormulaOneToErgastForCircuitPoints(
335+
snapshot
336+
.data![
337+
'raceCustomBBParameter']
338+
.country,
339+
),
340+
),
341+
isDialog: true,
302342
)
303343
: Container(),
304344
snapshot.data!['raceResults'] != null &&
@@ -688,17 +728,19 @@ class RaceResults extends StatelessWidget {
688728
bottomRight: Radius.circular(15),
689729
),
690730
child: ElevatedButton(
691-
onPressed: () => Navigator.push(
692-
context,
693-
MaterialPageRoute(
694-
builder: (context) => RaceDetailsScreen(
695-
race,
696-
snapshot.data!['meetingContext']['timetables'][2]
697-
['session'] ==
698-
's',
699-
tab: 10,
700-
),
701-
),
731+
onPressed: () => context.pushNamed(
732+
'results',
733+
pathParameters: {
734+
'meetingId': snapshot.data!['meetingContext']
735+
['meetingKey'],
736+
},
737+
extra: {
738+
'race': race,
739+
'hasSprint': snapshot.data!['meetingContext']
740+
['timetables'][2]['session'] ==
741+
's',
742+
'tab': 10,
743+
},
702744
),
703745
style: ElevatedButton.styleFrom(
704746
shape: const ContinuousRectangleBorder(

0 commit comments

Comments
 (0)