Skip to content

Commit

Permalink
feat: yt queue chip
Browse files Browse the repository at this point in the history
ref #1
  • Loading branch information
MSOB7YY committed Jan 7, 2024
1 parent 8b4c395 commit 3148650
Show file tree
Hide file tree
Showing 8 changed files with 634 additions and 103 deletions.
10 changes: 9 additions & 1 deletion lib/controller/navigator_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import 'package:namida/core/themes.dart';
import 'package:namida/core/translations/language.dart';
import 'package:namida/packages/inner_drawer.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/youtube/widgets/yt_queue_chip.dart';

class NamidaNavigator {
static NamidaNavigator get inst => _instance;
Expand All @@ -36,13 +37,15 @@ class NamidaNavigator {

bool isytLocalSearchInFullPage = false;
bool isInYTCommentsSubpage = false;
bool isQueueSheetOpen = false;

final RxList<NamidaRoute> currentWidgetStack = <NamidaRoute>[].obs;
NamidaRoute? get currentRoute => currentWidgetStack.lastOrNull;
int _currentDialogNumber = 0;
int _currentMenusNumber = 0;

final GlobalKey<InnerDrawerState> innerDrawerKey = GlobalKey<InnerDrawerState>();
final innerDrawerKey = GlobalKey<InnerDrawerState>();
final ytQueueSheetKey = GlobalKey<YTMiniplayerQueueChipState>();
final heroController = HeroController();

bool _isInLanscape = false;
Expand Down Expand Up @@ -349,6 +352,11 @@ class NamidaNavigator {
return;
}

if (isQueueSheetOpen) {
ytQueueSheetKey.currentState?.dismissSheet();
isQueueSheetOpen = false;
return;
}
if (isInYTCommentsSubpage) {
ytMiniplayerCommentsPageKey?.currentState?.pop();
isInYTCommentsSubpage = false;
Expand Down
2 changes: 2 additions & 0 deletions lib/core/dimensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,5 @@ const kYoutubeHistoryDayListTopPadding = 6.0;
const kYoutubeHistoryDayListBottomPadding = 12.0;

const kYoutubeHistoryDayHeaderHeightWithPadding = kYoutubeHistoryDayHeaderHeight + kYoutubeHistoryDayListTopPadding + kYoutubeHistoryDayListBottomPadding;

const kYTQueueSheetMinHeight = 60.0;
1 change: 1 addition & 0 deletions lib/core/translations/keys.dart
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ abstract class LanguageKeys {
String get NEW_TRACKS_SIMILARR_RELEASE_DATE_SUBTITLE => _getKey('NEW_TRACKS_SIMILARR_RELEASE_DATE_SUBTITLE');
String get NEW_TRACKS_SIMILARR_RELEASE_DATE => _getKey('NEW_TRACKS_SIMILARR_RELEASE_DATE');
String get NEW_TRACKS_UNKNOWN_YEAR => _getKey('NEW_TRACKS_UNKNOWN_YEAR');
String get NEXT => _getKey('NEXT');
String get NO_CHANGES_FOUND => _getKey('NO_CHANGES_FOUND');
String get NO_ENOUGH_TRACKS => _getKey('NO_ENOUGH_TRACKS');
String get NO_EXCLUDED_FOLDERS => _getKey('NO_EXCLUDED_FOLDERS');
Expand Down
5 changes: 3 additions & 2 deletions lib/ui/pages/subpages/playlist_tracks_subpage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,8 @@ class NormalPlaylistTracksPage extends StatelessWidget {

class ThreeLineSmallContainers extends StatelessWidget {
final bool enabled;
const ThreeLineSmallContainers({Key? key, required this.enabled}) : super(key: key);
final Color? color;
const ThreeLineSmallContainers({Key? key, required this.enabled, this.color}) : super(key: key);

@override
Widget build(BuildContext context) {
Expand All @@ -461,7 +462,7 @@ class ThreeLineSmallContainers extends StatelessWidget {
width: enabled ? 9.0 : 2.0,
height: 1.2,
margin: const EdgeInsets.symmetric(vertical: 1),
color: context.theme.listTileTheme.iconColor?.withAlpha(120),
color: color ?? context.theme.listTileTheme.iconColor?.withAlpha(120),
),
),
);
Expand Down
256 changes: 156 additions & 100 deletions lib/youtube/widgets/yt_history_video_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:namida/controller/player_controller.dart';
import 'package:namida/core/dimensions.dart';
import 'package:namida/core/enums.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/ui/pages/subpages/playlist_tracks_subpage.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/youtube/class/youtube_id.dart';
import 'package:namida/youtube/controller/youtube_controller.dart';
Expand All @@ -28,6 +29,7 @@ class YTHistoryVideoCard extends StatelessWidget {
final bool reversedList;
final String playlistName;
final bool openMenuOnLongPress;
final bool fromPlayerQueue;

const YTHistoryVideoCard({
super.key,
Expand All @@ -43,6 +45,7 @@ class YTHistoryVideoCard extends StatelessWidget {
this.reversedList = false,
required this.playlistName,
this.openMenuOnLongPress = true,
this.fromPlayerQueue = false,
});

@override
Expand All @@ -64,7 +67,7 @@ class YTHistoryVideoCard extends StatelessWidget {
videoYTID: video,
);
final videoTitle = info?.name ?? YoutubeController.inst.getVideoName(video.id) ?? video.id;
final videoSubtitle = info?.uploaderName ?? YoutubeController.inst.getVideoChannelName(video.id);
final videoChannel = info?.uploaderName ?? YoutubeController.inst.getVideoChannelName(video.id);
final watchMS = video.dateTimeAdded.millisecondsSinceEpoch;
final dateText = !displayTimeAgo
? ''
Expand All @@ -76,112 +79,165 @@ class YTHistoryVideoCard extends StatelessWidget {
openOnTap: false,
openOnLongPress: openMenuOnLongPress,
childrenDefault: menuItems,
child: Obx(
() {
final isCurrentlyPlaying = Player.inst.nowPlayingVideoID == video;
final sameDay = day == YoutubeHistoryController.inst.dayOfHighLight.value;
final sameIndex = index == YoutubeHistoryController.inst.indexToHighlight.value;
final hightlightedColor = sameDay && sameIndex ? context.theme.colorScheme.onBackground.withAlpha(40) : null;
final children = [
SizedBox(
width: minimalCard ? null : Dimensions.youtubeCardItemVerticalPadding,
height: minimalCard ? 1.0 : null,
),
Center(
child: YoutubeThumbnail(
key: Key(video.id),
borderRadius: 8.0,
isImportantInCache: true,
width: thumbWidth - 3.0,
height: thumbHeight - 3.0,
videoId: video.id,
smallBoxText: duration,
),
),
const SizedBox(width: 12.0),
Expanded(
child: Padding(
padding: minimalCard ? const EdgeInsets.all(4.0) : EdgeInsets.zero,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
videoTitle,
maxLines: minimalCard ? 1 : 2,
overflow: TextOverflow.ellipsis,
style: context.textTheme.displayMedium?.copyWith(
fontSize: minimalCard ? 12.0.multipliedFontScale : null,
color: isCurrentlyPlaying ? Colors.white.withOpacity(0.7) : null,
),
),
if (videoSubtitle != null)
Text(
videoSubtitle,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context.textTheme.displaySmall?.copyWith(
fontSize: minimalCard ? 11.5.multipliedFontScale : null,
color: isCurrentlyPlaying ? Colors.white.withOpacity(0.6) : null,
child: Stack(
children: [
Obx(
() {
final isCurrentlyPlaying = Player.inst.nowPlayingVideoID == video;
final sameDay = day == YoutubeHistoryController.inst.dayOfHighLight.value;
final sameIndex = index == YoutubeHistoryController.inst.indexToHighlight.value;
final hightlightedColor = sameDay && sameIndex ? context.theme.colorScheme.onBackground.withAlpha(40) : null;
final itemsColor7 = isCurrentlyPlaying ? Colors.white.withOpacity(0.7) : null;
final itemsColor6 = isCurrentlyPlaying ? Colors.white.withOpacity(0.6) : null;
final itemsColor5 = isCurrentlyPlaying ? Colors.white.withOpacity(0.5) : null;
final children = [
if (fromPlayerQueue) ThreeLineSmallContainers(enabled: true, color: itemsColor5),
SizedBox(
width: minimalCard ? null : Dimensions.youtubeCardItemVerticalPadding,
height: minimalCard ? 1.0 : null,
),
Center(
child: YoutubeThumbnail(
key: Key(video.id),
borderRadius: 8.0,
isImportantInCache: true,
width: thumbWidth - 3.0,
height: thumbHeight - 3.0,
videoId: video.id,
smallBoxText: duration,
),
),
const SizedBox(width: 12.0),
Expanded(
child: Padding(
padding: minimalCard ? const EdgeInsets.all(4.0) : EdgeInsets.zero,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
videoTitle,
maxLines: minimalCard ? 1 : 2,
overflow: TextOverflow.ellipsis,
style: context.textTheme.displayMedium?.copyWith(
fontSize: minimalCard ? 12.0.multipliedFontScale : null,
color: itemsColor7,
),
),
),
if (dateText != '')
Text(
dateText,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context.textTheme.displaySmall?.copyWith(
fontSize: minimalCard ? 11.0.multipliedFontScale : null,
color: isCurrentlyPlaying ? Colors.white.withOpacity(0.5) : null,
if (videoChannel != null)
Text(
videoChannel,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context.textTheme.displaySmall?.copyWith(
fontSize: minimalCard ? 11.5.multipliedFontScale : null,
color: itemsColor6,
),
),
if (dateText != '')
Text(
dateText,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context.textTheme.displaySmall?.copyWith(
fontSize: minimalCard ? 11.0.multipliedFontScale : null,
color: itemsColor5,
),
),
],
)),
),
const SizedBox(width: 12.0),
];
return NamidaInkWell(
borderRadius: minimalCard ? 8.0 : 10.0,
width: minimalCard ? thumbWidth : null,
onTap: () {
YTUtils.expandMiniplayer();
if (fromPlayerQueue) {
final i = this.index;
if (i == Player.inst.currentIndex) {
Player.inst.togglePlayPause();
} else {
Player.inst.skipToQueueItem(this.index);
}
}
Player.inst.playOrPause(
this.index, (reversedList ? videos.reversed : videos).map((e) => YoutubeID(id: e.id, watchNull: e.watchNull, playlistID: playlistID)), QueueSource.others);
},
height: minimalCard ? null : Dimensions.youtubeCardItemExtent,
margin: EdgeInsets.symmetric(horizontal: minimalCard ? 2.0 : 4.0, vertical: Dimensions.youtubeCardItemVerticalPadding),
bgColor: isCurrentlyPlaying ? CurrentColor.inst.color.withAlpha(140) : (hightlightedColor ?? context.theme.cardColor),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.0.multipliedRadius),
),
child: Stack(
children: [
minimalCard
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
)
: Row(
children: children,
),
Positioned(
bottom: 6.0,
right: minimalCard ? 6.0 : 12.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: YTUtils.getVideoCacheStatusIcons(
context: context,
videoId: video.id,
iconsColor: itemsColor5,
overrideListens: overrideListens,
displayCacheIcons: !minimalCard,
),
],
)),
),
const SizedBox(width: 12.0),
];
return NamidaInkWell(
borderRadius: minimalCard ? 8.0 : 10.0,
width: minimalCard ? thumbWidth : null,
onTap: () {
YTUtils.expandMiniplayer();
Player.inst.playOrPause(
this.index, (reversedList ? videos.reversed : videos).map((e) => YoutubeID(id: e.id, watchNull: e.watchNull, playlistID: playlistID)), QueueSource.others);
},
height: minimalCard ? 100 : Dimensions.youtubeCardItemExtent,
margin: EdgeInsets.symmetric(horizontal: minimalCard ? 2.0 : 4.0, vertical: Dimensions.youtubeCardItemVerticalPadding),
bgColor: isCurrentlyPlaying ? CurrentColor.inst.color.withAlpha(140) : (hightlightedColor ?? context.theme.cardColor),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.0.multipliedRadius),
),
child: Stack(
children: [
minimalCard
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
)
: Row(
children: children,
),
Positioned(
bottom: 6.0,
right: minimalCard ? 6.0 : 12.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: YTUtils.getVideoCacheStatusIcons(
context: context,
videoId: video.id,
iconsColor: isCurrentlyPlaying ? Colors.white.withOpacity(0.5) : null,
overrideListens: overrideListens,
displayCacheIcons: !minimalCard,
),
),
if (fromPlayerQueue)
Positioned(
top: 0.0,
right: 0.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: NamidaPopupWrapper(
childrenDefault: YTUtils.getVideoCardMenuItems(
videoId: video.id,
url: info?.url,
channelUrl: info?.uploaderUrl,
playlistID: playlistID,
idsNamesLookup: {video.id: videoTitle},
),
child: MoreIcon(
iconSize: 16.0,
iconColor: itemsColor6,
),
),
),
),
],
),
],
);
},
),
if (fromPlayerQueue && !minimalCard)
Positioned(
left: 0,
bottom: 0,
top: 0,
child: NamidaReordererableListener(
durationMs: 80,
isInQueue: true,
index: index,
child: Container(
color: Colors.transparent,
height: thumbHeight,
width: thumbWidth, // not fully but better, to avoid accidents
),
),
),
);
},
],
),
);
}
Expand Down
Loading

0 comments on commit 3148650

Please sign in to comment.