Skip to content

Commit

Permalink
feat: rework queue (#1076)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feichtmeier authored Dec 3, 2024
1 parent ba9fe1a commit 6c74a2a
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 243 deletions.
7 changes: 7 additions & 0 deletions lib/app/app_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ class AppModel extends SafeChangeNotifier {
notifyListeners();
}

bool _showQueueOverlay = false;
bool get showQueueOverlay => _showQueueOverlay;
void setOrToggleQueueOverlay({bool? value}) {
_showQueueOverlay = value ?? !_showQueueOverlay;
notifyListeners();
}

bool? _fullWindowMode;
bool? get fullWindowMode => _fullWindowMode;
Future<void> setFullWindowMode(bool? value) async {
Expand Down
7 changes: 5 additions & 2 deletions lib/app/view/desktop_home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '../../common/view/ui_constants.dart';
import '../../extensions/build_context_x.dart';
import '../../l10n/l10n.dart';
import '../../patch_notes/patch_notes_dialog.dart';
import '../../player/player_model.dart';
import '../../player/view/player_view.dart';
import '../../podcasts/download_model.dart';
import '../../settings/settings_model.dart';
Expand Down Expand Up @@ -47,6 +48,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> {
Widget build(BuildContext context) {
final playerToTheRight = context.mediaQuerySize.width > kSideBarThreshHold;
final isFullScreen = watchPropertyValue((AppModel m) => m.fullWindowMode);
final isVideo = watchPropertyValue((PlayerModel m) => m.isVideo == true);
final enableDiscordRPC =
watchPropertyValue((SettingsModel m) => m.enableDiscordRPC);

Expand Down Expand Up @@ -97,8 +99,9 @@ class _DesktopHomePageState extends State<DesktopHomePage> {
],
),
if (isFullScreen == true)
const Scaffold(
body: PlayerView(position: PlayerPosition.fullWindow),
Scaffold(
backgroundColor: isVideo ? Colors.black : null,
body: const PlayerView(position: PlayerPosition.fullWindow),
),
],
);
Expand Down
16 changes: 14 additions & 2 deletions lib/app/view/mobile_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import 'package:flutter/material.dart';
import 'package:watch_it/watch_it.dart';

import '../../common/view/snackbars.dart';
import '../../common/view/theme.dart';
import '../../extensions/build_context_x.dart';
import '../../player/player_model.dart';
import '../../player/view/full_height_player.dart';
import '../../player/view/player_view.dart';
import '../../podcasts/download_model.dart';
Expand Down Expand Up @@ -42,8 +44,18 @@ class MobilePage extends StatelessWidget with WatchItMixin {
if (fullWindowMode)
Material(
color: context.theme.scaffoldBackgroundColor,
child: const FullHeightPlayer(
playerPosition: PlayerPosition.fullWindow,
child: GestureDetector(
onVerticalDragEnd: (details) {
if (details.primaryVelocity != null &&
details.primaryVelocity! > 150) {
di<AppModel>().setFullWindowMode(false);
}
di<PlayerModel>().bottomPlayerHeight =
bottomPlayerDefaultHeight;
},
child: const FullHeightPlayer(
playerPosition: PlayerPosition.fullWindow,
),
),
)
else
Expand Down
6 changes: 3 additions & 3 deletions lib/common/view/icons.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ class Iconz {

static IconData get remove {
return yaruStyled
? YaruIcons.minus
? YaruIcons.trash
: appleStyled
? CupertinoIcons.minus
: Icons.remove_rounded;
? CupertinoIcons.trash
: Icons.delete_outline_rounded;
}

static IconData get check => yaruStyled
Expand Down
9 changes: 9 additions & 0 deletions lib/common/view/theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,15 @@ double? get bottomPlayerPageGap => isMobilePlatform
? bottomPlayerDefaultHeight + navigationBarHeight + kLargestSpace
: null;

EdgeInsets get playerTopControlsPadding => EdgeInsets.only(
right: kLargestSpace,
top: Platform.isMacOS
? 0
: isMobilePlatform
? 2 * kLargestSpace
: kLargestSpace,
);

NavigationBarThemeData navigationBarTheme({required ThemeData theme}) =>
theme.navigationBarTheme.copyWith(
iconTheme: WidgetStatePropertyAll(
Expand Down
8 changes: 3 additions & 5 deletions lib/player/view/bottom_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ class BottomPlayer extends StatelessWidget with WatchItMixin {
final isOnline = watchPropertyValue((ConnectivityModel m) => m.isOnline);

final active = audio?.path != null || isOnline;
final showQueueButton = watchPropertyValue(
(PlayerModel m) =>
m.queue.length > 1 || audio?.audioType == AudioType.local,
);

final children = [
PlayerTrack(
Expand Down Expand Up @@ -107,7 +103,9 @@ class BottomPlayer extends StatelessWidget with WatchItMixin {
if (audio?.audioType == AudioType.podcast)
PlaybackRateButton(active: active),
if (!isMobilePlatform) const VolumeSliderPopup(),
if (showQueueButton) const QueueButton(),
const QueueButton(
isSelected: false,
),
IconButton(
tooltip: context.l10n.fullWindow,
icon: Icon(
Expand Down
111 changes: 44 additions & 67 deletions lib/player/view/full_height_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import '../../app/connectivity_model.dart';
import '../../app_config.dart';
import '../../common/data/audio_type.dart';
import '../../common/view/header_bar.dart';
import '../../common/view/theme.dart';
import '../../common/view/ui_constants.dart';
import '../../extensions/build_context_x.dart';
import '../../player/player_model.dart';
Expand Down Expand Up @@ -34,53 +33,58 @@ class FullHeightPlayer extends StatelessWidget with WatchItMixin {
final theme = context.theme;
final size = context.mediaQuerySize;
final isOnline = watchPropertyValue((ConnectivityModel m) => m.isOnline);
final appModel = di<AppModel>();
final audio = watchPropertyValue((PlayerModel m) => m.audio);
final isVideo = watchPropertyValue((PlayerModel m) => m.isVideo == true);

final active = audio?.path != null || isOnline;
final iconColor = isVideo ? Colors.white : theme.colorScheme.onSurface;

final showQueue = watchPropertyValue((AppModel m) => m.showQueueOverlay);
final playerWithSidePanel = playerPosition == PlayerPosition.fullWindow &&
context.mediaQuerySize.width > 1000;

final Widget bodyWithControls;
final Widget body;
if (isVideo) {
bodyWithControls = FullHeightVideoPlayer(
body = FullHeightVideoPlayer(
playerPosition: playerPosition,
);
} else {
final column = Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
if (!isMobilePlatform || context.isPortrait)
const FullHeightPlayerImage(),
const SizedBox(
height: kLargestSpace,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: PlayerTitleAndArtist(
playerPosition: playerPosition,
if (showQueue && !playerWithSidePanel)
const Padding(
padding: EdgeInsets.only(bottom: 2 * kLargestSpace),
child: QueueBody(),
)
else ...[
if (!isMobilePlatform || context.isPortrait)
const FullHeightPlayerImage(),
const SizedBox(
height: kLargestSpace,
),
),
const SizedBox(
height: kLargestSpace,
),
SizedBox(
height: kLargestSpace,
width: playerWithSidePanel ? 400 : 350,
child: const PlayerTrack(),
),
const SizedBox(
height: kLargestSpace,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: PlayerTitleAndArtist(
playerPosition: playerPosition,
),
),
const SizedBox(
height: kLargestSpace,
),
SizedBox(
height: kLargestSpace,
width: playerWithSidePanel ? 400 : 350,
child: const PlayerTrack(),
),
const SizedBox(
height: kLargestSpace,
),
],
PlayerMainControls(active: active),
],
);

bodyWithControls = Stack(
body = Stack(
alignment: Alignment.topRight,
children: [
Center(
Expand All @@ -99,7 +103,6 @@ class FullHeightPlayer extends StatelessWidget with WatchItMixin {
),
)
: QueueBody(
advancedList: false,
selectedColor: theme.colorScheme.onSurface,
),
],
Expand All @@ -109,27 +112,12 @@ class FullHeightPlayer extends StatelessWidget with WatchItMixin {
FullHeightPlayerTopControls(
iconColor: iconColor,
playerPosition: playerPosition,
showQueueButton: !playerWithSidePanel,
),
],
);
}

final body = isMobilePlatform
? GestureDetector(
onVerticalDragEnd: (details) {
if (details.primaryVelocity != null &&
details.primaryVelocity! > 150) {
appModel.setFullWindowMode(false);
}
di<PlayerModel>().bottomPlayerHeight = bottomPlayerDefaultHeight;
},
child: Padding(
padding: const EdgeInsets.only(top: 40),
child: bodyWithControls,
),
)
: bodyWithControls;

final headerBar = HeaderBar(
adaptive: false,
includeBackButton: false,
Expand All @@ -143,30 +131,19 @@ class FullHeightPlayer extends StatelessWidget with WatchItMixin {
backgroundColor: isVideo == true ? Colors.black : Colors.transparent,
);

final fullHeightPlayer = isVideo
? Scaffold(
backgroundColor: Colors.black,
appBar: headerBar,
body: body,
)
: Column(
children: [
if (!isMobilePlatform) headerBar,
Expanded(
child: body,
),
],
);
final fullHeightPlayer = Column(
children: [
if (!isMobilePlatform) headerBar,
Expanded(child: body),
],
);

if (!isVideo) {
return Stack(
children: [
BlurredFullHeightPlayerImage(size: size),
fullHeightPlayer,
],
);
if (isVideo) {
return fullHeightPlayer;
}

return fullHeightPlayer;
return Stack(
children: [BlurredFullHeightPlayerImage(size: size), fullHeightPlayer],
);
}
}
Loading

0 comments on commit 6c74a2a

Please sign in to comment.