follow and favorite callbacks

This commit is contained in:
wgh19
2024-05-22 20:59:15 +08:00
parent 7641cc8f5c
commit 1d49f1c387
4 changed files with 105 additions and 26 deletions

View File

@@ -9,6 +9,8 @@ import '../network/network.dart';
import '../pages/illust_page.dart'; import '../pages/illust_page.dart';
import 'md.dart'; import 'md.dart';
typedef UpdateFavoriteFunc = void Function(bool v);
class IllustWidget extends StatefulWidget { class IllustWidget extends StatefulWidget {
const IllustWidget(this.illust, {this.onTap, super.key}); const IllustWidget(this.illust, {this.onTap, super.key});
@@ -16,6 +18,8 @@ class IllustWidget extends StatefulWidget {
final void Function()? onTap; final void Function()? onTap;
static Map<String, UpdateFavoriteFunc> favoriteCallbacks = {};
@override @override
State<IllustWidget> createState() => _IllustWidgetState(); State<IllustWidget> createState() => _IllustWidgetState();
} }
@@ -26,6 +30,22 @@ class _IllustWidgetState extends State<IllustWidget> {
final contextController = FlyoutController(); final contextController = FlyoutController();
final contextAttachKey = GlobalKey(); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constrains) { return LayoutBuilder(builder: (context, constrains) {
@@ -48,11 +68,7 @@ class _IllustWidgetState extends State<IllustWidget> {
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
child: GestureDetector( child: GestureDetector(
onTap: widget.onTap ?? (){ onTap: widget.onTap ?? (){
context.to(() => IllustPage(widget.illust, favoriteCallback: (v) { context.to(() => IllustPage(widget.illust));
setState(() {
widget.illust.isBookmarked = v;
});
},));
}, },
onSecondaryTapUp: showMenu, onSecondaryTapUp: showMenu,
child: ClipRRect( child: ClipRRect(
@@ -181,11 +197,7 @@ class _IllustWidgetState extends State<IllustWidget> {
return MenuFlyout( return MenuFlyout(
items: [ items: [
MenuFlyoutItem(text: Text("View".tl), onPressed: (){ MenuFlyoutItem(text: Text("View".tl), onPressed: (){
context.to(() => IllustPage(widget.illust, favoriteCallback: (v) { context.to(() => IllustPage(widget.illust));
setState(() {
widget.illust.isBookmarked = v;
});
},));
}), }),
MenuFlyoutItem(text: Text("Private Favorite".tl), onPressed: (){ MenuFlyoutItem(text: Text("Private Favorite".tl), onPressed: (){
favorite("private"); favorite("private");

View File

@@ -4,22 +4,43 @@ import 'package:fluent_ui/fluent_ui.dart';
import 'package:pixes/components/animated_image.dart'; import 'package:pixes/components/animated_image.dart';
import 'package:pixes/foundation/app.dart'; import 'package:pixes/foundation/app.dart';
import 'package:pixes/foundation/image_provider.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/pages/user_info_page.dart';
import 'package:pixes/utils/translation.dart'; import 'package:pixes/utils/translation.dart';
import '../network/network.dart'; import '../network/network.dart';
import 'md.dart'; import 'md.dart';
typedef UpdateFollowCallback = void Function(bool isFollowed);
class UserPreviewWidget extends StatefulWidget { class UserPreviewWidget extends StatefulWidget {
const UserPreviewWidget(this.user, {super.key}); const UserPreviewWidget(this.user, {super.key});
final UserPreview user; final UserPreview user;
static Map<String, UpdateFollowCallback> followCallbacks = {};
@override @override
State<UserPreviewWidget> createState() => _UserPreviewWidgetState(); State<UserPreviewWidget> createState() => _UserPreviewWidgetState();
} }
class _UserPreviewWidgetState extends State<UserPreviewWidget> { class _UserPreviewWidgetState extends State<UserPreviewWidget> {
@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; bool isFollowing = false;
void follow() async { void follow() async {
@@ -39,6 +60,9 @@ class _UserPreviewWidgetState extends State<UserPreviewWidget> {
setState(() { setState(() {
isFollowing = false; isFollowing = false;
}); });
UserInfoPage.followCallbacks[widget.user.id.toString()]
?.call(widget.user.isFollowed);
IllustPage.updateFollow(widget.user.id.toString(), widget.user.isFollowed);
} }
@override @override

View File

@@ -11,6 +11,7 @@ import 'package:pixes/components/loading.dart';
import 'package:pixes/components/message.dart'; import 'package:pixes/components/message.dart';
import 'package:pixes/components/page_route.dart'; import 'package:pixes/components/page_route.dart';
import 'package:pixes/components/title_bar.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/app.dart';
import 'package:pixes/foundation/image_provider.dart'; import 'package:pixes/foundation/image_provider.dart';
import 'package:pixes/network/download.dart'; import 'package:pixes/network/download.dart';
@@ -128,22 +129,47 @@ class _IllustGalleryPageState extends State<IllustGalleryPage> {
} }
class IllustPage extends StatefulWidget { class IllustPage extends StatefulWidget {
const IllustPage(this.illust, const IllustPage(this.illust, {this.nextPage, this.previousPage, super.key});
{this.favoriteCallback, this.nextPage, this.previousPage, super.key});
final Illust illust; final Illust illust;
final void Function(bool)? favoriteCallback;
final void Function()? nextPage; final void Function()? nextPage;
final void Function()? previousPage; final void Function()? previousPage;
static Map<String, UpdateFollowCallback> followCallbacks = {};
static void updateFollow(String uid, bool isFollowed) {
followCallbacks.forEach((key, value) {
if (key.startsWith("$uid#")) {
value(isFollowed);
}
});
}
@override @override
State<IllustPage> createState() => _IllustPageState(); State<IllustPage> createState() => _IllustPageState();
} }
class _IllustPageState extends State<IllustPage> { class _IllustPageState extends State<IllustPage> {
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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var isBlocked = checkIllusts([widget.illust]).isEmpty; var isBlocked = checkIllusts([widget.illust]).isEmpty;
@@ -168,7 +194,6 @@ class _IllustPageState extends State<IllustPage> {
widget.illust, widget.illust,
constrains.maxHeight, constrains.maxHeight,
constrains.maxWidth, constrains.maxWidth,
favoriteCallback: widget.favoriteCallback,
updateCallback: () => setState(() {}), updateCallback: () => setState(() {}),
), ),
if (isBlocked) if (isBlocked)
@@ -320,10 +345,7 @@ class _IllustPageState extends State<IllustPage> {
} }
class _BottomBar extends StatefulWidget { class _BottomBar extends StatefulWidget {
const _BottomBar(this.illust, this.height, this.width, const _BottomBar(this.illust, this.height, this.width, {this.updateCallback});
{this.favoriteCallback, this.updateCallback});
final void Function(bool)? favoriteCallback;
final void Function()? updateCallback; final void Function()? updateCallback;
@@ -538,6 +560,10 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin {
setState(() { setState(() {
isFollowing = false; 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; final bool showUserName = MediaQuery.of(context).size.width > 640;
@@ -561,9 +587,6 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin {
child: GestureDetector( child: GestureDetector(
onTap: () => context.to(() => UserInfoPage( onTap: () => context.to(() => UserInfoPage(
widget.illust.author.id.toString(), widget.illust.author.id.toString(),
followCallback: (b) => setState(() {
widget.illust.author.isFollowed = b;
}),
)), )),
child: AnimatedImage( child: AnimatedImage(
image: CachedImageProvider(widget.illust.author.avatar), image: CachedImageProvider(widget.illust.author.avatar),
@@ -633,7 +656,8 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin {
} }
} else { } else {
widget.illust.isBookmarked = !widget.illust.isBookmarked; widget.illust.isBookmarked = !widget.illust.isBookmarked;
widget.favoriteCallback?.call(widget.illust.isBookmarked); IllustWidget.favoriteCallbacks[widget.illust.id.toString()]
?.call(widget.illust.isBookmarked);
} }
setState(() { setState(() {
isBookmarking = false; isBookmarking = false;

View File

@@ -21,17 +21,34 @@ import '../components/illust_widget.dart';
import 'illust_page.dart'; import 'illust_page.dart';
class UserInfoPage extends StatefulWidget { class UserInfoPage extends StatefulWidget {
const UserInfoPage(this.id, {this.followCallback, super.key}); const UserInfoPage(this.id, {super.key});
final String id; final String id;
final void Function(bool)? followCallback; static Map<String, UpdateFollowCallback> followCallbacks = {};
@override @override
State<UserInfoPage> createState() => _UserInfoPageState(); State<UserInfoPage> createState() => _UserInfoPageState();
} }
class _UserInfoPageState extends LoadingState<UserInfoPage, UserDetails> { class _UserInfoPageState extends LoadingState<UserInfoPage, UserDetails> {
@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; int page = 0;
@override @override
@@ -94,7 +111,9 @@ class _UserInfoPageState extends LoadingState<UserInfoPage, UserDetails> {
} }
} else { } else {
data!.isFollowed = !data!.isFollowed; 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(() { setState(() {
isFollowing = false; isFollowing = false;