~repos /only-bible-app

#kotlin#android#ios

GIT_CONFIG_PARAMETERS="'http.version=HTTP/1.1'" git clone https://git.pyrossh.dev/only-bible-app.git
Discussions: https://groups.google.com/g/rust-embed-devs

The only bible app you will ever need. No ads. No in-app purchases. No distractions.


lib/app.dart CHANGED
@@ -1,20 +1,111 @@
1
1
  import "package:flutter/material.dart";
2
+ import "package:go_router/go_router.dart";
2
3
  import "package:only_bible_app/l10n/app_localizations.dart";
3
4
  import "package:only_bible_app/screens/bible_select_screen.dart";
5
+ import "package:only_bible_app/screens/book_select_screen.dart";
6
+ import "package:only_bible_app/screens/chapter_select_screen.dart";
4
7
  import "package:only_bible_app/screens/chapter_view_screen.dart";
8
+ import "package:only_bible_app/screens/webview_screen.dart";
5
9
  import "package:only_bible_app/store/state.dart";
6
10
  import "package:only_bible_app/theme.dart";
7
11
  import "package:only_bible_app/utils.dart";
8
12
 
9
13
  final globalNavigatorKey = GlobalKey<NavigatorState>();
10
14
 
15
+ final router = GoRouter(
16
+ navigatorKey: globalNavigatorKey,
17
+ initialLocation: firstOpenAtom.value
18
+ ? "/bible"
19
+ : "/chapter/${Uri.encodeComponent(bibleNameAtom.value)}/${savedBookAtom.value}/${savedChapterAtom.value}",
20
+ routes: [
21
+ GoRoute(
22
+ path: "/bible",
23
+ pageBuilder: (context, state) => const NoTransitionPage(
24
+ child: BibleSelectScreen(),
25
+ ),
26
+ ),
27
+ GoRoute(
28
+ path: "/chapter/:bibleName/:bookIndex/:chapterIndex",
29
+ pageBuilder: (context, state) {
30
+ final bibleName =
31
+ Uri.decodeComponent(state.pathParameters["bibleName"]!);
32
+ final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
33
+ final chapterIndex = int.parse(state.pathParameters["chapterIndex"]!);
34
+ final slideDir = state.extra as TextDirection?;
35
+ if (slideDir != null) {
36
+ return CustomTransitionPage(
37
+ key: state.pageKey,
38
+ child: ChapterViewScreen(
39
+ bibleName: bibleName,
40
+ bookIndex: bookIndex,
41
+ chapterIndex: chapterIndex,
42
+ ),
43
+ transitionsBuilder:
44
+ (context, animation, secondaryAnimation, child) {
45
+ const begin = Offset(1.0, 0.0);
46
+ const end = Offset.zero;
47
+ const curve = Curves.ease;
48
+ final tween =
49
+ Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
50
+ return SlideTransition(
51
+ textDirection: slideDir,
52
+ position: animation.drive(tween),
53
+ child: child,
54
+ );
55
+ },
56
+ );
57
+ }
58
+ return NoTransitionPage(
59
+ key: state.pageKey,
60
+ child: ChapterViewScreen(
61
+ bibleName: bibleName,
62
+ bookIndex: bookIndex,
63
+ chapterIndex: chapterIndex,
64
+ ),
65
+ );
66
+ },
67
+ ),
68
+ GoRoute(
69
+ path: "/books/:bibleName",
70
+ pageBuilder: (context, state) {
71
+ final bibleName =
72
+ Uri.decodeComponent(state.pathParameters["bibleName"]!);
73
+ return NoTransitionPage(
74
+ child: BookSelectScreen(bibleName: bibleName),
75
+ );
76
+ },
77
+ ),
78
+ GoRoute(
79
+ path: "/chapters/:bibleName/:bookIndex",
80
+ pageBuilder: (context, state) {
81
+ final bibleName =
82
+ Uri.decodeComponent(state.pathParameters["bibleName"]!);
83
+ final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
84
+ return NoTransitionPage(
85
+ child:
86
+ ChapterSelectScreen(bibleName: bibleName, bookIndex: bookIndex),
87
+ );
88
+ },
89
+ ),
90
+ GoRoute(
91
+ path: "/webview",
92
+ pageBuilder: (context, state) {
93
+ final url = state.extra as String;
94
+ return NoTransitionPage(
95
+ child: WebViewScreen(url: url),
96
+ );
97
+ },
98
+ ),
99
+ ],
100
+ );
101
+
11
102
  class App extends StatelessWidget {
12
103
  const App({super.key});
13
104
 
14
105
  @override
15
106
  Widget build(BuildContext context) {
16
- return MaterialApp(
107
+ return MaterialApp.router(
17
- navigatorKey: globalNavigatorKey,
108
+ routerConfig: router,
18
109
  onGenerateTitle: (context) => context.l.title,
19
110
  localizationsDelegates: AppLocalizations.localizationsDelegates,
20
111
  supportedLocales: AppLocalizations.supportedLocales,
@@ -23,13 +114,6 @@ class App extends StatelessWidget {
23
114
  theme: lightTheme,
24
115
  darkTheme: darkTheme,
25
116
  locale: Locale(languageCodeAtom.watch(context)),
26
- home: firstOpenAtom.value
27
- ? const BibleSelectScreen()
28
- : ChapterViewScreen(
29
- bibleName: bibleNameAtom.value,
30
- bookIndex: savedBookAtom.value,
31
- chapterIndex: savedChapterAtom.value,
32
- ),
33
117
  );
34
118
  }
35
119
  }
lib/navigation.dart CHANGED
@@ -2,18 +2,14 @@ import "package:atoms_state/atoms_state.dart";
2
2
  import "package:flutter/material.dart";
3
3
  import "package:flutter/services.dart";
4
4
  import "package:app_review/app_review.dart";
5
+ import "package:go_router/go_router.dart";
5
6
  import "package:only_bible_app/models.dart";
6
- import "package:only_bible_app/screens/bible_select_screen.dart";
7
- import "package:only_bible_app/screens/book_select_screen.dart";
8
- import "package:only_bible_app/screens/chapter_select_screen.dart";
9
- import "package:only_bible_app/screens/chapter_view_screen.dart";
10
7
  import "package:only_bible_app/sheets/actions_sheet.dart";
11
8
  import "package:only_bible_app/sheets/highlight_sheet.dart";
12
9
  import "package:only_bible_app/sheets/settings_sheet.dart";
13
10
  import "package:only_bible_app/store/actions.dart";
14
11
  import "package:only_bible_app/store/state.dart";
15
12
  import "package:only_bible_app/utils.dart";
16
- import "package:only_bible_app/screens/webview_screen.dart";
17
13
  import "package:share_plus/share_plus.dart";
18
14
 
19
15
  final actionsShownAtom = Atom(
@@ -38,73 +34,42 @@ final highlightsShownAtom = Atom(
38
34
  },
39
35
  );
40
36
 
41
- PageRouteBuilder<dynamic> createNoTransitionPageRoute(Widget page) {
42
- return PageRouteBuilder(
43
- opaque: false,
44
- transitionDuration: Duration.zero,
45
- reverseTransitionDuration: Duration.zero,
46
- pageBuilder: (context, _, __) => page,
47
- );
48
- }
49
-
50
- PageRouteBuilder<dynamic> createSlideRoute({
51
- required BuildContext context,
52
- TextDirection? slideDir,
53
- required Widget page,
54
- }) {
55
- if (slideDir == null) {
56
- return PageRouteBuilder(
57
- pageBuilder: (context, _, __) {
58
- return page;
59
- },
60
- );
61
- }
62
- return PageRouteBuilder(
63
- pageBuilder: (context, animation, secondaryAnimation) => page,
64
- transitionsBuilder: (context, animation, secondaryAnimation, child) {
37
+ String _chapterPath(String bibleName, int book, int chapter) {
65
- const begin = Offset(1.0, 0.0);
66
- const end = Offset.zero;
67
- const curve = Curves.ease;
68
- var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
38
+ return "/chapter/${Uri.encodeComponent(bibleName)}/$book/$chapter";
69
- return SlideTransition(
70
- textDirection: slideDir,
71
- position: animation.drive(tween),
72
- child: child,
73
- );
74
- },
75
- );
76
39
  }
77
40
 
78
41
  void updateStatusBar(bool v) {
79
42
  if (v) {
80
- SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
43
+ SystemChrome.setSystemUIOverlayStyle(
44
+ const SystemUiOverlayStyle(
81
- systemNavigationBarColor: Color(0xFF1F1F22),
45
+ systemNavigationBarColor: Color(0xFF1F1F22),
82
- statusBarColor: Color(0xFF1F1F22),
46
+ statusBarColor: Color(0xFF1F1F22),
83
- systemNavigationBarIconBrightness: Brightness.light,
47
+ systemNavigationBarIconBrightness: Brightness.light,
84
- statusBarIconBrightness: Brightness.light,
48
+ statusBarIconBrightness: Brightness.light,
85
- ),);
49
+ ),
50
+ );
86
51
  } else {
87
- SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
52
+ SystemChrome.setSystemUIOverlayStyle(
53
+ const SystemUiOverlayStyle(
88
- systemNavigationBarColor: Colors.white,
54
+ systemNavigationBarColor: Colors.white,
89
- statusBarColor: Colors.white,
55
+ statusBarColor: Colors.white,
90
- systemNavigationBarIconBrightness: Brightness.dark,
56
+ systemNavigationBarIconBrightness: Brightness.dark,
91
- statusBarIconBrightness: Brightness.dark,
57
+ statusBarIconBrightness: Brightness.dark,
92
- ),);
58
+ ),
59
+ );
93
60
  }
94
61
  }
95
62
 
96
- void pushBookChapter(BuildContext context, String bibleName, int book, int chapter,
63
+ void pushBookChapter(
64
+ BuildContext context,
65
+ String bibleName,
66
+ int book,
67
+ int chapter,
97
- TextDirection? dir,) {
68
+ TextDirection? dir,
69
+ ) {
98
70
  dispatch(UpdateChapter(book, chapter));
99
71
  clearEvents(context);
100
- Navigator.of(context).push(
101
- createSlideRoute(
102
- context: context,
103
- slideDir: dir,
104
- page: ChapterViewScreen(
105
- bibleName: bibleName, bookIndex: book, chapterIndex: chapter,),
72
+ context.push(_chapterPath(bibleName, book, chapter), extra: dir);
106
- ),
107
- );
108
73
  }
109
74
 
110
75
  void replaceBookChapter(
@@ -115,27 +80,29 @@ void replaceBookChapter(
115
80
  ) {
116
81
  dispatch(UpdateChapter(book, chapter));
117
82
  clearEvents(context);
118
- Navigator.of(context).pushReplacement(
119
- createNoTransitionPageRoute(
120
- ChapterViewScreen(
121
- bibleName: bibleName,
122
- bookIndex: book,
123
- chapterIndex: chapter,
83
+ context.go(_chapterPath(bibleName, book, chapter));
124
- ),
125
- ),
126
- );
127
84
  }
128
85
 
129
86
  void nextChapter(BuildContext context, Bible bible, int book, int chapter) {
130
87
  final selectedBook = bible.books[book];
131
88
  if (selectedBook.chapters.length > chapter + 1) {
89
+ pushBookChapter(
90
+ context,
91
+ bible.name,
132
- pushBookChapter(context, bible.name, selectedBook.index, chapter + 1,
92
+ selectedBook.index,
93
+ chapter + 1,
133
- TextDirection.ltr,);
94
+ TextDirection.ltr,
95
+ );
134
96
  } else {
135
97
  if (selectedBook.index + 1 < bible.books.length) {
136
98
  final nextBook = bible.books[selectedBook.index + 1];
137
99
  pushBookChapter(
100
+ context,
101
+ bible.name,
102
+ nextBook.index,
103
+ 0,
138
- context, bible.name, nextBook.index, 0, TextDirection.ltr,);
104
+ TextDirection.ltr,
105
+ );
139
106
  }
140
107
  }
141
108
  }
@@ -146,85 +113,66 @@ void previousChapter(BuildContext context, Bible bible, int book, int chapter) {
146
113
  // if (Navigator.of(context).canPop()) {
147
114
  // Navigator.of(context).pop();
148
115
  // } else {
116
+ pushBookChapter(
117
+ context,
118
+ bible.name,
149
- pushBookChapter(context, bible.name, selectedBook.index, chapter - 1,
119
+ selectedBook.index,
120
+ chapter - 1,
150
- TextDirection.rtl,);
121
+ TextDirection.rtl,
122
+ );
151
123
  // }
152
124
  } else {
153
125
  if (selectedBook.index - 1 >= 0) {
154
126
  final prevBook = bible.books[selectedBook.index - 1];
155
- pushBookChapter(context, bible.name, prevBook.index,
127
+ pushBookChapter(
128
+ context,
129
+ bible.name,
130
+ prevBook.index,
156
- prevBook.chapters.length - 1, TextDirection.rtl,);
131
+ prevBook.chapters.length - 1,
132
+ TextDirection.rtl,
133
+ );
157
134
  }
158
135
  }
159
136
  }
160
137
 
161
138
  void showAboutUs(BuildContext context) {
162
- Navigator.of(context).push(
163
- createNoTransitionPageRoute(
164
- const WebViewScreen(
165
- url: "https://onlybible.app/about-us",
139
+ context.push("/webview", extra: "https://onlybible.app/about-us");
166
- ),
167
- ),
168
- );
169
140
  }
170
141
 
171
142
  void showPrivacyPolicy(BuildContext context) {
172
- Navigator.of(context).push(
173
- createNoTransitionPageRoute(
174
- const WebViewScreen(
175
- url: "https://onlybible.app/privacy-policy",
143
+ context.push("/webview", extra: "https://onlybible.app/privacy-policy");
176
- ),
177
- ),
178
- );
179
144
  }
180
145
 
181
146
  void showTermsAndConditions(BuildContext context) {
182
- Navigator.of(context).push(
183
- createNoTransitionPageRoute(
184
- const WebViewScreen(
185
- url: "https://onlybible.app/terms-and-conditions",
147
+ context.push("/webview", extra: "https://onlybible.app/terms-and-conditions");
186
- ),
187
- ),
188
- );
189
148
  }
190
149
 
191
150
  void changeBible(BuildContext context) {
192
- Navigator.of(context).pushReplacement(
193
- createNoTransitionPageRoute(
151
+ context.go("/bible");
194
- const BibleSelectScreen(),
195
- ),
196
- );
197
152
  }
198
153
 
199
154
  void changeBibleFromHeader(BuildContext context) {
200
- Navigator.of(context).push(
201
- createNoTransitionPageRoute(
155
+ context.push("/bible");
202
- const BibleSelectScreen(),
203
- ),
204
- );
205
156
  }
206
157
 
207
158
  void changeBook(BuildContext context, Bible bible) {
208
- Navigator.of(context).push(
209
- createNoTransitionPageRoute(
210
- BookSelectScreen(bible: bible),
159
+ context.push("/books/${Uri.encodeComponent(bible.name)}");
211
- ),
212
- );
213
160
  }
214
161
 
215
162
  void changeChapter(BuildContext context, Bible bible, Book book, int index) {
216
- Navigator.of(context).push(
217
- createNoTransitionPageRoute(
218
- ChapterSelectScreen(bible: bible, book: book, selectedBookIndex: index),
163
+ context.push("/chapters/${Uri.encodeComponent(bible.name)}/${book.index}");
219
- ),
220
- );
221
164
  }
222
165
 
223
- Future<void> updateCurrentBible(BuildContext context, String name, String code, int book,
166
+ Future<void> updateCurrentBible(
167
+ BuildContext context,
168
+ String name,
169
+ String code,
170
+ int book,
224
- int chapter,) async {
171
+ int chapter,
172
+ ) async {
225
173
  hideActions(context);
226
174
  dispatch(UpdateBible(name, code));
227
- pushBookChapter(context, name, book, chapter, null);
175
+ context.go(_chapterPath(name, book, chapter));
228
176
  }
229
177
 
230
178
  void shareAppLink(BuildContext context) {
@@ -245,7 +193,8 @@ Future<void> rateApp(BuildContext context) async {
245
193
  AppReview.requestReview;
246
194
  }
247
195
 
196
+ Future<void> shareVerses(
248
- Future<void> shareVerses(BuildContext context, Bible bible, List<Verse> verses) async {
197
+ BuildContext context, Bible bible, List<Verse> verses) async {
249
198
  final name = context.bookNames[verses.first.book];
250
199
  final chapter = verses.first.chapter + 1;
251
200
  final items = verses.sortedBy((e) => e.index).map((e) => e.index + 1);
lib/screens/book_select_screen.dart CHANGED
@@ -1,66 +1,79 @@
1
1
  import "package:flutter/material.dart";
2
+ import "package:go_router/go_router.dart";
2
3
  import "package:only_bible_app/navigation.dart";
4
+ import "package:only_bible_app/store/state.dart";
3
5
  import "package:only_bible_app/utils.dart";
4
6
  import "package:only_bible_app/widgets/scaffold_menu.dart";
5
- import "package:only_bible_app/screens/chapter_select_screen.dart";
6
7
  import "package:only_bible_app/widgets/sliver_heading.dart";
7
8
  import "package:only_bible_app/widgets/sliver_tile_grid.dart";
8
9
  import "package:only_bible_app/models.dart";
9
10
 
10
11
  class BookSelectScreen extends StatelessWidget {
11
- final Bible bible;
12
+ final String bibleName;
12
13
 
13
- const BookSelectScreen({super.key, required this.bible});
14
+ const BookSelectScreen({super.key, required this.bibleName});
14
15
 
15
- dynamic onBookSelected(BuildContext context, int index) {
16
+ dynamic onBookSelected(BuildContext context, Bible bible, int index) {
16
17
  final book = bible.books[index];
17
18
  if (book.chapters.length == 1) {
18
19
  return replaceBookChapter(context, bible.name, index, 0);
19
20
  }
20
- Navigator.of(context).pushReplacement(
21
- PageRouteBuilder(
22
- opaque: false,
23
- transitionDuration: Duration.zero,
24
- reverseTransitionDuration: Duration.zero,
25
- pageBuilder: (context, _, __) => ChapterSelectScreen(
21
+ context.go("/chapters/${Uri.encodeComponent(bible.name)}/${book.index}");
26
- bible: bible,
27
- book: book,
28
- selectedBookIndex: index,
29
- ),
30
- ),
31
- );
32
22
  }
33
23
 
34
24
  @override
35
25
  Widget build(BuildContext context) {
36
- return ScaffoldMenu(
26
+ return FutureBuilder(
27
+ future: bibleAtom.getValue(bibleName),
37
- child: CustomScrollView(
28
+ builder: (context, state) {
38
- physics: const BouncingScrollPhysics(),
39
- slivers: [
40
- SliverHeading(title: context.l.oldTestamentTitle, showClose: true),
41
- SliverTileGrid(
42
- children: List.of(
43
- bible.getOldBooks().map((book) {
44
- return TextButton(
29
+ return state.when(
30
+ loading: () => ColoredBox(
45
- child: Text(book.shortName(context.bookNames[book.index])),
31
+ color: Theme.of(context).colorScheme.surface,
46
- onPressed: () => onBookSelected(context, book.index),
32
+ child: const Center(child: CircularProgressIndicator()),
47
- );
48
- }),
49
- ),
50
33
  ),
34
+ success: (Bible? bible) {
35
+ return ScaffoldMenu(
36
+ child: CustomScrollView(
37
+ physics: const BouncingScrollPhysics(),
38
+ slivers: [
39
+ SliverHeading(
51
- SliverHeading(title: context.l.newTestamentTitle, top: 30, bottom: 20),
40
+ title: context.l.oldTestamentTitle, showClose: true),
52
- SliverTileGrid(
41
+ SliverTileGrid(
53
- children: List.of(
42
+ children: List.of(
43
+ bible!.getOldBooks().map((book) {
44
+ return TextButton(
45
+ child: Text(
46
+ book.shortName(context.bookNames[book.index])),
47
+ onPressed: () =>
48
+ onBookSelected(context, bible, book.index),
49
+ );
50
+ }),
51
+ ),
52
+ ),
53
+ SliverHeading(
54
+ title: context.l.newTestamentTitle, top: 30, bottom: 20),
55
+ SliverTileGrid(
56
+ children: List.of(
54
- bible.getNewBooks().map((book) {
57
+ bible.getNewBooks().map((book) {
55
- return TextButton(
58
+ return TextButton(
59
+ child: Text(
56
- child: Text(book.shortName(context.bookNames[book.index])),
60
+ book.shortName(context.bookNames[book.index])),
61
+ onPressed: () =>
57
- onPressed: () => onBookSelected(context, book.index),
62
+ onBookSelected(context, bible, book.index),
58
- );
63
+ );
59
- }),
64
+ }),
60
- ),
65
+ ),
66
+ ),
67
+ ],
68
+ ),
69
+ );
70
+ },
71
+ error: () => ColoredBox(
72
+ color: Theme.of(context).colorScheme.surface,
73
+ child: Center(child: Text("Could not load bible ${state.error}")),
61
74
  ),
75
+ );
62
- ],
76
+ },
63
- ),
64
77
  );
65
78
  }
66
79
  }
lib/screens/chapter_select_screen.dart CHANGED
@@ -1,35 +1,56 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:only_bible_app/models.dart";
3
3
  import "package:only_bible_app/navigation.dart";
4
+ import "package:only_bible_app/store/state.dart";
4
5
  import "package:only_bible_app/utils.dart";
5
6
  import "package:only_bible_app/widgets/scaffold_menu.dart";
6
7
  import "package:only_bible_app/widgets/sliver_tile_grid.dart";
7
8
  import "package:only_bible_app/widgets/sliver_heading.dart";
8
9
 
9
10
  class ChapterSelectScreen extends StatelessWidget {
10
- final Bible bible;
11
+ final String bibleName;
11
- final Book book;
12
- final int selectedBookIndex;
12
+ final int bookIndex;
13
13
 
14
+ const ChapterSelectScreen(
14
- const ChapterSelectScreen({super.key, required this.bible, required this.selectedBookIndex, required this.book});
15
+ {super.key, required this.bibleName, required this.bookIndex});
15
16
 
16
17
  @override
17
18
  Widget build(BuildContext context) {
18
- return ScaffoldMenu(
19
+ return FutureBuilder(
20
+ future: bibleAtom.getValue(bibleName),
19
- child: CustomScrollView(
21
+ builder: (context, state) {
20
- physics: const BouncingScrollPhysics(),
21
- slivers: [
22
- SliverHeading(title: context.bookNames[book.index], showClose: true),
23
- SliverTileGrid(
24
- children: List.generate(book.chapters.length, (index) {
25
- return TextButton(
22
+ return state.when(
23
+ loading: () => ColoredBox(
26
- child: Text("${index + 1}"),
24
+ color: Theme.of(context).colorScheme.surface,
27
- onPressed: () => replaceBookChapter(context, bible.name, selectedBookIndex, index),
25
+ child: const Center(child: CircularProgressIndicator()),
28
- );
29
- }),
30
26
  ),
27
+ success: (Bible? bible) {
28
+ final book = bible!.books[bookIndex];
29
+ return ScaffoldMenu(
30
+ child: CustomScrollView(
31
+ physics: const BouncingScrollPhysics(),
32
+ slivers: [
33
+ SliverHeading(
34
+ title: context.bookNames[book.index], showClose: true),
35
+ SliverTileGrid(
36
+ children: List.generate(book.chapters.length, (index) {
37
+ return TextButton(
38
+ child: Text("${index + 1}"),
39
+ onPressed: () => replaceBookChapter(
40
+ context, bible.name, bookIndex, index),
41
+ );
42
+ }),
43
+ ),
31
- ],
44
+ ],
32
- ),
45
+ ),
46
+ );
47
+ },
48
+ error: () => ColoredBox(
49
+ color: Theme.of(context).colorScheme.surface,
50
+ child: Center(child: Text("Could not load bible ${state.error}")),
51
+ ),
52
+ );
53
+ },
33
54
  );
34
55
  }
35
56
  }
lib/widgets/sliver_heading.dart CHANGED
@@ -1,4 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
+ import "package:go_router/go_router.dart";
2
3
 
3
4
  class SliverHeading extends StatelessWidget {
4
5
  final String title;
@@ -24,13 +25,14 @@ class SliverHeading extends StatelessWidget {
24
25
  crossAxisAlignment: CrossAxisAlignment.center,
25
26
  children: [
26
27
  Expanded(
28
+ child: Text(title,
27
- child: Text(title, style: Theme.of(context).textTheme.headlineMedium),
29
+ style: Theme.of(context).textTheme.headlineMedium),
28
30
  ),
29
31
  if (showClose)
30
32
  IconButton(
31
33
  icon: const Icon(Icons.close, size: 26),
32
34
  onPressed: () {
33
- Navigator.of(context).pop();
35
+ context.pop();
34
36
  },
35
37
  ),
36
38
  ],
pubspec.lock CHANGED
@@ -423,6 +423,14 @@ packages:
423
423
  url: "https://pub.dev"
424
424
  source: hosted
425
425
  version: "2.1.3"
426
+ go_router:
427
+ dependency: "direct main"
428
+ description:
429
+ name: go_router
430
+ sha256: "7974313e217a7771557add6ff2238acb63f635317c35fa590d348fb238f00896"
431
+ url: "https://pub.dev"
432
+ source: hosted
433
+ version: "17.1.0"
426
434
  graphs:
427
435
  dependency: transitive
428
436
  description:
pubspec.yaml CHANGED
@@ -30,6 +30,7 @@ dependencies:
30
30
  atoms_state: ^0.0.2
31
31
  webview_flutter: ^4.13.1
32
32
  app_review: ^3.0.0
33
+ go_router: ^17.1.0
33
34
 
34
35
  dev_dependencies:
35
36
  flutter_test: