mirror of
https://github.com/git-touch/git-touch
synced 2024-12-13 08:56:22 +01:00
refactor: table view
This commit is contained in:
parent
08f70164f4
commit
aac5fb866b
@ -1,15 +1,17 @@
|
||||
import 'dart:convert';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.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:git_touch/widgets/table_view.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:universal_io/io.dart';
|
||||
|
||||
class BbObjectScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
@ -52,13 +54,15 @@ class BbObjectScreen extends StatelessWidget {
|
||||
if (pl is String) {
|
||||
return BlobView(path, text: pl);
|
||||
} else if (pl is BbTree) {
|
||||
return ObjectTreeItem(
|
||||
name: p.basename(pl.path),
|
||||
type: pl.type,
|
||||
// size: v.type == 'commit_file' ? v.size : null,
|
||||
size: pl.size,
|
||||
url: '/bitbucket/$owner/$name/src/$ref?path=${pl.path.urlencode}',
|
||||
downloadUrl: pl.links!['self']['href'] as String?,
|
||||
return TableViewItemWidget(
|
||||
createObjectTreeItem(
|
||||
name: basename(pl.path),
|
||||
type: pl.type,
|
||||
// size: v.type == 'commit_file' ? v.size : null,
|
||||
size: pl.size,
|
||||
url: '/bitbucket/$owner/$name/src/$ref?path=${pl.path.urlencode}',
|
||||
downloadUrl: pl.links!['self']['href'] as String?,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
|
@ -1,14 +1,14 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.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/object_tree.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GeTreeScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
@ -34,21 +34,16 @@ class GeTreeScreen extends StatelessWidget {
|
||||
return TableView(
|
||||
items: [
|
||||
for (var item in data)
|
||||
ObjectTreeItem(
|
||||
createObjectTreeItem(
|
||||
type: item.type,
|
||||
name: item.path,
|
||||
size: item.size,
|
||||
downloadUrl: '', // TODO:
|
||||
url: (() {
|
||||
switch (item.type) {
|
||||
case 'tree':
|
||||
return '/gitee/$owner/$name/tree/${item.sha}?path=${item.path.urlencode}';
|
||||
case 'blob':
|
||||
return '/gitee/$owner/$name/blob/${item.sha}?path=${item.path.urlencode}';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})(),
|
||||
url: item.type == 'tree'
|
||||
? '/gitee/$owner/$name/tree/${item.sha}?path=${item.path.urlencode}'
|
||||
: item.type == 'blob'
|
||||
? '/gitee/$owner/$name/blob/${item.sha}?path=${item.path.urlencode}'
|
||||
: '',
|
||||
)
|
||||
],
|
||||
);
|
||||
|
@ -39,7 +39,7 @@ class GhGistsFilesScreen extends StatelessWidget {
|
||||
'content': v.text,
|
||||
},
|
||||
).toString();
|
||||
return ObjectTreeItem(
|
||||
return createObjectTreeItem(
|
||||
url: uri,
|
||||
type: 'file',
|
||||
name: v.name ?? '',
|
||||
|
@ -1,12 +1,12 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.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:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:github/github.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -69,7 +69,7 @@ class GhObjectScreen extends StatelessWidget {
|
||||
...(v.downloadUrl == null ? {} : {'raw': v.downloadUrl}),
|
||||
},
|
||||
).toString();
|
||||
return ObjectTreeItem(
|
||||
return createObjectTreeItem(
|
||||
name: v.name ?? '',
|
||||
type: v.type ?? '',
|
||||
url: uri.toString(),
|
||||
|
@ -1,12 +1,13 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitlab.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/object_tree.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GlTreeScreen extends StatelessWidget {
|
||||
final int id;
|
||||
@ -37,21 +38,18 @@ class GlTreeScreen extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
itemBuilder: (item) {
|
||||
return ObjectTreeItem(
|
||||
type: item.type,
|
||||
name: item.name,
|
||||
downloadUrl:
|
||||
'${auth.activeAccount!.domain}/api/v4/projects/$id/repository/files/${item.path.urlencode}/raw?ref=master', // TODO:
|
||||
url: (() {
|
||||
switch (item.type) {
|
||||
case 'tree':
|
||||
return '/gitlab/projects/$id/tree/$ref?path=${item.path.urlencode}';
|
||||
case 'blob':
|
||||
return '/gitlab/projects/$id/blob/$ref?path=${item.path.urlencode}';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})(),
|
||||
return TableViewItemWidget(
|
||||
createObjectTreeItem(
|
||||
type: item.type,
|
||||
name: item.name,
|
||||
downloadUrl:
|
||||
'${auth.activeAccount!.domain}/api/v4/projects/$id/repository/files/${item.path.urlencode}/raw?ref=master', // TODO:
|
||||
url: item.type == 'tree'
|
||||
? '/gitlab/projects/$id/tree/$ref?path=${item.path.urlencode}'
|
||||
: item.type == 'blob'
|
||||
? '/gitlab/projects/$id/blob/$ref?path=${item.path.urlencode}'
|
||||
: '',
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -47,7 +47,7 @@ class GoObjectScreen extends StatelessWidget {
|
||||
});
|
||||
return TableView(items: [
|
||||
for (var v in items)
|
||||
ObjectTreeItem(
|
||||
createObjectTreeItem(
|
||||
name: v.name,
|
||||
type: v.type,
|
||||
size: v.type == 'file' ? v.size : null,
|
||||
|
@ -46,7 +46,7 @@ class GtObjectScreen extends StatelessWidget {
|
||||
});
|
||||
return TableView(items: [
|
||||
for (var v in items)
|
||||
ObjectTreeItem(
|
||||
createObjectTreeItem(
|
||||
name: v.name,
|
||||
type: v.type,
|
||||
size: v.type == 'file' ? v.size : null,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/code.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
@ -13,7 +14,6 @@ import 'package:launch_review/launch_review.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class SettingsScreen extends StatelessWidget {
|
||||
@override
|
||||
@ -203,9 +203,8 @@ class SettingsScreen extends StatelessWidget {
|
||||
TableViewItem(
|
||||
text: Text(AppLocalizations.of(context)!.submitAnIssue),
|
||||
rightWidget: const Text('git-touch/git-touch'),
|
||||
url: '${auth.activeAccount!.platform == PlatformType.github
|
||||
? '/github'
|
||||
: 'https://github.com'}/git-touch/git-touch/issues/new',
|
||||
url:
|
||||
'${auth.activeAccount!.platform == PlatformType.github ? '/github' : 'https://github.com'}/git-touch/git-touch/issues/new',
|
||||
),
|
||||
TableViewItem(
|
||||
text: Text(AppLocalizations.of(context)!.rateThisApp),
|
||||
@ -241,9 +240,8 @@ class SettingsScreen extends StatelessWidget {
|
||||
TableViewItem(
|
||||
text: Text(AppLocalizations.of(context)!.sourceCode),
|
||||
rightWidget: const Text('git-touch/git-touch'),
|
||||
url: '${auth.activeAccount!.platform == PlatformType.github
|
||||
? '/github'
|
||||
: 'https://github.com'}/git-touch/git-touch',
|
||||
url:
|
||||
'${auth.activeAccount!.platform == PlatformType.github ? '/github' : 'https://github.com'}/git-touch/git-touch',
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -1,72 +1,61 @@
|
||||
import 'package:file_icon/file_icon.dart';
|
||||
import 'package:filesize/filesize.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:primer/primer.dart';
|
||||
import 'package:file_icon/file_icon.dart';
|
||||
|
||||
class ObjectTreeItem extends StatelessWidget {
|
||||
final String type;
|
||||
final String name;
|
||||
final int? size;
|
||||
final String? url;
|
||||
final String? downloadUrl;
|
||||
|
||||
const ObjectTreeItem({
|
||||
required this.type,
|
||||
required this.name,
|
||||
this.size,
|
||||
this.url,
|
||||
this.downloadUrl,
|
||||
});
|
||||
|
||||
Widget _buildIcon() {
|
||||
switch (type) {
|
||||
case 'blob': // github gql, gitlab
|
||||
case 'file': // github rest, gitea
|
||||
case 'commit_file': // bitbucket
|
||||
return FileIcon(name, size: 36);
|
||||
case 'tree': // github gql, gitlab
|
||||
case 'dir': // github rest, gitea
|
||||
case 'commit_directory': // bitbucket
|
||||
return const Icon(
|
||||
Octicons.file_directory,
|
||||
color: PrimerColors.blue300,
|
||||
size: 24,
|
||||
);
|
||||
case 'commit':
|
||||
return const Icon(
|
||||
Octicons.file_submodule,
|
||||
color: PrimerColors.blue300,
|
||||
size: 24,
|
||||
);
|
||||
default:
|
||||
throw 'object type error';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TableViewItem(
|
||||
leftWidget: _buildIcon(),
|
||||
text: Text(name),
|
||||
rightWidget: size == null ? null : Text(filesize(size)),
|
||||
url: [
|
||||
// Let system browser handle these files
|
||||
//
|
||||
// TODO:
|
||||
// Unhandled Exception: PlatformException(Error, Error while launching
|
||||
// https://github.com/flutter/flutter/issues/49162
|
||||
|
||||
// Docs
|
||||
'pdf', 'docx', 'doc', 'pptx', 'ppt', 'xlsx', 'xls',
|
||||
// Fonts
|
||||
'ttf', 'otf', 'eot', 'woff', 'woff2',
|
||||
'svg',
|
||||
].contains(name.ext)
|
||||
? downloadUrl
|
||||
: url,
|
||||
hideRightChevron: size != null,
|
||||
);
|
||||
Widget _buildIcon(String type, String name) {
|
||||
switch (type) {
|
||||
case 'blob': // github gql, gitlab
|
||||
case 'file': // github rest, gitea
|
||||
case 'commit_file': // bitbucket
|
||||
return FileIcon(name, size: 36);
|
||||
case 'tree': // github gql, gitlab
|
||||
case 'dir': // github rest, gitea
|
||||
case 'commit_directory': // bitbucket
|
||||
return const Icon(
|
||||
Octicons.file_directory,
|
||||
color: PrimerColors.blue300,
|
||||
size: 24,
|
||||
);
|
||||
case 'commit':
|
||||
return const Icon(
|
||||
Octicons.file_submodule,
|
||||
color: PrimerColors.blue300,
|
||||
size: 24,
|
||||
);
|
||||
default:
|
||||
throw 'object type error';
|
||||
}
|
||||
}
|
||||
|
||||
TableViewItem createObjectTreeItem({
|
||||
required String name,
|
||||
required String type,
|
||||
required String url,
|
||||
String? downloadUrl,
|
||||
int? size,
|
||||
}) {
|
||||
return TableViewItem(
|
||||
leftWidget: _buildIcon(type, name),
|
||||
text: Text(name),
|
||||
rightWidget: size == null ? null : Text(filesize(size)),
|
||||
url: [
|
||||
// Let system browser handle these files
|
||||
//
|
||||
// TODO:
|
||||
// Unhandled Exception: PlatformException(Error, Error while launching
|
||||
// https://github.com/flutter/flutter/issues/49162
|
||||
|
||||
// Docs
|
||||
'pdf', 'docx', 'doc', 'pptx', 'ppt', 'xlsx', 'xls',
|
||||
// Fonts
|
||||
'ttf', 'otf', 'eot', 'woff', 'woff2',
|
||||
'svg',
|
||||
].contains(name.ext)
|
||||
? downloadUrl
|
||||
: url,
|
||||
hideRightChevron: size != null,
|
||||
);
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/border_view.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'link.dart';
|
||||
|
||||
class TableViewHeader extends StatelessWidget {
|
||||
final String? title;
|
||||
|
||||
const TableViewHeader(this.title);
|
||||
const TableViewHeader(this.title, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -24,7 +24,7 @@ class TableViewHeader extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class TableViewItem extends StatelessWidget {
|
||||
class TableViewItem {
|
||||
final Widget text;
|
||||
final IconData? leftIconData;
|
||||
final Widget? leftWidget;
|
||||
@ -42,14 +42,20 @@ class TableViewItem extends StatelessWidget {
|
||||
this.url,
|
||||
this.hideRightChevron = false,
|
||||
}) : assert(leftIconData == null || leftWidget == null);
|
||||
}
|
||||
|
||||
class TableViewItemWidget extends StatelessWidget {
|
||||
const TableViewItemWidget(this.item, {super.key});
|
||||
|
||||
final TableViewItem item;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
|
||||
return LinkWidget(
|
||||
onTap: onTap,
|
||||
url: url,
|
||||
onTap: item.onTap,
|
||||
url: item.url,
|
||||
child: DefaultTextStyle(
|
||||
style: TextStyle(fontSize: 17, color: theme.palette.text),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@ -58,27 +64,30 @@ class TableViewItem extends StatelessWidget {
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: (leftWidget == null && leftIconData == null) ? 12 : 44,
|
||||
width: (item.leftWidget == null && item.leftIconData == null)
|
||||
? 12
|
||||
: 44,
|
||||
child: Center(
|
||||
child: leftWidget ??
|
||||
child: item.leftWidget ??
|
||||
Icon(
|
||||
leftIconData,
|
||||
item.leftIconData,
|
||||
color: theme.palette.primary,
|
||||
size: 20,
|
||||
)),
|
||||
),
|
||||
Expanded(child: text),
|
||||
if (rightWidget != null) ...[
|
||||
Expanded(child: item.text),
|
||||
if (item.rightWidget != null) ...[
|
||||
DefaultTextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.tertiaryText,
|
||||
),
|
||||
child: rightWidget!,
|
||||
child: item.rightWidget!,
|
||||
),
|
||||
const SizedBox(width: 6)
|
||||
],
|
||||
if ((onTap != null || url != null) && !hideRightChevron)
|
||||
if ((item.onTap != null || item.url != null) &&
|
||||
!item.hideRightChevron)
|
||||
Icon(Ionicons.chevron_forward,
|
||||
size: 20, color: theme.palette.tertiaryText)
|
||||
else
|
||||
@ -94,10 +103,15 @@ class TableViewItem extends StatelessWidget {
|
||||
|
||||
class TableView extends StatelessWidget {
|
||||
final String? headerText;
|
||||
final Iterable<Widget> items;
|
||||
final Iterable<TableViewItem> items;
|
||||
final bool? hasIcon;
|
||||
|
||||
const TableView({this.headerText, required this.items, this.hasIcon = true});
|
||||
const TableView({
|
||||
super.key,
|
||||
this.headerText,
|
||||
required this.items,
|
||||
this.hasIcon = true,
|
||||
});
|
||||
|
||||
double get _leftPadding => hasIcon == true ? 44 : 12;
|
||||
|
||||
@ -109,7 +123,7 @@ class TableView extends StatelessWidget {
|
||||
if (headerText != null) TableViewHeader(headerText),
|
||||
...join(
|
||||
BorderView(leftPadding: _leftPadding),
|
||||
items.toList(),
|
||||
[for (final item in items) TableViewItemWidget(item)],
|
||||
),
|
||||
CommonStyle.border,
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user