Skip to content

Commit

Permalink
feat(yt): sort yt playlists
Browse files Browse the repository at this point in the history
ref: #227
  • Loading branch information
MSOB7YY committed Aug 20, 2024
1 parent ff4632d commit 99eaea8
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class _ChannelInfoController {
return res.read();
}

Future<YoutiPieChannelTabResult?> fetchChannelTab({required String channelId, required ChannelTab tab, YoutiPieChannelItemsSort? sort, ExecuteDetails? details}) {
Future<YoutiPieChannelTabResult?> fetchChannelTab({required String channelId, required ChannelTab tab, YoutiPieItemsSort? sort, ExecuteDetails? details}) {
return YoutiPie.channel.fetchChannelTab(channelId: channelId, tab: tab, sort: sort, details: details);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/youtube/controller/youtube_info_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'dart:io';
import 'package:logger/logger.dart';
import 'package:namico_db_wrapper/namico_db_wrapper.dart';
import 'package:queue/queue.dart';
import 'package:youtipie/class/channels/channel_items_sort.dart';
import 'package:youtipie/class/items_sort.dart';
import 'package:youtipie/class/channels/channel_page_about.dart';
import 'package:youtipie/class/channels/channel_page_result.dart';
import 'package:youtipie/class/channels/channel_tab.dart';
Expand Down
80 changes: 76 additions & 4 deletions lib/youtube/pages/youtube_main_page_fetcher_acc_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart';

import 'package:youtipie/class/cache_details.dart';
import 'package:youtipie/class/execute_details.dart';
import 'package:youtipie/class/items_sort.dart';
import 'package:youtipie/class/map_serializable.dart';
import 'package:youtipie/class/result_wrapper/list_wrapper_base.dart';

Expand All @@ -13,6 +14,7 @@ import 'package:namida/class/route.dart';
import 'package:namida/controller/connectivity.dart';
import 'package:namida/controller/navigator_controller.dart';
import 'package:namida/core/dimensions.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/core/icon_fonts/broken_icons.dart';
import 'package:namida/core/translations/language.dart';
import 'package:namida/core/utils.dart';
Expand All @@ -30,6 +32,7 @@ class YoutubeMainPageFetcherAccBase<W extends YoutiPieListWrapper<T>, T extends
final String title;
final CacheDetails<W> cacheReader;
final Future<W?> Function(ExecuteDetails details) networkFetcher;
final bool isSortable;
final Widget dummyCard;
final double itemExtent;
final YoutubeMainPageFetcherItemBuilder<T, W> itemBuilder;
Expand All @@ -55,6 +58,7 @@ class YoutubeMainPageFetcherAccBase<W extends YoutiPieListWrapper<T>, T extends
required this.title,
required this.cacheReader,
required this.networkFetcher,
this.isSortable = false,
required this.dummyCard,
required this.itemExtent,
required this.itemBuilder,
Expand Down Expand Up @@ -102,6 +106,7 @@ class _YoutubePageState<W extends YoutiPieListWrapper<T>, T extends MapSerializa
final _lastFetchWasCached = false.obs;
final _refreshButtonShown = false.obs;
final _currentFeed = Rxn<W>();
Rxn<YoutiPieItemsSort>? _currentSort;

bool get _hasConnection => ConnectivityController.inst.hasConnection;
void _showNetworkError() {
Expand Down Expand Up @@ -167,6 +172,7 @@ class _YoutubePageState<W extends YoutiPieListWrapper<T>, T extends MapSerializa
@override
void initState() {
super.initState();
if (widget.isSortable) _currentSort = Rxn<YoutiPieItemsSort>();
widget.onInitState?.call(_currentFeed);
YoutubeAccountController.current.addOnAccountChanged(_onAccChanged);
if (widget.onListUpdated != null) _currentFeed.addListener(_onListUpdated);
Expand All @@ -182,6 +188,7 @@ class _YoutubePageState<W extends YoutiPieListWrapper<T>, T extends MapSerializa
_controller.dispose();
_isLoadingCurrentFeed.close();
_currentFeed.close();
_currentSort?.close();
_lastFetchWasCached.close();
super.dispose();
}
Expand Down Expand Up @@ -231,14 +238,79 @@ class _YoutubePageState<W extends YoutiPieListWrapper<T>, T extends MapSerializa

@override
Widget build(BuildContext context) {
Widget headerTitle = Text(
widget.title,
style: context.textTheme.displayLarge?.copyWith(fontSize: 28.0),
);
if (widget.isSortable) {
headerTitle = Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
headerTitle,
const SizedBox(height: 2.0),
ObxO(
rx: _currentFeed,
builder: (listItemsPre) {
if (listItemsPre is YoutiPieListSorterMixin) {
final listItems = listItemsPre as YoutiPieListSorterMixin;
final selectedSort = listItems.customSort ?? listItems.itemsSort.firstWhereEff((e) => e.initiallySelected);
return NamidaPopupWrapper(
childrenDefault: () {
return (listItems).itemsSort.map(
(s) {
return NamidaPopupItem(
icon: s.title == selectedSort?.title ? Broken.tick_circle : Broken.arrow_swap,
title: s.title,
onTap: () async {
final currentSort = _currentSort;
if (currentSort!.value?.title == s.title) return;

final initialSort = currentSort.value;

_isLoadingCurrentFeed.value = true;
currentSort.value = s;

final didFetch = await listItems.fetchWithNewSort(sort: s, details: ExecuteDetails.forceRequest());
if (currentSort.value?.title != s.title) return; // if interrupted

_isLoadingCurrentFeed.value = false;

if (didFetch) {
if (mounted) _currentFeed.refresh();
} else {
currentSort.value = initialSort;
}
},
);
},
).toList();
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 2.0),
child: ObxO(
rx: _currentSort!,
builder: (sort) => Text(
sort?.title ?? selectedSort?.title ?? '?',
style: context.textTheme.displaySmall?.copyWith(
color: context.theme.colorScheme.secondary,
),
),
),
),
);
}
return const SizedBox();
},
),
],
);
}
Widget header = Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: Text(
widget.title,
style: context.textTheme.displayLarge?.copyWith(fontSize: 28.0),
),
child: headerTitle,
),
const SizedBox(width: 12.0),
ObxO(
Expand Down
1 change: 1 addition & 0 deletions lib/youtube/pages/youtube_user_playlists_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class _YoutubeUserPlaylistsPageState extends State<YoutubeUserPlaylistsPage> {
},
onPullToRefresh: () => (horizontalHistoryKey.currentState as dynamic)?.forceFetchFeed() as Future<void>,
title: lang.PLAYLISTS,
isSortable: true,
headerTrailing: NamidaIconButton(
icon: Broken.add_circle,
iconSize: 22.0,
Expand Down
2 changes: 1 addition & 1 deletion lib/youtube/pages/yt_channel_subpage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import 'package:photo_view/photo_view_gallery.dart';
import 'package:youtipie/class/channels/channel_about_link.dart';
import 'package:youtipie/class/channels/channel_home_section.dart';
import 'package:youtipie/class/channels/channel_info.dart';
import 'package:youtipie/class/channels/channel_items_sort.dart';
import 'package:youtipie/class/items_sort.dart';
import 'package:youtipie/class/channels/channel_page_about.dart';
import 'package:youtipie/class/channels/channel_page_result.dart';
import 'package:youtipie/class/channels/channel_tab.dart';
Expand Down
4 changes: 2 additions & 2 deletions lib/youtube/pages/yt_channel_subpage_about.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class YTChannelSubpageAbout extends StatefulWidget {
final ScrollController scrollController;
final String channelId;
final YoutiPieChannelPageResult? Function() channelInfo;
final Future<void> Function(Future<ChannelPageAbout?> Function({YoutiPieChannelItemsSort? sort, bool forceRequest}) fetch) tabFetcher;
final Future<void> Function(Future<ChannelPageAbout?> Function({YoutiPieItemsSort? sort, bool forceRequest}) fetch) tabFetcher;
final bool Function() shouldForceRequest;
final void Function() onSuccessFetch;

Expand All @@ -26,7 +26,7 @@ class _YTChannelSubpageAboutState extends State<YTChannelSubpageAbout> {
ChannelPageAbout? _aboutResult;
bool _isLoadingInitial = false;

Future<ChannelPageAbout?> fetchAboutAndUpdate({YoutiPieChannelItemsSort? sort, bool? forceRequest}) async {
Future<ChannelPageAbout?> fetchAboutAndUpdate({YoutiPieItemsSort? sort, bool? forceRequest}) async {
forceRequest ??= widget.shouldForceRequest();

if (forceRequest == false && _aboutResult != null) return null; // prevent calling widget.onSuccessFetch
Expand Down
8 changes: 4 additions & 4 deletions lib/youtube/pages/yt_channel_subpage_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class YTChannelSubpageTab extends StatefulWidget {
final ScrollController scrollController;
final String channelId;
final ChannelTab tab;
final Future<void> Function(Future<YoutiPieChannelTabResult?> Function({YoutiPieChannelItemsSort? sort, bool forceRequest}) fetch) tabFetcher;
final Future<void> Function(Future<YoutiPieChannelTabResult?> Function({YoutiPieItemsSort? sort, bool forceRequest}) fetch) tabFetcher;
final bool Function() shouldForceRequest;
final void Function() onSuccessFetch;

Expand All @@ -24,11 +24,11 @@ class YTChannelSubpageTab extends StatefulWidget {

class _YTChannelSubpageTabState extends State<YTChannelSubpageTab> {
YoutiPieChannelTabResult? _tabResult;
YoutiPieChannelItemsSort? _currentSort;
YoutiPieItemsSort? _currentSort;
bool _isLoadingInitial = false;
final _isLoadingMoreItems = false.obs;

Future<YoutiPieChannelTabResult?> fetchTabAndUpdate({YoutiPieChannelItemsSort? sort, bool? forceRequest}) async {
Future<YoutiPieChannelTabResult?> fetchTabAndUpdate({YoutiPieItemsSort? sort, bool? forceRequest}) async {
sort ??= _currentSort; // use set sort when refreshing.
forceRequest ??= widget.shouldForceRequest();

Expand Down Expand Up @@ -116,7 +116,7 @@ class _YTChannelSubpageTabState extends State<YTChannelSubpageTab> {
margin: const EdgeInsets.symmetric(horizontal: 4.0),
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0),
onTap: () async {
if (_currentSort == s) return;
if (_currentSort?.title == s.title) return;

try {
widget.scrollController.jumpTo(0);
Expand Down
14 changes: 6 additions & 8 deletions lib/youtube/youtube_playlists_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,12 @@ class YoutubePlaylistsView extends StatelessWidget with NamidaRouteWidget {
],
),
],
child: NamidaInkWell(
child: ObxO(
rx: settings.ytPlaylistSort,
builder: (ytPlaylistSort) => Text(
ytPlaylistSort.toText(),
style: context.textTheme.displaySmall?.copyWith(
color: context.theme.colorScheme.secondary,
),
child: ObxO(
rx: settings.ytPlaylistSort,
builder: (ytPlaylistSort) => Text(
ytPlaylistSort.toText(),
style: context.textTheme.displaySmall?.copyWith(
color: context.theme.colorScheme.secondary,
),
),
),
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: namida
description: A Beautiful and Feature-rich Music Player, With YouTube & Video Support Built in Flutter
publish_to: "none"
version: 3.9.6-beta+240819222
version: 3.9.7-beta+240820016

environment:
sdk: ">=3.4.0 <4.0.0"
Expand Down

0 comments on commit 99eaea8

Please sign in to comment.