refactor: using path for router

This commit is contained in:
Rongjian Zhang 2019-12-12 20:29:56 +08:00
parent 8097eb3bb4
commit 2400513007
22 changed files with 148 additions and 157 deletions

View File

@ -3,16 +3,21 @@ import 'package:flutter/cupertino.dart';
import 'package:git_touch/models/code.dart'; import 'package:git_touch/models/code.dart';
import 'package:git_touch/models/auth.dart'; import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/screens/commits.dart';
import 'package:git_touch/screens/credits.dart';
import 'package:git_touch/screens/gitlab_todos.dart'; import 'package:git_touch/screens/gitlab_todos.dart';
import 'package:git_touch/screens/gitlab_user.dart'; import 'package:git_touch/screens/gitlab_user.dart';
import 'package:git_touch/screens/issue_form.dart';
import 'package:git_touch/screens/issues.dart'; import 'package:git_touch/screens/issues.dart';
import 'package:git_touch/screens/notification.dart'; import 'package:git_touch/screens/notification.dart';
import 'package:git_touch/screens/object.dart';
import 'package:git_touch/screens/repository.dart'; import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/screens/repositories.dart'; import 'package:git_touch/screens/repositories.dart';
import 'package:git_touch/screens/user.dart'; import 'package:git_touch/screens/user.dart';
import 'package:primer/primer.dart'; import 'package:primer/primer.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:git_touch/models/notification.dart'; import 'package:git_touch/models/notification.dart';
import 'package:fluro/fluro.dart';
import 'screens/news.dart'; import 'screens/news.dart';
import 'screens/search.dart'; import 'screens/search.dart';
import 'screens/login.dart'; import 'screens/login.dart';
@ -132,30 +137,30 @@ class _HomeState extends State<Home> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final authModel = Provider.of<AuthModel>(context); final auth = Provider.of<AuthModel>(context);
final themeModel = Provider.of<ThemeModel>(context); final theme = Provider.of<ThemeModel>(context);
final themData = ThemeData( final themData = ThemeData(
brightness: themeModel.brightness, brightness: theme.brightness,
primaryColor: PrimerColors.white, primaryColor: PrimerColors.white,
accentColor: PrimerColors.blue500, accentColor: PrimerColors.blue500,
); );
// TODO: // TODO:
if (!authModel.ready || !Provider.of<ThemeModel>(context).ready) { if (!auth.ready || !Provider.of<ThemeModel>(context).ready) {
return MaterialApp(theme: themData, home: Scaffold(body: Text('a'))); return MaterialApp(theme: themData, home: Scaffold(body: Text('a')));
} }
// Fimber.d(settings.activeLogin); // Fimber.d(settings.activeLogin);
if (authModel.activeAccount == null) { if (auth.activeAccount == null) {
return MaterialApp(theme: themData, home: LoginScreen()); return MaterialApp(theme: themData, home: LoginScreen());
} }
switch (themeModel.theme) { switch (theme.theme) {
case AppThemeType.cupertino: case AppThemeType.cupertino:
return CupertinoApp( return CupertinoApp(
theme: CupertinoThemeData( theme: CupertinoThemeData(
brightness: themeModel.brightness, brightness: theme.brightness,
primaryColor: PrimerColors.blue500, primaryColor: PrimerColors.blue500,
), ),
home: CupertinoTabScaffold( home: CupertinoTabScaffold(
@ -223,6 +228,71 @@ void main() async {
codeModel.init(), codeModel.init(),
]); ]);
// TODO: gitlab
themeModel.router.define('/login', handler: Handler(
handlerFunc: (context, params) {
return LoginScreen();
},
));
themeModel.router.define('/help/credits', handler: Handler(
handlerFunc: (context, params) {
return CreditsScreen();
},
));
themeModel.router.define('/:login', handler: Handler(
handlerFunc: (context, params) {
return UserScreen(params['login'][0]);
},
));
themeModel.router.define('/:owner/:name', handler: Handler(
handlerFunc: (context, params) {
return RepositoryScreen(params['owner'][0], params['name'][0]);
},
));
themeModel.router.define('/:owner/:name/issues', handler: Handler(
handlerFunc: (context, params) {
return IssuesScreen(params['owner'][0], params['name'][0]);
},
));
themeModel.router.define('/:owner/:name/pulls', handler: Handler(
handlerFunc: (context, params) {
return IssuesScreen(params['owner'][0], params['name'][0],
isPullRequest: true);
},
));
themeModel.router.define('/:owner/:name/issues/:number', handler: Handler(
handlerFunc: (context, params) {
return IssueScreen(params['owner'][0], params['name'][0],
int.parse(params['number'][0]));
},
));
themeModel.router.define('/:owner/:name/pulls/:number', handler: Handler(
handlerFunc: (context, params) {
return IssueScreen(
params['owner'][0],
params['name'][0],
int.parse(params['number'][0]),
isPullRequest: true,
);
},
));
themeModel.router.define('/:owner/:name/commits', handler: Handler(
handlerFunc: (context, params) {
return CommitsScreen(params['owner'][0], params['name'][0]);
},
));
themeModel.router.define('/:owner/:name/blob/:ref', handler: Handler(
handlerFunc: (context, params) {
return ObjectScreen(
params['owner'][0], params['name'][0], params['ref'][0]);
},
));
themeModel.router.define('/:owner/:name/issues/new', handler: Handler(
handlerFunc: (context, params) {
return IssueFormScreen(params['owner'][0], params['name'][0]);
},
));
runApp(MultiProvider( runApp(MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (context) => notificationModel), ChangeNotifierProvider(create: (context) => notificationModel),

View File

@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'dart:async'; import 'dart:async';
import 'package:fimber/fimber.dart'; import 'package:fimber/fimber.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/widgets/action_button.dart'; import 'package:git_touch/widgets/action_button.dart';
@ -98,6 +99,8 @@ class ThemeModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
final router = Router();
Palette get palette { Palette get palette {
switch (brightness) { switch (brightness) {
case Brightness.light: case Brightness.light:
@ -149,6 +152,13 @@ class ThemeModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
push(BuildContext context, String path) {
return router.navigateTo(context, path,
transition: theme == AppThemeType.cupertino
? TransitionType.cupertino
: TransitionType.material);
}
pushRoute( pushRoute(
BuildContext context, BuildContext context,
WidgetBuilder builder, { WidgetBuilder builder, {

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/scaffolds/single.dart'; import 'package:git_touch/scaffolds/single.dart';
import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/table_view.dart'; import 'package:git_touch/widgets/table_view.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
@ -48,22 +47,14 @@ class CreditsScreen extends StatelessWidget {
TableView( TableView(
headerText: 'packages', headerText: 'packages',
items: projects.map((t) { items: projects.map((t) {
return TableViewItem( return TableViewItem(text: Text(t.item1), url: t.item2);
text: Text(t.item1),
screenBuilder: (_) {
final repo = parseRepositoryFullName(t.item2);
return RepositoryScreen(repo.item1, repo.item2);
});
}), }),
), ),
CommonStyle.verticalGap, CommonStyle.verticalGap,
TableView( TableView(
headerText: 'fonts', headerText: 'fonts',
items: fonts.map((font) { items: fonts.map((font) {
return TableViewItem( return TableViewItem(text: Text(font), url: '/google/fonts');
text: Text(font),
screenBuilder: (_) => RepositoryScreen('google', 'fonts'),
);
}), }),
), ),
], ],

View File

@ -3,7 +3,6 @@ import 'package:flutter/cupertino.dart';
import 'package:git_touch/models/auth.dart'; import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/gitlab.dart'; import 'package:git_touch/models/gitlab.dart';
import 'package:git_touch/scaffolds/refresh_stateful.dart'; import 'package:git_touch/scaffolds/refresh_stateful.dart';
import 'package:git_touch/screens/gitlab_tree.dart';
import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/app_bar_title.dart'; import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/entry_item.dart'; import 'package:git_touch/widgets/entry_item.dart';
@ -70,7 +69,6 @@ class GitlabProjectScreen extends StatelessWidget {
data.forksCount, data.forksCount,
data.languages.keys.first, data.languages.keys.first,
null, null,
null,
[], [],
inRepoScreen: true), inRepoScreen: true),
CommonStyle.border, CommonStyle.border,
@ -116,7 +114,7 @@ class GitlabProjectScreen extends StatelessWidget {
TableViewItem( TableViewItem(
leftIconData: Octicons.code, leftIconData: Octicons.code,
text: Text('Code'), text: Text('Code'),
screenBuilder: (_) => GitlabTreeScreen(data.id), url: '/tree/$id',
), ),
if (data.issuesEnabled) if (data.issuesEnabled)
TableViewItem( TableViewItem(

View File

@ -1,7 +1,6 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:git_touch/models/gitlab.dart'; import 'package:git_touch/models/gitlab.dart';
import 'package:git_touch/scaffolds/refresh_stateful.dart'; import 'package:git_touch/scaffolds/refresh_stateful.dart';
import 'package:git_touch/screens/gitlab_blob.dart';
import 'package:git_touch/widgets/app_bar_title.dart'; import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/table_view.dart'; import 'package:git_touch/widgets/table_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -56,16 +55,16 @@ class GitlabTreeScreen extends StatelessWidget {
return TableViewItem( return TableViewItem(
leftWidget: _buildIcon(item), leftWidget: _buildIcon(item),
text: Text(item.name), text: Text(item.name),
screenBuilder: (_) { url: (() {
switch (item.type) { switch (item.type) {
case 'tree': case 'tree':
return GitlabTreeScreen(id, path: item.path); return '/tree/$id?path=${item.path}';
case 'blob': case 'blob':
return GitlabBlobScreen(id, item.path); return '/blob/$id?path=${item.path}';
default: default:
return null; return null;
} }
}, })(),
); );
}), }),
); );

View File

@ -122,15 +122,11 @@ class ObjectScreen extends StatelessWidget {
return TableViewItem( return TableViewItem(
leftWidget: _buildIcon(item), leftWidget: _buildIcon(item),
text: Text(item.name), text: Text(item.name),
screenBuilder: (_) { url: (() {
if (item.type == 'commit') return null; if (item.type == 'commit') return null;
return ObjectScreen( final p = [...paths, item.name].join('/');
owner, return '/$owner/$name/blob/$branch?path=$p';
name, })(),
branch,
paths: [...paths, item.name],
);
},
); );
}), }),
); );

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/graphql/github_repositories.dart'; import 'package:git_touch/graphql/github_repositories.dart';
import 'package:git_touch/scaffolds/list_stateful.dart'; import 'package:git_touch/scaffolds/list_stateful.dart';
import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/app_bar_title.dart'; import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/models/auth.dart'; import 'package:git_touch/models/auth.dart';
@ -74,7 +73,6 @@ class RepositoriesScreen extends StatelessWidget {
item.forks.totalCount, item.forks.totalCount,
item.primaryLanguage?.name, item.primaryLanguage?.name,
item.primaryLanguage?.color, item.primaryLanguage?.color,
(_) => RepositoryScreen(item.owner.login, item.name),
[], [],
); );
}); });

View File

@ -12,12 +12,9 @@ import 'package:git_touch/widgets/markdown_view.dart';
import 'package:git_touch/widgets/table_view.dart'; import 'package:git_touch/widgets/table_view.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/screens/commits.dart';
import 'package:git_touch/screens/object.dart';
import 'package:git_touch/widgets/repository_item.dart'; import 'package:git_touch/widgets/repository_item.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
import '../widgets/entry_item.dart'; import '../widgets/entry_item.dart';
import '../screens/issues.dart';
import 'package:git_touch/widgets/action_button.dart'; import 'package:git_touch/widgets/action_button.dart';
class RepositoryScreen extends StatelessWidget { class RepositoryScreen extends StatelessWidget {
@ -134,7 +131,6 @@ class RepositoryScreen extends StatelessWidget {
repo.forks.totalCount, repo.forks.totalCount,
repo.primaryLanguage?.name, repo.primaryLanguage?.name,
repo.primaryLanguage?.color, repo.primaryLanguage?.color,
null,
repo.repositoryTopics.nodes, repo.repositoryTopics.nodes,
inRepoScreen: true), inRepoScreen: true),
CommonStyle.border, CommonStyle.border,
@ -192,11 +188,7 @@ class RepositoryScreen extends StatelessWidget {
leftIconData: Octicons.code, leftIconData: Octicons.code,
text: Text('Code'), text: Text('Code'),
rightWidget: Text(filesize(repo.diskUsage * 1000)), rightWidget: Text(filesize(repo.diskUsage * 1000)),
screenBuilder: (_) => ObjectScreen( url: '/$owner/$name/blob/${ref.name}',
owner,
name,
ref.name,
),
), ),
if (repo.hasIssuesEnabled) if (repo.hasIssuesEnabled)
TableViewItem( TableViewItem(
@ -204,15 +196,14 @@ class RepositoryScreen extends StatelessWidget {
text: Text('Issues'), text: Text('Issues'),
rightWidget: rightWidget:
Text(numberFormat.format(repo.issues.totalCount)), Text(numberFormat.format(repo.issues.totalCount)),
screenBuilder: (_) => IssuesScreen(owner, name), url: '/$owner/$name/issues',
), ),
TableViewItem( TableViewItem(
leftIconData: Octicons.git_pull_request, leftIconData: Octicons.git_pull_request,
text: Text('Pull requests'), text: Text('Pull requests'),
rightWidget: rightWidget:
Text(numberFormat.format(repo.pullRequests.totalCount)), Text(numberFormat.format(repo.pullRequests.totalCount)),
screenBuilder: (_) => url: '/$owner/$name/pulls',
IssuesScreen(owner, name, isPullRequest: true),
), ),
TableViewItem( TableViewItem(
leftIconData: Octicons.project, leftIconData: Octicons.project,
@ -238,8 +229,7 @@ class RepositoryScreen extends StatelessWidget {
?.totalCount, ?.totalCount,
), ),
), ),
screenBuilder: (_) => url: '/$owner/$name/commits',
CommitsScreen(owner, name, branch: branch),
), ),
if (repo.refs != null) if (repo.refs != null)
TableViewItem( TableViewItem(

View File

@ -2,9 +2,6 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/scaffolds/single.dart'; import 'package:git_touch/scaffolds/single.dart';
import 'package:git_touch/screens/credits.dart';
import 'package:git_touch/screens/issue_form.dart';
import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/app_bar_title.dart'; import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -30,7 +27,7 @@ class SettingsScreen extends StatelessWidget {
TableView(headerText: 'ACCOUNTS', items: [ TableView(headerText: 'ACCOUNTS', items: [
TableViewItem( TableViewItem(
text: Text('Switch to another account'), text: Text('Switch to another account'),
screenBuilder: (_) => LoginScreen(), url: '/login',
), ),
]), ]),
CommonStyle.verticalGap, CommonStyle.verticalGap,
@ -60,18 +57,10 @@ class SettingsScreen extends StatelessWidget {
]), ]),
CommonStyle.verticalGap, CommonStyle.verticalGap,
TableView(headerText: 'ABOUT', items: [ TableView(headerText: 'ABOUT', items: [
TableViewItem(text: Text('Source Code'), url: '/pd4d10/git-touch'),
TableViewItem( TableViewItem(
text: Text('Source Code'), text: Text('Feedback'), url: '/pd4d10/git-touch/issues/new'),
screenBuilder: (_) => RepositoryScreen('pd4d10', 'git-touch'), TableViewItem(text: Text('Credits'), url: '/help/credits'),
),
TableViewItem(
text: Text('Feedback'),
screenBuilder: (_) => IssueFormScreen('pd4d10', 'git-touch'),
),
TableViewItem(
text: Text('Credits'),
screenBuilder: (_) => CreditsScreen(),
),
TableViewItem( TableViewItem(
text: Text('Rate This App'), text: Text('Rate This App'),
onTap: () { onTap: () {

View File

@ -2,7 +2,6 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/models/github.dart'; import 'package:git_touch/models/github.dart';
import 'package:git_touch/scaffolds/tab_stateful.dart'; import 'package:git_touch/scaffolds/tab_stateful.dart';
import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/app_bar_title.dart'; import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/user_item.dart'; import 'package:git_touch/widgets/user_item.dart';
@ -39,7 +38,6 @@ class TrendingScreen extends StatelessWidget {
item.forks ?? 0, item.forks ?? 0,
item.language, item.language,
item.languageColor, item.languageColor,
(_) => RepositoryScreen(item.author, item.name),
[], [],
); );
case 1: case 1:

View File

@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/screens/user.dart';
import 'package:git_touch/widgets/border_view.dart'; import 'package:git_touch/widgets/border_view.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:primer/primer.dart'; import 'package:primer/primer.dart';
@ -59,7 +58,7 @@ void nextTick(Function callback, [int milliseconds = 0]) {
TextSpan createLinkSpan( TextSpan createLinkSpan(
BuildContext context, BuildContext context,
String text, String text,
Widget Function(BuildContext) builder, String url,
) { ) {
return TextSpan( return TextSpan(
text: text, text: text,
@ -69,13 +68,13 @@ TextSpan createLinkSpan(
), ),
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()
..onTap = () { ..onTap = () {
Provider.of<ThemeModel>(context).pushRoute(context, builder); Provider.of<ThemeModel>(context).push(context, url);
}, },
); );
} }
TextSpan createUserSpan(BuildContext context, String login) { TextSpan createUserSpan(BuildContext context, String login) {
return createLinkSpan(context, login, (_) => UserScreen(login)); return createLinkSpan(context, login, '/$login');
} }
Tuple2<String, String> parseRepositoryFullName(String fullName) { Tuple2<String, String> parseRepositoryFullName(String fullName) {

View File

@ -1,8 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:git_touch/screens/issue.dart';
import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/screens/user.dart';
import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/utils/utils.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
@ -32,23 +29,24 @@ class ActionItem {
ActionItem.user(String login) ActionItem.user(String login)
: text = '@$login', : text = '@$login',
onPress = ((context) { onPress = ((context) {
Provider.of<ThemeModel>(context) Provider.of<ThemeModel>(context).push(context, '/$login');
.pushRoute(context, (_) => UserScreen(login));
}); });
ActionItem.repository(String owner, String name) ActionItem.repository(String owner, String name)
: text = '$owner/$name', : text = '$owner/$name',
onPress = ((context) { onPress = ((context) {
Provider.of<ThemeModel>(context) Provider.of<ThemeModel>(context).push(context, '/$owner/$name');
.pushRoute(context, (_) => RepositoryScreen(owner, name));
}); });
ActionItem.issue(String owner, String name, int number, ActionItem.issue(String owner, String name, int number)
{isPullRequest = false})
: text = '$owner/$name #$number', : text = '$owner/$name #$number',
onPress = ((context) { onPress = ((context) {
Provider.of<ThemeModel>(context).pushRoute( Provider.of<ThemeModel>(context)
context, .push(context, '/$owner/$name/issues/$number');
(_) => IssueScreen(owner, name, number, });
isPullRequest: isPullRequest)); ActionItem.pullRequest(String owner, String name, int number)
: text = '$owner/$name #$number',
onPress = ((context) {
Provider.of<ThemeModel>(context)
.push(context, '/$owner/$name/pulls/$number');
}); });
} }

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/screens/user.dart';
import 'package:git_touch/widgets/markdown_view.dart'; import 'package:git_touch/widgets/markdown_view.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:timeago/timeago.dart' as timeago; import 'package:timeago/timeago.dart' as timeago;
@ -47,8 +46,8 @@ class CommentItem extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Row(children: <Widget>[ Row(children: <Widget>[
Link( Link(
url: '/' + payload['author']['login'],
child: Avatar.medium(url: payload['author']['avatarUrl']), child: Avatar.medium(url: payload['author']['avatarUrl']),
screenBuilder: (_) => UserScreen(payload['author']['login']),
), ),
SizedBox(width: 8), SizedBox(width: 8),
Expanded( Expanded(

View File

@ -2,12 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:git_touch/models/github.dart'; import 'package:git_touch/models/github.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/widgets/action_button.dart'; import 'package:git_touch/widgets/action_button.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:timeago/timeago.dart' as timeago; import 'package:timeago/timeago.dart' as timeago;
import '../screens/issue.dart';
import '../screens/user.dart';
import 'avatar.dart'; import 'avatar.dart';
import '../widgets/link.dart'; import '../widgets/link.dart';
import '../utils/utils.dart'; import '../utils/utils.dart';
@ -43,7 +40,6 @@ class EventItem extends StatelessWidget {
String detail, String detail,
Widget detailWidget, Widget detailWidget,
IconData iconData = Octicons.octoface, IconData iconData = Octicons.octoface,
WidgetBuilder screenBuilder,
String url, String url,
List<ActionItem> actionItems, List<ActionItem> actionItems,
}) { }) {
@ -55,7 +51,6 @@ class EventItem extends StatelessWidget {
} }
return Link( return Link(
screenBuilder: screenBuilder,
url: url, url: url,
child: Container( child: Container(
padding: CommonStyle.padding, padding: CommonStyle.padding,
@ -66,8 +61,8 @@ class EventItem extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Link( Link(
url: '/' + event.actor.login,
child: Avatar.medium(url: event.actor.avatarUrl), child: Avatar.medium(url: event.actor.avatarUrl),
screenBuilder: (_) => UserScreen(event.actor.login),
), ),
SizedBox(width: 10), SizedBox(width: 10),
Expanded( Expanded(
@ -170,7 +165,7 @@ class EventItem extends StatelessWidget {
_buildRepo(theme), _buildRepo(theme),
], ],
iconData: Octicons.repo_forked, iconData: Octicons.repo_forked,
screenBuilder: (_) => RepositoryScreen(forkeeOwner, forkeeName), url: '/$forkeeOwner/$forkeeName',
actionItems: [ actionItems: [
..._getUserActions([event.actor.login, forkeeOwner]), ..._getUserActions([event.actor.login, forkeeOwner]),
ActionItem.repository(forkeeOwner, forkeeName), ActionItem.repository(forkeeOwner, forkeeName),
@ -201,16 +196,11 @@ class EventItem extends StatelessWidget {
], ],
detail: event.payload['comment']['body'], detail: event.payload['comment']['body'],
iconData: Octicons.comment_discussion, iconData: Octicons.comment_discussion,
screenBuilder: (_) => IssueScreen( url:
event.repoOwner, '/${event.repoOwner}/${event.repoName}/${isPullRequest ? 'pulls' : 'issues'}/$number',
event.repoName,
number,
isPullRequest: isPullRequest,
),
actionItems: [ actionItems: [
..._getUserActions([event.actor.login, event.repoOwner]), ..._getUserActions([event.actor.login, event.repoOwner]),
ActionItem.issue(event.repoOwner, event.repoName, number, ActionItem.pullRequest(event.repoOwner, event.repoName, number),
isPullRequest: isPullRequest),
], ],
); );
case 'IssuesEvent': case 'IssuesEvent':
@ -227,8 +217,7 @@ class EventItem extends StatelessWidget {
], ],
iconData: Octicons.issue_opened, iconData: Octicons.issue_opened,
detail: event.payload['issue']['title'], detail: event.payload['issue']['title'],
screenBuilder: (_) => url: '/${event.repoOwner}/${event.repoName}/issues/$number',
IssueScreen(event.repoOwner, event.repoName, number),
actionItems: [ actionItems: [
..._getUserActions([event.actor.login, event.repoOwner]), ..._getUserActions([event.actor.login, event.repoOwner]),
ActionItem.repository(event.repoOwner, event.repoName), ActionItem.repository(event.repoOwner, event.repoName),
@ -263,17 +252,11 @@ class EventItem extends StatelessWidget {
], ],
iconData: Octicons.git_pull_request, iconData: Octicons.git_pull_request,
detail: event.payload['pull_request']['title'], detail: event.payload['pull_request']['title'],
screenBuilder: (_) => IssueScreen( url: '/${event.repoOwner}/${event.repoName}/pulls/$number',
event.repoOwner,
event.repoName,
number,
isPullRequest: true,
),
actionItems: [ actionItems: [
..._getUserActions([event.actor.login, event.repoOwner]), ..._getUserActions([event.actor.login, event.repoOwner]),
ActionItem.repository(event.repoOwner, event.repoName), ActionItem.repository(event.repoOwner, event.repoName),
ActionItem.issue(event.repoOwner, event.repoName, number, ActionItem.pullRequest(event.repoOwner, event.repoName, number),
isPullRequest: true),
], ],
); );
case 'PullRequestReviewEvent': case 'PullRequestReviewEvent':
@ -291,17 +274,11 @@ class EventItem extends StatelessWidget {
_buildRepo(theme), _buildRepo(theme),
], ],
detail: event.payload['comment']['body'], detail: event.payload['comment']['body'],
screenBuilder: (_) => IssueScreen( url: '/${event.repoOwner}/${event.repoName}/pulls/$number',
event.repoOwner,
event.repoName,
number,
isPullRequest: true,
),
actionItems: [ actionItems: [
..._getUserActions([event.actor.login, event.repoOwner]), ..._getUserActions([event.actor.login, event.repoOwner]),
ActionItem.repository(event.repoOwner, event.repoName), ActionItem.repository(event.repoOwner, event.repoName),
ActionItem.issue(event.repoOwner, event.repoName, number, ActionItem.pullRequest(event.repoOwner, event.repoName, number),
isPullRequest: true),
], ],
); );
case 'PushEvent': case 'PushEvent':
@ -365,8 +342,7 @@ class EventItem extends StatelessWidget {
context: context, context: context,
spans: [TextSpan(text: ' starred '), _buildRepo(theme)], spans: [TextSpan(text: ' starred '), _buildRepo(theme)],
iconData: Octicons.star, iconData: Octicons.star,
screenBuilder: (_) => url: '/${event.repoOwner}/${event.repoName}',
RepositoryScreen(event.repoOwner, event.repoName),
actionItems: [ actionItems: [
..._getUserActions([event.actor.login, event.repoOwner]), ..._getUserActions([event.actor.login, event.repoOwner]),
ActionItem.repository(event.repoOwner, event.repoName), ActionItem.repository(event.repoOwner, event.repoName),

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/screens/user.dart';
import 'package:git_touch/widgets/avatar.dart'; import 'package:git_touch/widgets/avatar.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:timeago/timeago.dart' as timeago; import 'package:timeago/timeago.dart' as timeago;
@ -123,10 +122,9 @@ class IssueItem extends StatelessWidget {
// FIXME: Deleted user // FIXME: Deleted user
if (payload['author'] != null) ...[ if (payload['author'] != null) ...[
Link( Link(
url: '/' + payload['author']['login'],
child: Avatar.extraSmall( child: Avatar.extraSmall(
url: payload['author']['avatarUrl']), url: payload['author']['avatarUrl']),
screenBuilder: (_) =>
UserScreen(payload['author']['login']),
), ),
SizedBox(width: 4), SizedBox(width: 4),
Text( Text(

View File

@ -27,9 +27,13 @@ class Link extends StatelessWidget {
return Provider.of<ThemeModel>(context).pushRoute(context, screenBuilder); return Provider.of<ThemeModel>(context).pushRoute(context, screenBuilder);
} }
if (url != null) { if (url != null) {
if (url.startsWith('/')) {
Provider.of<ThemeModel>(context).push(context, url);
} else {
launchUrl(url); launchUrl(url);
} }
} }
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -5,8 +5,6 @@ import 'package:git_touch/graphql/github_user.dart';
import 'package:git_touch/models/gitea.dart'; import 'package:git_touch/models/gitea.dart';
import 'package:git_touch/models/gitlab.dart'; import 'package:git_touch/models/gitlab.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/screens/gitlab_project.dart';
import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/widgets/action_button.dart'; import 'package:git_touch/widgets/action_button.dart';
import 'package:git_touch/widgets/avatar.dart'; import 'package:git_touch/widgets/avatar.dart';
import 'package:primer/primer.dart'; import 'package:primer/primer.dart';
@ -46,7 +44,6 @@ class RepositoryItem extends StatelessWidget {
final int forkCount; final int forkCount;
final String primaryLanguageName; final String primaryLanguageName;
final String primaryLanguageColor; final String primaryLanguageColor;
final Widget Function(BuildContext context) screenBuilder;
final bool inRepoScreen; final bool inRepoScreen;
final Iterable<GithubRepositoryRepositoryTopic> topics; final Iterable<GithubRepositoryRepositoryTopic> topics;
@ -60,7 +57,6 @@ class RepositoryItem extends StatelessWidget {
this.forkCount, this.forkCount,
this.primaryLanguageName, this.primaryLanguageName,
this.primaryLanguageColor, this.primaryLanguageColor,
this.screenBuilder,
this.topics, this.topics,
{this.inRepoScreen = false}); {this.inRepoScreen = false});
@ -78,8 +74,6 @@ class RepositoryItem extends StatelessWidget {
this.primaryLanguageColor = payload['primaryLanguage'] == null this.primaryLanguageColor = payload['primaryLanguage'] == null
? null ? null
: payload['primaryLanguage']['color'], : payload['primaryLanguage']['color'],
this.screenBuilder = ((_) =>
RepositoryScreen(payload['owner']['login'], payload['name'])),
this.topics = []; this.topics = [];
RepositoryItem.github(GithubUserRepository payload, RepositoryItem.github(GithubUserRepository payload,
@ -93,8 +87,6 @@ class RepositoryItem extends StatelessWidget {
this.forkCount = payload.forks.totalCount, this.forkCount = payload.forks.totalCount,
this.primaryLanguageName = payload.primaryLanguage?.name, this.primaryLanguageName = payload.primaryLanguage?.name,
this.primaryLanguageColor = payload.primaryLanguage?.color, this.primaryLanguageColor = payload.primaryLanguage?.color,
this.screenBuilder =
((_) => RepositoryScreen(payload.owner.login, payload.name)),
this.topics = []; // TODO: this.topics = []; // TODO:
// this.topics = payload['repositoryTopics'] == null // this.topics = payload['repositoryTopics'] == null
// ? [] // ? []
@ -123,7 +115,6 @@ class RepositoryItem extends StatelessWidget {
this.forkCount = payload.forksCount, this.forkCount = payload.forksCount,
this.primaryLanguageName = null, this.primaryLanguageName = null,
this.primaryLanguageColor = null, this.primaryLanguageColor = null,
this.screenBuilder = ((_) => GitlabProjectScreen(payload.id)),
this.topics = []; this.topics = [];
RepositoryItem.gitea(GiteaRepository payload, {this.inRepoScreen = false}) RepositoryItem.gitea(GiteaRepository payload, {this.inRepoScreen = false})
@ -136,7 +127,6 @@ class RepositoryItem extends StatelessWidget {
this.forkCount = payload.forksCount, this.forkCount = payload.forksCount,
this.primaryLanguageName = null, this.primaryLanguageName = null,
this.primaryLanguageColor = null, this.primaryLanguageColor = null,
this.screenBuilder = ((_) => RepositoryScreen('', '')), // TODO:
this.topics = []; this.topics = [];
static IconData _buildIconData(payload) { static IconData _buildIconData(payload) {
@ -153,9 +143,9 @@ class RepositoryItem extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Provider.of<ThemeModel>(context); final theme = Provider.of<ThemeModel>(context);
// TODO: text style // TODO: text style inRepoScreen
return Link( return Link(
screenBuilder: inRepoScreen ? null : screenBuilder, url: '/$owner/$name',
onLongPress: () async { onLongPress: () async {
await Provider.of<ThemeModel>(context).showActions(context, [ await Provider.of<ThemeModel>(context).showActions(context, [
ActionItem.user(owner), ActionItem.user(owner),

View File

@ -31,7 +31,6 @@ class TableViewItem {
final Widget rightWidget; final Widget rightWidget;
final void Function() onTap; final void Function() onTap;
final String url; final String url;
final WidgetBuilder screenBuilder;
final bool hideRightChevron; final bool hideRightChevron;
TableViewItem({ TableViewItem({
@ -41,7 +40,6 @@ class TableViewItem {
this.rightWidget, this.rightWidget,
this.onTap, this.onTap,
this.url, this.url,
this.screenBuilder,
this.hideRightChevron = false, this.hideRightChevron = false,
}) : assert(leftIconData == null || leftWidget == null); }) : assert(leftIconData == null || leftWidget == null);
} }
@ -104,9 +102,7 @@ class TableView extends StatelessWidget {
), ),
SizedBox(width: 6) SizedBox(width: 6)
], ],
if ((item.onTap != null || if ((item.onTap != null || item.url != null) &&
item.screenBuilder != null ||
item.url != null) &&
!item.hideRightChevron) !item.hideRightChevron)
Icon(CupertinoIcons.right_chevron, Icon(CupertinoIcons.right_chevron,
size: 20, color: themeModel.palette.tertiaryText) size: 20, color: themeModel.palette.tertiaryText)
@ -118,12 +114,7 @@ class TableView extends StatelessWidget {
), ),
); );
return Link( return Link(onTap: item.onTap, url: item.url, child: widget);
onTap: item.onTap,
screenBuilder: item.screenBuilder,
url: item.url,
child: widget,
);
}).toList()), }).toList()),
CommonStyle.border, CommonStyle.border,
], ],

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/screens/user.dart';
import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/utils/utils.dart';
class TextContainsOrganization extends StatelessWidget { class TextContainsOrganization extends StatelessWidget {
@ -22,8 +21,8 @@ class TextContainsOrganization extends StatelessWidget {
if (chunks[index].isNotEmpty) { if (chunks[index].isNotEmpty) {
spans.add(TextSpan(text: chunks[index])); spans.add(TextSpan(text: chunks[index]));
} }
spans.add(createLinkSpan( spans.add(
context, orgs[index], (_) => UserScreen(orgs[index].substring(1)))); createLinkSpan(context, orgs[index], '/' + orgs[index].substring(1)));
} }
if (chunks.last.isNotEmpty) { if (chunks.last.isNotEmpty) {
spans.add(TextSpan(text: chunks.last)); spans.add(TextSpan(text: chunks.last));

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:git_touch/models/theme.dart'; import 'package:git_touch/models/theme.dart';
import 'package:git_touch/screens/user.dart';
import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/avatar.dart'; import 'package:git_touch/widgets/avatar.dart';
import 'package:git_touch/widgets/link.dart'; import 'package:git_touch/widgets/link.dart';
@ -41,7 +40,7 @@ class UserItem extends StatelessWidget {
final theme = Provider.of<ThemeModel>(context); final theme = Provider.of<ThemeModel>(context);
return Link( return Link(
screenBuilder: inUserScreen ? null : (_) => UserScreen(login), url: '/$login',
child: Container( child: Container(
padding: CommonStyle.padding, padding: CommonStyle.padding,
child: Row( child: Row(

View File

@ -1,7 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:git_touch/widgets/link.dart';
import '../screens/user.dart';
import 'link.dart';
final style = TextStyle(fontWeight: FontWeight.w600); final style = TextStyle(fontWeight: FontWeight.w600);
@ -13,7 +11,7 @@ class UserName extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Link( return Link(
screenBuilder: (_) => UserScreen(login), url: '/$login',
child: Container( child: Container(
// padding: EdgeInsets.all(2), // padding: EdgeInsets.all(2),
decoration: BoxDecoration( decoration: BoxDecoration(

View File

@ -40,6 +40,7 @@ dependencies:
gql: ^0.11.1 gql: ^0.11.1
artemis: ^2.1.2 artemis: ^2.1.2
gql_link: ^0.2.0 gql_link: ^0.2.0
fluro: ^1.5.1
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.