Skip to content

Instantly share code, notes, and snippets.

@riscait
Created May 22, 2023 10:42
Show Gist options
  • Save riscait/4609d950170f32ef59a2db4190b48971 to your computer and use it in GitHub Desktop.
Save riscait/4609d950170f32ef59a2db4190b48971 to your computer and use it in GitHub Desktop.
import 'package:authenticator/authenticator.dart';
import 'package:awaitable_button/awaitable_button.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:themes/themes.dart';
import '../../../router/router.dart';
import '../../../util/providers/providers.dart';
import '../../commons/signin_page_controller_provider.dart';
import '../../widgets/snack_bar/show_snack_bar.dart';
extension SigningMethodExtension on SigningMethod {
/// サインインボタンに表示するラベル
String get label {
switch (this) {
case SigningMethod.apple:
return 'Appleでサインイン';
case SigningMethod.google:
return 'Googleでサインイン';
case SigningMethod.phone:
return '電話番号でサインイン';
}
}
/// サインインボタンに表示するアイコン
Widget get icon {
switch (this) {
case SigningMethod.apple:
return const FaIcon(FontAwesomeIcons.apple);
case SigningMethod.google:
return const FaIcon(FontAwesomeIcons.google);
case SigningMethod.phone:
return const Icon(Icons.phone_android_sharp);
}
}
Future<void> signin(Authenticator authenticator) async {
switch (this) {
case SigningMethod.apple:
await authenticator.signInWithApple();
return;
case SigningMethod.google:
await authenticator.signInWithGoogle();
return;
case SigningMethod.phone:
throw UnimplementedError();
}
}
}
class SigninButton extends ConsumerWidget {
const SigninButton({
super.key,
required this.method,
});
factory SigninButton.phone() {
return const SigninButton(
method: SigningMethod.phone,
);
}
factory SigninButton.google() {
return const SigninButton(
method: SigningMethod.google,
);
}
factory SigninButton.apple() {
return const SigninButton(
method: SigningMethod.apple,
);
}
final SigningMethod method;
@override
Widget build(BuildContext context, WidgetRef ref) {
if (method == SigningMethod.phone) {
return ElevatedButton.icon(
onPressed: () async {
await context.push(const PhoneAuthRoute());
},
icon: method.icon,
label: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
method.label,
style: const TextStyle(fontSize: 12),
),
),
);
}
return AwaitableOutlinedButton<void>(
onPressed: () async {
// ローディング表示
ref.read(isLoadingProvider.notifier).show();
// サインイン処理
await method.signin(ref.read(authenticatorProvider));
},
whenComplete: (_) async {
// サインイン後の画面へ遷移
await ref.read(signinPageControllerProvider).goToAfterSigninPage(
context: context,
);
},
onError: (exception, stackTrace) {
// ローディング非表示
ref.read(isLoadingProvider.notifier).hide();
final authError = AuthError.fromError(exception);
if (authError is AuthCancelled) {
// 認証キャンセルの場合は後続の処理を行わない
return;
}
showSnackBar(
context: context,
text: '$authError',
);
},
buttonStyle: OutlinedButton.styleFrom(
foregroundColor: method == SigningMethod.apple
? Colors.black
: context.colors.primary,
side: BorderSide(
color: method == SigningMethod.apple
? const Color(0xff5D5757)
: context.colors.primary,
),
minimumSize: const Size.fromHeight(43),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
method.icon,
const Gap(16),
Text(
method.label,
style: const TextStyle(fontSize: 12),
),
],
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment