refactor to use useMemoized and make subscribe button functional

This commit is contained in:
krawieck 2020-09-15 15:25:07 +02:00
parent 08c80b2568
commit e553089032
1 changed files with 125 additions and 55 deletions

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/gestures.dart';
@ -7,47 +9,60 @@ import 'package:intl/intl.dart';
import 'package:lemmy_api_client/lemmy_api_client.dart';
import 'package:url_launcher/url_launcher.dart' as ul;
import '../hooks/memo_future.dart';
import '../util/api_extensions.dart';
import '../util/goto.dart';
import '../util/hooks/memo_future.dart';
import '../util/intl.dart';
import '../util/text_color.dart';
import '../util/token_or_null.dart';
import '../widgets/badge.dart';
import '../widgets/bottom_modal.dart';
import '../widgets/fullscreenable_image.dart';
import '../widgets/markdown_text.dart';
class CommunityPage extends HookWidget {
final Future<FullCommunityView> _fullCommunityFuture;
final CommunityView _community;
final String instanceUrl;
final String communityName;
final int communityId;
CommunityPage.fromName(
{@required String communityName, @required this.instanceUrl})
: assert(communityName != null),
CommunityPage.fromName({
@required this.communityName,
@required this.instanceUrl,
}) : assert(communityName != null),
assert(instanceUrl != null),
_fullCommunityFuture =
LemmyApi(instanceUrl).v1.getCommunity(name: communityName),
communityId = null,
_community = null;
CommunityPage.fromId({@required int communityId, @required this.instanceUrl})
: assert(communityId != null),
CommunityPage.fromId({
@required this.communityId,
@required this.instanceUrl,
}) : assert(communityId != null),
assert(instanceUrl != null),
_fullCommunityFuture =
LemmyApi(instanceUrl).v1.getCommunity(id: communityId),
communityName = null,
_community = null;
CommunityPage.fromCommunityView(this._community)
: instanceUrl = _community.instanceUrl,
_fullCommunityFuture = LemmyApi(_community.instanceUrl)
.v1
.getCommunity(name: _community.name);
void _subscribe() {
print('SUBSCRIBE');
}
communityId = _community.id,
communityName = _community.name;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
var fullCommunitySnap = useFuture(_fullCommunityFuture);
var fullCommunitySnap = useMemoFuture(() {
final auth = tokenOrNull(context, instanceUrl);
if (communityId != null && instanceUrl != null) {
return LemmyApi(_community.instanceUrl).v1.getCommunity(
id: _community.id,
auth: auth,
);
} else {
return LemmyApi(instanceUrl).v1.getCommunity(
name: communityName,
auth: auth,
);
}
});
final colorOnCard = textColorBasedOnBackground(theme.cardColor);
@ -169,11 +184,8 @@ class CommunityPage extends HookWidget {
icon: Icon(Icons.more_vert), onPressed: _openMoreMenu),
],
flexibleSpace: FlexibleSpaceBar(
background: _CommunityOverview(
community,
instanceUrl: instanceUrl,
subscribe: _subscribe,
),
background:
_CommunityOverview(community, instanceUrl: instanceUrl),
),
),
SliverPersistentHeader(
@ -218,20 +230,16 @@ class CommunityPage extends HookWidget {
class _CommunityOverview extends StatelessWidget {
final CommunityView community;
final String instanceUrl;
final void Function() subscribe;
_CommunityOverview(
this.community, {
@required this.instanceUrl,
@required this.subscribe,
}) : assert(instanceUrl != null),
assert(goToInstance != null),
assert(subscribe != null);
assert(goToInstance != null);
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final colorOnTopOfAccent = textColorBasedOnBackground(theme.accentColor);
final shadow = BoxShadow(color: theme.canvasColor, blurRadius: 5);
final icon = community.icon != null
@ -272,7 +280,6 @@ class _CommunityOverview extends StatelessWidget {
],
)
: null;
final subscribed = community.subscribed ?? false;
return Stack(children: [
if (community.banner != null)
@ -359,32 +366,7 @@ class _CommunityOverview extends StatelessWidget {
],
),
),
// SUBSCRIBE BUTTON
Center(
child: SizedBox(
height: 27,
child: RaisedButton.icon(
padding:
EdgeInsets.symmetric(vertical: 0, horizontal: 20),
onPressed: subscribe,
icon: subscribed
? Icon(Icons.remove,
size: 18, color: colorOnTopOfAccent)
: Icon(Icons.add,
size: 18, color: colorOnTopOfAccent),
color: theme.accentColor,
label: Text(
'${subscribed ? 'un' : ''}subscribe',
style: TextStyle(
color: colorOnTopOfAccent,
fontSize: theme.textTheme.subtitle1.fontSize),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
),
_FollowButton(community),
],
),
),
@ -541,3 +523,91 @@ class _Divider extends StatelessWidget {
child: Divider(),
);
}
class _FollowButton extends HookWidget {
final CommunityView community;
_FollowButton(this.community);
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final colorOnTopOfAccent = textColorBasedOnBackground(theme.accentColor);
final subscribed = community.subscribed ?? false;
final token = tokenOrNull(context, community.instanceUrl);
final isSubbed = useState(subscribed);
final showSpinner = useState(false);
final isPending = useState(false);
subscribe() async {
if (token == null) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text("can't sub when you're not logged in")));
return;
}
isPending.value = true;
var spinnerTimer =
Timer(Duration(milliseconds: 500), () => showSpinner.value = true);
final api = LemmyApi(community.instanceUrl).v1;
try {
await api.followCommunity(
communityId: community.id, follow: !isSubbed.value, auth: token);
isSubbed.value = !isSubbed.value;
// ignore: avoid_catches_without_on_clauses
} catch (e) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Row(
children: [
Icon(Icons.warning),
SizedBox(width: 10),
Text("couldn't ${isSubbed.value ? 'un' : ''}sub :<"),
],
)));
}
// clean up
spinnerTimer.cancel();
isPending.value = false;
showSpinner.value = false;
}
return Center(
child: SizedBox(
height: 27,
width: 160,
child: showSpinner.value
? RaisedButton(
onPressed: null,
child: SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
)
: RaisedButton.icon(
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 20),
onPressed: isPending.value ? () {} : subscribe,
icon: isSubbed.value
? Icon(Icons.remove, size: 18, color: colorOnTopOfAccent)
: Icon(Icons.add, size: 18, color: colorOnTopOfAccent),
color: theme.accentColor,
label: Text(
'${isSubbed.value ? 'un' : ''}subscribe',
style: TextStyle(
color: colorOnTopOfAccent,
fontSize: theme.textTheme.subtitle1.fontSize),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
);
}
}