diff --git a/lib/models/account.dart b/lib/models/account.dart index 7b5012a..3ef5efd 100644 --- a/lib/models/account.dart +++ b/lib/models/account.dart @@ -7,12 +7,20 @@ part 'account.g.dart'; class AccountModel { String avatarUrl; String token; + + @JsonKey(ignore: true) + String platform; + @JsonKey(ignore: true) String domain; + @JsonKey(ignore: true) + String login; AccountModel({ @required this.avatarUrl, @required this.token, + this.platform, this.domain, + this.login, }); factory AccountModel.fromJson(Map json) => diff --git a/lib/models/account.g.dart b/lib/models/account.g.dart index a34e5ae..0c5118e 100644 --- a/lib/models/account.g.dart +++ b/lib/models/account.g.dart @@ -8,14 +8,8 @@ part of 'account.dart'; AccountModel _$AccountModelFromJson(Map json) { return AccountModel( - avatarUrl: json['avatarUrl'] as String, - token: json['token'] as String, - domain: json['domain'] as String); + avatarUrl: json['avatarUrl'] as String, token: json['token'] as String); } Map _$AccountModelToJson(AccountModel instance) => - { - 'avatarUrl': instance.avatarUrl, - 'token': instance.token, - 'domain': instance.domain - }; + {'avatarUrl': instance.avatarUrl, 'token': instance.token}; diff --git a/lib/providers/settings.dart b/lib/providers/settings.dart index df126d4..b88e39e 100644 --- a/lib/providers/settings.dart +++ b/lib/providers/settings.dart @@ -13,8 +13,14 @@ import '../utils/constants.dart'; import '../models/account.dart'; class PlatformType { - static const github = 0; - static const gitlab = 1; + static const github = 'github'; + static const gitlab = 'gitlab'; +} + +class StorageKeys { + static const account = 'account'; + static const github = 'github'; + static const theme = 'theme'; } // abstract class Model { @@ -61,9 +67,10 @@ class SettingsProviderState extends State { int theme; Map githubAccountMap; - Map gitlabAccountMap; + Map>> accountMap; - int activePlatform; + String activePlatform; + String activeDomain; String activeLogin; StreamSubscription _sub; @@ -77,7 +84,7 @@ class SettingsProviderState extends State { SharedPreferences prefs = await SharedPreferences.getInstance(); theme = _theme; - await prefs.setInt('theme', theme); + await prefs.setInt(StorageKeys.theme, theme); print('write theme: $theme'); setState(() {}); @@ -89,10 +96,8 @@ class SettingsProviderState extends State { switch (activePlatform) { case PlatformType.github: return githubAccountMap[activeLogin].token; - case PlatformType.gitlab: - return gitlabAccountMap[activeLogin].token; default: - return null; + return accountMap[activePlatform][activeDomain][activeLogin].token; } } @@ -162,7 +167,7 @@ class SettingsProviderState extends State { // write SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setString( - 'github', + StorageKeys.github, json.encode(githubAccountMap .map((login, account) => MapEntry(login, account.toJson())))); @@ -187,14 +192,25 @@ class SettingsProviderState extends State { String login = info['username']; String avatarUrl = info['avatar_url']; - gitlabAccountMap[login] = - AccountModel(token: token, avatarUrl: avatarUrl, domain: domain); + + if (accountMap[PlatformType.gitlab] == null) + accountMap[PlatformType.gitlab] = {}; + if (accountMap[PlatformType.gitlab][domain] == null) + accountMap[PlatformType.gitlab][domain] = {}; + + accountMap[PlatformType.gitlab][domain][login] = + AccountModel(token: token, avatarUrl: avatarUrl); SharedPreferences prefs = await SharedPreferences.getInstance(); - await prefs.setString( - 'gitlab', - json.encode(gitlabAccountMap - .map((login, account) => MapEntry(login, account.toJson())))); + + String str = json.encode(accountMap.map((type, v0) { + return MapEntry(type, v0.map((domain, v1) { + return MapEntry(domain, v1.map((login, v2) { + return MapEntry(login, v2.toJson()); + })); + })); + })); + await prefs.setString(StorageKeys.account, str); } catch (err) { print(err); // TODO: show errors @@ -210,7 +226,7 @@ class SettingsProviderState extends State { // read GitHub accounts try { - String str = prefs.getString('github'); + String str = prefs.getString(StorageKeys.github); print('read github: $str'); Map data = json.decode(str ?? '{}'); @@ -221,19 +237,39 @@ class SettingsProviderState extends State { githubAccountMap = {}; } + // read accounts try { - String str = prefs.getString('gitlab'); - print('read gitlab: $str'); + String str = prefs.getString(StorageKeys.account); + print('read account: $str'); - Map data = json.decode(str ?? '{}'); - gitlabAccountMap = data.map((login, _accountMap) => - MapEntry(login, AccountModel.fromJson(_accountMap))); + var data = Map>.from( + Map.from(json.decode(str ?? '{}'))); + + accountMap = {}; + data.forEach((platform, v0) { + accountMap[platform] = {}; + v0.forEach((domain, v1) { + accountMap[platform][domain] = {}; + v1.forEach((login, v2) { + accountMap[platform][domain][login] = AccountModel.fromJson(v2); + }); + }); + }); + + // TODO: type cast + // accountMap = data.map((type, v0) { + // return MapEntry(type, v0.map((domain, v1) { + // return MapEntry(domain, v1.map((login, v2) { + // return MapEntry(login, AccountModel.fromJson(v2)); + // })); + // })); + // }); } catch (err) { print(err); - gitlabAccountMap = {}; + accountMap = {}; } - int _theme = prefs.getInt('theme'); + int _theme = prefs.getInt(StorageKeys.theme); print('read theme: $_theme'); if (ThemeMap.values.contains(_theme)) { theme = _theme; @@ -246,10 +282,11 @@ class SettingsProviderState extends State { }); } - void setActiveAccount(String login, int type) { + void setActiveAccount(String platform, String domain, String login) { setState(() { + activePlatform = platform; + activeDomain = domain; activeLogin = login; - activePlatform = type; }); } diff --git a/lib/screens/login.dart b/lib/screens/login.dart index 551d0a5..8594d81 100644 --- a/lib/screens/login.dart +++ b/lib/screens/login.dart @@ -14,13 +14,14 @@ class LoginScreen extends StatefulWidget { } class _LoginScreenState extends State { - Widget _buildAccountItem(MapEntry entry, int type) { + Widget _buildAccountItem(AccountModel account) { var settings = SettingsProvider.of(context); return Link( onTap: () { // Navigator.of(context).pop(); - settings.setActiveAccount(entry.key, type); + settings.setActiveAccount( + account.platform, account.domain, account.login); }, child: Container( padding: EdgeInsets.all(10), @@ -30,7 +31,7 @@ class _LoginScreenState extends State { child: Row(children: [ CircleAvatar( backgroundColor: Colors.transparent, - backgroundImage: NetworkImage(entry.value.avatarUrl), + backgroundImage: NetworkImage(account.avatarUrl), radius: 24, ), Padding(padding: EdgeInsets.only(left: 10)), @@ -38,13 +39,17 @@ class _LoginScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(entry.key, style: TextStyle(fontSize: 20)), + Text(account.login, style: TextStyle(fontSize: 20)), Padding(padding: EdgeInsets.only(top: 6)), - Text(entry.value.domain ?? 'https://github.com') + Text(account.domain) ], ), ), - settings.activeLogin == entry.key ? Icon(Icons.check) : Container(), + (settings.activePlatform == account.platform && + settings.activeDomain == account.domain && + settings.activeLogin == account.login) + ? Icon(Icons.check) + : Container(), ]), ), ); @@ -75,6 +80,21 @@ class _LoginScreenState extends State { Widget build(BuildContext context) { var settings = SettingsProvider.of(context); + List accounts = []; + settings.accountMap.forEach((platform, v0) { + v0.forEach((domain, v1) { + v1.forEach((login, v2) { + accounts.add(AccountModel( + avatarUrl: v2.avatarUrl, + token: v2.token, + platform: platform, + domain: domain, + login: login, + )); + }); + }); + }); + return SimpleScaffold( title: Text('Select account'), bodyBuilder: () { @@ -85,15 +105,14 @@ class _LoginScreenState extends State { return Container( child: Column( children: settings.githubAccountMap.entries - .map( - (entry) => _buildAccountItem(entry, PlatformType.github)) + .map((entry) => _buildAccountItem(AccountModel( + avatarUrl: entry.value.avatarUrl, + token: entry.value.token, + platform: PlatformType.github, + domain: 'https://github.com', + login: entry.key))) .toList() - ..addAll( - settings.gitlabAccountMap.entries - .map((entry) => - _buildAccountItem(entry, PlatformType.gitlab)) - .toList(), - ) + ..addAll(accounts.map(_buildAccountItem)) ..addAll([ _buildAddItem( text: 'GitHub Account',