Skip to content

Commit 51df718

Browse files
authored
[go_router_builder] Proposal: add json support, custom string encoder/decoder (#8665)
Add initial json support for use in go_router_builder Adds annotation that enable custom string encoder/decoder, its enable conversion for base64 This allow custom type conversion for parameters, like mentionated in [#117261](flutter/flutter#117261) and [#110781](flutter/flutter#110781)
1 parent e730c1d commit 51df718

22 files changed

+1262
-39
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,4 @@ LinXunFeng <[email protected]>
8080
Hashir Shoaib <[email protected]>
8181
Ricardo Dalarme <[email protected]>
8282
Andrei Kabylin <[email protected]>
83+
Ernesto Ramirez <[email protected]>

packages/go_router_builder/CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
## 4.1.0
2+
3+
- Adds support for classes that support fromJson/toJson. [#117261](https://github.com/flutter/flutter/issues/117261)
4+
- Adds annotation that enable custom string encoder/decoder [#110781](https://github.com/flutter/flutter/issues/110781)
5+
16
## 4.0.1
27

3-
- Fixes unnecessary whitespace in generated `RelativeGoRouteData`.
8+
- Fixes unnecessary whitespace in generated `RelativeGoRouteData`.
49

510
## 4.0.0
611

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// ignore_for_file: public_member_api_docs, unreachable_from_main
6+
7+
import 'dart:convert';
8+
9+
import 'package:flutter/material.dart';
10+
import 'package:go_router/go_router.dart';
11+
12+
part 'custom_encoder_example.g.dart';
13+
14+
void main() => runApp(App());
15+
16+
class App extends StatelessWidget {
17+
App({super.key});
18+
19+
@override
20+
Widget build(BuildContext context) =>
21+
MaterialApp.router(routerConfig: _router, title: _appTitle);
22+
23+
final GoRouter _router = GoRouter(routes: $appRoutes);
24+
}
25+
26+
@TypedGoRoute<HomeRoute>(
27+
path: '/',
28+
name: 'Home',
29+
routes: <TypedGoRoute<GoRouteData>>[
30+
TypedGoRoute<EncodedRoute>(path: 'encoded'),
31+
],
32+
)
33+
class HomeRoute extends GoRouteData with $HomeRoute {
34+
const HomeRoute();
35+
36+
@override
37+
Widget build(BuildContext context, GoRouterState state) => const HomeScreen();
38+
}
39+
40+
class EncodedRoute extends GoRouteData with $EncodedRoute {
41+
const EncodedRoute(this.token);
42+
43+
@CustomParameterCodec(encode: toBase64, decode: fromBase64)
44+
final String token;
45+
46+
@override
47+
Widget build(BuildContext context, GoRouterState state) =>
48+
EncodedScreen(token: token);
49+
}
50+
51+
class HomeScreen extends StatelessWidget {
52+
const HomeScreen({super.key});
53+
54+
@override
55+
Widget build(BuildContext context) => Scaffold(
56+
appBar: AppBar(title: const Text(_appTitle)),
57+
body: ListView(
58+
children: <Widget>[
59+
ListTile(
60+
title: const Text('Base64Token'),
61+
onTap: () => const EncodedRoute('Base64Token').go(context),
62+
),
63+
ListTile(
64+
title: const Text('from url only'),
65+
// like in deep links
66+
onTap: () => context.go('/encoded?token=ZW5jb2RlZCBpbmZvIQ'),
67+
),
68+
],
69+
),
70+
);
71+
}
72+
73+
class EncodedScreen extends StatelessWidget {
74+
const EncodedScreen({super.key, required this.token});
75+
final String token;
76+
77+
@override
78+
Widget build(BuildContext context) => Scaffold(
79+
appBar: AppBar(title: const Text('Base64Token')),
80+
body: Center(child: Text(token)),
81+
);
82+
}
83+
84+
String fromBase64(String value) {
85+
return const Utf8Decoder().convert(
86+
base64Url.decode(base64Url.normalize(value)),
87+
);
88+
}
89+
90+
String toBase64(String value) {
91+
return base64Url.encode(const Utf8Encoder().convert(value));
92+
}
93+
94+
const String _appTitle = 'GoRouter Example: custom encoder';

packages/go_router_builder/example/lib/custom_encoder_example.g.dart

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// ignore_for_file: public_member_api_docs, unreachable_from_main
6+
7+
import 'dart:convert';
8+
9+
import 'package:flutter/material.dart';
10+
import 'package:go_router/go_router.dart';
11+
12+
import 'shared/json_example.dart';
13+
14+
part 'json_example.g.dart';
15+
16+
void main() => runApp(App());
17+
18+
class App extends StatelessWidget {
19+
App({super.key});
20+
21+
@override
22+
Widget build(BuildContext context) =>
23+
MaterialApp.router(routerConfig: _router, title: _appTitle);
24+
25+
final GoRouter _router = GoRouter(routes: $appRoutes);
26+
}
27+
28+
@TypedGoRoute<HomeRoute>(
29+
path: '/',
30+
name: 'Home',
31+
routes: <TypedGoRoute<GoRouteData>>[TypedGoRoute<JsonRoute>(path: 'json')],
32+
)
33+
class HomeRoute extends GoRouteData with $HomeRoute {
34+
const HomeRoute();
35+
36+
@override
37+
Widget build(BuildContext context, GoRouterState state) => const HomeScreen();
38+
}
39+
40+
class JsonRoute extends GoRouteData with $JsonRoute {
41+
const JsonRoute(this.json);
42+
43+
final JsonExample json;
44+
45+
@override
46+
Widget build(BuildContext context, GoRouterState state) =>
47+
JsonScreen(json: json);
48+
}
49+
50+
class HomeScreen extends StatelessWidget {
51+
const HomeScreen({super.key});
52+
53+
@override
54+
Widget build(BuildContext context) => Scaffold(
55+
appBar: AppBar(title: const Text(_appTitle)),
56+
body: ListView(
57+
children: <Widget>[
58+
for (final JsonExample json in jsonData)
59+
ListTile(
60+
title: Text(json.name),
61+
onTap: () => JsonRoute(json).go(context),
62+
),
63+
],
64+
),
65+
);
66+
}
67+
68+
class JsonScreen extends StatelessWidget {
69+
const JsonScreen({required this.json, super.key});
70+
final JsonExample json;
71+
72+
@override
73+
Widget build(BuildContext context) => Scaffold(
74+
appBar: AppBar(title: Text(json.name)),
75+
body: ListView(
76+
key: ValueKey<String>(json.id),
77+
children: <Widget>[Text(json.id), Text(json.name)],
78+
),
79+
);
80+
}
81+
82+
const String _appTitle = 'GoRouter Example: builder';

packages/go_router_builder/example/lib/json_example.g.dart

Lines changed: 65 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)