diff --git a/lib/screens/repository.dart b/lib/screens/repository.dart index ec647b7..3bbfe9e 100644 --- a/lib/screens/repository.dart +++ b/lib/screens/repository.dart @@ -240,10 +240,12 @@ class RepositoryScreen extends StatelessWidget { ), ], ), - CommonStyle.verticalGap, - if (repo.languages.edges.isNotEmpty) - GestureDetector( - onTap: () { + if (repo.languages.edges.isNotEmpty) ...[ + CommonStyle.border, + CupertinoButton( + padding: EdgeInsets.zero, + minSize: 0, + onPressed: () { showCupertinoModalPopup( context: context, builder: (context) { @@ -305,6 +307,7 @@ class RepositoryScreen extends StatelessWidget { ), ), ), + ], TableView( hasIcon: true, items: [ @@ -373,7 +376,6 @@ class RepositoryScreen extends StatelessWidget { ], ], ), - CommonStyle.verticalGap, if (readme != null) Container( padding: CommonStyle.padding, diff --git a/lib/screens/user.dart b/lib/screens/user.dart index 434c4c4..1ba0029 100644 --- a/lib/screens/user.dart +++ b/lib/screens/user.dart @@ -15,7 +15,6 @@ import 'package:git_touch/widgets/text_contains_organization.dart'; import 'package:git_touch/models/auth.dart'; import 'package:provider/provider.dart'; import 'package:git_touch/widgets/action_button.dart'; -import 'package:timeago/timeago.dart' as t; final userRouter = RouterScreen( '/:login', @@ -84,7 +83,8 @@ class UserScreen extends StatelessWidget { } Widget _buildHeader(BuildContext context, String avatarUrl, String name, - String login, DateTime createdAt, String bio) { + String login, DateTime createdAt, String bio, + {Widget followWidget}) { final theme = Provider.of(context); return Container( @@ -95,59 +95,51 @@ class UserScreen extends StatelessWidget { Row( children: [ Avatar(url: avatarUrl, size: AvatarSize.large), - SizedBox(width: 10), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - if (name != null) ...[ - Text( - name, - style: TextStyle( - color: theme.palette.primary, - fontSize: 19, - fontWeight: FontWeight.w500, - ), - ), - SizedBox(width: 4), - ], - Text( - '($login)', - style: TextStyle( - color: theme.palette.secondaryText, - fontSize: 16, - ), - ), - ], - ), - SizedBox(height: 6), - Row( - children: [ - Icon( - Octicons.clock, - size: 15, - color: theme.palette.secondaryText, - ), - SizedBox(width: 4), - Text( - 'Joined on ${dateFormat.format(createdAt)}', - style: TextStyle( - color: theme.palette.secondaryText, - fontSize: 15, - ), - ), - ], - ), - ], + if (followWidget != null) ...[ + Expanded(child: Container()), + followWidget, + ] + ], + ), + SizedBox(height: 8), + if (name != null) ...[ + Text( + name, + style: TextStyle( + color: theme.palette.primary, + fontSize: 20, + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 4), + ], + Text( + login, + style: TextStyle( + color: theme.palette.secondaryText, + fontSize: 18, + ), + ), + SizedBox(height: 8), + Row( + children: [ + Icon( + Octicons.clock, + size: 16, + color: theme.palette.tertiaryText, + ), + SizedBox(width: 4), + Text( + 'Joined on ${dateFormat.format(createdAt)}', + style: TextStyle( + color: theme.palette.tertiaryText, + fontSize: 16, ), - ) + ), ], ), if (bio != null && bio.isNotEmpty) ...[ - SizedBox(height: 12), + SizedBox(height: 10), Text( bio, style: TextStyle( @@ -161,14 +153,52 @@ class UserScreen extends StatelessWidget { ); } - Widget _buildUser(BuildContext context, GhUserUser user) { + Widget _buildUser(BuildContext context, GhUserUser user, + void Function(void Function()) setState) { final theme = Provider.of(context); + final auth = Provider.of(context); final login = user.login; + return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildHeader(context, user.avatarUrl, user.name, user.login, - user.createdAt, user.bio), + _buildHeader( + context, + user.avatarUrl, + user.name, + user.login, + user.createdAt, + user.bio, + followWidget: user.viewerCanFollow == true + ? CupertinoButton( + onPressed: () async { + final res = await auth.gqlClient.execute( + GhFollowQuery( + variables: GhFollowArguments( + id: user.id, + flag: !user.viewerIsFollowing, + ), + ), + ); + setState(() { + user.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( @@ -193,8 +223,6 @@ class UserScreen extends StatelessWidget { ), ]), CommonStyle.border, - CommonStyle.verticalGap, - CommonStyle.border, Container( color: theme.palette.background, padding: CommonStyle.padding, @@ -228,8 +256,6 @@ class UserScreen extends StatelessWidget { ), ), CommonStyle.border, - CommonStyle.verticalGap, - CommonStyle.border, TableView( hasIcon: true, items: [ @@ -320,7 +346,6 @@ class UserScreen extends StatelessWidget { url: '/${payload.login}?tab=people', ), ]), - CommonStyle.verticalGap, TableView( hasIcon: true, items: [ @@ -386,29 +411,8 @@ class UserScreen extends StatelessWidget { return ActionButton( title: 'User Actions', items: [ - if (user.viewerCanFollow) - ActionItem( - text: user.viewerIsFollowing ? 'Unfollow' : 'Follow', - onTap: (_) async { - final res = await auth.gqlClient.execute( - GhFollowQuery( - variables: GhFollowArguments( - id: user.id, - flag: !user.viewerIsFollowing, - ), - ), - ); - setState(() { - user.viewerIsFollowing = - res.data.unfollowUser?.user?.viewerIsFollowing ?? - res.data.followUser.user.viewerIsFollowing; - }); - }, - ), - if (payload != null) ...[ - ActionItem.share(user.url), - ActionItem.launch(user.url), - ], + ActionItem.share(user.url), + ActionItem.launch(user.url), ], ); case 'Organization': @@ -426,13 +430,13 @@ class UserScreen extends StatelessWidget { return null; } }, - bodyBuilder: (payload, _) { + bodyBuilder: (payload, setState) { if (isViewer) { - return _buildUser(context, payload as GhUserUser); + return _buildUser(context, payload as GhUserUser, setState); } switch (payload.resolveType) { case 'User': - return _buildUser(context, payload as GhUserUser); + return _buildUser(context, payload as GhUserUser, setState); case 'Organization': return _buildOrganization(context, payload as GhUserOrganization); default: