import 'package:comunic/enums/post_target.dart'; import 'package:comunic/helpers/posts_helper.dart'; import 'package:comunic/models/advanced_user_info.dart'; import 'package:comunic/models/displayed_content.dart'; import 'package:comunic/models/friend_status.dart'; import 'package:comunic/ui/routes/main_route/main_route.dart'; import 'package:comunic/ui/widgets/FrienshipStatusWidget.dart'; import 'package:comunic/ui/widgets/account_image_widget.dart'; import 'package:comunic/ui/widgets/like_widget.dart'; import 'package:comunic/ui/widgets/post_create_form_widget.dart'; import 'package:comunic/ui/widgets/posts_list_widget.dart'; import 'package:comunic/ui/widgets/text_widget.dart'; import 'package:comunic/utils/account_utils.dart'; import 'package:comunic/utils/conversations_utils.dart'; import 'package:comunic/utils/date_utils.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; /// Tablet mode of user page /// /// @author Pierre HUBERT class UserPageTablet extends StatefulWidget { final AdvancedUserInfo userInfo; final FriendStatus friendshipStatus; final void Function() onNeedRefresh; const UserPageTablet({ Key key, @required this.userInfo, @required this.friendshipStatus, @required this.onNeedRefresh, }) : assert(userInfo != null), assert(onNeedRefresh != null), super(key: key); @override _UserPageTabletState createState() => _UserPageTabletState(); } class _UserPageTabletState extends State { AdvancedUserInfo get _userInfo => widget.userInfo; bool get _isCurrentUser => _userInfo.id == userID(); @override Widget build(BuildContext context) => Padding( padding: const EdgeInsets.all(8.0), child: Flex( direction: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildLeftColumn(), Expanded(child: _buildRightColumn()) ], ), ); Widget _buildLeftColumn() => SingleChildScrollView( child: Column( children: [ _buildMainCard(), _buildActionsCard(), _buildAboutCard(), ], ), ); Widget _buildRightColumn() => PostsListWidget( disablePullToRefresh: true, topWidgets: [ _userInfo.canPostTexts ? PostCreateFormWidget( postTarget: PostTarget.USER_PAGE, targetID: _userInfo.id, onCreated: widget.onNeedRefresh, ) : Container() ], getPostsList: () => PostsHelper().getUserPosts(_userInfo.id), getOlder: (from) => PostsHelper().getUserPosts(_userInfo.id, from: from), showPostsTarget: false, ); /// Main user information card Widget _buildMainCard() => _LeftPaneContainer( child: Column( children: [ Center(child: AccountImageWidget(user: _userInfo, width: 75)), _MainCardSpacer(), Text( _userInfo.displayName, textAlign: TextAlign.center, style: TextStyle(fontSize: 20), ), _MainCardSpacer(), Container( child: _userInfo.hasVirtualDirectory ? Text("@${_userInfo.virtualDirectory}") : null), _MainCardSpacer(visible: _userInfo.hasVirtualDirectory), LikeWidget(likeElement: _userInfo), _MainCardSpacer(visible: !_isCurrentUser), _isCurrentUser ? Container() : FriendshipStatusWidget( status: widget.friendshipStatus, onFriendshipUpdated: widget.onNeedRefresh, ) ], ), ); /// Actions card Widget _buildActionsCard() => _LeftPaneContainer( child: ButtonTheme( minWidth: 30, padding: EdgeInsets.all(0), child: Row( children: [ // Friends list of the user _userInfo.isFriendsListPublic ? Expanded( child: OutlinedButton.icon( onPressed: () => MainController.of(context) .openUserFriendsList(_userInfo.id), icon: Icon(Icons.group), label: Text("${_userInfo.numberFriends}"), ), ) : Container(), // Private messages !_isCurrentUser ? Expanded( child: OutlineButton( onPressed: () => openPrivateConversation(context, _userInfo.id), child: Icon(Icons.message), )) : Container(), ], ), ), ); /// Build user information card Widget _buildAboutCard() => _LeftPaneContainer( child: Column( children: [ // User membership _AboutUserEntry( icon: Icons.access_time, title: tr("Membership"), value: tr("Member for %t%", args: { "t": diffTimeFromNowToStr(_userInfo.accountCreationTime) })), // User public note _AboutUserEntry( icon: Icons.note, title: tr("Note"), value: _userInfo.publicNote, visible: _userInfo.hasPublicNote, parsed: true, ), // User website _AboutUserEntry( icon: Icons.link, title: tr("Website"), value: _userInfo.personalWebsite, visible: _userInfo.hasPersonalWebsite, parsed: true, ), ], ), ); } class _LeftPaneContainer extends StatelessWidget { final Widget child; const _LeftPaneContainer({Key key, this.child}) : super(key: key); @override Widget build(BuildContext context) { return ConstrainedBox( constraints: BoxConstraints(maxWidth: 200), child: Card( child: Padding( padding: const EdgeInsets.all(8.0), child: child, ), ), ); } } class _MainCardSpacer extends StatelessWidget { final bool visible; const _MainCardSpacer({this.visible = true, Key key}) : assert(visible != null), super(key: key); @override Widget build(BuildContext context) => visible ? SizedBox(height: 10) : Container(); } class _AboutUserEntry extends StatelessWidget { final IconData icon; final String title; final String value; final bool visible; final bool parsed; const _AboutUserEntry({ Key key, @required this.icon, @required this.title, @required this.value, this.visible = true, this.parsed = false, }) : assert(icon != null), assert(title != null), assert(visible != null), super(key: key); @override Widget build(BuildContext context) { if (!visible) return Container(); return ListTile( title: RichText( text: TextSpan( children: [ WidgetSpan( child: Icon(icon, size: 15), alignment: PlaceholderAlignment.middle, ), TextSpan(text: " $title") ], ), ), subtitle: parsed ? TextWidget( content: DisplayedString(value), style: TextStyle(), ) : Text(value), dense: true, ); } }