feat: volume slider mouse scroll and preference for Rotating Album Art #255

This commit is contained in:
Kingkor Roy Tirtho 2022-10-09 10:52:51 +06:00
parent 6d4c6b1738
commit edb6f3cd1c
4 changed files with 89 additions and 28 deletions

View File

@ -1,3 +1,4 @@
import 'package:flutter/gestures.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/components/Player/PlayerActions.dart'; import 'package:spotube/components/Player/PlayerActions.dart';
@ -122,7 +123,19 @@ class Player extends HookConsumerWidget {
} }
return null; return null;
}, [playback.volume]); }, [playback.volume]);
return Slider.adaptive( 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, min: 0,
max: 1, max: 1,
value: volume.value, value: volume.value,
@ -139,6 +152,7 @@ class Player extends HookConsumerWidget {
logger.e("onChange", e, stack); logger.e("onChange", e, stack);
} }
}, },
),
); );
}), }),
), ),

View File

@ -1,6 +1,5 @@
import 'dart:ui'; import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -15,6 +14,7 @@ import 'package:spotube/hooks/useBreakpoints.dart';
import 'package:spotube/hooks/useCustomStatusBarColor.dart'; import 'package:spotube/hooks/useCustomStatusBarColor.dart';
import 'package:spotube/hooks/usePaletteColor.dart'; import 'package:spotube/hooks/usePaletteColor.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/UserPreferences.dart';
import 'package:spotube/utils/type_conversion_utils.dart'; import 'package:spotube/utils/type_conversion_utils.dart';
class PlayerView extends HookConsumerWidget { class PlayerView extends HookConsumerWidget {
@ -28,6 +28,9 @@ class PlayerView extends HookConsumerWidget {
(value) => value.track, (value) => value.track,
)); ));
final breakpoint = useBreakpoints(); final breakpoint = useBreakpoints();
final canRotate = ref.watch(
userPreferencesProvider.select((s) => s.rotatingAlbumArt),
);
useEffect(() { useEffect(() {
if (breakpoint.isMoreThan(Breakpoints.md)) { if (breakpoint.isMoreThan(Breakpoints.md)) {
@ -108,18 +111,41 @@ class PlayerView extends HookConsumerWidget {
final controller = useAnimationController( final controller = useAnimationController(
duration: const Duration(seconds: 10), duration: const Duration(seconds: 10),
vsync: ticker, vsync: ticker,
)..repeat(); );
useEffect(
() {
controller.repeat();
if (!canRotate) controller.stop();
return null;
},
[controller],
);
return RotationTransition( return RotationTransition(
turns: Tween(begin: 0.0, end: 1.0).animate(controller), turns: Tween(begin: 0.0, end: 1.0).animate(controller),
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: canRotate
? Border.all(
color: paletteColor.titleTextColor, color: paletteColor.titleTextColor,
width: 2, width: 2,
)
: null,
borderRadius:
!canRotate ? BorderRadius.circular(15) : null,
shape:
canRotate ? BoxShape.circle : BoxShape.rectangle,
), ),
shape: BoxShape.circle, child: !canRotate
? ClipRRect(
borderRadius: BorderRadius.circular(15),
child: UniversalImage(
path: albumArt,
width: MediaQuery.of(context).size.width *
(breakpoint.isSm ? 0.8 : 0.5),
), ),
child: CircleAvatar( )
: CircleAvatar(
backgroundImage: backgroundImage:
UniversalImage.imageProvider(albumArt), UniversalImage.imageProvider(albumArt),
radius: MediaQuery.of(context).size.width * radius: MediaQuery.of(context).size.width *

View File

@ -231,6 +231,17 @@ class Settings extends HookConsumerWidget {
), ),
onTap: pickColorScheme(ColorSchemeType.background), 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( const Text(
" Playback", " Playback",
style: style:

View File

@ -36,6 +36,7 @@ class UserPreferences extends PersistedChangeNotifier {
String downloadLocation; String downloadLocation;
LayoutMode layoutMode; LayoutMode layoutMode;
bool rotatingAlbumArt;
UserPreferences({ UserPreferences({
required this.geniusAccessToken, required this.geniusAccessToken,
@ -51,6 +52,7 @@ class UserPreferences extends PersistedChangeNotifier {
this.audioQuality = AudioQuality.high, this.audioQuality = AudioQuality.high,
this.skipSponsorSegments = true, this.skipSponsorSegments = true,
this.downloadLocation = "", this.downloadLocation = "",
this.rotatingAlbumArt = true,
}) : super() { }) : super() {
if (downloadLocation.isEmpty) { if (downloadLocation.isEmpty) {
_getDefaultDownloadDirectory().then( _getDefaultDownloadDirectory().then(
@ -140,6 +142,12 @@ class UserPreferences extends PersistedChangeNotifier {
updatePersistence(); updatePersistence();
} }
void setRotatingAlbumArt(bool should) {
rotatingAlbumArt = should;
notifyListeners();
updatePersistence();
}
Future<String> _getDefaultDownloadDirectory() async { Future<String> _getDefaultDownloadDirectory() async {
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube"; if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
@ -182,6 +190,7 @@ class UserPreferences extends PersistedChangeNotifier {
(mode) => mode.name == map["layoutMode"], (mode) => mode.name == map["layoutMode"],
orElse: () => kIsDesktop ? LayoutMode.extended : LayoutMode.compact, orElse: () => kIsDesktop ? LayoutMode.extended : LayoutMode.compact,
); );
rotatingAlbumArt = map["rotatingAlbumArt"] ?? rotatingAlbumArt;
} }
@override @override
@ -200,6 +209,7 @@ class UserPreferences extends PersistedChangeNotifier {
"skipSponsorSegments": skipSponsorSegments, "skipSponsorSegments": skipSponsorSegments,
"downloadLocation": downloadLocation, "downloadLocation": downloadLocation,
"layoutMode": layoutMode.name, "layoutMode": layoutMode.name,
"rotatingAlbumArt": rotatingAlbumArt,
}; };
} }
} }