Skip to content

Commit

Permalink
feat(yt): list user playlists
Browse files Browse the repository at this point in the history
ref #227
  • Loading branch information
MSOB7YY committed Jul 8, 2024
1 parent 4db65a5 commit f462bce
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 16 deletions.
1 change: 1 addition & 0 deletions lib/core/enums.dart
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ enum YTHomePages {
notifications,
channels,
playlists,
userplaylists,
downloads,
}

Expand Down
1 change: 1 addition & 0 deletions lib/core/namida_converter_ext.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,7 @@ class _NamidaConverters {
YTHomePages.notifications: lang.NOTIFICATIONS,
YTHomePages.channels: lang.CHANNELS,
YTHomePages.playlists: lang.PLAYLISTS,
YTHomePages.userplaylists: '${lang.PLAYLISTS} (${lang.YOUTUBE})',
YTHomePages.downloads: lang.DOWNLOADS,
},
TrackSearchFilter: {
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/widgets/custom_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3355,7 +3355,7 @@ class _NamidaTabViewState extends State<NamidaTabView> with SingleTickerProvider
tabs: widget.tabs
.map(
(e) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 10.0),
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 10.0),
child: Text(e, maxLines: 1, overflow: TextOverflow.ellipsis),
),
)
Expand Down
1 change: 1 addition & 0 deletions lib/youtube/controller/youtube_info_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class YoutubeInfoController {

static const video = _VideoInfoController();
static const playlist = YoutiPie.playlist;
static const userplaylist = YoutiPie.userplaylist;
static const comment = YoutiPie.comment;
static const search = _SearchInfoController();
static const feed = YoutiPie.feed;
Expand Down
3 changes: 3 additions & 0 deletions lib/youtube/pages/youtube_feed_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@ class YoutubeHomeFeedPage extends StatelessWidget {
const (PlaylistInfoItem) => YoutubePlaylistCard(
key: Key((item as PlaylistInfoItem).id),
playlist: item,
firstVideoID: item.initialVideos.firstOrNull?.id,
thumbnailWidth: thumbnailWidth,
thumbnailHeight: thumbnailHeight,
subtitle: item.subtitle,
playOnTap: true,
playingId: null,
isMixPlaylist: item.isMix,
),
_ => const YoutubeVideoCardDummy(
shimmerEnabled: true,
Expand Down
2 changes: 2 additions & 0 deletions lib/youtube/pages/youtube_home_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:namida/core/namida_converter_ext.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/youtube/pages/youtube_feed_page.dart';
import 'package:namida/youtube/pages/youtube_notifications_page.dart';
import 'package:namida/youtube/pages/youtube_user_playlists_page.dart';
import 'package:namida/youtube/pages/yt_channels_page.dart';
import 'package:namida/youtube/pages/yt_downloads_page.dart';
import 'package:namida/youtube/youtube_playlists_view.dart';
Expand All @@ -32,6 +33,7 @@ class YouTubeHomeView extends StatelessWidget with NamidaRouteWidget {
YoutubeNotificationsPage(),
YoutubeChannelsPage(),
YoutubePlaylistsView(),
YoutubePlaylistsPage(),
YTDownloadsPage(),
],
),
Expand Down
48 changes: 48 additions & 0 deletions lib/youtube/pages/youtube_user_playlists_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:youtipie/class/result_wrapper/playlist_user_result.dart';
import 'package:youtipie/class/youtipie_feed/playlist_info_item_user.dart';
import 'package:youtipie/youtipie.dart';

import 'package:namida/core/dimensions.dart';
import 'package:namida/core/translations/language.dart';
import 'package:namida/youtube/controller/youtube_info_controller.dart';
import 'package:namida/youtube/pages/youtube_main_page_fetcher_acc_base.dart';
import 'package:namida/youtube/widgets/yt_playlist_card.dart';
import 'package:namida/youtube/widgets/yt_video_card.dart';

class YoutubePlaylistsPage extends StatelessWidget {
const YoutubePlaylistsPage({super.key});

@override
Widget build(BuildContext context) {
const multiplier = 0.8;
const thumbnailHeight = multiplier * Dimensions.youtubeThumbnailHeight;
const thumbnailWidth = multiplier * Dimensions.youtubeThumbnailWidth;
const thumbnailItemExtent = thumbnailHeight + 8.0 * 2;

return YoutubeMainPageFetcherAccBase<YoutiPieUserPlaylistsResult, PlaylistInfoItemUser>(
transparentShimmer: true,
title: lang.PLAYLISTS,
cacheReader: YoutiPie.cacheBuilder.forUserPlaylists(),
networkFetcher: (details) => YoutubeInfoController.userplaylist.getUserPlaylists(details: details),
itemExtent: thumbnailItemExtent,
dummyCard: const YoutubeVideoCardDummy(
thumbnailWidth: thumbnailWidth,
thumbnailHeight: thumbnailHeight,
shimmerEnabled: true,
),
itemBuilder: (playlist, index, list) {
return YoutubePlaylistCard(
key: Key(playlist.id),
playlist: playlist,
subtitle: playlist.infoTexts?.join(' - '),
thumbnailWidth: thumbnailWidth,
thumbnailHeight: thumbnailHeight,
firstVideoID: null,
isMixPlaylist: false, // TODO: is it possible?
playingId: null,
playOnTap: false,
);
});
}
}
3 changes: 3 additions & 0 deletions lib/youtube/pages/yt_search_results_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,10 @@ class YoutubeSearchResultsPageState extends State<YoutubeSearchResultsPage> with
thumbnailWidth: thumbnailWidth,
playOnTap: false,
playlist: item as PlaylistInfoItem,
firstVideoID: item.initialVideos.firstOrNull?.id,
subtitle: item.subtitle.isNotEmpty ? item.subtitle : item.initialVideos.firstOrNull?.title,
isMixPlaylist: item.isMix,
playingId: null,
),
const (ChannelInfoItem) => YoutubeChannelCard(
channel: item as ChannelInfoItem,
Expand Down
25 changes: 12 additions & 13 deletions lib/youtube/widgets/yt_playlist_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:youtipie/class/execute_details.dart';
import 'package:youtipie/class/result_wrapper/playlist_result_base.dart';
import 'package:youtipie/class/youtipie_feed/playlist_basic_info.dart';
import 'package:youtipie/class/youtipie_feed/playlist_info_item.dart';
import 'package:youtipie/core/enum.dart';
import 'package:youtipie/youtipie.dart';

Expand All @@ -24,12 +23,14 @@ import 'package:namida/youtube/widgets/yt_thumbnail.dart';

/// Playlist info is fetched automatically after 3 seconds of being displayed, or after attempting an action.
class YoutubePlaylistCard extends StatefulWidget {
final PlaylistInfoItem playlist;
final PlaylistBasicInfo playlist;
final String? subtitle;
final double? thumbnailWidth;
final double? thumbnailHeight;
final bool playOnTap;
final String? playingId;
final String? firstVideoID;
final String Function()? playingId;
final bool isMixPlaylist;

const YoutubePlaylistCard({
super.key,
Expand All @@ -38,26 +39,24 @@ class YoutubePlaylistCard extends StatefulWidget {
this.thumbnailWidth,
this.thumbnailHeight,
this.playOnTap = false,
this.playingId,
required this.firstVideoID,
required this.playingId,
required this.isMixPlaylist,
});

@override
State<YoutubePlaylistCard> createState() => _YoutubePlaylistCardState();
}

class _YoutubePlaylistCardState extends State<YoutubePlaylistCard> {
String? get firstVideoID {
return widget.playlist.initialVideos.firstOrNull?.id;
}

YoutiPiePlaylistResultBase? playlistToFetch;
Timer? _fetchTimer;
final _isFetching = Rxn<bool>();

Future<YoutiPiePlaylistResultBase?> _fetchFunction({required bool forceRequest}) {
final executeDetails = forceRequest ? ExecuteDetails.forceRequest() : ExecuteDetails.cache(CacheDecision.cacheOnly);
if (widget.playlist.isMix) {
final videoId = firstVideoID ?? widget.playingId;
if (widget.isMixPlaylist) {
final videoId = widget.firstVideoID ?? widget.playingId?.call();
if (videoId == null) return Future.value(null);
return YoutubeInfoController.playlist.getMixPlaylist(
videoId: videoId,
Expand Down Expand Up @@ -120,14 +119,14 @@ class _YoutubePlaylistCardState extends State<YoutubePlaylistCard> {
Widget build(BuildContext context) {
final playlist = widget.playlist;
String countText;
if (playlist.isMix) {
if (widget.isMixPlaylist) {
countText = '+25';
} else {
countText = playlist.videosCount?.formatDecimalShort() ?? '?';
}
final thumbnailUrl = playlist.thumbnails.pick()?.url;
final firstVideoID = this.firstVideoID;
final goodVideoID = firstVideoID != null && firstVideoID != '';
final firstVideoID = widget.firstVideoID;
final goodVideoID = firstVideoID != null && firstVideoID.isNotEmpty;
return NamidaPopupWrapper(
openOnTap: false,
openOnLongPress: true,
Expand Down
4 changes: 3 additions & 1 deletion lib/youtube/youtube_miniplayer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,9 @@ class YoutubeMiniPlayerState extends State<YoutubeMiniPlayer> {
playlist: item,
subtitle: item.subtitle,
playOnTap: true,
playingId: currentId,
firstVideoID: item.initialVideos.firstOrNull?.id,
playingId: () => currentId,
isMixPlaylist: item.isMix,
),
_ => dummyVideoCard,
};
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.0.8-beta+240708232
version: 3.0.9-beta+240708233

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

0 comments on commit f462bce

Please sign in to comment.