Skip to content

Commit

Permalink
feat(yt): video like/dislike
Browse files Browse the repository at this point in the history
- this forced yt local favourite button to be moved to video menu as "favourites" button & favourites playlist tile inside add-to-playlists bottom sheet
- also "Liked" Playlist name is reverted to "Favourites"
  • Loading branch information
MSOB7YY committed Jul 11, 2024
1 parent dd1eb4a commit c3b6742
Show file tree
Hide file tree
Showing 8 changed files with 1,117 additions and 970 deletions.
4 changes: 2 additions & 2 deletions lib/core/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ extension FavouriteYoutubeID on YoutubeID {
}

extension PLNAME on String {
String translatePlaylistName({bool liked = false}) => replaceFirst(k_PLAYLIST_NAME_AUTO_GENERATED, lang.AUTO_GENERATED)
.replaceFirst(k_PLAYLIST_NAME_FAV, liked ? lang.LIKED : lang.FAVOURITES)
String translatePlaylistName() => replaceFirst(k_PLAYLIST_NAME_AUTO_GENERATED, lang.AUTO_GENERATED)
.replaceFirst(k_PLAYLIST_NAME_FAV, lang.FAVOURITES)
.replaceFirst(k_PLAYLIST_NAME_HISTORY, lang.HISTORY)
.replaceFirst(k_PLAYLIST_NAME_MOST_PLAYED, lang.MOST_PLAYED);
}
Expand Down
22 changes: 19 additions & 3 deletions lib/youtube/controller/youtube_account_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class YoutubeAccountController {
static const _operationNeedsAccount = <YoutiPieOperation, bool>{
YoutiPieOperation.fetchNotifications: true,
YoutiPieOperation.fetchNotificationsNext: true,
YoutiPieOperation.markNotificationRead: true,
YoutiPieOperation.fetchFeed: true,
YoutiPieOperation.fetchFeedNext: true,
YoutiPieOperation.fetchHistory: true,
YoutiPieOperation.fetchHistoryNext: true,
YoutiPieOperation.addVideoToHistory: true,
Expand Down Expand Up @@ -77,7 +80,7 @@ class YoutubeAccountController {
if (_operationNeedsAccount[operation] == true) {
if (current.activeAccountChannel.value == null) {
// -- no account
_showError(lang.OPERATION_REQUIRES_ACCOUNT.replaceFirst('_NAME_', '`${operation.name}`'));
_showError(lang.OPERATION_REQUIRES_ACCOUNT.replaceFirst('_NAME_', '`${operation.name}`'), manageAccountButton: true);
return false;
} else {
final needsMembership = _operationNeedsMembership[operation] ?? true;
Expand All @@ -97,6 +100,14 @@ class YoutubeAccountController {
return true;
};

YoutiPie.onOperationFailNoAccount = (operation) {
if (current.activeAccountChannel.value == null) {
_showError(lang.OPERATION_REQUIRES_ACCOUNT.replaceFirst('_NAME_', '`${operation.name}`'), manageAccountButton: true);
return true;
}
return false;
};

final patreonSupportTier = NamicoSubscriptionManager.patreon.getUserSupportTierInCacheValid();
if (patreonSupportTier != null) {
final ms = patreonSupportTier.toMembershipType();
Expand Down Expand Up @@ -205,7 +216,7 @@ class YoutubeAccountController {
}
}

static void _showError(String msg, {Object? exception, bool manageSubscriptionButton = false}) {
static void _showError(String msg, {Object? exception, bool manageSubscriptionButton = false, bool manageAccountButton = false}) {
String title = lang.ERROR;
if (exception != null) title += ': $exception';

Expand All @@ -219,7 +230,12 @@ class YoutubeAccountController {
lang.MANAGE,
const YoutubeManageSubscriptionPage().navigate,
)
: null,
: manageAccountButton
? (
lang.SIGN_IN,
const YoutubeAccountManagePage().navigate,
)
: null,
);
}

Expand Down
2 changes: 2 additions & 0 deletions lib/youtube/functions/add_to_playlist_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ void showAddToPlaylistSheet({
await Future.delayed(Duration.zero); // delay bcz sometimes doesnt show
await showModalBottomSheet(
useRootNavigator: true,
isScrollControlled: true,
backgroundColor: Colors.transparent,
// ignore: use_build_context_synchronously
context: context,
builder: (context) {
final bottomPadding = MediaQuery.viewInsetsOf(context).bottom + MediaQuery.paddingOf(context).bottom;
return Container(
height: context.height * 0.65 + bottomPadding,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0.multipliedRadius),
color: context.theme.scaffoldBackgroundColor,
Expand Down
2 changes: 1 addition & 1 deletion lib/youtube/pages/yt_playlist_subpage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ class _YTNormalPlaylistSubpageState extends State<YTNormalPlaylistSubpage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
playlistCurrentName.translatePlaylistName(liked: true),
playlistCurrentName.translatePlaylistName(),
style: context.textTheme.displayLarge,
),
const SizedBox(height: 6.0),
Expand Down
1,944 changes: 1,013 additions & 931 deletions lib/youtube/youtube_miniplayer.dart

Large diffs are not rendered by default.

109 changes: 78 additions & 31 deletions lib/youtube/youtube_playlists_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,37 @@ class YoutubePlaylistsView extends StatelessWidget with NamidaRouteWidget {
);
}

void _onAddToPlaylist({required YoutubePlaylist playlist, required bool? idsExist}) {
if (idsExist == true) {
final indexes = <int>[];
playlist.tracks.loopAdv((e, index) {
if (idsToAdd.contains(e.id)) {
indexes.add(index);
}
});
NamidaNavigator.inst.navigateDialog(
dialog: CustomBlurryDialog(
isWarning: true,
normalTitleStyle: true,
bodyText: "${lang.REMOVE_FROM_PLAYLIST} ${playlist.name.addDQuotation()}?",
actions: [
const CancelButton(),
const SizedBox(width: 6.0),
NamidaButton(
text: lang.REMOVE.toUpperCase(),
onPressed: () {
NamidaNavigator.inst.closeDialog();
YoutubePlaylistController.inst.removeTracksFromPlaylist(playlist, indexes);
},
)
],
),
);
} else {
YoutubePlaylistController.inst.addTracksToPlaylist(playlist, idsToAdd);
}
}

@override
Widget build(BuildContext context) {
final isMinimalView = minimalView ?? idsToAdd.isNotEmpty;
Expand Down Expand Up @@ -144,8 +175,8 @@ class YoutubePlaylistsView extends StatelessWidget with NamidaRouteWidget {
rx: YoutubePlaylistController.inst.favouritesPlaylist,
builder: (favs) {
return _HorizontalSliverList(
title: lang.LIKED,
icon: Broken.like_1,
title: lang.FAVOURITES,
icon: Broken.heart_circle,
viewAllPage: () => const YTLikedVideosPage(),
videos: getFavouriteVideos(favs.value),
playlistName: k_PLAYLIST_NAME_FAV,
Expand Down Expand Up @@ -255,6 +286,44 @@ class YoutubePlaylistsView extends StatelessWidget with NamidaRouteWidget {
),
),
const SliverPadding(padding: EdgeInsets.only(bottom: 8.0)),
if (idsToAdd.isNotEmpty)
SliverToBoxAdapter(
child: ObxOClass(
rx: YoutubePlaylistController.inst.favouritesPlaylist,
builder: (favouritesPlaylist) => YoutubeCard(
thumbnailType: ThumbnailType.playlist,
isImageImportantInCache: true,
extractColor: true,
thumbnailWidthPercentage: 0.75,
videoId: favouritesPlaylist.value.tracks.firstOrNull?.id,
thumbnailUrl: null,
shimmerEnabled: false,
title: favouritesPlaylist.value.name.translatePlaylistName(),
subtitle: favouritesPlaylist.value.creationDate.dateFormattedOriginal,
displaythirdLineText: true,
thirdLineText: Jiffy.parseFromMillisecondsSinceEpoch(favouritesPlaylist.value.modifiedDate).fromNow(),
displayChannelThumbnail: false,
channelThumbnailUrl: '',
thumbnailHeight: playlistThumbnailHeight,
thumbnailWidth: playlistThumbnailWidth,
onTap: () {
final idsExists = favouritesPlaylist.isSubItemFavourite(idsToAdd.first);
_onAddToPlaylist(
playlist: favouritesPlaylist.value,
idsExist: idsExists,
);
},
smallBoxText: favouritesPlaylist.value.tracks.length.formatDecimal(),
smallBoxIcon: Broken.play_cricle,
checkmarkStatus: favouritesPlaylist.isSubItemFavourite(idsToAdd.first),
menuChildrenDefault: displayMenu ? () => getMenuItems(favouritesPlaylist.value) : null,
),
),
),
if (idsToAdd.isNotEmpty)
const SliverToBoxAdapter(
child: NamidaContainerDivider(margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0)),
),
Obx(
() {
final playlistsMap = YoutubePlaylistController.inst.playlistsMap.valueR;
Expand All @@ -265,7 +334,12 @@ class YoutubePlaylistsView extends StatelessWidget with NamidaRouteWidget {
itemBuilder: (context, index) {
final name = playlistsNames[index];
final playlist = playlistsMap[name]!;
final idsExist = idsToAdd.isEmpty ? null : playlist.tracks.firstWhereEff((e) => e.id == idsToAdd.firstOrNull) != null;
bool? idsExist;
if (idsToAdd.isNotEmpty) {
final firstId = idsToAdd.firstOrNull;
if (firstId != null) idsExist = playlist.tracks.firstWhereEff((e) => e.id == firstId) != null;
}

return NamidaPopupWrapper(
childrenDefault: displayMenu ? () => getMenuItems(playlist) : null,
openOnTap: false,
Expand All @@ -287,34 +361,7 @@ class YoutubePlaylistsView extends StatelessWidget with NamidaRouteWidget {
thumbnailWidth: playlistThumbnailWidth,
onTap: () {
if (idsToAdd.isNotEmpty) {
if (idsExist == true) {
final indexes = <int>[];
playlist.tracks.loopAdv((e, index) {
if (idsToAdd.contains(e.id)) {
indexes.add(index);
}
});
NamidaNavigator.inst.navigateDialog(
dialog: CustomBlurryDialog(
isWarning: true,
normalTitleStyle: true,
bodyText: "${lang.REMOVE_FROM_PLAYLIST} ${playlist.name.addDQuotation()}?",
actions: [
const CancelButton(),
const SizedBox(width: 6.0),
NamidaButton(
text: lang.REMOVE.toUpperCase(),
onPressed: () {
NamidaNavigator.inst.closeDialog();
YoutubePlaylistController.inst.removeTracksFromPlaylist(playlist, indexes);
},
)
],
),
);
} else {
YoutubePlaylistController.inst.addTracksToPlaylist(playlist, idsToAdd);
}
_onAddToPlaylist(playlist: playlist, idsExist: idsExist);
} else {
YTNormalPlaylistSubpage(playlistName: playlist.name).navigate();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/youtube/yt_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ class YTUtils {
NamidaPopupItem(
icon: Broken.box_remove,
title: lang.REMOVE_FROM_PLAYLIST,
subtitle: playlistName.translatePlaylistName(liked: true),
subtitle: playlistName.translatePlaylistName(),
onTap: () => YTUtils.onRemoveVideosFromPlaylist(playlistName, [videoYTID]),
),
if (moreMenuChildren != null) ...moreMenuChildren,
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.1.7-beta+240711002
version: 3.1.9-beta+240711239

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

0 comments on commit c3b6742

Please sign in to comment.