Skip to content

Commit b8594b7

Browse files
committed
update widgets
1 parent 8ad4ed0 commit b8594b7

File tree

8 files changed

+100
-76
lines changed

8 files changed

+100
-76
lines changed

dataconnect/lib/destination.dart

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
11
import 'package:flutter/material.dart';
22

3-
class Destination {
4-
const Destination({required this.label, required this.icon});
5-
final String label;
6-
final IconData icon;
7-
}
8-
93
class Route {
10-
Route({required this.path, required this.label, required this.iconData});
4+
Route({
5+
required this.path,
6+
required this.label,
7+
required this.iconData,
8+
});
119
final String path;
1210
final String label;
1311
final IconData iconData;
1412
}
1513

16-
var homePath = Route(path: '/home', label: 'Home', iconData: Icons.home);
17-
var searchPath =
18-
Route(path: '/search', label: 'Search', iconData: Icons.search);
19-
var profilePath =
20-
Route(path: '/profile', label: 'Profile', iconData: Icons.person);
21-
var paths = [homePath, searchPath, profilePath];
14+
final homePath = Route(
15+
path: '/home',
16+
label: 'Home',
17+
iconData: Icons.home,
18+
);
19+
final searchPath = Route(
20+
path: '/search',
21+
label: 'Search',
22+
iconData: Icons.search,
23+
);
24+
final profilePath = Route(
25+
path: '/profile',
26+
label: 'Profile',
27+
iconData: Icons.person,
28+
);
29+
30+
final paths = [homePath, searchPath, profilePath];

dataconnect/lib/login.dart

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ class Login extends StatefulWidget {
1111

1212
class _LoginState extends State<Login> {
1313
final _formKey = GlobalKey<FormState>();
14-
String _username = '';
15-
String _password = '';
14+
final _username = TextEditingController();
15+
final _password = TextEditingController();
1616

1717
Future<void> logIn(BuildContext context) async {
1818
final messenger = ScaffoldMessenger.of(context);
1919
final navigator = GoRouter.of(context);
2020
messenger.showSnackBar(const SnackBar(content: Text('Signing In')));
2121
try {
2222
await FirebaseAuth.instance.signInWithEmailAndPassword(
23-
email: _username,
24-
password: _password,
23+
email: _username.text,
24+
password: _password.text,
2525
);
2626
if (mounted) {
2727
navigator.go('/home');
@@ -51,11 +51,7 @@ class _LoginState extends State<Login> {
5151
hintText: "Username",
5252
border: OutlineInputBorder(),
5353
),
54-
onChanged: (value) {
55-
setState(() {
56-
_username = value;
57-
});
58-
},
54+
controller: _username,
5955
validator: (value) {
6056
if (value == null || value.isEmpty) {
6157
return 'Please enter some text';
@@ -71,11 +67,7 @@ class _LoginState extends State<Login> {
7167
hintText: "Password",
7268
border: OutlineInputBorder(),
7369
),
74-
onChanged: (value) {
75-
setState(() {
76-
_password = value;
77-
});
78-
},
70+
controller: _password,
7971
validator: (value) {
8072
if (value == null || value.isEmpty) {
8173
return 'Please enter a password';

dataconnect/lib/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import 'movies_connector/movies.dart';
66
import 'models/movie.dart';
77
import 'movie_state.dart';
88
import 'router.dart';
9+
import 'util/auth.dart';
910
import 'widgets/list_movies.dart';
1011

1112
void main() async {
1213
WidgetsFlutterBinding.ensureInitialized();
1314
await Firebase.initializeApp(
1415
options: DefaultFirebaseOptions.currentPlatform,
1516
);
17+
await Auth.instance.init();
1618
MoviesConnector.instance.dataConnect
1719
.useDataConnectEmulator('localhost', 9399);
1820
FirebaseAuth.instance.useAuthEmulator('localhost', 9400);

dataconnect/lib/movie_detail.dart

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,14 @@ class _MovieDetailState extends State<MovieDetail> {
113113
mainAxisAlignment: MainAxisAlignment.spaceBetween,
114114
children: [
115115
LoginGuard(
116-
widgetToGuard: OutlinedButton.icon(
117-
onPressed: () {
118-
_toggleFavorite();
119-
},
120-
icon: Icon(_favorited ? Icons.favorite : Icons.favorite_border),
121-
label: Text(_getFavoriteLabelText()),
122-
))
116+
builder: (context) => OutlinedButton.icon(
117+
onPressed: () {
118+
_toggleFavorite();
119+
},
120+
icon: Icon(_favorited ? Icons.favorite : Icons.favorite_border),
121+
label: Text(_getFavoriteLabelText()),
122+
),
123+
)
123124
],
124125
)
125126
];
@@ -224,28 +225,31 @@ class _MovieDetailState extends State<MovieDetail> {
224225
},
225226
),
226227
LoginGuard(
227-
widgetToGuard: TextField(
228-
decoration: const InputDecoration(
229-
hintText: "Write your review",
230-
border: OutlineInputBorder(),
231-
),
232-
controller: _reviewTextController,
228+
builder: (context) => TextField(
229+
decoration: const InputDecoration(
230+
hintText: "Write your review",
231+
border: OutlineInputBorder(),
233232
),
234-
message: "writing a review"),
233+
controller: _reviewTextController,
234+
),
235+
message: "writing a review",
236+
),
235237
LoginGuard(
236-
widgetToGuard: OutlinedButton.icon(
238+
builder: (context) => OutlinedButton.icon(
237239
onPressed: () {
238240
MoviesConnector.instance
239241
.addReview(
240242
movieId: widget.id,
241243
rating: _ratingValue.toInt(),
242244
reviewText: _reviewTextController.text)
243245
.execute()
244-
.then((_) {
245-
_refreshData();
246-
_reviewTextController.clear();
247-
MovieState.triggerUpdateFavorite();
248-
});
246+
.then(
247+
(_) {
248+
_refreshData();
249+
_reviewTextController.clear();
250+
MovieState.triggerUpdateFavorite();
251+
},
252+
);
249253
},
250254
label: const Text('Submit Review'),
251255
),

dataconnect/lib/profile.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@ class _ProfileState extends State<Profile>
3131
@override
3232
void initState() {
3333
super.initState();
34-
Auth.getCurrentUser().then((user) {
35-
if (mounted) {
36-
setState(() {
37-
_currentUser = user;
38-
});
39-
}
40-
});
4134
_listener = MovieState.subscribeToCurrentUser().listen((res) {
4235
if (mounted) {
4336
setState(() {

dataconnect/lib/router.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ var router = GoRouter(initialLocation: homePath.path, routes: [
4747
GoRoute(
4848
path: "/profile",
4949
redirect: (context, state) async {
50-
return (await Auth.isLoggedIn()) ? null : '/login';
50+
return Auth.instance.isLoggedIn ? null : '/login';
5151
},
5252
builder: (context, state) => const Profile()),
5353
GoRoute(
5454
path: "/login",
5555
builder: (context, state) => const Login(),
5656
redirect: (context, state) async {
57-
return (await Auth.isLoggedIn()) ? '/profile' : null;
57+
return Auth.instance.isLoggedIn ? '/profile' : null;
5858
},
5959
),
6060
GoRoute(

dataconnect/lib/util/auth.dart

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,44 @@
1+
import 'dart:async';
2+
13
import 'package:firebase_auth/firebase_auth.dart';
4+
import 'package:flutter/foundation.dart';
25

3-
class Auth {
4-
static Future<bool> isLoggedIn() async {
5-
User? user = await FirebaseAuth.instance.authStateChanges().first;
6-
if (user == null) {
7-
return false;
8-
}
6+
typedef AuthState = ({User? user, String? token});
7+
8+
class Auth extends ValueNotifier<AuthState> {
9+
bool get isLoggedIn => value.user != null && value.token != null;
10+
User? get currentUser => value.user;
11+
String? get token => value.token;
12+
13+
StreamSubscription? _cleanup;
14+
15+
Future<void> init() async {
16+
final user = FirebaseAuth.instance.currentUser;
17+
final token = await user?.token;
18+
value = (user: user, token: token);
19+
_cleanup = FirebaseAuth.instance.authStateChanges().listen((user) async {
20+
final token = await user?.token;
21+
value = (user: user, token: token);
22+
});
23+
}
24+
25+
@override
26+
void dispose() {
27+
super.dispose();
28+
_cleanup?.cancel();
29+
}
30+
31+
static Auth instance = Auth((user: null, token: null));
32+
33+
Auth(super.value);
34+
}
35+
36+
extension on User {
37+
Future<String?> get token async {
938
try {
10-
String? idToken = await user.getIdToken();
11-
return idToken != null;
39+
return await getIdToken();
1240
} catch (_) {
13-
return false;
41+
return null;
1442
}
1543
}
16-
17-
static getCurrentUser() {
18-
return FirebaseAuth.instance.authStateChanges().first;
19-
}
2044
}

dataconnect/lib/widgets/login_guard.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ import 'package:flutter/material.dart';
44
class LoginGuard extends StatelessWidget {
55
const LoginGuard({
66
super.key,
7-
required this.widgetToGuard,
7+
required this.builder,
88
this.message,
99
});
1010

11-
final Widget widgetToGuard;
11+
final WidgetBuilder builder;
1212
final String? message;
1313

1414
@override
1515
Widget build(BuildContext context) {
16-
return FutureBuilder(
17-
future: Auth.isLoggedIn(),
18-
builder: (context, state) {
19-
final isLoggedIn = state.data ?? false;
16+
return ValueListenableBuilder(
17+
valueListenable: Auth.instance,
18+
builder: (context, state, _) {
19+
final isLoggedIn = Auth.instance.isLoggedIn;
2020
if (!isLoggedIn) {
2121
if (message == null) {
2222
return const SizedBox();
@@ -26,7 +26,7 @@ class LoginGuard extends StatelessWidget {
2626
'to log in before $message',
2727
);
2828
}
29-
return widgetToGuard;
29+
return builder(context);
3030
},
3131
);
3232
}

0 commit comments

Comments
 (0)