Code review changes
* remove useless comment from post_status.dart * move fixed in changelog into a proper section * move refresh into a provider create in UserBlocksWrapper * use errorTerm in UserBlocks instead of hardcoded message * add missing trailing comma * add route method BlocksPage * remove useless lint ignore * use originPreferredName instead of referredName * make UserBlocksWrapper private * revise AsyncStoreListener
This commit is contained in:
parent
cb76875cee
commit
aa448adeb7
|
@ -5,7 +5,10 @@
|
||||||
- Logging: local logs about some actions/errors. Can be accessed from **settings > about lemmur > logs**
|
- Logging: local logs about some actions/errors. Can be accessed from **settings > about lemmur > logs**
|
||||||
- Android theme-aware splash screen (thanks to [@mimi89999](https://github.com/mimi89999))
|
- Android theme-aware splash screen (thanks to [@mimi89999](https://github.com/mimi89999))
|
||||||
- Blocking of users and communities (from post and from comment)
|
- Blocking of users and communities (from post and from comment)
|
||||||
|
-
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed a bug where post would go out of sync with full version of the post
|
||||||
## v0.6.0 - 2021-09-06
|
## v0.6.0 - 2021-09-06
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -13,10 +16,6 @@
|
||||||
- Support for Lemmy v0.12.0
|
- Support for Lemmy v0.12.0
|
||||||
- Show cake day on a user's profile and next to their name in a comment
|
- Show cake day on a user's profile and next to their name in a comment
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed a bug where post would go out of sync with full version of the post
|
|
||||||
|
|
||||||
## v0.5.0 - 2021-04-29
|
## v0.5.0 - 2021-04-29
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -58,9 +58,8 @@ class FullPostPage extends StatelessWidget {
|
||||||
child: AsyncStoreListener<BlockedCommunity>(
|
child: AsyncStoreListener<BlockedCommunity>(
|
||||||
asyncStore: context.read<FullPostStore>().communityBlockingState,
|
asyncStore: context.read<FullPostStore>().communityBlockingState,
|
||||||
successMessageBuilder: (context, asyncStore) {
|
successMessageBuilder: (context, asyncStore) {
|
||||||
final name =
|
final name = asyncStore.communityView.community.originPreferredName;
|
||||||
asyncStore.data.communityView.community.originPreferredName;
|
return '${asyncStore.blocked ? 'Blocked' : 'Unblocked'} $name';
|
||||||
return '${asyncStore.data.blocked ? 'Blocked' : 'Unblocked'} $name';
|
|
||||||
},
|
},
|
||||||
child: const _FullPostPage(),
|
child: const _FullPostPage(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -38,7 +38,7 @@ class BlocksPage extends HookWidget {
|
||||||
body: TabBarView(
|
body: TabBarView(
|
||||||
children: [
|
children: [
|
||||||
for (final instance in accStore.loggedInInstances)
|
for (final instance in accStore.loggedInInstances)
|
||||||
UserBlocksWrapper(
|
_UserBlocksWrapper(
|
||||||
instanceHost: instance,
|
instanceHost: instance,
|
||||||
username: accStore.defaultUsernameFor(instance)!,
|
username: accStore.defaultUsernameFor(instance)!,
|
||||||
)
|
)
|
||||||
|
@ -47,13 +47,17 @@ class BlocksPage extends HookWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Route route() =>
|
||||||
|
MaterialPageRoute(builder: (context) => const BlocksPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserBlocksWrapper extends StatelessWidget {
|
class _UserBlocksWrapper extends StatelessWidget {
|
||||||
final String instanceHost;
|
final String instanceHost;
|
||||||
final String username;
|
final String username;
|
||||||
|
|
||||||
const UserBlocksWrapper({required this.instanceHost, required this.username});
|
const _UserBlocksWrapper(
|
||||||
|
{required this.instanceHost, required this.username});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -64,7 +68,7 @@ class UserBlocksWrapper extends StatelessWidget {
|
||||||
.read<AccountsStore>()
|
.read<AccountsStore>()
|
||||||
.userDataFor(instanceHost, username)!
|
.userDataFor(instanceHost, username)!
|
||||||
.jwt,
|
.jwt,
|
||||||
),
|
)..refresh(),
|
||||||
child: const _UserBlocks(),
|
child: const _UserBlocks(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -75,8 +79,6 @@ class _UserBlocks extends HookWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
useMemoized(() => context.read<BlocksStore>().refresh(), []);
|
|
||||||
|
|
||||||
return ObserverBuilder<BlocksStore>(
|
return ObserverBuilder<BlocksStore>(
|
||||||
builder: (context, store) {
|
builder: (context, store) {
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
|
@ -91,16 +93,19 @@ class _UserBlocks extends HookWidget {
|
||||||
child: Center(child: CircularProgressIndicator.adaptive()),
|
child: Center(child: CircularProgressIndicator.adaptive()),
|
||||||
)
|
)
|
||||||
else if (store.blocksState.errorTerm != null)
|
else if (store.blocksState.errorTerm != null)
|
||||||
const Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 64),
|
padding: const EdgeInsets.only(top: 64),
|
||||||
child: Center(child: Text('error UwU')),
|
child: Center(child: Text(store.blocksState.errorTerm!)),
|
||||||
)
|
)
|
||||||
else ...[
|
else ...[
|
||||||
for (final user in store.blockedUsers)
|
for (final user in store.blockedUsers)
|
||||||
_BlockPersonTile(user, key: ValueKey(user)),
|
_BlockPersonTile(user, key: ValueKey(user)),
|
||||||
if (store.blockedUsers.isEmpty)
|
if (store.blockedUsers.isEmpty)
|
||||||
const ListTile(
|
const ListTile(
|
||||||
title: Center(child: Text('No users blocked'))),
|
title: Center(
|
||||||
|
child: Text('No users blocked'),
|
||||||
|
),
|
||||||
|
),
|
||||||
// TODO: add user search & block
|
// TODO: add user search & block
|
||||||
// ListTile(
|
// ListTile(
|
||||||
// leading: const Padding(
|
// leading: const Padding(
|
||||||
|
@ -166,7 +171,6 @@ class _BlockPersonTile extends HookWidget {
|
||||||
);
|
);
|
||||||
} on SocketException {
|
} on SocketException {
|
||||||
showSnackBar('Network error');
|
showSnackBar('Network error');
|
||||||
// ignore: avoid_catches_without_on_clauses
|
|
||||||
} on LemmyApiException catch (e) {
|
} on LemmyApiException catch (e) {
|
||||||
showSnackBar(e.message);
|
showSnackBar(e.message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -178,7 +182,7 @@ class _BlockPersonTile extends HookWidget {
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: Avatar(url: person.avatar),
|
leading: Avatar(url: person.avatar),
|
||||||
title: Text(person.preferredName),
|
title: Text(person.originPreferredName),
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
icon: pending.value
|
icon: pending.value
|
||||||
? const CircularProgressIndicator.adaptive()
|
? const CircularProgressIndicator.adaptive()
|
||||||
|
@ -225,7 +229,6 @@ class _BlockCommunityTile extends HookWidget {
|
||||||
showSnackBar('Network error');
|
showSnackBar('Network error');
|
||||||
} on LemmyApiException catch (e) {
|
} on LemmyApiException catch (e) {
|
||||||
showSnackBar(e.message);
|
showSnackBar(e.message);
|
||||||
// ignore: avoid_catches_without_on_clauses
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showSnackBar(e.toString());
|
showSnackBar(e.toString());
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -22,6 +22,7 @@ class SettingsPage extends HookWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final hasAnyUsers = useAccountsStoreSelect((store) => !store.hasNoAccount);
|
final hasAnyUsers = useAccountsStoreSelect((store) => !store.hasNoAccount);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(L10n.of(context)!.settings),
|
title: Text(L10n.of(context)!.settings),
|
||||||
|
@ -47,7 +48,7 @@ class SettingsPage extends HookWidget {
|
||||||
leading: const Icon(Icons.block),
|
leading: const Icon(Icons.block),
|
||||||
title: const Text('Blocks'),
|
title: const Text('Blocks'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
goTo(context, (_) => const BlocksPage());
|
Navigator.of(context).push(BlocksPage.route());
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
|
|
@ -7,17 +7,15 @@ import 'observer_consumers.dart';
|
||||||
|
|
||||||
class AsyncStoreListener<T> extends StatelessWidget {
|
class AsyncStoreListener<T> extends StatelessWidget {
|
||||||
final AsyncStore<T> asyncStore;
|
final AsyncStore<T> asyncStore;
|
||||||
final String? successMessage;
|
|
||||||
final String Function(
|
final String Function(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
AsyncStateData<T> asyncStore,
|
T data,
|
||||||
)? successMessageBuilder;
|
)? successMessageBuilder;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
const AsyncStoreListener({
|
const AsyncStoreListener({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.asyncStore,
|
required this.asyncStore,
|
||||||
this.successMessage,
|
|
||||||
this.successMessageBuilder,
|
this.successMessageBuilder,
|
||||||
required this.child,
|
required this.child,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
@ -34,15 +32,12 @@ class AsyncStoreListener<T> extends StatelessWidget {
|
||||||
..hideCurrentSnackBar()
|
..hideCurrentSnackBar()
|
||||||
..showSnackBar(SnackBar(content: Text(errorTerm.tr(context))));
|
..showSnackBar(SnackBar(content: Text(errorTerm.tr(context))));
|
||||||
} else if (store.asyncState is AsyncStateData &&
|
} else if (store.asyncState is AsyncStateData &&
|
||||||
(successMessage != null || successMessageBuilder != null)) {
|
(successMessageBuilder != null)) {
|
||||||
ScaffoldMessenger.of(context)
|
ScaffoldMessenger.of(context)
|
||||||
..hideCurrentSnackBar()
|
..hideCurrentSnackBar()
|
||||||
..showSnackBar(SnackBar(
|
..showSnackBar(SnackBar(
|
||||||
content: Text(successMessageBuilder?.call(
|
content: Text(successMessageBuilder!(
|
||||||
context,
|
context, (store.asyncState as AsyncStateData).data))));
|
||||||
store.asyncState as AsyncStateData<T>,
|
|
||||||
) ??
|
|
||||||
successMessage!)));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: child,
|
child: child,
|
||||||
|
|
|
@ -93,8 +93,8 @@ class CommentWidget extends StatelessWidget {
|
||||||
builder: (context, child) => AsyncStoreListener<BlockedPerson>(
|
builder: (context, child) => AsyncStoreListener<BlockedPerson>(
|
||||||
asyncStore: context.read<CommentStore>().blockingState,
|
asyncStore: context.read<CommentStore>().blockingState,
|
||||||
successMessageBuilder: (context, state) {
|
successMessageBuilder: (context, state) {
|
||||||
final name = state.data.personView.person.preferredName;
|
final name = state.personView.person.preferredName;
|
||||||
return state.data.blocked ? '$name blocked' : '$name unblocked';
|
return state.blocked ? '$name blocked' : '$name unblocked';
|
||||||
},
|
},
|
||||||
child: AsyncStoreListener(
|
child: AsyncStoreListener(
|
||||||
asyncStore: context.read<CommentStore>().votingState,
|
asyncStore: context.read<CommentStore>().votingState,
|
||||||
|
|
|
@ -40,8 +40,8 @@ class PostTile extends StatelessWidget {
|
||||||
child: AsyncStoreListener<BlockedPerson>(
|
child: AsyncStoreListener<BlockedPerson>(
|
||||||
asyncStore: context.read<PostStore>().userBlockingState,
|
asyncStore: context.read<PostStore>().userBlockingState,
|
||||||
successMessageBuilder: (context, state) {
|
successMessageBuilder: (context, state) {
|
||||||
final name = state.data.personView.person.preferredName;
|
final name = state.personView.person.preferredName;
|
||||||
return state.data.blocked ? '$name blocked' : '$name unblocked';
|
return state.blocked ? '$name blocked' : '$name unblocked';
|
||||||
},
|
},
|
||||||
child: const _Post(),
|
child: const _Post(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,7 +1 @@
|
||||||
// class PostStatus {
|
|
||||||
// final bool full;
|
|
||||||
|
|
||||||
// const PostStatus({required this.full});
|
|
||||||
// }
|
|
||||||
|
|
||||||
typedef IsFullPost = bool;
|
typedef IsFullPost = bool;
|
||||||
|
|
Loading…
Reference in New Issue