diff --git a/lib/network/network.dart b/lib/network/network.dart index e8cdc10..f4bab25 100644 --- a/lib/network/network.dart +++ b/lib/network/network.dart @@ -358,4 +358,16 @@ class Network { return Res.error(res.errorMessage); } } + + /// mode: day, week, month, day_male, day_female, week_original, week_rookie, day_manga, week_manga, month_manga, day_r18_manga, day_r18 + Future>> getRanking(String mode, [String? nextUrl]) async { + var res = await apiGet(nextUrl ?? "/v1/illust/ranking?filter=for_android&mode=$mode"); + 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); + } + } } diff --git a/lib/pages/download_page.dart b/lib/pages/download_page.dart new file mode 100644 index 0000000..968b40f --- /dev/null +++ b/lib/pages/download_page.dart @@ -0,0 +1,15 @@ +import 'package:fluent_ui/fluent_ui.dart'; + +class DownloadPage extends StatefulWidget { + const DownloadPage({super.key}); + + @override + State createState() => _DownloadPageState(); +} + +class _DownloadPageState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} diff --git a/lib/pages/explore_page.dart b/lib/pages/explore_page.dart deleted file mode 100644 index 9b16de9..0000000 --- a/lib/pages/explore_page.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class ExplorePage extends StatelessWidget { - const ExplorePage({super.key}); - - @override - Widget build(BuildContext context) { - return const Center( - child: Text("Explore"), - ); - } -} diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 39393ce..cd1ed08 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -8,8 +8,8 @@ import "package:pixes/components/md.dart"; import "package:pixes/foundation/app.dart"; import "package:pixes/network/network.dart"; import "package:pixes/pages/bookmarks.dart"; -import "package:pixes/pages/explore_page.dart"; import "package:pixes/pages/following_artworks.dart"; +import "package:pixes/pages/ranking.dart"; import "package:pixes/pages/recommendation_page.dart"; import "package:pixes/pages/login_page.dart"; import "package:pixes/pages/search_page.dart"; @@ -20,6 +20,7 @@ import "package:pixes/utils/translation.dart"; import "package:window_manager/window_manager.dart"; import "../components/page_route.dart"; +import "download_page.dart"; const _kAppBarHeight = 36.0; @@ -33,7 +34,7 @@ class MainPage extends StatefulWidget { class _MainPageState extends State with WindowListener { final navigatorKey = GlobalKey(); - int index = 2; + int index = 3; int windowButtonKey = 0; @@ -100,8 +101,13 @@ class _MainPageState extends State with WindowListener { title: Text('Search'.tl), body: const SizedBox.shrink(), ), + PaneItem( + icon: const Icon(MdIcons.download, size: 20,), + title: Text('Download'.tl), + body: const SizedBox.shrink(), + ), PaneItemSeparator(), - PaneItemHeader(header: Text("Artwork".tl).paddingVertical(4).paddingLeft(8)), + PaneItemHeader(header: Text("Artwork".tl).paddingBottom(4).paddingLeft(8)), PaneItem( icon: const Icon(MdIcons.explore_outlined, size: 20,), title: Text('Explore'.tl), @@ -117,10 +123,9 @@ class _MainPageState extends State with WindowListener { title: Text('Following'.tl), body: const SizedBox.shrink(), ), - PaneItemSeparator(), PaneItem( - icon: const Icon(MdIcons.explore_outlined, size: 20), - title: Text('Explore'.tl), + icon: const Icon(MdIcons.leaderboard_outlined, size: 20), + title: Text('Ranking'.tl), body: const SizedBox.shrink(), ), ], @@ -140,13 +145,14 @@ class _MainPageState extends State with WindowListener { )); } - static final pageBuilders = [ + static final pageBuilders = [ () => UserInfoPage(appdata.account!.user.id), () => const SearchPage(), + () => const DownloadPage(), () => const RecommendationPage(), () => const BookMarkedArtworkPage(), () => const FollowingArtworksPage(), - () => const ExplorePage(), + () => const RankingPage(), () => const SettingsPage(), ]; diff --git a/lib/pages/ranking.dart b/lib/pages/ranking.dart index 5b22329..9d86567 100644 --- a/lib/pages/ranking.dart +++ b/lib/pages/ranking.dart @@ -1,4 +1,11 @@ import 'package:fluent_ui/fluent_ui.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +import 'package:pixes/foundation/app.dart'; +import 'package:pixes/utils/translation.dart'; + +import '../components/illust_widget.dart'; +import '../components/loading.dart'; +import '../network/network.dart'; class RankingPage extends StatefulWidget { const RankingPage({super.key}); @@ -8,8 +15,104 @@ class RankingPage extends StatefulWidget { } class _RankingPageState extends State { + String type = "day"; + + /// mode: day, week, month, day_male, day_female, week_original, week_rookie, day_manga, week_manga, month_manga, day_r18_manga, day_r18 + static const types = { + "day": "Daily", + "week": "Weekly", + "month": "Monthly", + "day_male": "For male", + "day_female": "For female", + "week_original": "Originals", + "week_rookie": "Rookies", + "day_manga": "Daily Manga", + "week_manga": "Weekly Manga", + "month_manga": "Monthly Manga", + "day_r18_manga": "R18", + }; + @override Widget build(BuildContext context) { - return const Placeholder(); + return ScaffoldPage( + padding: EdgeInsets.zero, + content: Column( + children: [ + buildHeader(), + Expanded( + child: _OneRankingPage(type, key: Key(type),), + ), + ], + ), + ); + } + + Widget buildHeader() { + return SizedBox( + child: Row( + children: [ + Text("Ranking".tl, style: const TextStyle( + fontSize: 20, fontWeight: FontWeight.bold),), + const Spacer(), + DropDownButton( + title: Text(types[type]!), + items: types.entries.map((e) => MenuFlyoutItem( + text: Text(e.value.tl), + onPressed: () { + setState(() { + type = e.key; + }); + }, + )).toList(), + ) + ], + ) + ).padding(const EdgeInsets.symmetric(vertical: 8, horizontal: 12)); } } + +class _OneRankingPage extends StatefulWidget { + const _OneRankingPage(this.type, {super.key}); + + final String type; + + @override + State<_OneRankingPage> createState() => _OneRankingPageState(); +} + +class _OneRankingPageState extends MultiPageLoadingState<_OneRankingPage, Illust> { + @override + Widget buildContent(BuildContext context, final List data) { + return LayoutBuilder(builder: (context, constrains){ + return MasonryGridView.builder( + gridDelegate: const SliverSimpleGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 240, + ), + itemCount: data.length, + itemBuilder: (context, index) { + if(index == data.length - 1){ + nextPage(); + } + return IllustWidget(data[index]); + }, + ); + }); + } + + String? nextUrl; + + @override + Future>> loadData(page) async{ + if(nextUrl == "end") { + return Res.error("No more data"); + } + var res = await Network().getRanking(widget.type, nextUrl); + if(!res.error) { + nextUrl = res.subData; + nextUrl ??= "end"; + } + return res; + } +} + +