diff --git a/lib/providers/settings.dart b/lib/providers/settings.dart index 8441d5f..df126d4 100644 --- a/lib/providers/settings.dart +++ b/lib/providers/settings.dart @@ -8,14 +8,14 @@ import 'package:url_launcher/url_launcher.dart'; // import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import '../utils/utils.dart'; +// import '../utils/utils.dart'; import '../utils/constants.dart'; import '../models/account.dart'; -// enum PlatformType { -// github, -// gitlab, -// } +class PlatformType { + static const github = 0; + static const gitlab = 1; +} // abstract class Model { // Future query(BuildContext context) { @@ -38,7 +38,7 @@ import '../models/account.dart'; class ThemeMap { static const material = 0; static const cupertino = 1; - static const all = [0, 1]; + static const values = [0, 1]; } class SettingsProvider extends StatefulWidget { @@ -61,8 +61,11 @@ class SettingsProviderState extends State { int theme; Map githubAccountMap; + Map gitlabAccountMap; + int activePlatform; String activeLogin; + StreamSubscription _sub; bool loading = false; @@ -80,11 +83,17 @@ class SettingsProviderState extends State { setState(() {}); } - get token { - if (activeLogin == null) { - return null; + String get token { + if (activeLogin == null) return null; + + switch (activePlatform) { + case PlatformType.github: + return githubAccountMap[activeLogin].token; + case PlatformType.gitlab: + return gitlabAccountMap[activeLogin].token; + default: + return null; } - return githubAccountMap[activeLogin].token; } @override @@ -152,35 +161,81 @@ class SettingsProviderState extends State { // write SharedPreferences prefs = await SharedPreferences.getInstance(); - var githubData = json.encode(githubAccountMap - .map((login, account) => MapEntry(login, account.toJson()))); - // print('write github: $githubData'); - await prefs.setString('github', githubData); + await prefs.setString( + 'github', + json.encode(githubAccountMap + .map((login, account) => MapEntry(login, account.toJson())))); setState(() { loading = false; }); } + Future loginToGitlab(String domain, String token) async { + setState(() { + loading = true; + }); + + try { + var res = await http + .get('$domain/api/v4/user', headers: {'Private-Token': token}); + var info = json.decode(res.body); + + if (info['message'] != null) { + throw info['message']; + } + + String login = info['username']; + String avatarUrl = info['avatar_url']; + gitlabAccountMap[login] = + AccountModel(token: token, avatarUrl: avatarUrl, domain: domain); + + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setString( + 'gitlab', + json.encode(gitlabAccountMap + .map((login, account) => MapEntry(login, account.toJson())))); + } catch (err) { + print(err); + // TODO: show errors + } finally { + setState(() { + loading = false; + }); + } + } + void _initDataFromPref() async { SharedPreferences prefs = await SharedPreferences.getInstance(); // read GitHub accounts try { - var str = prefs.getString('github'); - // print('read github: $str'); - Map github = json.decode(str); - githubAccountMap = github.map( - (login, _accountMap) => - MapEntry(login, AccountModel.fromJson(_accountMap))); + String str = prefs.getString('github'); + print('read github: $str'); + + Map data = json.decode(str ?? '{}'); + githubAccountMap = data.map((login, _accountMap) => + MapEntry(login, AccountModel.fromJson(_accountMap))); } catch (err) { print(err); githubAccountMap = {}; } + try { + String str = prefs.getString('gitlab'); + print('read gitlab: $str'); + + Map data = json.decode(str ?? '{}'); + gitlabAccountMap = data.map((login, _accountMap) => + MapEntry(login, AccountModel.fromJson(_accountMap))); + } catch (err) { + print(err); + gitlabAccountMap = {}; + } + int _theme = prefs.getInt('theme'); print('read theme: $_theme'); - if (ThemeMap.all.contains(_theme)) { + if (ThemeMap.values.contains(_theme)) { theme = _theme; } else if (Platform.isIOS) { theme = ThemeMap.cupertino; @@ -189,14 +244,12 @@ class SettingsProviderState extends State { setState(() { ready = true; }); - - // print(counter); - // await prefs.setInt('counter', counter); } - void setActiveAccount(String login) { + void setActiveAccount(String login, int type) { setState(() { activeLogin = login; + activePlatform = type; }); } diff --git a/lib/screens/login.dart b/lib/screens/login.dart index 54a2c77..551d0a5 100644 --- a/lib/screens/login.dart +++ b/lib/screens/login.dart @@ -5,6 +5,7 @@ import '../scaffolds/simple.dart'; import '../utils/constants.dart'; import '../widgets/link.dart'; import '../widgets/loading.dart'; +import '../models/account.dart'; import 'login_gitlab.dart'; class LoginScreen extends StatefulWidget { @@ -13,6 +14,42 @@ class LoginScreen extends StatefulWidget { } class _LoginScreenState extends State { + Widget _buildAccountItem(MapEntry entry, int type) { + var settings = SettingsProvider.of(context); + + return Link( + onTap: () { + // Navigator.of(context).pop(); + settings.setActiveAccount(entry.key, type); + }, + child: Container( + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + border: Border(bottom: BorderSide(color: Colors.black12)), + ), + child: Row(children: [ + CircleAvatar( + backgroundColor: Colors.transparent, + backgroundImage: NetworkImage(entry.value.avatarUrl), + radius: 24, + ), + Padding(padding: EdgeInsets.only(left: 10)), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(entry.key, style: TextStyle(fontSize: 20)), + Padding(padding: EdgeInsets.only(top: 6)), + Text(entry.value.domain ?? 'https://github.com') + ], + ), + ), + settings.activeLogin == entry.key ? Icon(Icons.check) : Container(), + ]), + ), + ); + } + Widget _buildAddItem( {String text, Function onTap, WidgetBuilder screenBuilder}) { return Link( @@ -47,56 +84,31 @@ class _LoginScreenState extends State { return Container( child: Column( - children: settings.githubAccountMap.entries.map((entry) { - return Link( - onTap: () { - // Navigator.of(context).pop(); - settings.setActiveAccount(entry.key); - }, - child: Container( - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - border: Border(bottom: BorderSide(color: Colors.black12)), - ), - child: Row(children: [ - CircleAvatar( - backgroundColor: Colors.transparent, - backgroundImage: NetworkImage(entry.value.avatarUrl), - radius: 24, + children: settings.githubAccountMap.entries + .map( + (entry) => _buildAccountItem(entry, PlatformType.github)) + .toList() + ..addAll( + settings.gitlabAccountMap.entries + .map((entry) => + _buildAccountItem(entry, PlatformType.gitlab)) + .toList(), + ) + ..addAll([ + _buildAddItem( + text: 'GitHub Account', + onTap: () { + var state = settings.generateRandomString(); + launch( + 'https://github.com/login/oauth/authorize?client_id=$clientId&redirect_uri=gittouch://login&scope=user%20repo&state=$state', + ); + }, ), - Padding(padding: EdgeInsets.only(left: 10)), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(entry.key, style: TextStyle(fontSize: 20)), - Padding(padding: EdgeInsets.only(top: 6)), - Text(entry.value.domain ?? 'https://github.com') - ], - ), - ), - settings.activeLogin == entry.key - ? Icon(Icons.check) - : Container(), + _buildAddItem( + text: 'GitLab Account', + screenBuilder: (_) => LoginGitlabScreen(), + ) ]), - ), - ); - }).toList() - ..addAll([ - _buildAddItem( - text: 'GitHub Account', - onTap: () { - var state = settings.generateRandomString(); - launch( - 'https://github.com/login/oauth/authorize?client_id=$clientId&redirect_uri=gittouch://login&scope=user%20repo&state=$state', - ); - }, - ), - _buildAddItem( - text: 'GitLab Account', - screenBuilder: (_) => LoginGitlabScreen(), - ) - ]), ), ); }, diff --git a/lib/screens/login_gitlab.dart b/lib/screens/login_gitlab.dart index 5349244..8175603 100644 --- a/lib/screens/login_gitlab.dart +++ b/lib/screens/login_gitlab.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import '../scaffolds/simple.dart'; +import '../providers/settings.dart'; class LoginGitlabScreen extends StatefulWidget { @override @@ -30,7 +31,10 @@ class _LoginGitlabScreenState extends State { ), MaterialButton( child: Text('Login'), - onPressed: () {}, + onPressed: () { + SettingsProvider.of(context).loginToGitlab(_domain, _token); + Navigator.of(context).pop(); + }, ) ], );