Skip to content

Commit

Permalink
feat: yt playlists support (normal, likes, most played, history)
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Nov 12, 2023
1 parent e719215 commit 73f9a24
Show file tree
Hide file tree
Showing 21 changed files with 995 additions and 263 deletions.
Binary file added assets/fonts/broken_filled.ttf
Binary file not shown.
2 changes: 1 addition & 1 deletion lib/controller/settings_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class SettingsController {
AppPaths.LATEST_QUEUE,
AppDirs.YT_PLAYLISTS,
AppDirs.YT_HISTORY_PLAYLIST,
AppPaths.YT_FAVOURITES_PLAYLIST,
AppPaths.YT_LIKES_PLAYLIST,
].obs;
final RxBool enableVideoPlayback = true.obs;
final RxBool enableLyrics = false.obs;
Expand Down
2 changes: 1 addition & 1 deletion lib/core/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class AppPaths {
static final NAMIDA_LOGO = '${AppDirs.ARTWORKS}.ARTWORKS.NAMIDA_DEFAULT_ARTWORK.PNG';

// ================= Youtube =================
static final YT_FAVOURITES_PLAYLIST = '${AppDirs.YOUTUBE_MAIN_DIRECTORY}/ytfavs.json';
static final YT_LIKES_PLAYLIST = '${AppDirs.YOUTUBE_MAIN_DIRECTORY}/yt_likes.json';
}

/// Directories used by Namida
Expand Down
5 changes: 5 additions & 0 deletions lib/core/enums.dart
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ enum RouteType {

// ----- Youtube -----
YOUTUBE_HOME,
YOUTUBE_PLAYLISTS,
YOUTUBE_PLAYLIST_SUBPAGE,
YOUTUBE_LIKED_SUBPAGE,
YOUTUBE_HISTORY_SUBPAGE,
YOUTUBE_MOST_PLAYED_SUBPAGE,

/// others
UNKNOWN,
Expand Down
5 changes: 5 additions & 0 deletions lib/core/icon_fonts/broken_icons.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import 'package:flutter/widgets.dart';
class Broken {
Broken._();

static const String _fontFamilyFilled = 'broken_filled';

static const IconData dislike_filled = IconData(0xe900, fontFamily: _fontFamilyFilled);
static const IconData like_filled = IconData(0xe901, fontFamily: _fontFamilyFilled);

static const String _fontFamily = 'broken';

static const IconData woman = IconData(0xe900, fontFamily: _fontFamily);
Expand Down
22 changes: 21 additions & 1 deletion lib/core/namida_converter_ext.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ import 'package:namida/controller/selected_tracks_controller.dart';
import 'package:namida/controller/settings_controller.dart';
import 'package:namida/core/constants.dart';
import 'package:namida/core/dimensions.dart';
import 'package:namida/core/functions.dart';
import 'package:namida/core/enums.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/core/functions.dart';
import 'package:namida/core/icon_fonts/broken_icons.dart';
import 'package:namida/core/translations/language.dart';
import 'package:namida/ui/dialogs/common_dialogs.dart';
Expand Down Expand Up @@ -64,6 +64,9 @@ import 'package:namida/youtube/controller/youtube_controller.dart';
import 'package:namida/youtube/functions/add_to_playlist_sheet.dart';
import 'package:namida/youtube/functions/download_sheet.dart';
import 'package:namida/youtube/pages/youtube_home_view.dart';
import 'package:namida/youtube/pages/yt_history_page.dart';
import 'package:namida/youtube/pages/yt_playlist_subpage.dart';
import 'package:namida/youtube/youtube_playlists_view.dart';

extension LibraryTabToEnum on int {
LibraryTab toEnum() => settings.libraryTabs.elementAt(this);
Expand Down Expand Up @@ -676,9 +679,26 @@ extension WidgetsPagess on Widget {
route = RouteType.SETTINGS_subpage;
name = (this as SettingsSubPage).title;
break;

case YouTubeHomeView:
route = RouteType.YOUTUBE_HOME;
break;
case YoutubePlaylistsView:
route = RouteType.YOUTUBE_PLAYLISTS;
break;
case YTNormalPlaylistSubpage:
route = RouteType.YOUTUBE_PLAYLIST_SUBPAGE;
name = (this as YTNormalPlaylistSubpage).playlist.name;
break;
case YoutubeHistoryPage:
route = RouteType.YOUTUBE_HISTORY_SUBPAGE;
break;
case YTMostPlayedVideosPage:
route = RouteType.YOUTUBE_MOST_PLAYED_SUBPAGE;
break;
case YTLikedVideosPage:
route = RouteType.YOUTUBE_LIKED_SUBPAGE;
break;
}

return NamidaRoute(route, name);
Expand Down
4 changes: 4 additions & 0 deletions lib/ui/dialogs/edit_tags_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@ class CustomTagTextField extends StatelessWidget {
final AutovalidateMode? validatorMode;
final void Function(String value)? onFieldSubmitted;
final double borderRadius;
final FocusNode? focusNode;

CustomTagTextField({
super.key,
required this.controller,
Expand All @@ -1155,6 +1157,7 @@ class CustomTagTextField extends StatelessWidget {
this.validatorMode,
this.onFieldSubmitted,
this.borderRadius = 16.0,
this.focusNode,
});
final RxBool didChange = false.obs;
@override
Expand All @@ -1164,6 +1167,7 @@ class CustomTagTextField extends StatelessWidget {
return SizedBox(
width: null,
child: TextFormField(
focusNode: focusNode,
validator: validator,
maxLength: maxLength,
controller: controller,
Expand Down
159 changes: 82 additions & 77 deletions lib/ui/pages/subpages/most_played_subpage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,91 +95,96 @@ class MostPlayedItemsPage<T extends ItemWithDate, E> extends StatelessWidget {
);
}

@override
Widget build(BuildContext context) {
return BackgroundWrapper(
child: Obx(
() {
final finalListenMap = historyController.currentTopTracksMapListens;
final mostplayedOptions = List<MostPlayedTimeRange>.from(MostPlayedTimeRange.values)..remove(MostPlayedTimeRange.custom);
final bottomWidget = Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
Widget getChipsRow(BuildContext context) {
final mostplayedOptions = List<MostPlayedTimeRange>.from(MostPlayedTimeRange.values)..remove(MostPlayedTimeRange.custom);

return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
const SizedBox(width: 8.0),
NamidaInkWell(
animationDurationMS: 200,
borderRadius: 6.0,
bgColor: context.theme.cardTheme.color,
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: _isEnabled(MostPlayedTimeRange.custom) ? Border.all(color: CurrentColor.inst.color) : null,
borderRadius: BorderRadius.circular(8.0.multipliedRadius),
),
child: Row(
children: [
const SizedBox(width: 8.0),
NamidaInkWell(
animationDurationMS: 200,
borderRadius: 6.0,
bgColor: context.theme.cardTheme.color,
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: _isEnabled(MostPlayedTimeRange.custom) ? Border.all(color: CurrentColor.inst.color) : null,
borderRadius: BorderRadius.circular(8.0.multipliedRadius),
),
child: Row(
children: [
const Icon(Broken.calendar, size: 18.0),
const SizedBox(width: 4.0),
Text(
lang.CUSTOM,
style: context.textTheme.displayMedium,
),
const SizedBox(width: 4.0),
const Icon(Broken.arrow_down_2, size: 14.0),
],
),
onTap: () {
showCalendarDialog(
title: lang.CHOOSE,
buttonText: lang.CONFIRM,
useHistoryDates: true,
onGenerate: (dates) => _onSelectingTimeRange(
dateCustom: DateRange(oldest: dates.first, newest: dates.last),
mptr: MostPlayedTimeRange.custom,
),
);
},
const Icon(Broken.calendar, size: 18.0),
const SizedBox(width: 4.0),
Text(
lang.CUSTOM,
style: context.textTheme.displayMedium,
),
const SizedBox(width: 4.0),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Obx(
() {
final dateRange = customDateRange.value;
return _getChipChild(
context: context,
mptr: MostPlayedTimeRange.custom,
dateCustom: dateRange,
trailing: (textColor) => NamidaIconButton(
padding: EdgeInsets.zero,
icon: Broken.close_circle,
iconSize: 14.0,
iconColor: textColor,
onPressed: () => _onSelectingTimeRange(mptr: MostPlayedTimeRange.allTime, dateCustom: DateRange.dummy()),
),
).animateEntrance(
showWhen: dateRange.oldest != DateTime(0),
durationMS: 400,
reverseDurationMS: 200,
);
},
),
...mostplayedOptions.map(
(action) => _getChipChild(
context: context,
mptr: action,
),
const Icon(Broken.arrow_down_2, size: 14.0),
],
),
onTap: () {
showCalendarDialog(
title: lang.CHOOSE,
buttonText: lang.CONFIRM,
useHistoryDates: true,
onGenerate: (dates) => _onSelectingTimeRange(
dateCustom: DateRange(oldest: dates.first, newest: dates.last),
mptr: MostPlayedTimeRange.custom,
),
);
},
),
const SizedBox(width: 4.0),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Obx(
() {
final dateRange = customDateRange.value;
return _getChipChild(
context: context,
mptr: MostPlayedTimeRange.custom,
dateCustom: dateRange,
trailing: (textColor) => NamidaIconButton(
padding: EdgeInsets.zero,
icon: Broken.close_circle,
iconSize: 14.0,
iconColor: textColor,
onPressed: () => _onSelectingTimeRange(mptr: MostPlayedTimeRange.allTime, dateCustom: DateRange.dummy()),
),
],
).animateEntrance(
showWhen: dateRange.oldest != DateTime(0),
durationMS: 400,
reverseDurationMS: 200,
);
},
),
...mostplayedOptions.map(
(action) => _getChipChild(
context: context,
mptr: action,
),
),
),
],
],
),
),
);
),
],
),
);
}

@override
Widget build(BuildContext context) {
return BackgroundWrapper(
child: Obx(
() {
final finalListenMap = historyController.currentTopTracksMapListens;
final bottomWidget = getChipsRow(context);
const bottomPadding = 0.0;
return NamidaListView(
itemExtents: itemExtents,
Expand Down

0 comments on commit 73f9a24

Please sign in to comment.