diff --git a/lib/components/user_preview.dart b/lib/components/user_preview.dart index 794c8c3..d923471 100644 --- a/lib/components/user_preview.dart +++ b/lib/components/user_preview.dart @@ -70,7 +70,11 @@ class _UserPreviewWidgetState extends State { Row( children: [ Button( - onPressed: () => context.to(() => UserInfoPage(widget.user.id.toString())), + onPressed: () => context.to(() => UserInfoPage(widget.user.id.toString(), followCallback: (v){ + setState(() { + widget.user.isFollowed = v; + }); + },)), child: Text("View".tl,), ), const SizedBox(width: 8,), diff --git a/lib/network/models.dart b/lib/network/models.dart index 4d4ab3f..82042bc 100644 --- a/lib/network/models.dart +++ b/lib/network/models.dart @@ -54,7 +54,7 @@ class UserDetails { final String account; final String avatar; final String comment; - final bool isFollowed; + bool isFollowed; final bool isBlocking; final String? webpage; final String gender; diff --git a/lib/pages/illust_page.dart b/lib/pages/illust_page.dart index 2bdbf52..6623a97 100644 --- a/lib/pages/illust_page.dart +++ b/lib/pages/illust_page.dart @@ -268,7 +268,11 @@ class _BottomBarState extends State<_BottomBar> { color: ColorScheme.of(context).secondaryContainer, child: GestureDetector( onTap: () => context.to(() => - UserInfoPage(widget.illust.author.id.toString())), + UserInfoPage( + widget.illust.author.id.toString(), + followCallback: (b) => setState(() { + widget.illust.author.isFollowed = b; + }),)), child: AnimatedImage( image: CachedImageProvider(widget.illust.author.avatar), width: 40, diff --git a/lib/pages/user_info_page.dart b/lib/pages/user_info_page.dart index 3880d63..264fb6d 100644 --- a/lib/pages/user_info_page.dart +++ b/lib/pages/user_info_page.dart @@ -1,6 +1,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +import 'package:pixes/appdata.dart'; import 'package:pixes/components/loading.dart'; import 'package:pixes/components/md.dart'; import 'package:pixes/foundation/app.dart'; @@ -13,10 +14,12 @@ import 'package:url_launcher/url_launcher_string.dart'; import '../components/illust_widget.dart'; class UserInfoPage extends StatefulWidget { - const UserInfoPage(this.id, {super.key}); + const UserInfoPage(this.id, {this.followCallback, super.key}); final String id; + final void Function(bool)? followCallback; + @override State createState() => _UserInfoPageState(); } @@ -36,6 +39,28 @@ class _UserInfoPageState extends LoadingState { ); } + bool isFollowing = false; + + void follow() async{ + if(isFollowing) return; + setState(() { + isFollowing = true; + }); + var method = data!.isFollowed ? "delete" : "add"; + var res = await Network().follow(data!.id.toString(), method); + if(res.error) { + if(mounted) { + context.showToast(message: "Network Error"); + } + } else { + data!.isFollowed = !data!.isFollowed; + widget.followCallback?.call(data!.isFollowed); + } + setState(() { + isFollowing = false; + }); + } + Widget buildUser() { return SliverToBoxAdapter( child: Column( @@ -71,6 +96,27 @@ class _UserInfoPageState extends LoadingState { ), style: const TextStyle(fontSize: 14), ), + if(widget.id != appdata.account?.user.id) + const SizedBox(height: 8,), + if(widget.id != appdata.account?.user.id) + if(isFollowing) + Button(onPressed: follow, child: const SizedBox( + width: 42, + height: 24, + child: Center( + child: SizedBox.square( + dimension: 18, + child: ProgressRing(strokeWidth: 2,), + ), + ), + )) + else if (!data!.isFollowed) + Button(onPressed: follow, child: Text("Follow".tl)) + else + Button( + onPressed: follow, + child: Text("Unfollow".tl, style: TextStyle(color: ColorScheme.of(context).error),), + ), ], ), ); @@ -105,7 +151,7 @@ class _UserInfoPageState extends LoadingState { return SliverToBoxAdapter( child: Column( children: [ - buildHeader("Infomation".tl), + buildHeader("Information".tl), buildItem(icon: MdIcons.comment_outlined, title: "Introduction".tl, content: data!.comment), buildItem(icon: MdIcons.cake_outlined, title: "Birthday".tl, content: data!.birth), buildItem(icon: MdIcons.location_city_outlined, title: "Region", content: data!.region),