From 1d49f1c387aefab4562e6b8d4e3f942da20426a3 Mon Sep 17 00:00:00 2001 From: wgh19 Date: Wed, 22 May 2024 20:59:15 +0800 Subject: [PATCH] follow and favorite callbacks --- lib/components/illust_widget.dart | 32 +++++++++++++------- lib/components/user_preview.dart | 24 +++++++++++++++ lib/pages/illust_page.dart | 50 +++++++++++++++++++++++-------- lib/pages/user_info_page.dart | 25 ++++++++++++++-- 4 files changed, 105 insertions(+), 26 deletions(-) diff --git a/lib/components/illust_widget.dart b/lib/components/illust_widget.dart index ceb1d6b..615253f 100644 --- a/lib/components/illust_widget.dart +++ b/lib/components/illust_widget.dart @@ -9,6 +9,8 @@ import '../network/network.dart'; import '../pages/illust_page.dart'; import 'md.dart'; +typedef UpdateFavoriteFunc = void Function(bool v); + class IllustWidget extends StatefulWidget { const IllustWidget(this.illust, {this.onTap, super.key}); @@ -16,6 +18,8 @@ class IllustWidget extends StatefulWidget { final void Function()? onTap; + static Map favoriteCallbacks = {}; + @override State createState() => _IllustWidgetState(); } @@ -26,6 +30,22 @@ class _IllustWidgetState extends State { final contextController = FlyoutController(); final contextAttachKey = GlobalKey(); + @override + void initState() { + IllustWidget.favoriteCallbacks[widget.illust.id.toString()] = (v) { + setState(() { + widget.illust.isBookmarked = v; + }); + }; + super.initState(); + } + + @override + void dispose() { + IllustWidget.favoriteCallbacks.remove(widget.illust.id.toString()); + super.dispose(); + } + @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constrains) { @@ -48,11 +68,7 @@ class _IllustWidgetState extends State { margin: EdgeInsets.zero, child: GestureDetector( onTap: widget.onTap ?? (){ - context.to(() => IllustPage(widget.illust, favoriteCallback: (v) { - setState(() { - widget.illust.isBookmarked = v; - }); - },)); + context.to(() => IllustPage(widget.illust)); }, onSecondaryTapUp: showMenu, child: ClipRRect( @@ -181,11 +197,7 @@ class _IllustWidgetState extends State { return MenuFlyout( items: [ MenuFlyoutItem(text: Text("View".tl), onPressed: (){ - context.to(() => IllustPage(widget.illust, favoriteCallback: (v) { - setState(() { - widget.illust.isBookmarked = v; - }); - },)); + context.to(() => IllustPage(widget.illust)); }), MenuFlyoutItem(text: Text("Private Favorite".tl), onPressed: (){ favorite("private"); diff --git a/lib/components/user_preview.dart b/lib/components/user_preview.dart index baa9317..3fecf41 100644 --- a/lib/components/user_preview.dart +++ b/lib/components/user_preview.dart @@ -4,22 +4,43 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:pixes/components/animated_image.dart'; import 'package:pixes/foundation/app.dart'; import 'package:pixes/foundation/image_provider.dart'; +import 'package:pixes/pages/illust_page.dart'; import 'package:pixes/pages/user_info_page.dart'; import 'package:pixes/utils/translation.dart'; import '../network/network.dart'; import 'md.dart'; +typedef UpdateFollowCallback = void Function(bool isFollowed); + class UserPreviewWidget extends StatefulWidget { const UserPreviewWidget(this.user, {super.key}); final UserPreview user; + static Map followCallbacks = {}; + @override State createState() => _UserPreviewWidgetState(); } class _UserPreviewWidgetState extends State { + @override + void initState() { + UserPreviewWidget.followCallbacks[widget.user.id.toString()] = (v) { + setState(() { + widget.user.isFollowed = v; + }); + }; + super.initState(); + } + + @override + void dispose() { + UserPreviewWidget.followCallbacks.remove(widget.user.id.toString()); + super.dispose(); + } + bool isFollowing = false; void follow() async { @@ -39,6 +60,9 @@ class _UserPreviewWidgetState extends State { setState(() { isFollowing = false; }); + UserInfoPage.followCallbacks[widget.user.id.toString()] + ?.call(widget.user.isFollowed); + IllustPage.updateFollow(widget.user.id.toString(), widget.user.isFollowed); } @override diff --git a/lib/pages/illust_page.dart b/lib/pages/illust_page.dart index b4cda2a..51d2715 100644 --- a/lib/pages/illust_page.dart +++ b/lib/pages/illust_page.dart @@ -11,6 +11,7 @@ import 'package:pixes/components/loading.dart'; import 'package:pixes/components/message.dart'; import 'package:pixes/components/page_route.dart'; import 'package:pixes/components/title_bar.dart'; +import 'package:pixes/components/user_preview.dart'; import 'package:pixes/foundation/app.dart'; import 'package:pixes/foundation/image_provider.dart'; import 'package:pixes/network/download.dart'; @@ -128,22 +129,47 @@ class _IllustGalleryPageState extends State { } class IllustPage extends StatefulWidget { - const IllustPage(this.illust, - {this.favoriteCallback, this.nextPage, this.previousPage, super.key}); + const IllustPage(this.illust, {this.nextPage, this.previousPage, super.key}); final Illust illust; - final void Function(bool)? favoriteCallback; - final void Function()? nextPage; final void Function()? previousPage; + static Map followCallbacks = {}; + + static void updateFollow(String uid, bool isFollowed) { + followCallbacks.forEach((key, value) { + if (key.startsWith("$uid#")) { + value(isFollowed); + } + }); + } + @override State createState() => _IllustPageState(); } class _IllustPageState extends State { + String get id => "${widget.illust.author.id}#${widget.illust.id}"; + + @override + void initState() { + IllustPage.followCallbacks[id] = (v) { + setState(() { + widget.illust.author.isFollowed = v; + }); + }; + super.initState(); + } + + @override + void dispose() { + IllustPage.followCallbacks.remove(id); + super.dispose(); + } + @override Widget build(BuildContext context) { var isBlocked = checkIllusts([widget.illust]).isEmpty; @@ -168,7 +194,6 @@ class _IllustPageState extends State { widget.illust, constrains.maxHeight, constrains.maxWidth, - favoriteCallback: widget.favoriteCallback, updateCallback: () => setState(() {}), ), if (isBlocked) @@ -320,10 +345,7 @@ class _IllustPageState extends State { } class _BottomBar extends StatefulWidget { - const _BottomBar(this.illust, this.height, this.width, - {this.favoriteCallback, this.updateCallback}); - - final void Function(bool)? favoriteCallback; + const _BottomBar(this.illust, this.height, this.width, {this.updateCallback}); final void Function()? updateCallback; @@ -538,6 +560,10 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin { setState(() { isFollowing = false; }); + UserInfoPage.followCallbacks[widget.illust.author.id.toString()] + ?.call(widget.illust.author.isFollowed); + UserPreviewWidget.followCallbacks[widget.illust.author.id.toString()] + ?.call(widget.illust.author.isFollowed); } final bool showUserName = MediaQuery.of(context).size.width > 640; @@ -561,9 +587,6 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin { child: GestureDetector( onTap: () => context.to(() => UserInfoPage( widget.illust.author.id.toString(), - followCallback: (b) => setState(() { - widget.illust.author.isFollowed = b; - }), )), child: AnimatedImage( image: CachedImageProvider(widget.illust.author.avatar), @@ -633,7 +656,8 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin { } } else { widget.illust.isBookmarked = !widget.illust.isBookmarked; - widget.favoriteCallback?.call(widget.illust.isBookmarked); + IllustWidget.favoriteCallbacks[widget.illust.id.toString()] + ?.call(widget.illust.isBookmarked); } setState(() { isBookmarking = false; diff --git a/lib/pages/user_info_page.dart b/lib/pages/user_info_page.dart index 7b2ce20..016f34f 100644 --- a/lib/pages/user_info_page.dart +++ b/lib/pages/user_info_page.dart @@ -21,17 +21,34 @@ import '../components/illust_widget.dart'; import 'illust_page.dart'; class UserInfoPage extends StatefulWidget { - const UserInfoPage(this.id, {this.followCallback, super.key}); + const UserInfoPage(this.id, {super.key}); final String id; - final void Function(bool)? followCallback; + static Map followCallbacks = {}; @override State createState() => _UserInfoPageState(); } class _UserInfoPageState extends LoadingState { + @override + void initState() { + UserInfoPage.followCallbacks[widget.id] = (v) { + if (data == null) return; + setState(() { + data!.isFollowed = v; + }); + }; + super.initState(); + } + + @override + void dispose() { + UserInfoPage.followCallbacks.remove(widget.id); + super.dispose(); + } + int page = 0; @override @@ -94,7 +111,9 @@ class _UserInfoPageState extends LoadingState { } } else { data!.isFollowed = !data!.isFollowed; - widget.followCallback?.call(data!.isFollowed); + UserPreviewWidget.followCallbacks[data!.id.toString()] + ?.call(data!.isFollowed); + IllustPage.updateFollow(data!.id.toString(), data!.isFollowed); } setState(() { isFollowing = false;