2021-09-11 01:04:15 +02:00
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
|
|
import 'package:lemmy_api_client/v3.dart';
|
2021-11-03 06:21:00 +01:00
|
|
|
import 'package:nested/nested.dart';
|
2021-09-11 01:04:15 +02:00
|
|
|
|
|
|
|
import '../../hooks/logged_in_action.dart';
|
2021-09-15 00:23:55 +02:00
|
|
|
import '../../stores/accounts_store.dart';
|
2021-09-11 01:04:15 +02:00
|
|
|
import '../../util/async_store_listener.dart';
|
|
|
|
import '../../util/extensions/api.dart';
|
|
|
|
import '../../util/icons.dart';
|
2021-12-04 18:03:54 +01:00
|
|
|
import '../../util/mobx_provider.dart';
|
2021-09-11 01:04:15 +02:00
|
|
|
import '../../util/observer_consumers.dart';
|
|
|
|
import '../../util/share.dart';
|
2021-11-25 18:12:36 +01:00
|
|
|
import '../../widgets/failed_to_load.dart';
|
2021-09-11 01:04:15 +02:00
|
|
|
import '../../widgets/post/post.dart';
|
|
|
|
import '../../widgets/post/post_more_menu.dart';
|
|
|
|
import '../../widgets/post/post_store.dart';
|
2021-09-11 01:27:21 +02:00
|
|
|
import '../../widgets/post/save_post_button.dart';
|
2021-11-12 17:01:17 +01:00
|
|
|
import '../../widgets/pull_to_refresh.dart';
|
2021-09-11 01:04:15 +02:00
|
|
|
import '../../widgets/reveal_after_scroll.dart';
|
|
|
|
import '../../widgets/write_comment.dart';
|
2021-10-01 23:39:43 +02:00
|
|
|
import 'comment_section.dart';
|
|
|
|
import 'full_post_store.dart';
|
2021-09-11 01:04:15 +02:00
|
|
|
|
2021-10-19 23:28:28 +02:00
|
|
|
/// Displays a post with its comment section
|
|
|
|
class FullPostPage extends HookWidget {
|
2021-10-19 23:42:28 +02:00
|
|
|
const FullPostPage._();
|
2021-09-11 01:04:15 +02:00
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2021-10-19 23:28:28 +02:00
|
|
|
final scrollController = useScrollController();
|
|
|
|
|
|
|
|
final loggedInAction =
|
|
|
|
useLoggedInAction(context.read<FullPostStore>().instanceHost);
|
|
|
|
|
2021-11-03 06:21:00 +01:00
|
|
|
return Nested(
|
|
|
|
children: [
|
|
|
|
AsyncStoreListener(
|
|
|
|
asyncStore: context.read<FullPostStore>().fullPostState,
|
|
|
|
),
|
|
|
|
AsyncStoreListener<BlockedCommunity>(
|
|
|
|
asyncStore: context.read<FullPostStore>().communityBlockingState,
|
|
|
|
successMessageBuilder: (context, data) {
|
|
|
|
final name = data.communityView.community.originPreferredName;
|
|
|
|
return '${data.blocked ? 'Blocked' : 'Unblocked'} $name';
|
|
|
|
},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
child: ObserverBuilder<FullPostStore>(
|
|
|
|
builder: (context, store) {
|
|
|
|
Future<void> refresh() async {
|
|
|
|
await store.refresh(context
|
|
|
|
.read<AccountsStore>()
|
|
|
|
.defaultUserDataFor(store.instanceHost)
|
|
|
|
?.jwt);
|
|
|
|
}
|
|
|
|
|
|
|
|
final postStore = store.postStore;
|
|
|
|
|
|
|
|
if (postStore == null) {
|
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(),
|
|
|
|
body: Center(
|
|
|
|
child: (store.fullPostState.isLoading)
|
|
|
|
? const CircularProgressIndicator.adaptive()
|
|
|
|
: FailedToLoad(
|
|
|
|
message: 'Post failed to load', refresh: refresh),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2021-10-19 23:42:28 +02:00
|
|
|
|
2021-11-03 06:21:00 +01:00
|
|
|
final post = postStore.postView;
|
2021-10-19 23:42:28 +02:00
|
|
|
|
2021-11-03 06:21:00 +01:00
|
|
|
// VARIABLES
|
2021-10-19 23:42:28 +02:00
|
|
|
|
2021-11-03 06:21:00 +01:00
|
|
|
sharePost() => share(post.post.apId, context: context);
|
2021-10-19 23:42:28 +02:00
|
|
|
|
2021-11-03 06:21:00 +01:00
|
|
|
comment() async {
|
|
|
|
final newComment = await Navigator.of(context).push(
|
|
|
|
WriteComment.toPostRoute(post.post),
|
|
|
|
);
|
2021-10-19 23:42:28 +02:00
|
|
|
|
2021-11-03 06:21:00 +01:00
|
|
|
if (newComment != null) {
|
|
|
|
store.addComment(newComment);
|
2021-10-19 23:42:28 +02:00
|
|
|
}
|
2021-11-03 06:21:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(
|
|
|
|
centerTitle: false,
|
|
|
|
title: RevealAfterScroll(
|
|
|
|
scrollController: scrollController,
|
|
|
|
after: 65,
|
|
|
|
child: Text(
|
|
|
|
post.community.originPreferredName,
|
|
|
|
overflow: TextOverflow.fade,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
actions: [
|
|
|
|
IconButton(icon: Icon(shareIcon), onPressed: sharePost),
|
2021-12-04 18:03:54 +01:00
|
|
|
MobxProvider.value(
|
2021-11-03 06:21:00 +01:00
|
|
|
value: postStore,
|
|
|
|
child: const SavePostButton(),
|
|
|
|
),
|
|
|
|
IconButton(
|
|
|
|
icon: Icon(moreIcon),
|
|
|
|
onPressed: () => PostMoreMenuButton.show(
|
|
|
|
context: context,
|
|
|
|
postStore: postStore,
|
|
|
|
fullPostStore: store,
|
2021-10-19 23:42:28 +02:00
|
|
|
),
|
|
|
|
),
|
2021-11-03 06:21:00 +01:00
|
|
|
],
|
|
|
|
),
|
|
|
|
floatingActionButton: post.post.locked
|
|
|
|
? null
|
|
|
|
: FloatingActionButton(
|
|
|
|
onPressed: loggedInAction((_) => comment()),
|
|
|
|
child: const Icon(Icons.comment),
|
2021-10-19 23:42:28 +02:00
|
|
|
),
|
2021-11-12 17:01:17 +01:00
|
|
|
body: PullToRefresh(
|
2021-11-03 06:21:00 +01:00
|
|
|
onRefresh: refresh,
|
|
|
|
child: ListView(
|
|
|
|
controller: scrollController,
|
|
|
|
physics: const AlwaysScrollableScrollPhysics(),
|
|
|
|
children: [
|
|
|
|
const SizedBox(height: 15),
|
|
|
|
PostTile.fromPostStore(postStore),
|
|
|
|
const CommentSection(),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
2021-09-11 01:04:15 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2021-10-18 01:11:04 +02:00
|
|
|
|
2021-10-19 01:30:30 +02:00
|
|
|
static Jwt? _tryGetJwt(BuildContext context, String instanceHost) {
|
|
|
|
return context.read<AccountsStore>().defaultUserDataFor(instanceHost)?.jwt;
|
2021-10-18 01:11:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static Route route(int id, String instanceHost) => MaterialPageRoute(
|
2021-12-04 18:03:54 +01:00
|
|
|
builder: (context) => MobxProvider(
|
2021-10-18 01:11:04 +02:00
|
|
|
create: (context) =>
|
|
|
|
FullPostStore(instanceHost: instanceHost, postId: id)
|
2021-10-19 01:30:30 +02:00
|
|
|
..refresh(_tryGetJwt(context, instanceHost)),
|
2021-10-19 23:42:28 +02:00
|
|
|
child: const FullPostPage._(),
|
2021-10-18 01:11:04 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
static Route fromPostViewRoute(PostView postView) => MaterialPageRoute(
|
2021-12-04 18:03:54 +01:00
|
|
|
builder: (context) => MobxProvider(
|
2021-10-18 01:11:04 +02:00
|
|
|
create: (context) => FullPostStore.fromPostView(postView)
|
2021-10-19 01:30:30 +02:00
|
|
|
..refresh(_tryGetJwt(context, postView.instanceHost)),
|
2021-10-19 23:42:28 +02:00
|
|
|
child: const FullPostPage._(),
|
2021-10-18 01:11:04 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
static Route fromPostStoreRoute(PostStore postStore) => MaterialPageRoute(
|
2021-12-04 18:03:54 +01:00
|
|
|
builder: (context) => MobxProvider(
|
2021-10-19 23:42:28 +02:00
|
|
|
create: (context) => FullPostStore.fromPostStore(postStore)
|
|
|
|
..refresh(_tryGetJwt(context, postStore.postView.instanceHost)),
|
|
|
|
child: const FullPostPage._(),
|
|
|
|
),
|
2021-10-18 01:11:04 +02:00
|
|
|
);
|
2021-09-11 01:04:15 +02:00
|
|
|
}
|