1
0
mirror of https://github.com/git-touch/git-touch synced 2025-01-31 08:04:51 +01:00

feat: gitlab account login

This commit is contained in:
Rongjian Zhang 2019-02-21 21:21:16 +08:00
parent c4399a9a72
commit beb8974caa
3 changed files with 143 additions and 74 deletions

View File

@ -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<T> {
// Future<T> 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<SettingsProvider> {
int theme;
Map<String, AccountModel> githubAccountMap;
Map<String, AccountModel> gitlabAccountMap;
int activePlatform;
String activeLogin;
StreamSubscription<Uri> _sub;
bool loading = false;
@ -80,11 +83,17 @@ class SettingsProviderState extends State<SettingsProvider> {
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<SettingsProvider> {
// 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<void> 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<String, dynamic> github = json.decode(str);
githubAccountMap = github.map<String, AccountModel>(
(login, _accountMap) =>
MapEntry(login, AccountModel.fromJson(_accountMap)));
String str = prefs.getString('github');
print('read github: $str');
Map<String, dynamic> data = json.decode(str ?? '{}');
githubAccountMap = data.map<String, AccountModel>((login, _accountMap) =>
MapEntry(login, AccountModel.fromJson(_accountMap)));
} catch (err) {
print(err);
githubAccountMap = {};
}
try {
String str = prefs.getString('gitlab');
print('read gitlab: $str');
Map<String, dynamic> data = json.decode(str ?? '{}');
gitlabAccountMap = data.map<String, AccountModel>((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<SettingsProvider> {
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;
});
}

View File

@ -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<LoginScreen> {
Widget _buildAccountItem(MapEntry<String, AccountModel> 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: <Widget>[
CircleAvatar(
backgroundColor: Colors.transparent,
backgroundImage: NetworkImage(entry.value.avatarUrl),
radius: 24,
),
Padding(padding: EdgeInsets.only(left: 10)),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
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<LoginScreen> {
return Container(
child: Column(
children: settings.githubAccountMap.entries.map<Widget>((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: <Widget>[
CircleAvatar(
backgroundColor: Colors.transparent,
backgroundImage: NetworkImage(entry.value.avatarUrl),
radius: 24,
children: settings.githubAccountMap.entries
.map<Widget>(
(entry) => _buildAccountItem(entry, PlatformType.github))
.toList()
..addAll(
settings.gitlabAccountMap.entries
.map<Widget>((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: <Widget>[
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(),
)
]),
),
);
},

View File

@ -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<LoginGitlabScreen> {
),
MaterialButton(
child: Text('Login'),
onPressed: () {},
onPressed: () {
SettingsProvider.of(context).loginToGitlab(_domain, _token);
Navigator.of(context).pop();
},
)
],
);