Skip to content

Commit

Permalink
feat: volume slider mouse scroll and preference for Rotating Album Art
Browse files Browse the repository at this point in the history
  • Loading branch information
KRTirtho committed Oct 9, 2022
1 parent 6d4c6b1 commit edb6f3c
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 28 deletions.
44 changes: 29 additions & 15 deletions lib/components/Player/Player.dart
@@ -1,3 +1,4 @@
import 'package:flutter/gestures.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/components/Player/PlayerActions.dart';
Expand Down Expand Up @@ -122,23 +123,36 @@ class Player extends HookConsumerWidget {
}
return null;
}, [playback.volume]);
return Slider.adaptive(
min: 0,
max: 1,
value: volume.value,
onChanged: (v) {
volume.value = v;
},
onChangeEnd: (value) async {
try {
// You don't really need to know why but this
// way it works only
await playback.setVolume(value);
await playback.setVolume(value);
} catch (e, stack) {
logger.e("onChange", e, stack);
return Listener(
onPointerSignal: (event) async {
if (event is PointerScrollEvent) {
if (event.scrollDelta.dy > 0) {
final value = volume.value - .2;
playback.setVolume(value < 0 ? 0 : value);
} else {
final value = volume.value + .2;
playback.setVolume(value > 1 ? 1 : value);
}
}
},
child: Slider.adaptive(
min: 0,
max: 1,
value: volume.value,
onChanged: (v) {
volume.value = v;
},
onChangeEnd: (value) async {
try {
// You don't really need to know why but this
// way it works only
await playback.setVolume(value);
await playback.setVolume(value);
} catch (e, stack) {
logger.e("onChange", e, stack);
}
},
),
);
}),
),
Expand Down
52 changes: 39 additions & 13 deletions lib/components/Player/PlayerView.dart
@@ -1,6 +1,5 @@
import 'dart:ui';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
Expand All @@ -15,6 +14,7 @@ import 'package:spotube/hooks/useBreakpoints.dart';
import 'package:spotube/hooks/useCustomStatusBarColor.dart';
import 'package:spotube/hooks/usePaletteColor.dart';
import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/UserPreferences.dart';
import 'package:spotube/utils/type_conversion_utils.dart';

class PlayerView extends HookConsumerWidget {
Expand All @@ -28,6 +28,9 @@ class PlayerView extends HookConsumerWidget {
(value) => value.track,
));
final breakpoint = useBreakpoints();
final canRotate = ref.watch(
userPreferencesProvider.select((s) => s.rotatingAlbumArt),
);

useEffect(() {
if (breakpoint.isMoreThan(Breakpoints.md)) {
Expand Down Expand Up @@ -108,23 +111,46 @@ class PlayerView extends HookConsumerWidget {
final controller = useAnimationController(
duration: const Duration(seconds: 10),
vsync: ticker,
)..repeat();
);

useEffect(
() {
controller.repeat();
if (!canRotate) controller.stop();
return null;
},
[controller],
);
return RotationTransition(
turns: Tween(begin: 0.0, end: 1.0).animate(controller),
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: paletteColor.titleTextColor,
width: 2,
),
shape: BoxShape.circle,
),
child: CircleAvatar(
backgroundImage:
UniversalImage.imageProvider(albumArt),
radius: MediaQuery.of(context).size.width *
(breakpoint.isSm ? 0.4 : 0.3),
border: canRotate
? Border.all(
color: paletteColor.titleTextColor,
width: 2,
)
: null,
borderRadius:
!canRotate ? BorderRadius.circular(15) : null,
shape:
canRotate ? BoxShape.circle : BoxShape.rectangle,
),
child: !canRotate
? ClipRRect(
borderRadius: BorderRadius.circular(15),
child: UniversalImage(
path: albumArt,
width: MediaQuery.of(context).size.width *
(breakpoint.isSm ? 0.8 : 0.5),
),
)
: CircleAvatar(
backgroundImage:
UniversalImage.imageProvider(albumArt),
radius: MediaQuery.of(context).size.width *
(breakpoint.isSm ? 0.4 : 0.3),
),
),
);
}),
Expand Down
11 changes: 11 additions & 0 deletions lib/components/Settings/Settings.dart
Expand Up @@ -231,6 +231,17 @@ class Settings extends HookConsumerWidget {
),
onTap: pickColorScheme(ColorSchemeType.background),
),
ListTile(
leading: const Icon(Icons.album_rounded),
title: const Text("Rotating Album Art"),
trailing: Switch.adaptive(
activeColor: Theme.of(context).primaryColor,
value: preferences.rotatingAlbumArt,
onChanged: (state) {
preferences.setRotatingAlbumArt(state);
},
),
),
const Text(
" Playback",
style:
Expand Down
10 changes: 10 additions & 0 deletions lib/provider/UserPreferences.dart
Expand Up @@ -36,6 +36,7 @@ class UserPreferences extends PersistedChangeNotifier {
String downloadLocation;

LayoutMode layoutMode;
bool rotatingAlbumArt;

UserPreferences({
required this.geniusAccessToken,
Expand All @@ -51,6 +52,7 @@ class UserPreferences extends PersistedChangeNotifier {
this.audioQuality = AudioQuality.high,
this.skipSponsorSegments = true,
this.downloadLocation = "",
this.rotatingAlbumArt = true,
}) : super() {
if (downloadLocation.isEmpty) {
_getDefaultDownloadDirectory().then(
Expand Down Expand Up @@ -140,6 +142,12 @@ class UserPreferences extends PersistedChangeNotifier {
updatePersistence();
}

void setRotatingAlbumArt(bool should) {
rotatingAlbumArt = should;
notifyListeners();
updatePersistence();
}

Future<String> _getDefaultDownloadDirectory() async {
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";

Expand Down Expand Up @@ -182,6 +190,7 @@ class UserPreferences extends PersistedChangeNotifier {
(mode) => mode.name == map["layoutMode"],
orElse: () => kIsDesktop ? LayoutMode.extended : LayoutMode.compact,
);
rotatingAlbumArt = map["rotatingAlbumArt"] ?? rotatingAlbumArt;
}

@override
Expand All @@ -200,6 +209,7 @@ class UserPreferences extends PersistedChangeNotifier {
"skipSponsorSegments": skipSponsorSegments,
"downloadLocation": downloadLocation,
"layoutMode": layoutMode.name,
"rotatingAlbumArt": rotatingAlbumArt,
};
}
}
Expand Down

0 comments on commit edb6f3c

Please sign in to comment.