mirror of
https://github.com/wgh136/pixes.git
synced 2025-09-27 21:07:24 +00:00
user artworks; update ui
This commit is contained in:
@@ -1,38 +0,0 @@
|
|||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
class ColorScheme extends InheritedWidget{
|
|
||||||
final Brightness brightness;
|
|
||||||
|
|
||||||
const ColorScheme({super.key, required this.brightness, required super.child});
|
|
||||||
|
|
||||||
static ColorScheme of(BuildContext context){
|
|
||||||
return context.dependOnInheritedWidgetOfExactType<ColorScheme>()!;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get _light => brightness == Brightness.light;
|
|
||||||
|
|
||||||
Color get primary => _light ? const Color(0xff00538a) : const Color(0xff9ccaff);
|
|
||||||
|
|
||||||
Color get primaryContainer => _light ? const Color(0xff5fbdff) : const Color(0xff0079c5);
|
|
||||||
|
|
||||||
Color get secondary => _light ? const Color(0xff426182) : const Color(0xffaac9ef);
|
|
||||||
|
|
||||||
Color get secondaryContainer => _light ? const Color(0xffc1dcff) : const Color(0xff1f3f5f);
|
|
||||||
|
|
||||||
Color get tertiary => _light ? const Color(0xff743192) : const Color(0xffebb2ff);
|
|
||||||
|
|
||||||
Color get tertiaryContainer => _light ? const Color(0xffcf9ae8) : const Color(0xff9c58ba);
|
|
||||||
|
|
||||||
Color get outline => _light ? const Color(0xff707883) : const Color(0xff89919d);
|
|
||||||
|
|
||||||
Color get outlineVariant => _light ? const Color(0xffbfc7d3) : const Color(0xff404752);
|
|
||||||
|
|
||||||
Color get errorColor => _light ? const Color(0xffff3131) : const Color(0xfff86a6a);
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool updateShouldNotify(covariant InheritedWidget oldWidget) {
|
|
||||||
return oldWidget is!ColorScheme || brightness != oldWidget.brightness;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -90,8 +90,7 @@ abstract class MultiPageLoadingState<T extends StatefulWidget, S extends Object>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
void initState() {
|
||||||
if(_isFirstLoading){
|
|
||||||
loadData(_page).then((value) {
|
loadData(_page).then((value) {
|
||||||
if(value.success) {
|
if(value.success) {
|
||||||
_page++;
|
_page++;
|
||||||
@@ -106,13 +105,27 @@ abstract class MultiPageLoadingState<T extends StatefulWidget, S extends Object>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildLoading(BuildContext context) {
|
||||||
return const Center(
|
return const Center(
|
||||||
child: ProgressRing(),
|
child: ProgressRing(),
|
||||||
);
|
);
|
||||||
} else if (_error != null){
|
}
|
||||||
|
|
||||||
|
Widget buildError(BuildContext context, String error) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(_error!),
|
child: Text(error),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if(_isFirstLoading){
|
||||||
|
return buildLoading(context);
|
||||||
|
} else if (_error != null){
|
||||||
|
return buildError(context, _error!);
|
||||||
} else {
|
} else {
|
||||||
return buildContent(context, _data!);
|
return buildContent(context, _data!);
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' as md;
|
||||||
|
|
||||||
typedef MdIcons = Icons;
|
typedef MdIcons = md.Icons;
|
||||||
|
|
||||||
|
class ColorScheme {
|
||||||
|
static md.ColorScheme of(md.BuildContext context) {
|
||||||
|
return md.Theme.of(context).colorScheme;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:pixes/foundation/app.dart';
|
import 'package:pixes/foundation/app.dart';
|
||||||
|
|
||||||
import 'color_scheme.dart';
|
import 'md.dart';
|
||||||
|
|
||||||
class SegmentedButton<T> extends StatelessWidget {
|
class SegmentedButton<T> extends StatelessWidget {
|
||||||
const SegmentedButton(
|
const SegmentedButton(
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:pixes/components/animated_image.dart';
|
import 'package:pixes/components/animated_image.dart';
|
||||||
import 'package:pixes/components/color_scheme.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/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';
|
||||||
|
|
||||||
class UserPreviewWidget extends StatefulWidget {
|
class UserPreviewWidget extends StatefulWidget {
|
||||||
const UserPreviewWidget(this.user, {super.key});
|
const UserPreviewWidget(this.user, {super.key});
|
||||||
@@ -90,7 +90,7 @@ class _UserPreviewWidgetState extends State<UserPreviewWidget> {
|
|||||||
else
|
else
|
||||||
Button(
|
Button(
|
||||||
onPressed: follow,
|
onPressed: follow,
|
||||||
child: Text("Unfollow".tl, style: TextStyle(color: ColorScheme.of(context).errorColor),),
|
child: Text("Unfollow".tl, style: TextStyle(color: ColorScheme.of(context).error),),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@@ -313,4 +313,15 @@ class Network {
|
|||||||
return Res.error(res.errorMessage);
|
return Res.error(res.errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Res<List<Illust>>> getUserIllusts(String uid) async {
|
||||||
|
var res = await apiGet("/v1/user/illusts?filter=for_android&user_id=$uid&type=illust");
|
||||||
|
if (res.success) {
|
||||||
|
return Res(
|
||||||
|
(res.data["illusts"] as List).map((e) => Illust.fromJson(e)).toList(),
|
||||||
|
subData: res.data["next_url"]);
|
||||||
|
} else {
|
||||||
|
return Res.error(res.errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,8 @@ import 'package:pixes/pages/image_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 '../components/color_scheme.dart';
|
import '../components/md.dart';
|
||||||
|
|
||||||
|
|
||||||
const _kBottomBarHeight = 64.0;
|
const _kBottomBarHeight = 64.0;
|
||||||
|
|
||||||
@@ -304,7 +305,7 @@ class _BottomBarState extends State<_BottomBar> {
|
|||||||
else
|
else
|
||||||
Button(
|
Button(
|
||||||
onPressed: follow,
|
onPressed: follow,
|
||||||
child: Text("Unfollow".tl, style: TextStyle(color: ColorScheme.of(context).errorColor),),
|
child: Text("Unfollow".tl, style: TextStyle(color: ColorScheme.of(context).error),),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -355,7 +356,7 @@ class _BottomBarState extends State<_BottomBar> {
|
|||||||
else if(widget.illust.isBookmarked)
|
else if(widget.illust.isBookmarked)
|
||||||
Icon(
|
Icon(
|
||||||
Icons.favorite,
|
Icons.favorite,
|
||||||
color: ColorScheme.of(context).errorColor,
|
color: ColorScheme.of(context).error,
|
||||||
size: 18,
|
size: 18,
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
@@ -2,8 +2,8 @@ import "dart:async";
|
|||||||
|
|
||||||
import "package:fluent_ui/fluent_ui.dart";
|
import "package:fluent_ui/fluent_ui.dart";
|
||||||
import "package:flutter/foundation.dart";
|
import "package:flutter/foundation.dart";
|
||||||
|
import "package:flutter/material.dart" as md;
|
||||||
import "package:pixes/appdata.dart";
|
import "package:pixes/appdata.dart";
|
||||||
import "package:pixes/components/color_scheme.dart";
|
|
||||||
import "package:pixes/components/md.dart";
|
import "package:pixes/components/md.dart";
|
||||||
import "package:pixes/foundation/app.dart";
|
import "package:pixes/foundation/app.dart";
|
||||||
import "package:pixes/network/network.dart";
|
import "package:pixes/network/network.dart";
|
||||||
@@ -73,8 +73,15 @@ class _MainPageState extends State<MainPage> with WindowListener {
|
|||||||
content: LoginPage(() => setState(() {})),
|
content: LoginPage(() => setState(() {})),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return ColorScheme(
|
return md.Theme(
|
||||||
|
data: md.ThemeData.from(
|
||||||
|
useMaterial3: true,
|
||||||
|
colorScheme: md.ColorScheme.fromSeed(
|
||||||
|
seedColor: FluentTheme.of(context).accentColor.withOpacity(1),
|
||||||
brightness: FluentTheme.of(context).brightness,
|
brightness: FluentTheme.of(context).brightness,
|
||||||
|
)),
|
||||||
|
child: DefaultSelectionStyle.merge(
|
||||||
|
selectionColor: FluentTheme.of(context).selectionColor.withOpacity(0.4),
|
||||||
child: NavigationView(
|
child: NavigationView(
|
||||||
appBar: buildAppBar(context, navigatorKey),
|
appBar: buildAppBar(context, navigatorKey),
|
||||||
pane: NavigationPane(
|
pane: NavigationPane(
|
||||||
@@ -122,7 +129,8 @@ class _MainPageState extends State<MainPage> with WindowListener {
|
|||||||
key: navigatorKey,
|
key: navigatorKey,
|
||||||
onGenerateRoute: (settings) => AppPageRoute(
|
onGenerateRoute: (settings) => AppPageRoute(
|
||||||
builder: (context) => const RecommendationPage()),
|
builder: (context) => const RecommendationPage()),
|
||||||
)));
|
)),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
static final pageBuilders = [
|
static final pageBuilders = [
|
||||||
|
@@ -10,9 +10,9 @@ import 'package:pixes/pages/user_info_page.dart';
|
|||||||
import 'package:pixes/utils/translation.dart';
|
import 'package:pixes/utils/translation.dart';
|
||||||
|
|
||||||
import '../components/animated_image.dart';
|
import '../components/animated_image.dart';
|
||||||
import '../components/color_scheme.dart';
|
|
||||||
import '../components/grid.dart';
|
import '../components/grid.dart';
|
||||||
import '../components/illust_widget.dart';
|
import '../components/illust_widget.dart';
|
||||||
|
import '../components/md.dart';
|
||||||
import '../foundation/image_provider.dart';
|
import '../foundation/image_provider.dart';
|
||||||
|
|
||||||
class SearchPage extends StatefulWidget {
|
class SearchPage extends StatefulWidget {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:pixes/components/color_scheme.dart';
|
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||||
import 'package:pixes/components/loading.dart';
|
import 'package:pixes/components/loading.dart';
|
||||||
import 'package:pixes/components/md.dart';
|
import 'package:pixes/components/md.dart';
|
||||||
import 'package:pixes/foundation/app.dart';
|
import 'package:pixes/foundation/app.dart';
|
||||||
@@ -8,6 +8,8 @@ import 'package:pixes/network/network.dart';
|
|||||||
import 'package:pixes/utils/translation.dart';
|
import 'package:pixes/utils/translation.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
|
import '../components/illust_widget.dart';
|
||||||
|
|
||||||
class UserInfoPage extends StatefulWidget {
|
class UserInfoPage extends StatefulWidget {
|
||||||
const UserInfoPage(this.id, {super.key});
|
const UserInfoPage(this.id, {super.key});
|
||||||
|
|
||||||
@@ -20,10 +22,22 @@ class UserInfoPage extends StatefulWidget {
|
|||||||
class _UserInfoPageState extends LoadingState<UserInfoPage, UserDetails> {
|
class _UserInfoPageState extends LoadingState<UserInfoPage, UserDetails> {
|
||||||
@override
|
@override
|
||||||
Widget buildContent(BuildContext context, UserDetails data) {
|
Widget buildContent(BuildContext context, UserDetails data) {
|
||||||
return SingleChildScrollView(
|
return ScaffoldPage(
|
||||||
|
content: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
buildUser(),
|
||||||
|
buildInformation(),
|
||||||
|
SliverToBoxAdapter(child: buildHeader("Artworks"),),
|
||||||
|
_UserArtworks(data.id.toString(), key: ValueKey(data.id),),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildUser() {
|
||||||
|
return SliverToBoxAdapter(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 16),
|
|
||||||
Container(
|
Container(
|
||||||
width: 64,
|
width: 64,
|
||||||
height: 64,
|
height: 64,
|
||||||
@@ -33,56 +47,28 @@ class _UserInfoPageState extends LoadingState<UserInfoPage, UserDetails> {
|
|||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(64),
|
borderRadius: BorderRadius.circular(64),
|
||||||
child: Image(
|
child: Image(
|
||||||
image: CachedImageProvider(data.avatar),
|
image: CachedImageProvider(data!.avatar),
|
||||||
width: 64,
|
width: 64,
|
||||||
height: 64,
|
height: 64,
|
||||||
),
|
),
|
||||||
),),
|
),),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(data.name, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500)),
|
Text(data!.name, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500)),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text.rich(
|
Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
children: [
|
children: [
|
||||||
TextSpan(text: 'Follows: '.tl),
|
TextSpan(text: 'Follows: '.tl),
|
||||||
TextSpan(text: '${data.totalFollowUsers}', style: const TextStyle(fontWeight: FontWeight.w500)),
|
TextSpan(text: '${data!.totalFollowUsers}', style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
style: const TextStyle(fontSize: 14),
|
style: const TextStyle(fontSize: 14),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8,),
|
|
||||||
buildHeader("Infomation".tl),
|
|
||||||
buildItem(icon: MdIcons.comment_outlined, title: "Comment".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),
|
|
||||||
buildItem(icon: MdIcons.work_outline, title: "Job".tl, content: data.job),
|
|
||||||
buildItem(icon: MdIcons.person_2_outlined, title: "Gender".tl, content: data.gender),
|
|
||||||
const SizedBox(height: 8,),
|
|
||||||
buildHeader("Social Network".tl),
|
|
||||||
buildItem(title: "Webpage", content: data.webpage, onTap: () => launchUrlString(data.webpage!)),
|
|
||||||
buildItem(title: "Twitter", content: data.twitterUrl, onTap: () => launchUrlString(data.twitterUrl!)),
|
|
||||||
buildItem(title: "pawoo", content: data.pawooUrl, onTap: () => launchUrlString(data.pawooUrl!))
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildItem({IconData? icon, required String title, required String? content, VoidCallback? onTap}) {
|
|
||||||
if(content == null || content.isEmpty) {
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
|
||||||
return Card(
|
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 2),
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
child: ListTile(
|
|
||||||
leading: icon == null ? null : Icon(icon, size: 20,),
|
|
||||||
title: Text(title),
|
|
||||||
subtitle: SelectableText(content),
|
|
||||||
onPressed: onTap,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildHeader(String title) {
|
Widget buildHeader(String title) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
@@ -92,9 +78,134 @@ class _UserInfoPageState extends LoadingState<UserInfoPage, UserDetails> {
|
|||||||
).toAlign(Alignment.centerLeft)).paddingLeft(16).paddingVertical(4);
|
).toAlign(Alignment.centerLeft)).paddingLeft(16).paddingVertical(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildInformation() {
|
||||||
|
Widget buildItem({IconData? icon, required String title, required String? content, Widget? trailing}) {
|
||||||
|
if(content == null || content.isEmpty) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 2),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
child: ListTile(
|
||||||
|
leading: icon == null ? null : Icon(icon, size: 20,),
|
||||||
|
title: Text(title),
|
||||||
|
subtitle: SelectableText(content),
|
||||||
|
trailing: trailing,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SliverToBoxAdapter(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
buildHeader("Infomation".tl),
|
||||||
|
buildItem(icon: MdIcons.comment_outlined, title: "Comment".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),
|
||||||
|
buildItem(icon: MdIcons.work_outline, title: "Job".tl, content: data!.job),
|
||||||
|
buildItem(icon: MdIcons.person_2_outlined, title: "Gender".tl, content: data!.gender),
|
||||||
|
const SizedBox(height: 8,),
|
||||||
|
buildHeader("Social Network".tl),
|
||||||
|
buildItem(title: "Webpage",
|
||||||
|
content: data!.webpage,
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(MdIcons.open_in_new, size: 18),
|
||||||
|
onPressed: () => launchUrlString(data!.twitterUrl!)
|
||||||
|
)),
|
||||||
|
buildItem(title: "Twitter",
|
||||||
|
content: data!.twitterUrl,
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(MdIcons.open_in_new, size: 18),
|
||||||
|
onPressed: () => launchUrlString(data!.twitterUrl!)
|
||||||
|
)),
|
||||||
|
buildItem(title: "pawoo",
|
||||||
|
content: data!.pawooUrl,
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(MdIcons.open_in_new, size: 18,),
|
||||||
|
onPressed: () => launchUrlString(data!.pawooUrl!)
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Res<UserDetails>> loadData() {
|
Future<Res<UserDetails>> loadData() {
|
||||||
return Network().getUserDetails(widget.id);
|
return Network().getUserDetails(widget.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _UserArtworks extends StatefulWidget {
|
||||||
|
const _UserArtworks(this.uid, {super.key});
|
||||||
|
|
||||||
|
final String uid;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_UserArtworks> createState() => _UserArtworksState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UserArtworksState extends MultiPageLoadingState<_UserArtworks, Illust> {
|
||||||
|
@override
|
||||||
|
Widget buildLoading(BuildContext context) {
|
||||||
|
return const SliverToBoxAdapter(
|
||||||
|
child: SizedBox(
|
||||||
|
child: Center(
|
||||||
|
child: ProgressRing(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildError(context, error) {
|
||||||
|
return SliverToBoxAdapter(
|
||||||
|
child: SizedBox(
|
||||||
|
child: Center(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(FluentIcons.info),
|
||||||
|
const SizedBox(width: 4,),
|
||||||
|
Text(error)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildContent(BuildContext context, final List<Illust> data) {
|
||||||
|
return SliverMasonryGrid(
|
||||||
|
gridDelegate: const SliverSimpleGridDelegateWithMaxCrossAxisExtent(
|
||||||
|
maxCrossAxisExtent: 240,
|
||||||
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
if(index == data.length - 1){
|
||||||
|
nextPage();
|
||||||
|
}
|
||||||
|
return IllustWidget(data[index]);
|
||||||
|
},
|
||||||
|
childCount: data.length,
|
||||||
|
),
|
||||||
|
).sliverPaddingHorizontal(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
String? nextUrl;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Res<List<Illust>>> loadData(page) async{
|
||||||
|
if(nextUrl == "end") {
|
||||||
|
return Res.error("No more data");
|
||||||
|
}
|
||||||
|
var res = nextUrl == null
|
||||||
|
? await Network().getUserIllusts(widget.uid)
|
||||||
|
: await Network().getIllustsWithNextUrl(nextUrl!);
|
||||||
|
if(!res.error) {
|
||||||
|
nextUrl = res.subData;
|
||||||
|
nextUrl ??= "end";
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user