refactor: use ant list

This commit is contained in:
Rongjian Zhang 2022-09-14 01:19:52 +08:00
parent aac5fb866b
commit 084bc3c86a
16 changed files with 323 additions and 320 deletions

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:filesize/filesize.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/bitbucket.dart';
import 'package:git_touch/models/theme.dart';
@ -13,7 +14,6 @@ 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:flutter_gen/gen_l10n/S.dart';
class BbRepoScreen extends StatelessWidget {
final String owner;
@ -59,33 +59,34 @@ class BbRepoScreen extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.code,
text: const Text('Code'),
rightWidget: Text(filesize(p.size)),
prefixIconData: Octicons.code,
child: const Text('Code'),
extra: Text(filesize(p.size)),
url:
'/bitbucket/$owner/$name/src/${branch ?? p.mainbranch!.name}',
),
TableViewItem(
leftIconData: Octicons.issue_opened,
text: const Text('Issues'),
prefixIconData: Octicons.issue_opened,
child: const Text('Issues'),
url: '/bitbucket/$owner/$name/issues',
),
TableViewItem(
leftIconData: Octicons.git_pull_request,
text: const Text('Pull requests'),
prefixIconData: Octicons.git_pull_request,
child: const Text('Pull requests'),
url: '/bitbucket/$owner/$name/pulls',
),
TableViewItem(
leftIconData: Octicons.history,
text: const Text('Commits'),
prefixIconData: Octicons.history,
child: const Text('Commits'),
url:
'/bitbucket/$owner/$name/commits/${branch ?? p.mainbranch!.name}',
),
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text('${(branch ?? p.mainbranch!.name)!}${branches.length}'),
onTap: () async {
prefixIconData: Octicons.git_branch,
child: Text(AppLocalizations.of(context)!.branches),
extra: Text(
'${(branch ?? p.mainbranch!.name)!}${branches.length}'),
onClick: () async {
if (branches.length < 2) return;
await theme.showPicker(

View File

@ -1,5 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/S.dart';
import 'package:flutter_highlight/flutter_highlight.dart';
import 'package:flutter_highlight/theme_map.dart';
import 'package:git_touch/models/code.dart';
@ -9,7 +10,6 @@ import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/table_view.dart';
import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/S.dart';
class CodeThemeScreen extends StatelessWidget {
String _getCode(bool isDark) => '''// ${isDark ? 'Dark' : 'Light'} Mode
@ -45,13 +45,12 @@ class MyApp extends StatelessWidget {
children: <Widget>[
CommonStyle.verticalGap,
TableView(
headerText: AppLocalizations.of(context)!.fontStyle,
hasIcon: false,
header: Text(AppLocalizations.of(context)!.fontStyle),
items: [
TableViewItem(
text: Text(AppLocalizations.of(context)!.fontSize),
rightWidget: Text(codeProvider.fontSize.toString()),
onTap: () {
child: Text(AppLocalizations.of(context)!.fontSize),
extra: Text(codeProvider.fontSize.toString()),
onClick: () {
theme.showPicker(
context,
PickerGroupItem(
@ -68,9 +67,9 @@ class MyApp extends StatelessWidget {
},
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.fontFamily),
rightWidget: Text(codeProvider.fontFamily),
onTap: () {
child: Text(AppLocalizations.of(context)!.fontFamily),
extra: Text(codeProvider.fontFamily),
onClick: () {
theme.showPicker(
context,
PickerGroupItem(
@ -89,12 +88,12 @@ class MyApp extends StatelessWidget {
),
CommonStyle.verticalGap,
TableView(
headerText: AppLocalizations.of(context)!.syntaxHighlighting,
header: Text(AppLocalizations.of(context)!.syntaxHighlighting),
items: [
TableViewItem(
text: Text(AppLocalizations.of(context)!.light),
rightWidget: Text(codeProvider.theme),
onTap: () {
child: Text(AppLocalizations.of(context)!.light),
extra: Text(codeProvider.theme),
onClick: () {
theme.showPicker(
context,
PickerGroupItem(
@ -110,9 +109,9 @@ class MyApp extends StatelessWidget {
},
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.dark),
rightWidget: Text(codeProvider.themeDark),
onTap: () {
child: Text(AppLocalizations.of(context)!.dark),
extra: Text(codeProvider.themeDark),
onClick: () {
theme.showPicker(
context,
PickerGroupItem(

View File

@ -1,6 +1,8 @@
import 'dart:convert';
import 'dart:io';
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/models/theme.dart';
@ -12,10 +14,9 @@ import 'package:git_touch/widgets/markdown_view.dart';
import 'package:git_touch/widgets/mutation_button.dart';
import 'package:git_touch/widgets/repo_header.dart';
import 'package:git_touch/widgets/table_view.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_gen/gen_l10n/S.dart';
class StatusPayload {
bool isWatching;
@ -41,8 +42,8 @@ class GeRepoScreen extends StatelessWidget {
});
md() => auth.fetchGitee('/repos/$owner/$name/readme').then((v) {
return (v['content'] as String?)?.base64ToUtf8 ?? '';
});
return (v['content'] as String?)?.base64ToUtf8 ?? '';
});
html() => md().then((v) async {
final res = await http.post(
Uri.parse('${auth.activeAccount!.domain}/api/v5/markdown'),
@ -134,34 +135,35 @@ class GeRepoScreen extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.code,
text: const Text('Code'),
rightWidget: Text(p.license ?? ''),
prefixIconData: Octicons.code,
child: const Text('Code'),
extra: Text(p.license ?? ''),
url: '/gitee/$owner/$name/tree/${branch ?? p.defaultBranch}',
),
TableViewItem(
leftIconData: Octicons.issue_opened,
text: const Text('Issues'),
rightWidget: Text(numberFormat.format(p.openIssuesCount)),
prefixIconData: Octicons.issue_opened,
child: const Text('Issues'),
extra: Text(numberFormat.format(p.openIssuesCount)),
url: '/gitee/$owner/$name/issues',
),
if (p.pullRequestsEnabled!)
TableViewItem(
leftIconData: Octicons.git_pull_request,
text: const Text('Pull requests'),
prefixIconData: Octicons.git_pull_request,
child: const Text('Pull requests'),
url: '/gitee/$owner/$name/pulls',
),
TableViewItem(
leftIconData: Octicons.history,
text: const Text('Commits'),
prefixIconData: Octicons.history,
child: const Text('Commits'),
url:
'/gitee/$owner/$name/commits?branch=${branch ?? p.defaultBranch}',
),
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text('${(branch ?? p.defaultBranch)!}${branches.length}'),
onTap: () async {
prefixIconData: Octicons.git_branch,
child: Text(AppLocalizations.of(context)!.branches),
extra: Text(
'${(branch ?? p.defaultBranch)!}${branches.length}'),
onClick: () async {
if (branches.length < 2) return;
await theme.showPicker(
@ -183,8 +185,8 @@ class GeRepoScreen extends StatelessWidget {
},
),
TableViewItem(
leftIconData: Octicons.organization,
text: const Text('Contributors'),
prefixIconData: Octicons.organization,
child: const Text('Contributors'),
url: '/gitee/$owner/$name/contributors'),
],
),

View File

@ -242,9 +242,9 @@ class GhRepoScreen extends StatelessWidget {
items: [
if (ref != null)
TableViewItem(
leftIconData: Octicons.code,
text: Text(repo.primaryLanguage?.name ?? 'Code'),
rightWidget: Text(
prefixIconData: Octicons.code,
child: Text(repo.primaryLanguage?.name ?? 'Code'),
extra: Text(
(license == null ? '' : '$license') +
filesize(repo.diskUsage! * 1000),
),
@ -252,35 +252,33 @@ class GhRepoScreen extends StatelessWidget {
),
if (repo.hasIssuesEnabled)
TableViewItem(
leftIconData: Octicons.issue_opened,
text: Text(AppLocalizations.of(context)!.issues),
rightWidget:
Text(numberFormat.format(repo.issues.totalCount)),
prefixIconData: Octicons.issue_opened,
child: Text(AppLocalizations.of(context)!.issues),
extra: Text(numberFormat.format(repo.issues.totalCount)),
url: '/github/$owner/$name/issues',
),
TableViewItem(
leftIconData: Octicons.git_pull_request,
text: Text(AppLocalizations.of(context)!.pullRequests),
rightWidget:
prefixIconData: Octicons.git_pull_request,
child: Text(AppLocalizations.of(context)!.pullRequests),
extra:
Text(numberFormat.format(repo.pullRequests.totalCount)),
url: '/github/$owner/$name/pulls',
),
if (ref != null) ...[
TableViewItem(
leftIconData: Octicons.history,
text: Text(AppLocalizations.of(context)!.commits),
rightWidget: Text(
((ref.target as GRepoCommit).history.totalCount)
.toString()),
prefixIconData: Octicons.history,
child: Text(AppLocalizations.of(context)!.commits),
extra: Text(((ref.target as GRepoCommit).history.totalCount)
.toString()),
url: '/github/$owner/$name/commits/${ref.name}',
),
if (repo.refs != null)
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text(
prefixIconData: Octicons.git_branch,
child: Text(AppLocalizations.of(context)!.branches),
extra: Text(
'${ref.name}${numberFormat.format(repo.refs!.totalCount)}'),
onTap: () async {
onClick: () async {
final refs = repo.refs!.nodes!;
if (refs.length < 2) return;
@ -303,9 +301,9 @@ class GhRepoScreen extends StatelessWidget {
},
),
TableViewItem(
leftIconData: Octicons.organization,
text: Text(AppLocalizations.of(context)!.contributors),
rightWidget: FutureBuilder<int>(
prefixIconData: Octicons.organization,
child: Text(AppLocalizations.of(context)!.contributors),
extra: FutureBuilder<int>(
future: contributionFuture,
builder: (context, snapshot) {
return Text(snapshot.data?.toString() ?? '');
@ -314,10 +312,10 @@ class GhRepoScreen extends StatelessWidget {
url: '/github/$owner/$name/contributors',
),
TableViewItem(
leftIconData: Octicons.book,
text: Text(AppLocalizations.of(context)!.releases),
prefixIconData: Octicons.book,
child: Text(AppLocalizations.of(context)!.releases),
url: '/github/$owner/$name/releases',
rightWidget: Text(repo.releases.totalCount.toString()),
extra: Text(repo.releases.totalCount.toString()),
),
],
],

View File

@ -1,25 +1,25 @@
import 'package:ferry/ferry.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/S.dart';
import 'package:git_touch/graphql/__generated__/github.data.gql.dart';
import 'package:git_touch/graphql/__generated__/github.req.gql.dart';
import 'package:git_touch/graphql/__generated__/github.var.gql.dart';
import 'package:git_touch/models/auth.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_button.dart';
import 'package:git_touch/widgets/action_entry.dart';
import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/contribution.dart';
import 'package:git_touch/widgets/mutation_button.dart';
import 'package:git_touch/widgets/entry_item.dart';
import 'package:git_touch/widgets/mutation_button.dart';
import 'package:git_touch/widgets/repository_item.dart';
import 'package:git_touch/widgets/table_view.dart';
import 'package:git_touch/widgets/text_with_at.dart';
import 'package:git_touch/models/auth.dart';
import 'package:git_touch/widgets/user_header.dart';
import 'package:provider/provider.dart';
import 'package:git_touch/widgets/action_button.dart';
import 'package:flutter_gen/gen_l10n/S.dart';
class _Repos extends StatelessWidget {
final String title;
@ -120,24 +120,24 @@ class _User extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.rss,
text: Text(AppLocalizations.of(context)!.events),
prefixIconData: Octicons.rss,
child: Text(AppLocalizations.of(context)!.events),
url: '/github/$login?tab=events',
),
TableViewItem(
leftIconData: Octicons.book,
text: Text(AppLocalizations.of(context)!.gists),
prefixIconData: Octicons.book,
child: Text(AppLocalizations.of(context)!.gists),
url: '/github/$login?tab=gists',
),
TableViewItem(
leftIconData: Octicons.home,
text: Text(AppLocalizations.of(context)!.organizations),
prefixIconData: Octicons.home,
child: Text(AppLocalizations.of(context)!.organizations),
url: '/github/$login?tab=organizations',
),
if (isNotNullOrEmpty(p!.company))
TableViewItem(
leftIconData: Octicons.organization,
text: TextWithAt(
prefixIconData: Octicons.organization,
child: TextWithAt(
text: p!.company!,
linkFactory: (text) => '/github/${text.substring(1)}',
style: TextStyle(fontSize: 17, color: theme.palette.text),
@ -146,25 +146,26 @@ class _User extends StatelessWidget {
),
if (isNotNullOrEmpty(p!.location))
TableViewItem(
leftIconData: Octicons.location,
text: Text(p!.location!),
onTap: () {
launchStringUrl('https://www.google.com/maps/place/${p!.location!.replaceAll(RegExp(r'\s+'), '')}');
prefixIconData: Octicons.location,
child: Text(p!.location!),
onClick: () {
launchStringUrl(
'https://www.google.com/maps/place/${p!.location!.replaceAll(RegExp(r'\s+'), '')}');
},
),
if (isNotNullOrEmpty(p!.email))
TableViewItem(
leftIconData: Octicons.mail,
text: Text(p!.email),
onTap: () {
prefixIconData: Octicons.mail,
child: Text(p!.email),
onClick: () {
launchStringUrl('mailto:${p!.email}');
},
),
if (isNotNullOrEmpty(p!.websiteUrl))
TableViewItem(
leftIconData: Octicons.link,
text: Text(p!.websiteUrl!),
onTap: () {
prefixIconData: Octicons.link,
child: Text(p!.websiteUrl!),
onClick: () {
var url = p!.websiteUrl!;
if (!url.startsWith('http')) {
url = 'http://$url';
@ -217,31 +218,32 @@ class _Org extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.rss,
text: Text(AppLocalizations.of(context)!.events),
prefixIconData: Octicons.rss,
child: Text(AppLocalizations.of(context)!.events),
url: '/github/${p!.login}?tab=events',
),
if (isNotNullOrEmpty(p!.location))
TableViewItem(
leftIconData: Octicons.location,
text: Text(p!.location!),
onTap: () {
launchStringUrl('https://www.google.com/maps/place/${p!.location!.replaceAll(RegExp(r'\s+'), '')}');
prefixIconData: Octicons.location,
child: Text(p!.location!),
onClick: () {
launchStringUrl(
'https://www.google.com/maps/place/${p!.location!.replaceAll(RegExp(r'\s+'), '')}');
},
),
if (isNotNullOrEmpty(p!.email))
TableViewItem(
leftIconData: Octicons.mail,
text: Text(p!.email!),
onTap: () {
prefixIconData: Octicons.mail,
child: Text(p!.email!),
onClick: () {
launchStringUrl('mailto:${p!.email!}');
},
),
if (isNotNullOrEmpty(p!.websiteUrl))
TableViewItem(
leftIconData: Octicons.link,
text: Text(p!.websiteUrl!),
onTap: () {
prefixIconData: Octicons.link,
child: Text(p!.websiteUrl!),
onClick: () {
var url = p!.websiteUrl!;
if (!url.startsWith('http')) {
url = 'http://$url';

View File

@ -1,21 +1,21 @@
import 'package:filesize/filesize.dart';
import 'package:flutter/material.dart';
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/models/theme.dart';
import 'package:git_touch/scaffolds/refresh_stateful.dart';
import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/action_button.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/language_bar.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:git_touch/models/theme.dart';
import 'package:git_touch/widgets/action_button.dart';
import 'package:tuple/tuple.dart';
import 'package:flutter_gen/gen_l10n/S.dart';
class GlProjectScreen extends StatelessWidget {
final int id;
@ -158,8 +158,8 @@ class GlProjectScreen extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.code,
text: FutureBuilder<Map<String, double>>(
prefixIconData: Octicons.code,
child: FutureBuilder<Map<String, double>>(
future: langFuture,
builder: (context, snapshot) {
if (snapshot.data == null) {
@ -172,40 +172,39 @@ class GlProjectScreen extends StatelessWidget {
}
},
),
rightWidget: p.statistics == null
extra: p.statistics == null
? null
: Text(filesize(p.statistics!.repositorySize)),
url:
'/gitlab/projects/$id/tree/${branch ?? p.defaultBranch}',
url: '/gitlab/projects/$id/tree/${branch ?? p.defaultBranch}',
),
if (p.issuesEnabled!)
TableViewItem(
leftIconData: Octicons.issue_opened,
text: Text(AppLocalizations.of(context)!.issues),
rightWidget: Text(numberFormat.format(p.openIssuesCount)),
prefixIconData: Octicons.issue_opened,
child: Text(AppLocalizations.of(context)!.issues),
extra: Text(numberFormat.format(p.openIssuesCount)),
url: '/gitlab/projects/$id/issues?prefix=$prefix',
),
if (p.mergeRequestsEnabled!)
TableViewItem(
leftIconData: Octicons.git_pull_request,
text: Text(AppLocalizations.of(context)!.mergeRequests),
prefixIconData: Octicons.git_pull_request,
child: Text(AppLocalizations.of(context)!.mergeRequests),
url: '/gitlab/projects/$id/merge_requests?prefix=$prefix',
),
TableViewItem(
leftIconData: Octicons.history,
text: Text(AppLocalizations.of(context)!.commits),
rightWidget: p.statistics == null
prefixIconData: Octicons.history,
child: Text(AppLocalizations.of(context)!.commits),
extra: p.statistics == null
? null
: Text(p.statistics!.commitCount.toString()),
url:
'/gitlab/projects/$id/commits?prefix=$prefix&branch=${branch ?? p.defaultBranch}', // EDIT
),
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text(
prefixIconData: Octicons.git_branch,
child: Text(AppLocalizations.of(context)!.branches),
extra: Text(
'${(branch ?? p.defaultBranch) ?? ''}${branches.length}'),
onTap: () async {
onClick: () async {
if (branches.length < 2) return;
await theme.showPicker(

View File

@ -1,5 +1,7 @@
import 'dart:convert';
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/gogs.dart';
import 'package:git_touch/models/theme.dart';
@ -10,10 +12,9 @@ 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:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_gen/gen_l10n/S.dart';
class GoRepoScreen extends StatelessWidget {
final String owner;
@ -92,30 +93,31 @@ class GoRepoScreen extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.code,
text: const Text('Code'),
prefixIconData: Octicons.code,
child: const Text('Code'),
url: '/gogs/$owner/$name/blob?ref=${branch ?? 'master'}',
),
TableViewItem(
leftIconData: Octicons.issue_opened,
text: const Text('Issues'),
prefixIconData: Octicons.issue_opened,
child: const Text('Issues'),
url: '/gogs/$owner/$name/issues',
),
const TableViewItem(
leftIconData: Octicons.git_pull_request,
text: Text(
prefixIconData: Octicons.git_pull_request,
child: Text(
'Pull requests'), // TODO: when API endpoint is available
),
TableViewItem(
leftIconData: Octicons.history,
text: const Text('Commits'),
prefixIconData: Octicons.history,
child: const Text('Commits'),
url: '/gogs/$owner/$name/commits?ref=${branch ?? 'master'}',
),
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text('${branch ?? 'master'}${branches.length.toString()}'),
onTap: () async {
prefixIconData: Octicons.git_branch,
child: Text(AppLocalizations.of(context)!.branches),
extra: Text(
'${branch ?? 'master'}${branches.length.toString()}'),
onClick: () async {
await theme.showPicker(
context,
PickerGroupItem(

View File

@ -74,8 +74,8 @@ class GoUserScreen extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.home,
text: const Text('Organizations'),
prefixIconData: Octicons.home,
child: const Text('Organizations'),
url:
'/gogs/${user.username}?tab=organizations&isViewer=$isViewer',
),

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:filesize/filesize.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/gitea.dart';
import 'package:git_touch/scaffolds/refresh_stateful.dart';
@ -11,10 +12,9 @@ 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:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_gen/gen_l10n/S.dart';
class GtRepoScreen extends StatelessWidget {
final String owner;
@ -83,26 +83,26 @@ class GtRepoScreen extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.code,
text: const Text('Code'),
rightWidget: Text(filesize(p.size! * 1000)),
prefixIconData: Octicons.code,
child: const Text('Code'),
extra: Text(filesize(p.size! * 1000)),
url: '/gitea/$owner/$name/blob',
),
TableViewItem(
leftIconData: Octicons.issue_opened,
text: const Text('Issues'),
rightWidget: Text(numberFormat.format(p.openIssuesCount)),
prefixIconData: Octicons.issue_opened,
child: const Text('Issues'),
extra: Text(numberFormat.format(p.openIssuesCount)),
url: '/gitea/$owner/$name/issues',
),
TableViewItem(
leftIconData: Octicons.git_pull_request,
text: const Text('Pull requests'),
rightWidget: Text(numberFormat.format(p.openPrCounter)),
prefixIconData: Octicons.git_pull_request,
child: const Text('Pull requests'),
extra: Text(numberFormat.format(p.openPrCounter)),
url: '/gitea/$owner/$name/pulls',
),
TableViewItem(
leftIconData: Octicons.history,
text: const Text('Commits'),
prefixIconData: Octicons.history,
child: const Text('Commits'),
url: '/gitea/$owner/$name/commits',
),
],

View File

@ -133,8 +133,8 @@ class GtUserScreen extends StatelessWidget {
TableView(
items: [
TableViewItem(
leftIconData: Octicons.home,
text: const Text('Organizations'),
prefixIconData: Octicons.home,
child: const Text('Organizations'),
url: '/gitea/$login?tab=organizations',
),
],

View File

@ -26,100 +26,93 @@ class SettingsScreen extends StatelessWidget {
body: Column(
children: <Widget>[
CommonStyle.verticalGap,
TableView(
hasIcon: false,
headerText: AppLocalizations.of(context)!.system,
items: [
if (auth.activeAccount!.platform == PlatformType.github) ...[
TableViewItem(
text: Text(AppLocalizations.of(context)!.githubStatus),
url: 'https://www.githubstatus.com/',
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.reviewPermissions),
url:
'https://github.com/settings/connections/applications/$clientId',
rightWidget: Text(auth.activeAccount!.login),
),
],
if (auth.activeAccount!.platform == PlatformType.gitlab)
TableViewItem(
text: Text(AppLocalizations.of(context)!.gitlabStatus),
url: '${auth.activeAccount!.domain}/help',
rightWidget: FutureBuilder<String>(
future: auth
.fetchGitlab('/version')
.then((v) => v['version']),
builder: (context, snapshot) {
return Text(snapshot.data ?? '');
},
),
),
if (auth.activeAccount!.platform == PlatformType.gitea)
TableViewItem(
leftIconData: Octicons.info,
text: Text(AppLocalizations.of(context)!.giteaStatus),
url: '/gitea/status',
rightWidget: FutureBuilder<String>(
future:
auth.fetchGitea('/version').then((v) => v['version']),
builder: (context, snapshot) {
return Text(snapshot.data ?? '');
},
),
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.switchAccounts),
url: '/login',
rightWidget: Text(auth.activeAccount!.login),
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.appLanguage),
rightWidget: Text(theme.locale == null
? AppLocalizations.of(context)!.followSystem
: localeNameMap[theme.locale!] ?? theme.locale!),
onTap: () {
theme.showActions(context, [
for (final key in [
null,
...AppLocalizations.supportedLocales
.map((l) => l.toString())
.where((key) => localeNameMap[key] != null)
])
ActionItem(
text: key == null
? AppLocalizations.of(context)!.followSystem
: localeNameMap[key],
onTap: (_) async {
final res = await theme.showConfirm(
context,
const Text(
'The app will reload to make the language setting take effect'),
);
if (res == true && theme.locale != key) {
await theme.setLocale(key);
auth.reloadApp();
}
},
)
]);
TableView(header: Text(AppLocalizations.of(context)!.system), items: [
if (auth.activeAccount!.platform == PlatformType.github) ...[
TableViewItem(
child: Text(AppLocalizations.of(context)!.githubStatus),
url: 'https://www.githubstatus.com/',
),
TableViewItem(
child: Text(AppLocalizations.of(context)!.reviewPermissions),
url:
'https://github.com/settings/connections/applications/$clientId',
extra: Text(auth.activeAccount!.login),
),
],
if (auth.activeAccount!.platform == PlatformType.gitlab)
TableViewItem(
child: Text(AppLocalizations.of(context)!.gitlabStatus),
url: '${auth.activeAccount!.domain}/help',
extra: FutureBuilder<String>(
future:
auth.fetchGitlab('/version').then((v) => v['version']),
builder: (context, snapshot) {
return Text(snapshot.data ?? '');
},
)
]),
),
),
if (auth.activeAccount!.platform == PlatformType.gitea)
TableViewItem(
prefixIconData: Octicons.info,
child: Text(AppLocalizations.of(context)!.giteaStatus),
url: '/gitea/status',
extra: FutureBuilder<String>(
future: auth.fetchGitea('/version').then((v) => v['version']),
builder: (context, snapshot) {
return Text(snapshot.data ?? '');
},
),
),
TableViewItem(
child: Text(AppLocalizations.of(context)!.switchAccounts),
url: '/login',
extra: Text(auth.activeAccount!.login),
),
TableViewItem(
child: Text(AppLocalizations.of(context)!.appLanguage),
extra: Text(theme.locale == null
? AppLocalizations.of(context)!.followSystem
: localeNameMap[theme.locale!] ?? theme.locale!),
onClick: () {
theme.showActions(context, [
for (final key in [
null,
...AppLocalizations.supportedLocales
.map((l) => l.toString())
.where((key) => localeNameMap[key] != null)
])
ActionItem(
text: key == null
? AppLocalizations.of(context)!.followSystem
: localeNameMap[key],
onTap: (_) async {
final res = await theme.showConfirm(
context,
const Text(
'The app will reload to make the language setting take effect'),
);
if (res == true && theme.locale != key) {
await theme.setLocale(key);
auth.reloadApp();
}
},
)
]);
},
)
]),
CommonStyle.verticalGap,
TableView(
hasIcon: false,
headerText: AppLocalizations.of(context)!.theme,
header: Text(AppLocalizations.of(context)!.theme),
items: [
TableViewItem(
text: Text(AppLocalizations.of(context)!.brightness),
rightWidget:
Text(theme.brighnessValue == AppBrightnessType.light
? AppLocalizations.of(context)!.light
: theme.brighnessValue == AppBrightnessType.dark
? AppLocalizations.of(context)!.dark
: AppLocalizations.of(context)!.followSystem),
onTap: () {
child: Text(AppLocalizations.of(context)!.brightness),
extra: Text(theme.brighnessValue == AppBrightnessType.light
? AppLocalizations.of(context)!.light
: theme.brighnessValue == AppBrightnessType.dark
? AppLocalizations.of(context)!.dark
: AppLocalizations.of(context)!.followSystem),
onClick: () {
theme.showActions(context, [
for (var t in [
Tuple2(AppLocalizations.of(context)!.followSystem,
@ -141,11 +134,11 @@ class SettingsScreen extends StatelessWidget {
},
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.scaffoldTheme),
rightWidget: Text(theme.theme == AppThemeType.cupertino
child: Text(AppLocalizations.of(context)!.scaffoldTheme),
extra: Text(theme.theme == AppThemeType.cupertino
? AppLocalizations.of(context)!.cupertino
: AppLocalizations.of(context)!.material),
onTap: () {
onClick: () {
theme.showActions(context, [
for (var t in [
Tuple2(AppLocalizations.of(context)!.material,
@ -165,16 +158,16 @@ class SettingsScreen extends StatelessWidget {
},
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.codeTheme),
child: Text(AppLocalizations.of(context)!.codeTheme),
url: '/choose-code-theme',
rightWidget: Text('${code.fontFamily}, ${code.fontSize}pt'),
extra: Text('${code.fontFamily}, ${code.fontSize}pt'),
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.markdownRenderEngine),
rightWidget: Text(theme.markdown == AppMarkdownType.flutter
child: Text(AppLocalizations.of(context)!.markdownRenderEngine),
extra: Text(theme.markdown == AppMarkdownType.flutter
? AppLocalizations.of(context)!.flutter
: AppLocalizations.of(context)!.webview),
onTap: () {
onClick: () {
theme.showActions(context, [
for (var t in [
Tuple2(AppLocalizations.of(context)!.flutter,
@ -197,18 +190,17 @@ class SettingsScreen extends StatelessWidget {
),
CommonStyle.verticalGap,
TableView(
hasIcon: false,
headerText: AppLocalizations.of(context)!.feedback,
header: Text(AppLocalizations.of(context)!.feedback),
items: [
TableViewItem(
text: Text(AppLocalizations.of(context)!.submitAnIssue),
rightWidget: const Text('git-touch/git-touch'),
child: Text(AppLocalizations.of(context)!.submitAnIssue),
extra: const Text('git-touch/git-touch'),
url:
'${auth.activeAccount!.platform == PlatformType.github ? '/github' : 'https://github.com'}/git-touch/git-touch/issues/new',
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.rateThisApp),
onTap: () {
child: Text(AppLocalizations.of(context)!.rateThisApp),
onClick: () {
LaunchReview.launch(
androidAppId: 'io.github.pd4d10.gittouch',
iOSAppId: '1452042346',
@ -216,8 +208,8 @@ class SettingsScreen extends StatelessWidget {
},
),
TableViewItem(
text: Text(AppLocalizations.of(context)!.email),
rightWidget: const Text('pd4d10@gmail.com'),
child: Text(AppLocalizations.of(context)!.email),
extra: const Text('pd4d10@gmail.com'),
hideRightChevron: true,
url: 'mailto:pd4d10@gmail.com',
),
@ -225,12 +217,11 @@ class SettingsScreen extends StatelessWidget {
),
CommonStyle.verticalGap,
TableView(
hasIcon: false,
headerText: AppLocalizations.of(context)!.about,
header: Text(AppLocalizations.of(context)!.about),
items: [
TableViewItem(
text: Text(AppLocalizations.of(context)!.version),
rightWidget: FutureBuilder<String>(
child: Text(AppLocalizations.of(context)!.version),
extra: FutureBuilder<String>(
future:
PackageInfo.fromPlatform().then((info) => info.version),
builder: (context, snapshot) {
@ -238,8 +229,8 @@ class SettingsScreen extends StatelessWidget {
},
)),
TableViewItem(
text: Text(AppLocalizations.of(context)!.sourceCode),
rightWidget: const Text('git-touch/git-touch'),
child: Text(AppLocalizations.of(context)!.sourceCode),
extra: const Text('git-touch/git-touch'),
url:
'${auth.activeAccount!.platform == PlatformType.github ? '/github' : 'https://github.com'}/git-touch/git-touch',
),

View File

@ -5,9 +5,10 @@ import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/theme.dart';
import 'package:git_touch/widgets/action_button.dart';
import 'package:git_touch/widgets/markdown_view.dart';
import 'package:primer/primer.dart';
import 'package:provider/provider.dart';
import 'package:timeago/timeago.dart' as timeago;
import 'package:primer/primer.dart';
import '../utils/utils.dart';
import 'avatar.dart';
import 'link.dart';

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:git_touch/models/theme.dart';
import 'package:provider/provider.dart';
// TODO:
class CupertinoLink extends StatefulWidget {

View File

@ -38,9 +38,9 @@ TableViewItem createObjectTreeItem({
int? size,
}) {
return TableViewItem(
leftWidget: _buildIcon(type, name),
text: Text(name),
rightWidget: size == null ? null : Text(filesize(size)),
prefix: _buildIcon(type, name),
child: Text(name),
extra: size == null ? null : Text(filesize(size)),
url: [
// Let system browser handle these files
//

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/S.dart';
import 'package:git_touch/graphql/__generated__/github.data.gql.dart';
import 'package:git_touch/models/theme.dart';
import 'package:git_touch/utils/utils.dart';
@ -7,7 +8,6 @@ import 'package:git_touch/widgets/markdown_view.dart';
import 'package:git_touch/widgets/table_view.dart';
import 'package:provider/provider.dart';
import 'package:timeago/timeago.dart' as timeago;
import 'package:flutter_gen/gen_l10n/S.dart';
class ReleaseItem extends StatelessWidget {
final String? login;
@ -61,7 +61,8 @@ class ReleaseItem extends StatelessWidget {
color: theme.palette.secondaryText,
fontSize: 16,
),
child: Text("${login!} ${AppLocalizations.of(context)!.released} ${timeago.format(publishedAt!)}"),
child: Text(
"${login!} ${AppLocalizations.of(context)!.released} ${timeago.format(publishedAt!)}"),
),
],
),
@ -87,12 +88,11 @@ class ReleaseItem extends StatelessWidget {
),
children: <Widget>[
TableView(
hasIcon: false,
items: [
if (releaseAssets != null)
for (var asset in releaseAssets!.nodes!)
TableViewItem(
text: Text(
child: Text(
asset.name,
style: TextStyle(
color: theme.palette.primary,
@ -100,7 +100,7 @@ class ReleaseItem extends StatelessWidget {
fontWeight: FontWeight.w400,
),
),
rightWidget: IconButton(
extra: IconButton(
onPressed: () {
theme.push(context, asset.downloadUrl);
},

View File

@ -1,8 +1,8 @@
import 'package:antd_mobile/antd_mobile.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';
@ -25,23 +25,23 @@ class TableViewHeader extends StatelessWidget {
}
class TableViewItem {
final Widget text;
final IconData? leftIconData;
final Widget? leftWidget;
final Widget? rightWidget;
final void Function()? onTap;
final Widget child;
final IconData? prefixIconData;
final Widget? prefix;
final Widget? extra;
final void Function()? onClick;
final String? url;
final bool hideRightChevron;
const TableViewItem({
required this.text,
this.leftIconData,
this.leftWidget,
this.rightWidget,
this.onTap,
required this.child,
this.prefixIconData,
this.prefix,
this.extra,
this.onClick,
this.url,
this.hideRightChevron = false,
}) : assert(leftIconData == null || leftWidget == null);
}) : assert(prefixIconData == null || prefix == null);
}
class TableViewItemWidget extends StatelessWidget {
@ -54,7 +54,7 @@ class TableViewItemWidget extends StatelessWidget {
final theme = Provider.of<ThemeModel>(context);
return LinkWidget(
onTap: item.onTap,
onTap: item.onClick,
url: item.url,
child: DefaultTextStyle(
style: TextStyle(fontSize: 17, color: theme.palette.text),
@ -64,29 +64,29 @@ class TableViewItemWidget extends StatelessWidget {
child: Row(
children: [
SizedBox(
width: (item.leftWidget == null && item.leftIconData == null)
width: (item.prefix == null && item.prefixIconData == null)
? 12
: 44,
child: Center(
child: item.leftWidget ??
child: item.prefix ??
Icon(
item.leftIconData,
item.prefixIconData,
color: theme.palette.primary,
size: 20,
)),
),
Expanded(child: item.text),
if (item.rightWidget != null) ...[
Expanded(child: item.child),
if (item.extra != null) ...[
DefaultTextStyle(
style: TextStyle(
fontSize: 17,
color: theme.palette.tertiaryText,
),
child: item.rightWidget!,
child: item.extra!,
),
const SizedBox(width: 6)
],
if ((item.onTap != null || item.url != null) &&
if ((item.onClick != null || item.url != null) &&
!item.hideRightChevron)
Icon(Ionicons.chevron_forward,
size: 20, color: theme.palette.tertiaryText)
@ -102,30 +102,38 @@ class TableViewItemWidget extends StatelessWidget {
}
class TableView extends StatelessWidget {
final String? headerText;
final Widget? header;
final Iterable<TableViewItem> items;
final bool? hasIcon;
const TableView({
super.key,
this.headerText,
this.header,
required this.items,
this.hasIcon = true,
});
double get _leftPadding => hasIcon == true ? 44 : 12;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (headerText != null) TableViewHeader(headerText),
...join(
BorderView(leftPadding: _leftPadding),
[for (final item in items) TableViewItemWidget(item)],
),
CommonStyle.border,
final theme = Provider.of<ThemeModel>(context);
return AntList(
header: header,
items: [
for (final item in items)
AntListItem(
child: item.child,
prefix: item.prefix ??
(item.prefixIconData == null
? null
: Icon(item.prefixIconData)),
extra: item.extra,
onClick: item.onClick != null
? item.onClick!
: item.url != null
? () {
theme.push(context, item.url!);
}
: null,
),
],
);
}