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:cached_network_image/cached_network_image.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/gestures.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:lemmy_api_client/lemmy_api_client.dart';
import 'package:url_launcher/url_launcher.dart' as ul; import 'package:url_launcher/url_launcher.dart' as ul;
import '../hooks/memo_future.dart';
import '../util/api_extensions.dart'; import '../util/api_extensions.dart';
import '../util/goto.dart'; import '../util/goto.dart';
import '../util/hooks/memo_future.dart';
import '../util/intl.dart'; import '../util/intl.dart';
import '../util/text_color.dart'; import '../util/text_color.dart';
import '../util/token_or_null.dart';
import '../widgets/badge.dart'; import '../widgets/badge.dart';
import '../widgets/bottom_modal.dart'; import '../widgets/bottom_modal.dart';
import '../widgets/fullscreenable_image.dart'; import '../widgets/fullscreenable_image.dart';
import '../widgets/markdown_text.dart'; import '../widgets/markdown_text.dart';
class CommunityPage extends HookWidget { class CommunityPage extends HookWidget {
final Future<FullCommunityView> _fullCommunityFuture;
final CommunityView _community; final CommunityView _community;
final String instanceUrl; final String instanceUrl;
final String communityName;
final int communityId;
CommunityPage.fromName( CommunityPage.fromName({
{@required String communityName, @required this.instanceUrl}) @required this.communityName,
: assert(communityName != null), @required this.instanceUrl,
}) : assert(communityName != null),
assert(instanceUrl != null), assert(instanceUrl != null),
_fullCommunityFuture = communityId = null,
LemmyApi(instanceUrl).v1.getCommunity(name: communityName),
_community = null; _community = null;
CommunityPage.fromId({@required int communityId, @required this.instanceUrl}) CommunityPage.fromId({
: assert(communityId != null), @required this.communityId,
@required this.instanceUrl,
}) : assert(communityId != null),
assert(instanceUrl != null), assert(instanceUrl != null),
_fullCommunityFuture = communityName = null,
LemmyApi(instanceUrl).v1.getCommunity(id: communityId),
_community = null; _community = null;
CommunityPage.fromCommunityView(this._community) CommunityPage.fromCommunityView(this._community)
: instanceUrl = _community.instanceUrl, : instanceUrl = _community.instanceUrl,
_fullCommunityFuture = LemmyApi(_community.instanceUrl) communityId = _community.id,
.v1 communityName = _community.name;
.getCommunity(name: _community.name);
void _subscribe() {
print('SUBSCRIBE');
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(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); final colorOnCard = textColorBasedOnBackground(theme.cardColor);
@ -169,11 +184,8 @@ class CommunityPage extends HookWidget {
icon: Icon(Icons.more_vert), onPressed: _openMoreMenu), icon: Icon(Icons.more_vert), onPressed: _openMoreMenu),
], ],
flexibleSpace: FlexibleSpaceBar( flexibleSpace: FlexibleSpaceBar(
background: _CommunityOverview( background:
community, _CommunityOverview(community, instanceUrl: instanceUrl),
instanceUrl: instanceUrl,
subscribe: _subscribe,
),
), ),
), ),
SliverPersistentHeader( SliverPersistentHeader(
@ -218,20 +230,16 @@ class CommunityPage extends HookWidget {
class _CommunityOverview extends StatelessWidget { class _CommunityOverview extends StatelessWidget {
final CommunityView community; final CommunityView community;
final String instanceUrl; final String instanceUrl;
final void Function() subscribe;
_CommunityOverview( _CommunityOverview(
this.community, { this.community, {
@required this.instanceUrl, @required this.instanceUrl,
@required this.subscribe,
}) : assert(instanceUrl != null), }) : assert(instanceUrl != null),
assert(goToInstance != null), assert(goToInstance != null);
assert(subscribe != null);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final colorOnTopOfAccent = textColorBasedOnBackground(theme.accentColor);
final shadow = BoxShadow(color: theme.canvasColor, blurRadius: 5); final shadow = BoxShadow(color: theme.canvasColor, blurRadius: 5);
final icon = community.icon != null final icon = community.icon != null
@ -272,7 +280,6 @@ class _CommunityOverview extends StatelessWidget {
], ],
) )
: null; : null;
final subscribed = community.subscribed ?? false;
return Stack(children: [ return Stack(children: [
if (community.banner != null) if (community.banner != null)
@ -359,32 +366,7 @@ class _CommunityOverview extends StatelessWidget {
], ],
), ),
), ),
// SUBSCRIBE BUTTON _FollowButton(community),
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),
),
),
),
),
], ],
), ),
), ),
@ -541,3 +523,91 @@ class _Divider extends StatelessWidget {
child: Divider(), 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),
),
),
),
);
}
}