diff --git a/lib/models/auth.dart b/lib/models/auth.dart index 330fc27f..45794bbd 100644 --- a/lib/models/auth.dart +++ b/lib/models/auth.dart @@ -735,13 +735,13 @@ class AuthModel with ChangeNotifier { } String? _oauthState; - void redirectToGithubOauth([publicOnly = false]) { + void redirectToGithubOauth(String login, [publicOnly = false]) { _oauthState = nanoid(); final repoScope = publicOnly ? 'public_repo' : 'repo'; final scope = Uri.encodeComponent( ['user', repoScope, 'read:org', 'notifications'].join(',')); launchUrl( - 'https://github.com/login/oauth/authorize?client_id=$clientId&redirect_uri=gittouch://login&scope=$scope&state=$_oauthState', + 'https://github.com/login/oauth/authorize?client_id=$clientId&redirect_uri=gittouch://login&scope=$scope&state=$_oauthState&login=$login', ); } diff --git a/lib/screens/login.dart b/lib/screens/login.dart index 24f92cfb..23751095 100644 --- a/lib/screens/login.dart +++ b/lib/screens/login.dart @@ -104,17 +104,16 @@ class _LoginScreenState extends State { ); } - Widget _buildPopup( - BuildContext context, { - List? notes, - bool showDomain = false, - }) { + Widget _buildPopup(BuildContext context, + {List? notes, + bool showDomain = false, + String placeholder = 'Access token'}) { return Column( children: [ if (showDomain) MyTextField(controller: _domainController, placeholder: 'Domain'), SizedBox(height: 8), - MyTextField(placeholder: 'Access token', controller: _tokenController), + MyTextField(placeholder: placeholder, controller: _tokenController), SizedBox(height: 8), if (notes != null) ...notes, ], @@ -126,6 +125,15 @@ class _LoginScreenState extends State { Text(AppLocalizations.of(context)!.somethingBadHappens + '$err')); } + // TODO: handle email + bool _checkAccountExists(BuildContext context, String domain, String login) { + final auth = context.read(); + final accountExists = auth.accounts?.any( + (account) => account.domain == domain && account.login == login) ?? + false; + return accountExists; + } + @override Widget build(BuildContext context) { final auth = Provider.of(context); @@ -145,14 +153,50 @@ class _LoginScreenState extends State { theme.showActions(context, [ ActionItem( text: 'via OAuth', - onTap: (_) { - auth.redirectToGithubOauth(); + onTap: (_) async { + await theme.showConfirm( + context, + _buildPopup( + context, + placeholder: 'Username', + ), + ); + + bool accountExists = _checkAccountExists(context, + 'https://github.com', _tokenController.text); + + if (accountExists) { + await theme.showWarning( + context, "Account already exists"); + } else { + auth.redirectToGithubOauth(_tokenController.text); + } + + _tokenController.clear(); }, ), ActionItem( text: 'via OAuth (Public repos only)', - onTap: (_) { - auth.redirectToGithubOauth(true); + onTap: (_) async { + await theme.showConfirm( + context, + _buildPopup( + context, + placeholder: 'Username or email', + )); + + bool accountExists = _checkAccountExists(context, + 'https://github.com', _tokenController.text); + + if (accountExists) { + await theme.showWarning( + context, "Account already exists"); + } else { + auth.redirectToGithubOauth( + _tokenController.text, true); + } + + _tokenController.clear(); }, ), ActionItem(