render contents of the tabs

This commit is contained in:
shilangyu 2020-09-30 23:43:21 +02:00
parent 4db7ec3fee
commit 701b6f8de3
2 changed files with 112 additions and 83 deletions

View File

@ -9,34 +9,29 @@ import '../widgets/user_profile.dart';
class UserPage extends HookWidget { class UserPage extends HookWidget {
final int userId; final int userId;
final String instanceUrl; final String instanceUrl;
final Future<UserView> _userView; final Future<UserDetails> _userDetails;
UserPage({@required this.userId, @required this.instanceUrl}) UserPage({@required this.userId, @required this.instanceUrl})
: assert(userId != null), : assert(userId != null),
assert(instanceUrl != null), assert(instanceUrl != null),
_userView = LemmyApi(instanceUrl) _userDetails = LemmyApi(instanceUrl).v1.getUserDetails(
.v1 userId: userId, savedOnly: true, sort: SortType.active);
.getUserDetails(
userId: userId, savedOnly: true, sort: SortType.active)
.then((res) => res.user);
UserPage.fromName({@required this.instanceUrl, @required String username}) UserPage.fromName({@required this.instanceUrl, @required String username})
: assert(instanceUrl != null), : assert(instanceUrl != null),
assert(username != null), assert(username != null),
userId = null, userId = null,
_userView = LemmyApi(instanceUrl) _userDetails = LemmyApi(instanceUrl).v1.getUserDetails(
.v1 username: username, savedOnly: true, sort: SortType.active);
.getUserDetails(
username: username, savedOnly: true, sort: SortType.active)
.then((res) => res.user);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final userViewSnap = useFuture(_userView); final userDetailsSnap = useFuture(_userDetails);
final body = () { final body = () {
if (userViewSnap.hasData) { if (userDetailsSnap.hasData) {
return UserProfile.fromUserView(userViewSnap.data); return UserProfile.fromUserDetails(userDetailsSnap.data);
} else if (userViewSnap.hasError) { } else if (userDetailsSnap.hasError) {
return Center(child: Text('Could not find that user.')); return Center(child: Text('Could not find that user.'));
} else { } else {
return Center(child: CircularProgressIndicator()); return Center(child: CircularProgressIndicator());
@ -49,15 +44,15 @@ class UserPage extends HookWidget {
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
shadowColor: Colors.transparent, shadowColor: Colors.transparent,
actions: [ actions: [
if (userViewSnap.hasData) ...[ if (userDetailsSnap.hasData) ...[
IconButton( IconButton(
icon: Icon(Icons.email), icon: Icon(Icons.email),
onPressed: () {}, // TODO: go to messaging page onPressed: () {}, // TODO: go to messaging page
), ),
IconButton( IconButton(
icon: Icon(Icons.share), icon: Icon(Icons.share),
onPressed: () => Share.text( onPressed: () => Share.text('Share user',
'Share user', userViewSnap.data.actorId, 'text/plain'), userDetailsSnap.data.user.actorId, 'text/plain'),
) )
] ]
], ],

View File

@ -11,33 +11,32 @@ import '../util/intl.dart';
import '../util/text_color.dart'; import '../util/text_color.dart';
import 'badge.dart'; import 'badge.dart';
import 'fullscreenable_image.dart'; import 'fullscreenable_image.dart';
import 'markdown_text.dart';
import 'sortable_infinite_list.dart';
/// Shared widget of UserPage and ProfileTab /// Shared widget of UserPage and ProfileTab
class UserProfile extends HookWidget { class UserProfile extends HookWidget {
final Future<UserView> _userView; final Future<UserDetails> _userDetails;
final String instanceUrl; final String instanceUrl;
UserProfile({@required int userId, @required this.instanceUrl}) UserProfile({@required int userId, @required this.instanceUrl})
: _userView = LemmyApi(instanceUrl) : _userDetails = LemmyApi(instanceUrl).v1.getUserDetails(
.v1 userId: userId, savedOnly: false, sort: SortType.active);
.getUserDetails(
userId: userId, savedOnly: true, sort: SortType.active)
.then((res) => res.user);
UserProfile.fromUserView(UserView userView) UserProfile.fromUserDetails(UserDetails userDetails)
: _userView = Future.value(userView), : _userDetails = Future.value(userDetails),
instanceUrl = userView.instanceUrl; instanceUrl = userDetails.user.instanceUrl;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final userViewSnap = useFuture(_userView, preserveState: false); final userDetailsSnap = useFuture(_userDetails, preserveState: false);
if (!userViewSnap.hasData) { if (!userDetailsSnap.hasData) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} }
final userView = userViewSnap.data; final userView = userDetailsSnap.data.user;
return DefaultTabController( return DefaultTabController(
length: 3, length: 3,
@ -65,47 +64,40 @@ class UserProfile extends HookWidget {
), ),
], ],
body: TabBarView(children: [ body: TabBarView(children: [
ListView(children: [ // TODO: first batch is already fetched on render
Text( // TODO: comment and post come from the same endpoint, could be shared
'Posts', InfinitePostList(
style: const TextStyle(fontSize: 36), fetcher: (page, batchSize, sort) => LemmyApi(instanceUrl)
.v1
.getUserDetails(
userId: userView.id,
savedOnly: false,
sort: SortType.active,
page: page,
limit: batchSize,
) )
]), .then((val) => val.posts),
ListView(children: [ ),
Text( InfiniteCommentList(
'Comments', fetcher: (page, batchSize, sort) => LemmyApi(instanceUrl)
style: const TextStyle(fontSize: 36), .v1
.getUserDetails(
userId: userView.id,
savedOnly: false,
sort: SortType.active,
page: page,
limit: batchSize,
) )
]), .then((val) => val.comments),
// InfinitePostList( ),
// fetcher: (page, batchSize, sort) => _AboutTab(userDetailsSnap.data),
// LemmyApi(community.instanceUrl).v1.getPosts(
// type: PostListingType.community,
// sort: sort,
// communityId: community.id,
// page: page,
// limit: batchSize,
// ),
// ),
// InfiniteCommentList(
// fetcher: (page, batchSize, sortType) =>
// LemmyApi(community.instanceUrl).v1.getComments(
// communityId: community.id,
// auth: accountsStore
// .defaultTokenFor(community.instanceUrl)
// ?.raw,
// type: CommentListingType.community,
// sort: sortType,
// limit: batchSize,
// page: page,
// )),
_AboutTab(userView),
]), ]),
), ),
); );
} }
} }
/// Content in the sliver flexible space
class _UserOverview extends HookWidget { class _UserOverview extends HookWidget {
final UserView userView; final UserView userView;
@ -311,28 +303,70 @@ class _UserOverview extends HookWidget {
} }
class _AboutTab extends HookWidget { class _AboutTab extends HookWidget {
final UserView userView; final UserDetails userDetails;
const _AboutTab(this.userView); const _AboutTab(this.userDetails);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bio = () { final theme = Theme.of(context);
if (userView.bio != null) { final instanceUrl = userDetails.user.instanceUrl;
return Padding(
padding: const EdgeInsets.all(10),
child: Text(userView.bio),
);
} else {
return Center(
child: Text(
'no bio',
style: const TextStyle(fontStyle: FontStyle.italic),
),
);
}
}();
return ListView(); const wallPadding = EdgeInsets.symmetric(horizontal: 15);
final divider = Padding(
padding: EdgeInsets.symmetric(
horizontal: wallPadding.horizontal / 2, vertical: 10),
child: Divider(),
);
return ListView(
padding: EdgeInsets.symmetric(vertical: 20),
children: [
if (userDetails.user.bio != null) ...[
Padding(
padding: wallPadding,
child:
MarkdownText(userDetails.user.bio, instanceUrl: instanceUrl)),
divider,
],
if (userDetails.moderates.isNotEmpty) ...[
Padding(
padding: wallPadding,
child: Text('Moderates', style: theme.textTheme.subtitle2),
),
for (final comm in userDetails.moderates)
ListTile(
dense: true,
title: Text('!${comm.communityName}'),
onTap: () =>
goToCommunity.byId(context, instanceUrl, comm.communityId),
),
divider
],
Padding(
padding: wallPadding,
child: Text('Subscribed', style: theme.textTheme.subtitle2),
),
if (userDetails.follows.isEmpty)
for (final comm in userDetails.follows)
ListTile(
dense: true,
title: Text('!${comm.communityName}'),
onTap: () =>
goToCommunity.byId(context, instanceUrl, comm.communityId),
)
else
Padding(
padding: const EdgeInsets.only(top: 8),
child: Center(
child: Text(
'this user does not subscribe to any community',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
)
],
);
} }
} }