mirror of
https://github.com/git-touch/git-touch
synced 2025-03-26 08:00:05 +01:00
parent
cb9bc89778
commit
4f1e0441d2
@ -8,6 +8,8 @@ import 'package:git_touch/screens/bb_teams.dart';
|
||||
import 'package:git_touch/screens/bb_user.dart';
|
||||
import 'package:git_touch/screens/ge_user.dart';
|
||||
import 'package:git_touch/screens/gl_search.dart';
|
||||
import 'package:git_touch/screens/go_search.dart';
|
||||
import 'package:git_touch/screens/go_user.dart';
|
||||
import 'package:git_touch/screens/gt_orgs.dart';
|
||||
import 'package:git_touch/screens/gt_user.dart';
|
||||
import 'package:git_touch/screens/gl_explore.dart';
|
||||
@ -98,6 +100,13 @@ class _HomeState extends State<Home> {
|
||||
return GeUserScreen(auth.activeAccount.login, isViewer: true);
|
||||
}
|
||||
break;
|
||||
case PlatformType.gogs:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return GoSearchScreen();
|
||||
case 1:
|
||||
return GoUserScreen(auth.activeAccount.login, isViewer: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,6 +215,14 @@ class _HomeState extends State<Home> {
|
||||
icon: Icon(Icons.person), label: S.of(context).me),
|
||||
];
|
||||
break;
|
||||
case PlatformType.gogs:
|
||||
navigationItems = [
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.search), label: S.of(context).search),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.person), label: S.of(context).me),
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
switch (theme.theme) {
|
||||
|
@ -66,7 +66,10 @@ void main() async {
|
||||
themeModel.router.define(GiteeRouter.prefix + screen.path,
|
||||
handler: Handler(handlerFunc: screen.handler));
|
||||
});
|
||||
|
||||
GogsRouter.routes.forEach((screen) {
|
||||
themeModel.router.define(GogsRouter.prefix + screen.path,
|
||||
handler: Handler(handlerFunc: screen.handler));
|
||||
});
|
||||
// To match status bar color to app bar color
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
|
@ -20,6 +20,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../utils/utils.dart';
|
||||
import 'account.dart';
|
||||
import 'gitlab.dart';
|
||||
import 'gogs.dart';
|
||||
|
||||
const clientId = 'df930d7d2e219f26142a';
|
||||
|
||||
@ -29,6 +30,7 @@ class PlatformType {
|
||||
static const bitbucket = 'bitbucket';
|
||||
static const gitea = 'gitea';
|
||||
static const gitee = 'gitee';
|
||||
static const gogs = 'gogs';
|
||||
}
|
||||
|
||||
class DataWithPage<T> {
|
||||
@ -320,6 +322,109 @@ class AuthModel with ChangeNotifier {
|
||||
);
|
||||
}
|
||||
|
||||
Future loginToGogs(String domain, String token) async {
|
||||
domain = domain.trim();
|
||||
token = token.trim();
|
||||
try {
|
||||
loading = true;
|
||||
notifyListeners();
|
||||
final res = await http.get('$domain/api/v1/user',
|
||||
headers: {'Authorization': 'token $token'});
|
||||
final info = json.decode(res.body);
|
||||
if (info['message'] != null) {
|
||||
throw info['message'];
|
||||
}
|
||||
final user = GogsUser.fromJson(info);
|
||||
|
||||
await _addAccount(Account(
|
||||
platform: PlatformType.gogs,
|
||||
domain: domain,
|
||||
token: token,
|
||||
login: user.username,
|
||||
avatarUrl: user.avatarUrl,
|
||||
));
|
||||
} finally {
|
||||
loading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: refactor
|
||||
Future fetchGogs(
|
||||
String p, {
|
||||
requestType = 'GET',
|
||||
Map<String, dynamic> body = const {},
|
||||
}) async {
|
||||
http.Response res;
|
||||
Map<String, String> headers = {
|
||||
'Authorization': 'token $token',
|
||||
HttpHeaders.contentTypeHeader: 'application/json'
|
||||
};
|
||||
switch (requestType) {
|
||||
case 'DELETE':
|
||||
{
|
||||
await http.delete(
|
||||
'${activeAccount.domain}/api/v1$p',
|
||||
headers: headers,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'POST':
|
||||
{
|
||||
res = await http.post(
|
||||
'${activeAccount.domain}/api/v1$p',
|
||||
headers: headers,
|
||||
body: jsonEncode(body),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'PATCH':
|
||||
{
|
||||
res = await http.patch(
|
||||
'${activeAccount.domain}/api/v1$p',
|
||||
headers: headers,
|
||||
body: jsonEncode(body),
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
res = await http.get('${activeAccount.domain}/api/v1$p',
|
||||
headers: headers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (requestType != 'DELETE') {
|
||||
final info = json.decode(utf8.decode(res.bodyBytes));
|
||||
return info;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Future<DataWithPage> fetchGogsWithPage(String path,
|
||||
{int page, int limit}) async {
|
||||
page = page ?? 1;
|
||||
limit = limit ?? pageSize;
|
||||
|
||||
var uri = Uri.parse('${activeAccount.domain}/api/v1$path');
|
||||
uri = uri.replace(
|
||||
queryParameters: {
|
||||
'page': page.toString(),
|
||||
'limit': limit.toString(),
|
||||
...uri.queryParameters,
|
||||
},
|
||||
);
|
||||
final res = await http.get(uri, headers: {'Authorization': 'token $token'});
|
||||
final info = json.decode(utf8.decode(res.bodyBytes));
|
||||
|
||||
return DataWithPage(
|
||||
data: info,
|
||||
cursor: page + 1,
|
||||
hasMore: info is List && info.length > 0,
|
||||
total: int.tryParse(res.headers['x-total-count'] ?? ''),
|
||||
);
|
||||
}
|
||||
|
||||
Future fetchGitee(
|
||||
String p, {
|
||||
requestType = 'GET',
|
||||
|
133
lib/models/gogs.dart
Normal file
133
lib/models/gogs.dart
Normal file
@ -0,0 +1,133 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'gogs.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsUser {
|
||||
int id;
|
||||
String username;
|
||||
String fullName;
|
||||
String avatarUrl;
|
||||
String email;
|
||||
GogsUser();
|
||||
factory GogsUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsRepository {
|
||||
int id;
|
||||
String fullName;
|
||||
bool private;
|
||||
GogsUser owner;
|
||||
String htmlUrl;
|
||||
String description;
|
||||
String defaultBranch;
|
||||
DateTime createdAt;
|
||||
DateTime updatedAt;
|
||||
int starsCount;
|
||||
int forksCount;
|
||||
String website;
|
||||
int watchersCount;
|
||||
GogsRepository();
|
||||
factory GogsRepository.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsRepositoryFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsOrg {
|
||||
int id;
|
||||
String username;
|
||||
String fullName;
|
||||
String avatarUrl;
|
||||
String description;
|
||||
String location;
|
||||
String website;
|
||||
GogsOrg();
|
||||
factory GogsOrg.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsOrgFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsTree {
|
||||
String type;
|
||||
String name;
|
||||
String path;
|
||||
int size;
|
||||
String downloadUrl;
|
||||
GogsTree();
|
||||
factory GogsTree.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsTreeFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsBlob extends GogsTree {
|
||||
String content;
|
||||
GogsBlob();
|
||||
factory GogsBlob.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsBlobFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsBranch {
|
||||
String name;
|
||||
GogsBranch();
|
||||
factory GogsBranch.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsBranchFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsCommit {
|
||||
GogsUser author;
|
||||
GogsCommitDetail commit;
|
||||
String sha;
|
||||
String htmlUrl;
|
||||
GogsCommit();
|
||||
factory GogsCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsCommitFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsCommitDetail {
|
||||
String message;
|
||||
GogsCommitAuthor author;
|
||||
GogsCommitAuthor committer;
|
||||
GogsCommitDetail();
|
||||
factory GogsCommitDetail.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsCommitDetailFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsCommitAuthor {
|
||||
String name;
|
||||
String email;
|
||||
DateTime date;
|
||||
GogsCommitAuthor();
|
||||
factory GogsCommitAuthor.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsCommitAuthorFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsIssue {
|
||||
int number;
|
||||
String state;
|
||||
String title;
|
||||
String body;
|
||||
GogsUser user;
|
||||
List<GogsLabel> labels;
|
||||
DateTime createdAt;
|
||||
DateTime updatedAt;
|
||||
int comments;
|
||||
GogsIssue();
|
||||
factory GogsIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsIssueFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsLabel {
|
||||
String name;
|
||||
String color;
|
||||
GogsLabel();
|
||||
factory GogsLabel.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsLabelFromJson(json);
|
||||
}
|
228
lib/models/gogs.g.dart
Normal file
228
lib/models/gogs.g.dart
Normal file
@ -0,0 +1,228 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'gogs.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GogsUser _$GogsUserFromJson(Map<String, dynamic> json) {
|
||||
return GogsUser()
|
||||
..id = json['id'] as int
|
||||
..username = json['username'] as String
|
||||
..fullName = json['full_name'] as String
|
||||
..avatarUrl = json['avatar_url'] as String
|
||||
..email = json['email'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsUserToJson(GogsUser instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'username': instance.username,
|
||||
'full_name': instance.fullName,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'email': instance.email,
|
||||
};
|
||||
|
||||
GogsRepository _$GogsRepositoryFromJson(Map<String, dynamic> json) {
|
||||
return GogsRepository()
|
||||
..id = json['id'] as int
|
||||
..fullName = json['full_name'] as String
|
||||
..private = json['private'] as bool
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: GogsUser.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..htmlUrl = json['html_url'] as String
|
||||
..description = json['description'] as String
|
||||
..defaultBranch = json['default_branch'] as String
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..starsCount = json['stars_count'] as int
|
||||
..forksCount = json['forks_count'] as int
|
||||
..website = json['website'] as String
|
||||
..watchersCount = json['watchers_count'] as int;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsRepositoryToJson(GogsRepository instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'full_name': instance.fullName,
|
||||
'private': instance.private,
|
||||
'owner': instance.owner,
|
||||
'html_url': instance.htmlUrl,
|
||||
'description': instance.description,
|
||||
'default_branch': instance.defaultBranch,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'stars_count': instance.starsCount,
|
||||
'forks_count': instance.forksCount,
|
||||
'website': instance.website,
|
||||
'watchers_count': instance.watchersCount,
|
||||
};
|
||||
|
||||
GogsOrg _$GogsOrgFromJson(Map<String, dynamic> json) {
|
||||
return GogsOrg()
|
||||
..id = json['id'] as int
|
||||
..username = json['username'] as String
|
||||
..fullName = json['full_name'] as String
|
||||
..avatarUrl = json['avatar_url'] as String
|
||||
..description = json['description'] as String
|
||||
..location = json['location'] as String
|
||||
..website = json['website'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsOrgToJson(GogsOrg instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'username': instance.username,
|
||||
'full_name': instance.fullName,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'description': instance.description,
|
||||
'location': instance.location,
|
||||
'website': instance.website,
|
||||
};
|
||||
|
||||
GogsTree _$GogsTreeFromJson(Map<String, dynamic> json) {
|
||||
return GogsTree()
|
||||
..type = json['type'] as String
|
||||
..name = json['name'] as String
|
||||
..path = json['path'] as String
|
||||
..size = json['size'] as int
|
||||
..downloadUrl = json['download_url'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsTreeToJson(GogsTree instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
'download_url': instance.downloadUrl,
|
||||
};
|
||||
|
||||
GogsBlob _$GogsBlobFromJson(Map<String, dynamic> json) {
|
||||
return GogsBlob()
|
||||
..type = json['type'] as String
|
||||
..name = json['name'] as String
|
||||
..path = json['path'] as String
|
||||
..size = json['size'] as int
|
||||
..downloadUrl = json['download_url'] as String
|
||||
..content = json['content'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsBlobToJson(GogsBlob instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
'download_url': instance.downloadUrl,
|
||||
'content': instance.content,
|
||||
};
|
||||
|
||||
GogsBranch _$GogsBranchFromJson(Map<String, dynamic> json) {
|
||||
return GogsBranch()..name = json['name'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsBranchToJson(GogsBranch instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GogsCommit _$GogsCommitFromJson(Map<String, dynamic> json) {
|
||||
return GogsCommit()
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GogsUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..commit = json['commit'] == null
|
||||
? null
|
||||
: GogsCommitDetail.fromJson(json['commit'] as Map<String, dynamic>)
|
||||
..sha = json['sha'] as String
|
||||
..htmlUrl = json['html_url'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsCommitToJson(GogsCommit instance) =>
|
||||
<String, dynamic>{
|
||||
'author': instance.author,
|
||||
'commit': instance.commit,
|
||||
'sha': instance.sha,
|
||||
'html_url': instance.htmlUrl,
|
||||
};
|
||||
|
||||
GogsCommitDetail _$GogsCommitDetailFromJson(Map<String, dynamic> json) {
|
||||
return GogsCommitDetail()
|
||||
..message = json['message'] as String
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GogsCommitAuthor.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..committer = json['committer'] == null
|
||||
? null
|
||||
: GogsCommitAuthor.fromJson(json['committer'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsCommitDetailToJson(GogsCommitDetail instance) =>
|
||||
<String, dynamic>{
|
||||
'message': instance.message,
|
||||
'author': instance.author,
|
||||
'committer': instance.committer,
|
||||
};
|
||||
|
||||
GogsCommitAuthor _$GogsCommitAuthorFromJson(Map<String, dynamic> json) {
|
||||
return GogsCommitAuthor()
|
||||
..name = json['name'] as String
|
||||
..email = json['email'] as String
|
||||
..date =
|
||||
json['date'] == null ? null : DateTime.parse(json['date'] as String);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsCommitAuthorToJson(GogsCommitAuthor instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'email': instance.email,
|
||||
'date': instance.date?.toIso8601String(),
|
||||
};
|
||||
|
||||
GogsIssue _$GogsIssueFromJson(Map<String, dynamic> json) {
|
||||
return GogsIssue()
|
||||
..number = json['number'] as int
|
||||
..state = json['state'] as String
|
||||
..title = json['title'] as String
|
||||
..body = json['body'] as String
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GogsUser.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..labels = (json['labels'] as List)
|
||||
?.map((e) =>
|
||||
e == null ? null : GogsLabel.fromJson(e as Map<String, dynamic>))
|
||||
?.toList()
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..comments = json['comments'] as int;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsIssueToJson(GogsIssue instance) => <String, dynamic>{
|
||||
'number': instance.number,
|
||||
'state': instance.state,
|
||||
'title': instance.title,
|
||||
'body': instance.body,
|
||||
'user': instance.user,
|
||||
'labels': instance.labels,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'comments': instance.comments,
|
||||
};
|
||||
|
||||
GogsLabel _$GogsLabelFromJson(Map<String, dynamic> json) {
|
||||
return GogsLabel()
|
||||
..name = json['name'] as String
|
||||
..color = json['color'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GogsLabelToJson(GogsLabel instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'color': instance.color,
|
||||
};
|
@ -35,6 +35,14 @@ import 'package:git_touch/screens/gh_org_repos.dart';
|
||||
import 'package:git_touch/screens/gl_commit.dart';
|
||||
import 'package:git_touch/screens/gl_issue_form.dart';
|
||||
import 'package:git_touch/screens/gl_starrers.dart';
|
||||
import 'package:git_touch/screens/go_commits.dart';
|
||||
import 'package:git_touch/screens/go_issues.dart';
|
||||
import 'package:git_touch/screens/go_object.dart';
|
||||
import 'package:git_touch/screens/go_orgs.dart';
|
||||
import 'package:git_touch/screens/go_repo.dart';
|
||||
import 'package:git_touch/screens/go_repos.dart';
|
||||
import 'package:git_touch/screens/go_user.dart';
|
||||
import 'package:git_touch/screens/go_users.dart';
|
||||
import 'package:git_touch/screens/gt_commits.dart';
|
||||
import 'package:git_touch/screens/gt_issue.dart';
|
||||
import 'package:git_touch/screens/gt_issue_comment.dart';
|
||||
@ -652,3 +660,63 @@ class GiteeRouter {
|
||||
parameters['owner'].first, parameters['name'].first),
|
||||
);
|
||||
}
|
||||
|
||||
class GogsRouter {
|
||||
static const prefix = '/gogs';
|
||||
static final routes = [
|
||||
GogsRouter.user,
|
||||
GogsRouter.repo,
|
||||
GogsRouter.object,
|
||||
GogsRouter.commits,
|
||||
GogsRouter.issues,
|
||||
];
|
||||
static final user = RouterScreen('/:login', (context, parameters) {
|
||||
final login = parameters['login'].first;
|
||||
final tab = parameters['tab']?.first;
|
||||
final isViewer = parameters['isViewer']?.first;
|
||||
switch (tab) {
|
||||
case 'followers':
|
||||
return GoUsersScreen.followers(login);
|
||||
case 'following':
|
||||
return GoUsersScreen.following(login);
|
||||
case 'repositories':
|
||||
return GoReposScreen(login,
|
||||
isViewer: isViewer == 'false' ? false : true);
|
||||
case 'organizations':
|
||||
return GoOrgsScreen.ofUser(login,
|
||||
isViewer: isViewer == 'false' ? false : true); // handle better?
|
||||
default:
|
||||
return GoUserScreen(parameters['login'].first);
|
||||
}
|
||||
});
|
||||
static final repo = RouterScreen(
|
||||
'/:owner/:name',
|
||||
(context, parameters) {
|
||||
if (parameters['branch'] == null) {
|
||||
return GoRepoScreen(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
} else {
|
||||
return GoRepoScreen(parameters['owner'].first, parameters['name'].first,
|
||||
branch: parameters['branch'].first);
|
||||
}
|
||||
},
|
||||
);
|
||||
static final object = RouterScreen(
|
||||
'/:owner/:name/blob',
|
||||
(context, parameters) => GoObjectScreen(
|
||||
parameters['owner'].first,
|
||||
parameters['name'].first,
|
||||
path: parameters['path']?.first,
|
||||
ref: parameters['ref']?.first,
|
||||
),
|
||||
);
|
||||
static final commits = RouterScreen(
|
||||
'/:owner/:name/commits',
|
||||
(context, parameters) => GoCommitsScreen(
|
||||
parameters['owner'].first, parameters['name'].first,
|
||||
branch: parameters['ref']?.first));
|
||||
static final issues = RouterScreen(
|
||||
'/:owner/:name/issues',
|
||||
(context, parameters) =>
|
||||
GoIssuesScreen(parameters['owner'].first, parameters['name'].first));
|
||||
}
|
||||
|
43
lib/screens/go_commits.dart
Normal file
43
lib/screens/go_commits.dart
Normal file
@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/commit_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../generated/l10n.dart';
|
||||
|
||||
class GoCommitsScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
final String branch;
|
||||
GoCommitsScreen(this.owner, this.name, {this.branch = 'master'});
|
||||
|
||||
// TODO: API only returns most recent commit. No provision for all commits.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GogsCommit, int>(
|
||||
title: AppBarTitle(S.of(context).commits),
|
||||
fetch: (page) async {
|
||||
final res = await context.read<AuthModel>().fetchGogsWithPage(
|
||||
'/repos/$owner/$name/commits/$branch',
|
||||
page: page);
|
||||
return ListPayload(
|
||||
cursor: res.cursor,
|
||||
hasMore: res.hasMore,
|
||||
items: [GogsCommit.fromJson(res.data)],
|
||||
);
|
||||
},
|
||||
itemBuilder: (c) {
|
||||
return CommitItem(
|
||||
author: c.author?.username ?? c.commit.author.name,
|
||||
avatarUrl: c.author.avatarUrl,
|
||||
avatarLink: '/gogs/${c.author.username}',
|
||||
createdAt: c.commit.author.date,
|
||||
message: c.commit.message,
|
||||
url: c.htmlUrl,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
62
lib/screens/go_issues.dart
Normal file
62
lib/screens/go_issues.dart
Normal file
@ -0,0 +1,62 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/generated/l10n.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:git_touch/widgets/label.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GoIssuesScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
final bool isPr;
|
||||
GoIssuesScreen(this.owner, this.name, {this.isPr = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GogsIssue, int>(
|
||||
title:
|
||||
AppBarTitle(isPr ? S.of(context).pullRequests : S.of(context).issues),
|
||||
fetch: (page) async {
|
||||
final type = isPr ? 'pulls' : 'issues';
|
||||
final res = await context.read<AuthModel>().fetchGogsWithPage(
|
||||
'/repos/$owner/$name/issues?state=open&type=$type',
|
||||
page: page);
|
||||
return ListPayload(
|
||||
cursor: res.cursor,
|
||||
hasMore: res.hasMore,
|
||||
items: (res.data as List).map((v) => GogsIssue.fromJson(v)).toList(),
|
||||
);
|
||||
},
|
||||
actionBuilder: () => ActionEntry(
|
||||
iconData: isPr ? null : Octicons.plus,
|
||||
url: isPr
|
||||
? '/gogs/$owner/$name/pulls/new' // TODO
|
||||
: '/gogs/$owner/$name/issues/new',
|
||||
),
|
||||
itemBuilder: (p) => IssueItem(
|
||||
author: p.user.username,
|
||||
avatarUrl: p.user.avatarUrl,
|
||||
commentCount: p.comments,
|
||||
subtitle: '#' + p.number.toString(),
|
||||
title: p.title,
|
||||
updatedAt: p.updatedAt,
|
||||
url: isPr
|
||||
? 'https://gogs.io' // TODO: PR endpoints are not supported in Gogs, htmlUrl prop non-existent
|
||||
: '/gogs/$owner/$name/issues/${p.number}',
|
||||
labels: isPr
|
||||
? null
|
||||
: p.labels.isEmpty
|
||||
? null
|
||||
: Wrap(spacing: 4, runSpacing: 4, children: [
|
||||
for (var label in p.labels)
|
||||
MyLabel(name: label.name, cssColor: label.color)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
66
lib/screens/go_object.dart
Normal file
66
lib/screens/go_object.dart
Normal file
@ -0,0 +1,66 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/generated/l10n.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/blob_view.dart';
|
||||
import 'package:git_touch/widgets/object_tree.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GoObjectScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
final String path;
|
||||
final String ref;
|
||||
GoObjectScreen(this.owner, this.name, {this.path, this.ref});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold(
|
||||
title: AppBarTitle(path ?? S.of(context).files),
|
||||
fetch: () async {
|
||||
final suffix = path == null ? '' : '/$path';
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
.fetchGogs('/repos/$owner/$name/contents$suffix?ref=$ref');
|
||||
return res;
|
||||
},
|
||||
actionBuilder: (p, _) {
|
||||
if (p is List) {
|
||||
return null;
|
||||
} else {
|
||||
return ActionEntry(
|
||||
iconData: Icons.settings,
|
||||
url: '/choose-code-theme',
|
||||
);
|
||||
}
|
||||
},
|
||||
bodyBuilder: (p, _) {
|
||||
if (p is List) {
|
||||
final items = p.map((t) => GogsTree.fromJson(t)).toList();
|
||||
items.sort((a, b) {
|
||||
return sortByKey('dir', a.type, b.type);
|
||||
});
|
||||
return ObjectTree(items: [
|
||||
for (var v in items)
|
||||
ObjectTreeItem(
|
||||
name: v.name,
|
||||
type: v.type,
|
||||
size: v.type == 'file' ? v.size : null,
|
||||
url:
|
||||
'/gogs/$owner/$name/blob?path=${v.path.urlencode}&ref=$ref',
|
||||
downloadUrl: v.downloadUrl,
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
final v = GogsBlob.fromJson(p);
|
||||
return BlobView(v.name,
|
||||
base64Text: v.content == null ? '' : v.content);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
43
lib/screens/go_orgs.dart
Normal file
43
lib/screens/go_orgs.dart
Normal file
@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/user_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../generated/l10n.dart';
|
||||
|
||||
class GoOrgsScreen extends StatelessWidget {
|
||||
final String api;
|
||||
final bool isViewer;
|
||||
// TODO: implement list of orgs screen when API is available
|
||||
GoOrgsScreen.ofUser(String login, {this.isViewer})
|
||||
: api = isViewer ? '/users/$login/orgs' : '/user/orgs';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<List<GogsOrg>>(
|
||||
title: AppBarTitle(S.of(context).organizations),
|
||||
fetch: () async {
|
||||
final res = await context.read<AuthModel>().fetchGogs(api);
|
||||
return [for (var v in res) GogsOrg.fromJson(v)];
|
||||
},
|
||||
bodyBuilder: (p, _) {
|
||||
return Column(
|
||||
children: [
|
||||
for (var org in p) ...[
|
||||
UserItem.gogs(
|
||||
avatarUrl: org.avatarUrl,
|
||||
login: org.username,
|
||||
name: org.fullName,
|
||||
bio: Text(org.description ?? org.website ?? org.location),
|
||||
),
|
||||
CommonStyle.border,
|
||||
]
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
152
lib/screens/go_repo.dart
Normal file
152
lib/screens/go_repo.dart
Normal file
@ -0,0 +1,152 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/entry_item.dart';
|
||||
import 'package:git_touch/widgets/markdown_view.dart';
|
||||
import 'package:git_touch/widgets/repo_header.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../generated/l10n.dart';
|
||||
|
||||
class GoRepoScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
final String branch;
|
||||
GoRepoScreen(this.owner, this.name, {this.branch});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<
|
||||
Tuple3<GogsRepository, MarkdownViewData, List<GogsBranch>>>(
|
||||
title: AppBarTitle(S.of(context).repository),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final repo = await auth.fetchGogs('/repos/$owner/$name').then((v) {
|
||||
return GogsRepository.fromJson(v);
|
||||
});
|
||||
|
||||
final md = () =>
|
||||
auth.fetchGogs('/repos/$owner/$name/contents/README.md').then((v) {
|
||||
return (v['content'] as String)?.base64ToUtf8;
|
||||
});
|
||||
final html = () => md().then((v) async {
|
||||
final res = await http.post(
|
||||
'${auth.activeAccount.domain}/api/v1/markdown/raw',
|
||||
headers: {'Authorization': 'token ${auth.token}'},
|
||||
body: v,
|
||||
);
|
||||
return utf8.decode(res.bodyBytes).normalizedHtml;
|
||||
});
|
||||
final readmeData = MarkdownViewData(context, md: md, html: html);
|
||||
final branches =
|
||||
await auth.fetchGogs('/repos/$owner/$name/branches').then((v) {
|
||||
if (!(v is List))
|
||||
return null; // Valid API Response only returned if repo contains >= 2 branches
|
||||
return [for (var branch in v) GogsBranch.fromJson(branch)];
|
||||
});
|
||||
|
||||
return Tuple3(repo, readmeData, branches);
|
||||
},
|
||||
bodyBuilder: (t, setState) {
|
||||
final p = t.item1;
|
||||
final branches = t.item3;
|
||||
final theme = context.read<ThemeModel>();
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
RepoHeader(
|
||||
avatarUrl: p.owner.avatarUrl,
|
||||
avatarLink: '/gogs/${p.owner.username}',
|
||||
owner: p.owner.username,
|
||||
name: p.fullName.split('/')[1],
|
||||
description: p.description,
|
||||
homepageUrl: p.website,
|
||||
),
|
||||
CommonStyle.border,
|
||||
Row(
|
||||
children: <Widget>[
|
||||
// TODO: when API is available
|
||||
EntryItem(
|
||||
count: p.watchersCount,
|
||||
text: 'Watchers',
|
||||
),
|
||||
EntryItem(
|
||||
count: p.starsCount,
|
||||
text: 'Stars',
|
||||
),
|
||||
EntryItem(
|
||||
count: p.forksCount,
|
||||
text: 'Forks',
|
||||
),
|
||||
],
|
||||
),
|
||||
CommonStyle.border,
|
||||
TableView(
|
||||
hasIcon: true,
|
||||
items: [
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.code,
|
||||
text: Text('Code'),
|
||||
url:
|
||||
'/gogs/$owner/$name/blob?ref=${branch == null ? 'master' : branch}',
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.issue_opened,
|
||||
text: Text('Issues'),
|
||||
url: '/gogs/$owner/$name/issues',
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_pull_request,
|
||||
text: Text(
|
||||
'Pull requests'), // TODO: when API endpoint is available
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.history,
|
||||
text: Text('Commits'),
|
||||
url:
|
||||
'/gogs/$owner/$name/commits?ref=${branch == null ? 'master' : branch}',
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_branch,
|
||||
text: Text(S.of(context).branches),
|
||||
rightWidget: Text((branch == null ? 'master' : branch) +
|
||||
' • ' +
|
||||
'${branches == null ? '1' : branches.length.toString()}'),
|
||||
onTap: () async {
|
||||
if (branches == null) return;
|
||||
|
||||
await theme.showPicker(
|
||||
context,
|
||||
PickerGroupItem(
|
||||
value: branch,
|
||||
items: branches
|
||||
.map((b) => PickerItem(b.name, text: b.name))
|
||||
.toList(),
|
||||
onClose: (ref) {
|
||||
if (ref != branch) {
|
||||
theme.push(
|
||||
context, '/gogs/$owner/$name?branch=$ref',
|
||||
replace: true);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
CommonStyle.verticalGap,
|
||||
MarkdownView(t.item2),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
44
lib/screens/go_repos.dart
Normal file
44
lib/screens/go_repos.dart
Normal file
@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
|
||||
class GoReposScreen extends StatelessWidget {
|
||||
final String api;
|
||||
final String title;
|
||||
final bool isViewer;
|
||||
|
||||
GoReposScreen(String owner, {this.isViewer = false})
|
||||
: api = isViewer ? '/users/$owner/repos' : '/user/repos',
|
||||
title = 'Repositories';
|
||||
GoReposScreen.org(String owner)
|
||||
: api = '/orgs/$owner/repos',
|
||||
title = 'Repositories',
|
||||
isViewer = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GogsRepository, int>(
|
||||
title: AppBarTitle(title),
|
||||
fetch: (page) async {
|
||||
final res =
|
||||
await context.read<AuthModel>().fetchGogsWithPage(api, page: page);
|
||||
return ListPayload(
|
||||
cursor: res.cursor,
|
||||
hasMore: res.hasMore,
|
||||
items: [for (var v in res.data) GogsRepository.fromJson(v)],
|
||||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
return RepositoryItem.go(
|
||||
payload: v,
|
||||
name: v.fullName.split('/')[1],
|
||||
owner: v.owner.username,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
9
lib/screens/go_search.dart
Normal file
9
lib/screens/go_search.dart
Normal file
@ -0,0 +1,9 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GoSearchScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(child: Text('Coming Soon...'));
|
||||
}
|
||||
}
|
105
lib/screens/go_user.dart
Normal file
105
lib/screens/go_user.dart
Normal file
@ -0,0 +1,105 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/entry_item.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:git_touch/widgets/user_header.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class GoUserScreen extends StatelessWidget {
|
||||
final String login;
|
||||
final bool isViewer;
|
||||
GoUserScreen(this.login, {this.isViewer = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple2<GogsUser, List<GogsRepository>>>(
|
||||
title: Text(isViewer ? 'Me' : login),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final res = await Future.wait([
|
||||
auth.fetchGogs(isViewer ? '/user' : '/users/$login'),
|
||||
auth.fetchGogsWithPage(
|
||||
isViewer ? '/user/repos' : '/users/$login/repos',
|
||||
limit: 6),
|
||||
]);
|
||||
|
||||
return Tuple2(GogsUser.fromJson(res[0]),
|
||||
[for (var repo in res[1].data) GogsRepository.fromJson(repo)]);
|
||||
},
|
||||
action: isViewer
|
||||
? ActionEntry(
|
||||
iconData: Icons.settings,
|
||||
url: '/settings',
|
||||
)
|
||||
: null,
|
||||
bodyBuilder: (p, _) {
|
||||
final user = p.item1;
|
||||
final repos = p.item2;
|
||||
if (p.item1 != null) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
UserHeader(
|
||||
login: user.username,
|
||||
avatarUrl: user.avatarUrl,
|
||||
name: user.fullName,
|
||||
createdAt:
|
||||
null, // TODO: API response does not have this attribute
|
||||
isViewer: isViewer,
|
||||
bio: null, // TODO: API response does not have this attribute
|
||||
),
|
||||
CommonStyle.border,
|
||||
Row(children: [
|
||||
EntryItem(
|
||||
text: 'Repositories',
|
||||
url: '/gogs/$login?tab=repositories&isViewer=$isViewer',
|
||||
),
|
||||
EntryItem(
|
||||
text: 'Followers',
|
||||
url: '/gogs/$login?tab=followers',
|
||||
),
|
||||
EntryItem(
|
||||
text: 'Following',
|
||||
url: '/gogs/$login?tab=following',
|
||||
),
|
||||
]),
|
||||
CommonStyle.border,
|
||||
TableView(
|
||||
hasIcon: true,
|
||||
items: [
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.home,
|
||||
text: Text('Organizations'),
|
||||
url:
|
||||
'/gogs/${user.username}?tab=organizations&isViewer=$isViewer',
|
||||
),
|
||||
],
|
||||
),
|
||||
CommonStyle.border,
|
||||
Column(
|
||||
children: <Widget>[
|
||||
for (var v in repos) ...[
|
||||
RepositoryItem.go(
|
||||
payload: v,
|
||||
name: v.fullName.split('/')[1],
|
||||
owner: v.owner.username,
|
||||
),
|
||||
CommonStyle.border,
|
||||
]
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text('404'); // TODO:
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
43
lib/screens/go_users.dart
Normal file
43
lib/screens/go_users.dart
Normal file
@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/user_item.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GoUsersScreen extends StatelessWidget {
|
||||
final String api;
|
||||
final String title;
|
||||
|
||||
GoUsersScreen.followers(String login)
|
||||
: api = '/users/$login/followers',
|
||||
title = 'Followers';
|
||||
GoUsersScreen.following(String login)
|
||||
: api = '/users/$login/following',
|
||||
title = "Following";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GogsUser, int>(
|
||||
title: AppBarTitle(title),
|
||||
fetch: (page) async {
|
||||
final res =
|
||||
await context.read<AuthModel>().fetchGogsWithPage(api, page: page);
|
||||
return ListPayload(
|
||||
cursor: res.cursor,
|
||||
hasMore: res.hasMore,
|
||||
items: [for (var v in res.data) GogsUser.fromJson(v)],
|
||||
);
|
||||
},
|
||||
itemBuilder: (payload) {
|
||||
return UserItem.gogs(
|
||||
login: payload.username,
|
||||
name: payload.fullName,
|
||||
avatarUrl: payload.avatarUrl,
|
||||
bio: null,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -348,6 +348,26 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||
}
|
||||
},
|
||||
),
|
||||
_buildAddItem(
|
||||
text: 'Gogs Account',
|
||||
brand: Octicons.git_branch, // TODO: brand icon
|
||||
onTap: () async {
|
||||
_domainController.text = 'https://gogs.com';
|
||||
final result = await theme.showConfirm(
|
||||
context,
|
||||
_buildPopup(context, showDomain: true),
|
||||
);
|
||||
if (result == true) {
|
||||
try {
|
||||
await auth.loginToGogs(
|
||||
_domainController.text, _tokenController.text);
|
||||
_tokenController.clear();
|
||||
} catch (err) {
|
||||
showError(err);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
Container(
|
||||
padding: CommonStyle.padding,
|
||||
child: Text(
|
||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/models/gitlab.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/avatar.dart';
|
||||
@ -39,6 +40,21 @@ class RepositoryItem extends StatelessWidget {
|
||||
@required this.avatarLink,
|
||||
});
|
||||
|
||||
RepositoryItem.go({
|
||||
@required GogsRepository payload,
|
||||
this.primaryLanguageName,
|
||||
this.primaryLanguageColor,
|
||||
this.note,
|
||||
this.owner,
|
||||
this.name,
|
||||
}) : url = '/gogs/${payload.fullName}',
|
||||
avatarUrl = payload.owner.avatarUrl,
|
||||
avatarLink = '/gogs/${payload.fullName}',
|
||||
description = payload.description,
|
||||
forkCount = payload.forksCount,
|
||||
starCount = payload.starsCount,
|
||||
iconData = payload.private ? Octicons.lock : null;
|
||||
|
||||
RepositoryItem.bb({
|
||||
@required BbRepo payload,
|
||||
this.primaryLanguageName,
|
||||
|
@ -63,6 +63,13 @@ class UserItem extends StatelessWidget {
|
||||
@required this.bio,
|
||||
}) : url = '/bitbucket/$login?team=1';
|
||||
|
||||
UserItem.gogs({
|
||||
@required this.login,
|
||||
@required this.name,
|
||||
@required this.avatarUrl,
|
||||
@required this.bio,
|
||||
}) : url = '/gogs/$login';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
|
Loading…
x
Reference in New Issue
Block a user