-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsign_in_page.dart
More file actions
121 lines (115 loc) · 3.88 KB
/
sign_in_page.dart
File metadata and controls
121 lines (115 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import 'package:async/async.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
// TODO(kim): アナリティクスマージ後にコメントアウトを解除
// import '../../core/analytics/analytics_service.dart';
import '../../core/themes.dart';
import '../../core/widgets/app_snack_bar.dart';
import '../photo/gallery/gallery_page.dart';
import 'auth_controller.dart';
/// サインインページ
class SignInPage extends HookConsumerWidget {
const SignInPage({super.key});
static const routeName = 'sign_in_page';
static const routePath = '/sign_in_page';
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
body: ColoredBox(
color: Themes.mainOrange,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Gap(160),
const Spacer(),
Image.asset(
'assets/images/sign_in/sign_in_icon.png',
width: 300,
height: 300,
),
const Gap(60),
const Spacer(),
// Googleで続けるボタン
_buildSignInButton(
context: context,
ref: ref,
label: 'Googleで続ける',
iconPath: 'assets/images/sign_in/google_icon.png',
backgroundColor: Colors.white,
foregroundColor: Colors.black,
signInMethod: ref.read(authControllerProvider).signInWithGoogle,
),
const Gap(20),
// Appleで続けるボタン
_buildSignInButton(
context: context,
ref: ref,
label: 'Appleで続ける',
iconPath: 'assets/images/sign_in/apple_icon.png',
backgroundColor: Colors.black,
foregroundColor: Colors.white,
signInMethod: ref.read(authControllerProvider).signInWithApple,
),
const Spacer(),
],
),
),
);
}
// TODO(masaki): AppElevatedButton との共通化 or プライベートクラス化
/// サインインボタンの共通化メソッド
Widget _buildSignInButton({
required BuildContext context,
required WidgetRef ref,
required String label,
required String iconPath,
required Color backgroundColor,
required Color foregroundColor,
required Future<void> Function() signInMethod,
}) {
// 多重を実行防止するためのキャッシュ
final asyncCache = useState(AsyncCache<dynamic>.ephemeral());
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: ElevatedButton.icon(
onPressed: () {
asyncCache.value
.fetch(() => _handleSignIn(signInMethod, context, ref));
},
icon: Image.asset(
iconPath,
width: 24,
),
label: Text(label),
style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor,
foregroundColor: foregroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
minimumSize: const Size(double.infinity, 50),
),
),
);
}
/// サインイン処理の共通化
Future<void> _handleSignIn(
Future<void> Function() signIn,
BuildContext context,
WidgetRef ref,
) async {
try {
await signIn();
if (!context.mounted) {
return;
}
// TODO(masaki): 遷移先として、写真選択画面 or ギャラリーページ(空の場合に写真選択画面へ促す)を相談
context.go(GalleryPage.routePath);
} on Exception catch (e) {
AppSnackBar.show(message: 'サインインに失敗しました: $e');
}
}
}