diff --git a/lib/main.dart b/lib/main.dart index c5936d1..ff2f50e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'package:git_touch/models/theme.dart'; import 'package:git_touch/screens/about.dart'; import 'package:git_touch/screens/code_theme.dart'; import 'package:git_touch/screens/commits.dart'; +import 'package:git_touch/screens/gitea_object.dart'; import 'package:git_touch/screens/gitea_repo.dart'; import 'package:git_touch/screens/gitea_user.dart'; import 'package:git_touch/screens/gitlab_blob.dart'; @@ -78,6 +79,7 @@ void main() async { gitlabCommitsRouter, giteaUserRouter, giteaRepoRouter, + giteaObjectRouter, loginRouter, settingsRouter, userRouter, diff --git a/lib/models/gitea.dart b/lib/models/gitea.dart index a54ba2f..9a3fe3f 100644 --- a/lib/models/gitea.dart +++ b/lib/models/gitea.dart @@ -31,3 +31,21 @@ class GiteaRepository { factory GiteaRepository.fromJson(Map json) => _$GiteaRepositoryFromJson(json); } + +@JsonSerializable(fieldRename: FieldRename.snake) +class GiteaTree { + String type; + String name; + String path; + GiteaTree(); + factory GiteaTree.fromJson(Map json) => + _$GiteaTreeFromJson(json); +} + +@JsonSerializable(fieldRename: FieldRename.snake) +class GiteaBlob extends GiteaTree { + String content; + GiteaBlob(); + factory GiteaBlob.fromJson(Map json) => + _$GiteaBlobFromJson(json); +} diff --git a/lib/models/gitea.g.dart b/lib/models/gitea.g.dart index 9067f84..0011b00 100644 --- a/lib/models/gitea.g.dart +++ b/lib/models/gitea.g.dart @@ -58,3 +58,31 @@ Map _$GiteaRepositoryToJson(GiteaRepository instance) => 'open_issues_count': instance.openIssuesCount, 'open_pr_counter': instance.openPrCounter, }; + +GiteaTree _$GiteaTreeFromJson(Map json) { + return GiteaTree() + ..type = json['type'] as String + ..name = json['name'] as String + ..path = json['path'] as String; +} + +Map _$GiteaTreeToJson(GiteaTree instance) => { + 'type': instance.type, + 'name': instance.name, + 'path': instance.path, + }; + +GiteaBlob _$GiteaBlobFromJson(Map json) { + return GiteaBlob() + ..type = json['type'] as String + ..name = json['name'] as String + ..path = json['path'] as String + ..content = json['content'] as String; +} + +Map _$GiteaBlobToJson(GiteaBlob instance) => { + 'type': instance.type, + 'name': instance.name, + 'path': instance.path, + 'content': instance.content, + }; diff --git a/lib/screens/gitea_object.dart b/lib/screens/gitea_object.dart new file mode 100644 index 0000000..9463ed1 --- /dev/null +++ b/lib/screens/gitea_object.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:git_touch/models/auth.dart'; +import 'package:git_touch/models/gitea.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/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'; + +final giteaObjectRouter = RouterScreen( + '/gitea/:owner/:name/blob', + (context, params) => GiteaObjectScreen( + params['owner'].first, + params['name'].first, + path: params['path']?.first?.urldecode, + ), +); + +class GiteaObjectScreen extends StatelessWidget { + final String owner; + final String name; + final String path; + GiteaObjectScreen(this.owner, this.name, {this.path}); + + @override + Widget build(BuildContext context) { + return RefreshStatefulScaffold( + title: AppBarTitle(path ?? 'Files'), + fetchData: () async { + final suffix = path == null ? '' : '/$path'; + final res = await Provider.of(context) + .fetchGitea('/repos/$owner/$name/contents$suffix'); + return res; + }, + actionBuilder: (p, _) { + if (p is List) { + return null; + } else { + final theme = Provider.of(context); + return ActionEntry( + iconData: Icons.settings, + onTap: () { + theme.push(context, '/choose-code-theme'); + }, + ); + } + }, + bodyBuilder: (p, _) { + if (p is List) { + return ObjectTree( + items: p.map((t) { + final v = GiteaTree.fromJson(t); + return ObjectTreeItem( + name: v.name, + type: v.type, + url: '/gitea/$owner/$name/blob?path=${v.path.urlencode}', + ); + }), + ); + } else { + final v = GiteaBlob.fromJson(p); + return BlobView(v.name, base64Text: v.content); + } + }, + ); + } +} diff --git a/lib/screens/gitea_repo.dart b/lib/screens/gitea_repo.dart index 1396002..9b35b29 100644 --- a/lib/screens/gitea_repo.dart +++ b/lib/screens/gitea_repo.dart @@ -74,7 +74,7 @@ class GiteaRepoScreen extends StatelessWidget { leftIconData: Octicons.code, text: Text('Code'), rightWidget: Text(filesize(p.size * 1000)), - url: '/gitea/blob', + url: '/gitea/$owner/$name/blob', ), TableViewItem( leftIconData: Octicons.issue_opened, diff --git a/lib/widgets/object_tree.dart b/lib/widgets/object_tree.dart index 6da6ee6..984adea 100644 --- a/lib/widgets/object_tree.dart +++ b/lib/widgets/object_tree.dart @@ -22,8 +22,10 @@ class ObjectTree extends StatelessWidget { Widget _buildIcon(ObjectTreeItem item) { switch (item.type) { case 'blob': + case 'file': // Gitea return SetiIcon(item.name, size: 36); case 'tree': + case 'dir': // Gitea return Icon( Octicons.file_directory, color: PrimerColors.blue300,