From ac9e6bc6bdf2c1dba0fb265eac885689c0ebf125 Mon Sep 17 00:00:00 2001 From: Rongjian Zhang Date: Sun, 12 Jan 2020 14:49:46 +0800 Subject: [PATCH] improvement: style tweaks --- lib/screens/about.dart | 19 ++++-- lib/screens/gitea_user.dart | 3 +- lib/screens/gitlab_user.dart | 3 +- lib/screens/repository.dart | 51 ++++++-------- lib/screens/user.dart | 110 ++++++++++++++----------------- lib/widgets/avatar.dart | 1 + lib/widgets/mutation_button.dart | 32 +++++++++ 7 files changed, 122 insertions(+), 97 deletions(-) create mode 100644 lib/widgets/mutation_button.dart diff --git a/lib/screens/about.dart b/lib/screens/about.dart index 62d4763..dc7c581 100644 --- a/lib/screens/about.dart +++ b/lib/screens/about.dart @@ -1,10 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:git_touch/models/theme.dart'; import 'package:git_touch/scaffolds/single.dart'; 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:launch_review/launch_review.dart'; import 'package:package_info/package_info.dart'; +import 'package:provider/provider.dart'; final aboutRouter = RouterScreen( '/about', @@ -33,16 +35,25 @@ class _AboutScreenState extends State { @override Widget build(BuildContext context) { + final theme = Provider.of(context); return SingleScaffold( title: AppBarTitle('About'), body: Column( children: [ SizedBox(height: 32), - Image.asset( - 'images/icon.png', - width: 96, + ClipRRect( + borderRadius: BorderRadius.circular(24), + child: Image.asset( + 'images/icon.png', + width: 96, + ), ), - SizedBox(height: 64), + SizedBox(height: 12), + Text( + 'GitTouch', + style: TextStyle(fontSize: 20, color: theme.palette.text), + ), + SizedBox(height: 48), TableView(items: [ TableViewItem(text: Text('Version'), rightWidget: Text(_version)), TableViewItem(text: Text('Source Code'), url: '/pd4d10/git-touch'), diff --git a/lib/screens/gitea_user.dart b/lib/screens/gitea_user.dart index 421c6c1..facca36 100644 --- a/lib/screens/gitea_user.dart +++ b/lib/screens/gitea_user.dart @@ -3,7 +3,6 @@ import 'package:git_touch/models/auth.dart'; import 'package:git_touch/models/gitea.dart'; import 'package:git_touch/scaffolds/refresh_stateful.dart'; import 'package:git_touch/utils/utils.dart'; -import 'package:git_touch/widgets/border_view.dart'; import 'package:git_touch/widgets/repository_item.dart'; import 'package:git_touch/widgets/user_item.dart'; import 'package:provider/provider.dart'; @@ -39,7 +38,7 @@ class GiteaUserScreen extends StatelessWidget { avatarUrl: user.avatarUrl, name: user.fullName, ), - BorderView(height: 10), + CommonStyle.border, Column( children: repos.map((v) { return RepositoryItem( diff --git a/lib/screens/gitlab_user.dart b/lib/screens/gitlab_user.dart index 5d3583d..45eb110 100644 --- a/lib/screens/gitlab_user.dart +++ b/lib/screens/gitlab_user.dart @@ -2,7 +2,6 @@ import 'package:flutter/widgets.dart'; import 'package:git_touch/models/auth.dart'; import 'package:git_touch/models/gitlab.dart'; import 'package:git_touch/scaffolds/refresh_stateful.dart'; -import 'package:git_touch/widgets/border_view.dart'; import 'package:git_touch/widgets/repository_item.dart'; import 'package:git_touch/widgets/user_item.dart'; import 'package:provider/provider.dart'; @@ -59,7 +58,7 @@ class GitlabUserScreen extends StatelessWidget { avatarUrl: user.avatarUrl, name: user.name, ), - BorderView(height: 10), + CommonStyle.border, Column( children: projects.map((v) { return RepositoryItem( diff --git a/lib/screens/repository.dart b/lib/screens/repository.dart index 3bbfe9e..c904ab9 100644 --- a/lib/screens/repository.dart +++ b/lib/screens/repository.dart @@ -8,6 +8,7 @@ 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/avatar.dart'; +import 'package:git_touch/widgets/mutation_button.dart'; import 'package:git_touch/widgets/link.dart'; import 'package:git_touch/widgets/markdown_view.dart'; import 'package:git_touch/widgets/table_view.dart'; @@ -94,11 +95,11 @@ class RepositoryScreen extends StatelessWidget { // }, // ), ActionItem( - text: 'Projects (${repo.projects.totalCount})', + text: 'Projects(${repo.projects.totalCount})', url: repo.projectsUrl, ), ActionItem( - text: 'Releases (${repo.releases.totalCount})', + text: 'Releases(${repo.releases.totalCount})', url: 'https://github.com/$owner/$name/releases', ), ActionItem.share(repo.url), @@ -144,36 +145,26 @@ class RepositoryScreen extends StatelessWidget { color: theme.palette.primary, ), ), - Expanded(child: Container()), - CupertinoButton( - onPressed: () async { - final res = await auth.gqlClient.execute( - GhStarQuery( - variables: GhStarArguments( - id: repo.id, - flag: !repo.viewerHasStarred, - ), - ), - ); - setState(() { - repo.viewerHasStarred = res.data.removeStar - ?.starrable?.viewerHasStarred ?? - res.data.addStar.starrable.viewerHasStarred; - }); - }, - minSize: 0, - color: theme.palette.primary, - padding: EdgeInsets.symmetric( - horizontal: 12, - vertical: 4, - ), - child: Text( - repo.viewerHasStarred ? 'Unstar' : 'Star', - style: TextStyle(fontSize: 17), - ), - ) ], ), + MutationButton( + text: repo.viewerHasStarred ? 'Unstar' : 'Star', + onPressed: () async { + final res = await auth.gqlClient.execute( + GhStarQuery( + variables: GhStarArguments( + id: repo.id, + flag: !repo.viewerHasStarred, + ), + ), + ); + setState(() { + repo.viewerHasStarred = + res.data.removeStar?.starrable?.viewerHasStarred ?? + res.data.addStar.starrable.viewerHasStarred; + }); + }, + ), if (repo.description != null && repo.description.isNotEmpty) Text( repo.description, diff --git a/lib/screens/user.dart b/lib/screens/user.dart index 1ba0029..bed1d3a 100644 --- a/lib/screens/user.dart +++ b/lib/screens/user.dart @@ -8,6 +8,7 @@ import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/widgets/app_bar_title.dart'; import 'package:git_touch/screens/repositories.dart'; import 'package:git_touch/widgets/avatar.dart'; +import 'package:git_touch/widgets/mutation_button.dart'; import 'package:git_touch/widgets/entry_item.dart'; import 'package:git_touch/widgets/repository_item.dart'; import 'package:git_touch/widgets/table_view.dart'; @@ -94,7 +95,7 @@ class UserScreen extends StatelessWidget { children: [ Row( children: [ - Avatar(url: avatarUrl, size: AvatarSize.large), + Avatar(url: avatarUrl, size: AvatarSize.extraLarge), if (followWidget != null) ...[ Expanded(child: Container()), followWidget, @@ -153,71 +154,62 @@ class UserScreen extends StatelessWidget { ); } - Widget _buildUser(BuildContext context, GhUserUser user, + Widget _buildUser(BuildContext context, GhUserUser p, void Function(void Function()) setState) { final theme = Provider.of(context); final auth = Provider.of(context); - final login = user.login; + final login = p.login; return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildHeader( context, - user.avatarUrl, - user.name, - user.login, - user.createdAt, - user.bio, - followWidget: user.viewerCanFollow == true - ? CupertinoButton( + p.avatarUrl, + p.name, + p.login, + p.createdAt, + p.bio, + followWidget: p.viewerCanFollow == true + ? MutationButton( + text: p.viewerIsFollowing ? 'Unfollow' : 'Follow', onPressed: () async { final res = await auth.gqlClient.execute( GhFollowQuery( variables: GhFollowArguments( - id: user.id, - flag: !user.viewerIsFollowing, + id: p.id, + flag: !p.viewerIsFollowing, ), ), ); setState(() { - user.viewerIsFollowing = + p.viewerIsFollowing = res.data.unfollowUser?.user?.viewerIsFollowing ?? res.data.followUser.user.viewerIsFollowing; }); }, - minSize: 0, - color: theme.palette.primary, - padding: EdgeInsets.symmetric( - horizontal: 12, - vertical: 4, - ), - child: Text( - user.viewerIsFollowing ? 'Unfollow' : 'Follow', - style: TextStyle(fontSize: 17), - ), ) : null, ), CommonStyle.border, Row(children: [ EntryItem( - count: user.repositories.totalCount, + count: p.repositories.totalCount, text: 'Repositories', url: '/$login?tab=repositories', ), EntryItem( - count: user.starredRepositories.totalCount, + count: p.starredRepositories.totalCount, text: 'Stars', url: '/$login?tab=stars', ), EntryItem( - count: user.followers.totalCount, + count: p.followers.totalCount, text: 'Followers', url: '/$login?tab=followers', ), EntryItem( - count: user.following.totalCount, + count: p.following.totalCount, text: 'Following', url: '/$login?tab=following', ), @@ -231,7 +223,7 @@ class UserScreen extends StatelessWidget { reverse: true, child: Wrap( spacing: 3, - children: user.contributionsCollection.contributionCalendar.weeks + children: p.contributionsCollection.contributionCalendar.weeks .map((week) { return Wrap( direction: Axis.vertical, @@ -259,38 +251,38 @@ class UserScreen extends StatelessWidget { TableView( hasIcon: true, items: [ - if (isNotNullOrEmpty(user.company)) + if (isNotNullOrEmpty(p.company)) TableViewItem( leftIconData: Octicons.organization, text: TextContainsOrganization( - user.company, + p.company, style: TextStyle(fontSize: 16, color: theme.palette.text), oneLine: true, ), ), - if (isNotNullOrEmpty(user.location)) + if (isNotNullOrEmpty(p.location)) TableViewItem( leftIconData: Octicons.location, - text: Text(user.location), + text: Text(p.location), onTap: () { launchUrl('https://www.google.com/maps/place/' + - user.location.replaceAll(RegExp(r'\s+'), '')); + p.location.replaceAll(RegExp(r'\s+'), '')); }, ), - if (isNotNullOrEmpty(user.email)) + if (isNotNullOrEmpty(p.email)) TableViewItem( leftIconData: Octicons.mail, - text: Text(user.email), + text: Text(p.email), onTap: () { - launchUrl('mailto:' + user.email); + launchUrl('mailto:' + p.email); }, ), - if (isNotNullOrEmpty(user.websiteUrl)) + if (isNotNullOrEmpty(p.websiteUrl)) TableViewItem( leftIconData: Octicons.link, - text: Text(user.websiteUrl), + text: Text(p.websiteUrl), onTap: () { - var url = user.websiteUrl; + var url = p.websiteUrl; if (!url.startsWith('http')) { url = 'http://$url'; } @@ -318,60 +310,60 @@ class UserScreen extends StatelessWidget { ) else ..._buildPinnedItems( - user.pinnedItems.nodes + p.pinnedItems.nodes .where((n) => n is GhUserRepository) .cast(), - user.repositories.nodes), + p.repositories.nodes), CommonStyle.verticalGap, ], ); } - Widget _buildOrganization(BuildContext context, GhUserOrganization payload) { + Widget _buildOrganization(BuildContext context, GhUserOrganization p) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildHeader(context, payload.avatarUrl, payload.name, payload.login, - payload.createdAt, payload.description), + _buildHeader( + context, p.avatarUrl, p.name, p.login, p.createdAt, p.description), CommonStyle.border, Row(children: [ EntryItem( - count: payload.pinnableItems.totalCount, + count: p.pinnableItems.totalCount, text: 'Repositories', - url: '/${payload.login}?tab=repositories', + url: '/${p.login}?tab=repositories', ), EntryItem( - count: payload.membersWithRole.totalCount, + count: p.membersWithRole.totalCount, text: 'Members', - url: '/${payload.login}?tab=people', + url: '/${p.login}?tab=people', ), ]), TableView( hasIcon: true, items: [ - if (isNotNullOrEmpty(payload.location)) + if (isNotNullOrEmpty(p.location)) TableViewItem( leftIconData: Octicons.location, - text: Text(payload.location), + text: Text(p.location), onTap: () { launchUrl('https://www.google.com/maps/place/' + - payload.location.replaceAll(RegExp(r'\s+'), '')); + p.location.replaceAll(RegExp(r'\s+'), '')); }, ), - if (isNotNullOrEmpty(payload.email)) + if (isNotNullOrEmpty(p.email)) TableViewItem( leftIconData: Octicons.mail, - text: Text(payload.email), + text: Text(p.email), onTap: () { - launchUrl('mailto:' + payload.email); + launchUrl('mailto:' + p.email); }, ), - if (isNotNullOrEmpty(payload.websiteUrl)) + if (isNotNullOrEmpty(p.websiteUrl)) TableViewItem( leftIconData: Octicons.link, - text: Text(payload.websiteUrl), + text: Text(p.websiteUrl), onTap: () { - var url = payload.websiteUrl; + var url = p.websiteUrl; if (!url.startsWith('http')) { url = 'http://$url'; } @@ -382,10 +374,10 @@ class UserScreen extends StatelessWidget { ), CommonStyle.verticalGap, ..._buildPinnedItems( - payload.pinnedItems.nodes + p.pinnedItems.nodes .where((n) => n is GhUserRepository) .cast(), - payload.pinnableItems.nodes + p.pinnableItems.nodes .where((n) => n is GhUserRepository) .cast(), ), diff --git a/lib/widgets/avatar.dart b/lib/widgets/avatar.dart index 9cf2f4b..35a4384 100644 --- a/lib/widgets/avatar.dart +++ b/lib/widgets/avatar.dart @@ -7,6 +7,7 @@ class AvatarSize { static const double small = 24; static const double medium = 36; static const double large = 48; + static const double extraLarge = 64; } class Avatar extends StatelessWidget { diff --git a/lib/widgets/mutation_button.dart b/lib/widgets/mutation_button.dart new file mode 100644 index 0000000..3090684 --- /dev/null +++ b/lib/widgets/mutation_button.dart @@ -0,0 +1,32 @@ +import 'package:flutter/cupertino.dart'; +import 'package:git_touch/models/theme.dart'; +import 'package:provider/provider.dart'; + +class MutationButton extends StatelessWidget { + final String text; + final VoidCallback onPressed; + + MutationButton({ + @required this.text, + @required this.onPressed, + }); + + @override + Widget build(BuildContext context) { + final theme = Provider.of(context); + return CupertinoButton( + onPressed: onPressed, + minSize: 0, + color: theme.palette.primary, + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 4, + ), + borderRadius: BorderRadius.all(Radius.circular(20)), + child: Text( + text, + style: TextStyle(fontSize: 16, color: theme.palette.background), + ), + ); + } +}