2020-05-16 09:04:58 +00:00
|
|
|
import 'package:comunic/enums/post_target.dart';
|
|
|
|
import 'package:comunic/helpers/posts_helper.dart';
|
|
|
|
import 'package:comunic/models/advanced_user_info.dart';
|
2020-05-17 12:53:26 +00:00
|
|
|
import 'package:comunic/models/displayed_content.dart';
|
2020-05-16 15:21:33 +00:00
|
|
|
import 'package:comunic/models/friend_status.dart';
|
|
|
|
import 'package:comunic/ui/routes/main_route/main_route.dart';
|
|
|
|
import 'package:comunic/ui/widgets/FrienshipStatusWidget.dart';
|
2020-05-16 11:41:11 +00:00
|
|
|
import 'package:comunic/ui/widgets/account_image_widget.dart';
|
|
|
|
import 'package:comunic/ui/widgets/like_widget.dart';
|
2020-05-16 09:04:58 +00:00
|
|
|
import 'package:comunic/ui/widgets/post_create_form_widget.dart';
|
|
|
|
import 'package:comunic/ui/widgets/posts_list_widget.dart';
|
2020-05-17 12:53:26 +00:00
|
|
|
import 'package:comunic/ui/widgets/text_widget.dart';
|
2020-05-16 15:21:33 +00:00
|
|
|
import 'package:comunic/utils/account_utils.dart';
|
|
|
|
import 'package:comunic/utils/conversations_utils.dart';
|
2020-05-17 12:17:37 +00:00
|
|
|
import 'package:comunic/utils/date_utils.dart';
|
|
|
|
import 'package:comunic/utils/intl_utils.dart';
|
2021-05-05 10:23:02 +00:00
|
|
|
import 'package:comunic/utils/ui_utils.dart';
|
2020-05-16 09:04:58 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
/// Tablet mode of user page
|
|
|
|
///
|
|
|
|
/// @author Pierre HUBERT
|
|
|
|
|
|
|
|
class UserPageTablet extends StatefulWidget {
|
|
|
|
final AdvancedUserInfo userInfo;
|
2020-05-16 15:21:33 +00:00
|
|
|
final FriendStatus friendshipStatus;
|
2020-05-16 09:04:58 +00:00
|
|
|
final void Function() onNeedRefresh;
|
|
|
|
|
|
|
|
const UserPageTablet({
|
|
|
|
Key key,
|
|
|
|
@required this.userInfo,
|
2020-05-16 15:21:33 +00:00
|
|
|
@required this.friendshipStatus,
|
2020-05-16 09:04:58 +00:00
|
|
|
@required this.onNeedRefresh,
|
|
|
|
}) : assert(userInfo != null),
|
|
|
|
assert(onNeedRefresh != null),
|
|
|
|
super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
_UserPageTabletState createState() => _UserPageTabletState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _UserPageTabletState extends State<UserPageTablet> {
|
|
|
|
AdvancedUserInfo get _userInfo => widget.userInfo;
|
|
|
|
|
2020-05-16 15:21:33 +00:00
|
|
|
bool get _isCurrentUser => _userInfo.id == userID();
|
|
|
|
|
2020-05-16 09:04:58 +00:00
|
|
|
@override
|
2020-05-17 12:56:21 +00:00
|
|
|
Widget build(BuildContext context) => Padding(
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
child: Flex(
|
|
|
|
direction: Axis.horizontal,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: <Widget>[
|
|
|
|
_buildLeftColumn(),
|
|
|
|
Expanded(child: _buildRightColumn())
|
|
|
|
],
|
|
|
|
),
|
2020-05-16 09:04:58 +00:00
|
|
|
);
|
|
|
|
|
2020-05-17 12:57:34 +00:00
|
|
|
Widget _buildLeftColumn() => SingleChildScrollView(
|
|
|
|
child: Column(
|
|
|
|
children: <Widget>[
|
|
|
|
_buildMainCard(),
|
|
|
|
_buildActionsCard(),
|
|
|
|
_buildAboutCard(),
|
|
|
|
],
|
|
|
|
),
|
2020-05-16 11:41:11 +00:00
|
|
|
);
|
2020-05-16 09:04:58 +00:00
|
|
|
|
|
|
|
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,
|
|
|
|
);
|
2020-05-16 11:41:11 +00:00
|
|
|
|
2020-05-16 12:01:59 +00:00
|
|
|
/// Main user information card
|
2020-05-16 15:21:33 +00:00
|
|
|
Widget _buildMainCard() => _LeftPaneContainer(
|
|
|
|
child: Column(
|
|
|
|
children: <Widget>[
|
|
|
|
Center(child: AccountImageWidget(user: _userInfo, width: 75)),
|
|
|
|
_MainCardSpacer(),
|
|
|
|
Text(
|
|
|
|
_userInfo.displayName,
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
style: TextStyle(fontSize: 20),
|
2020-05-16 11:41:11 +00:00
|
|
|
),
|
2020-05-16 15:21:33 +00:00
|
|
|
_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: <Widget>[
|
|
|
|
// Friends list of the user
|
|
|
|
_userInfo.isFriendsListPublic
|
|
|
|
? Expanded(
|
2021-03-13 14:14:54 +00:00
|
|
|
child: OutlinedButton.icon(
|
2020-05-16 15:21:33 +00:00
|
|
|
onPressed: () => MainController.of(context)
|
|
|
|
.openUserFriendsList(_userInfo.id),
|
|
|
|
icon: Icon(Icons.group),
|
|
|
|
label: Text("${_userInfo.numberFriends}"),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
: Container(),
|
|
|
|
|
|
|
|
// Private messages
|
|
|
|
!_isCurrentUser
|
|
|
|
? Expanded(
|
2021-03-13 14:38:43 +00:00
|
|
|
child: OutlinedButton(
|
2020-05-16 15:21:33 +00:00
|
|
|
onPressed: () =>
|
|
|
|
openPrivateConversation(context, _userInfo.id),
|
|
|
|
child: Icon(Icons.message),
|
|
|
|
))
|
|
|
|
: Container(),
|
|
|
|
],
|
2020-05-16 11:41:11 +00:00
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2020-05-16 12:01:59 +00:00
|
|
|
/// Build user information card
|
2020-05-17 12:17:37 +00:00
|
|
|
Widget _buildAboutCard() => _LeftPaneContainer(
|
|
|
|
child: Column(
|
|
|
|
children: <Widget>[
|
|
|
|
// User membership
|
|
|
|
_AboutUserEntry(
|
|
|
|
icon: Icons.access_time,
|
|
|
|
title: tr("Membership"),
|
|
|
|
value: tr("Member for %t%", args: {
|
|
|
|
"t": diffTimeFromNowToStr(_userInfo.accountCreationTime)
|
|
|
|
})),
|
2020-05-17 12:26:52 +00:00
|
|
|
|
|
|
|
// User public note
|
|
|
|
_AboutUserEntry(
|
|
|
|
icon: Icons.note,
|
|
|
|
title: tr("Note"),
|
2020-05-17 12:53:26 +00:00
|
|
|
value: _userInfo.publicNote,
|
2020-05-17 12:26:52 +00:00
|
|
|
visible: _userInfo.hasPublicNote,
|
2020-05-17 12:53:26 +00:00
|
|
|
parsed: true,
|
|
|
|
),
|
|
|
|
|
2021-04-17 06:52:00 +00:00
|
|
|
// User email address
|
|
|
|
_AboutUserEntry(
|
|
|
|
icon: Icons.mail_outline,
|
|
|
|
title: tr("Email address"),
|
|
|
|
value: _userInfo.emailAddress,
|
|
|
|
visible: _userInfo.emailAddress != null,
|
|
|
|
),
|
|
|
|
|
|
|
|
// Location
|
|
|
|
_AboutUserEntry(
|
|
|
|
icon: Icons.location_on,
|
|
|
|
title: tr("Location"),
|
|
|
|
value: _userInfo.location,
|
|
|
|
visible: _userInfo.location != null,
|
|
|
|
),
|
|
|
|
|
2020-05-17 12:53:26 +00:00
|
|
|
// User website
|
|
|
|
_AboutUserEntry(
|
|
|
|
icon: Icons.link,
|
|
|
|
title: tr("Website"),
|
|
|
|
value: _userInfo.personalWebsite,
|
|
|
|
visible: _userInfo.hasPersonalWebsite,
|
|
|
|
parsed: true,
|
2020-05-17 12:26:52 +00:00
|
|
|
),
|
2020-05-17 12:17:37 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
2020-05-16 09:04:58 +00:00
|
|
|
}
|
2020-05-16 12:01:59 +00:00
|
|
|
|
2020-05-16 15:21:33 +00:00
|
|
|
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,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-16 12:01:59 +00:00
|
|
|
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();
|
|
|
|
}
|
2020-05-17 12:17:37 +00:00
|
|
|
|
|
|
|
class _AboutUserEntry extends StatelessWidget {
|
|
|
|
final IconData icon;
|
|
|
|
final String title;
|
|
|
|
final String value;
|
|
|
|
final bool visible;
|
2020-05-17 12:53:26 +00:00
|
|
|
final bool parsed;
|
2020-05-17 12:17:37 +00:00
|
|
|
|
|
|
|
const _AboutUserEntry({
|
|
|
|
Key key,
|
|
|
|
@required this.icon,
|
|
|
|
@required this.title,
|
|
|
|
@required this.value,
|
|
|
|
this.visible = true,
|
2020-05-17 12:53:26 +00:00
|
|
|
this.parsed = false,
|
2020-05-17 12:17:37 +00:00
|
|
|
}) : 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(
|
2021-05-05 10:23:02 +00:00
|
|
|
style: TextStyle(color: darkTheme() ? null : Colors.black),
|
2020-05-17 12:17:37 +00:00
|
|
|
children: [
|
|
|
|
WidgetSpan(
|
|
|
|
child: Icon(icon, size: 15),
|
|
|
|
alignment: PlaceholderAlignment.middle,
|
|
|
|
),
|
|
|
|
TextSpan(text: " $title")
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
2020-05-17 12:53:26 +00:00
|
|
|
subtitle: parsed
|
|
|
|
? TextWidget(
|
|
|
|
content: DisplayedString(value),
|
|
|
|
style: TextStyle(),
|
|
|
|
)
|
|
|
|
: Text(value),
|
2020-05-17 12:17:37 +00:00
|
|
|
dense: true,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|