fix buttons that require navigation in track menu

wakelock when lyrics screen open
This commit is contained in:
Pato05 2024-04-27 01:25:33 +02:00
parent 36f8666906
commit 2e67b50332
No known key found for this signature in database
GPG Key ID: F53CA394104BA0CB
7 changed files with 1857 additions and 1856 deletions

View File

@ -143,6 +143,7 @@ class AudioPlayerTask extends BaseAudioHandler {
JustAudioMediaKit.ensureInitialized(); JustAudioMediaKit.ensureInitialized();
JustAudioMediaKit.title = 'Freezer'; JustAudioMediaKit.title = 'Freezer';
JustAudioMediaKit.protocolWhitelist = const ['http']; JustAudioMediaKit.protocolWhitelist = const ['http'];
JustAudioMediaKit.prefetchPlaylist = true;
//JustAudioMediaKit.bufferSize = 128; //JustAudioMediaKit.bufferSize = 128;
_deezerAPI = initArgs.deezerAPI; _deezerAPI = initArgs.deezerAPI;
@ -366,23 +367,6 @@ class AudioPlayerTask extends BaseAudioHandler {
return Future.value(); return Future.value();
} }
// unused.
@override
Future<void> seekForward(bool begin) => Future.value();
Future<void> seekBackward(bool begin) async {
// (un)favourite action
if (cache.libraryTracks.contains(currentMediaItem.id)) {
cache.libraryTracks.remove(currentMediaItem.id);
_broadcastState();
return _deezerAPI.removeFavorite(currentMediaItem.id);
}
cache.libraryTracks.add(currentMediaItem.id);
_broadcastState();
return _deezerAPI.addFavoriteTrack(currentMediaItem.id);
}
//Remove item from queue //Remove item from queue
@override @override
Future<void> removeQueueItem(MediaItem mediaItem) async { Future<void> removeQueueItem(MediaItem mediaItem) async {
@ -415,13 +399,9 @@ class AudioPlayerTask extends BaseAudioHandler {
@override @override
Future<void> skipToPrevious() async { Future<void> skipToPrevious() async {
if (_queueIndex == 0) return; if (_queueIndex == 0) return;
//Update buffering state
//_skipState = AudioProcessingState.skippingToPrevious;
//Normal skip to previous
unawaited(_logListenedTrack(currentMediaItem.id, sync: false, prev: true)); unawaited(_logListenedTrack(currentMediaItem.id, sync: false, prev: true));
_queueIndex--; _queueIndex--;
await _player.seekToPrevious(); await _player.seekToPrevious();
//_skipState = null;
} }
Future<void> _logListenedTrack(String trackId, Future<void> _logListenedTrack(String trackId,
@ -479,42 +459,52 @@ class AudioPlayerTask extends BaseAudioHandler {
customAction: CustomMediaAction(name: 'favorite')); customAction: CustomMediaAction(name: 'favorite'));
} }
Future<void> toggleFavoriteCurrent() async {
// (un)favourite action
if (cache.libraryTracks.contains(currentMediaItem.id)) {
cache.libraryTracks.remove(currentMediaItem.id);
_broadcastState();
await _deezerAPI.removeFavorite(currentMediaItem.id);
return;
}
cache.libraryTracks.add(currentMediaItem.id);
_broadcastState();
await _deezerAPI.addFavoriteTrack(currentMediaItem.id);
}
//Update state on all clients //Update state on all clients
void _broadcastState() { void _broadcastState() {
final controls = !currentMediaItemIsShow
? [
if (queue.value.isNotEmpty) favoriteControl(),
if (_queueIndex != 0) MediaControl.skipToPrevious,
_player.playing ? MediaControl.pause : MediaControl.play,
MediaControl.stop,
if (queue.hasValue && _queueIndex != queue.value.length - 1)
MediaControl.skipToNext,
]
: [
const MediaControl(
androidIcon: 'drawable/ic_replay_30',
label: 'replay 30',
action: MediaAction.rewind,
), // acts as prev-30
_player.playing ? MediaControl.pause : MediaControl.play,
MediaControl.stop,
const MediaControl(
androidIcon: 'drawable/ic_forward_30',
label: 'forward 30',
action: MediaAction.fastForward,
), // next-30
];
playbackState.add(PlaybackState( playbackState.add(PlaybackState(
controls: !currentMediaItemIsShow controls: controls,
? [
if (queue.value.isNotEmpty) favoriteControl(),
/*if (_queueIndex != 0)*/ MediaControl.skipToPrevious,
_player.playing ? MediaControl.pause : MediaControl.play,
/**/ MediaControl.skipToNext,
//Stop -- USELESS.
// MediaControl(
// androidIcon: 'drawable/ic_action_stop',
// label: 'stop',
// action: MediaAction.stop),
// i mean, the user can just swipe the notification away to stop
]
: [
const MediaControl(
androidIcon: 'drawable/ic_replay_30',
label: 'replay 30',
action: MediaAction.rewind,
), // acts as prev-30
_player.playing ? MediaControl.pause : MediaControl.play,
const MediaControl(
androidIcon: 'drawable/ic_forward_30',
label: 'forward 30',
action: MediaAction.fastForward,
), // next-30
],
systemActions: !currentMediaItemIsShow systemActions: !currentMediaItemIsShow
? { ? const {
MediaAction.seek, MediaAction.seek,
if (queue.hasValue && _queueIndex != queue.value.length - 1) MediaAction.seekForward,
MediaAction.skipToNext, MediaAction.seekBackward,
if (_queueIndex != 0) MediaAction.skipToPrevious,
MediaAction.stop
} }
: const { : const {
MediaAction.seek, MediaAction.seek,
@ -527,8 +517,9 @@ class AudioPlayerTask extends BaseAudioHandler {
bufferedPosition: _player.bufferedPosition, bufferedPosition: _player.bufferedPosition,
speed: _player.speed, speed: _player.speed,
queueIndex: _queueIndex, queueIndex: _queueIndex,
androidCompactActionIndices: androidCompactActionIndices: List.generate(controls.length, (i) => i)
!currentMediaItemIsShow ? const [1, 2, 3] : const [0, 1, 2], .whereNot((i) => controls[i].action == MediaAction.stop)
.toList(growable: false),
repeatMode: _repeatMode, repeatMode: _repeatMode,
shuffleMode: _originalQueue == null shuffleMode: _originalQueue == null
? AudioServiceShuffleMode.none ? AudioServiceShuffleMode.none
@ -536,16 +527,16 @@ class AudioPlayerTask extends BaseAudioHandler {
)); ));
} }
//just_audio state -> audio_service state. If skipping, use _skipState //just_audio state -> audio_service state.
AudioProcessingState _convertProcessingState( AudioProcessingState _convertProcessingState(
ProcessingState processingState) { ProcessingState processingState) {
return const <ProcessingState, AudioProcessingState>{ return switch (processingState) {
ProcessingState.idle: AudioProcessingState.idle, ProcessingState.idle => AudioProcessingState.idle,
ProcessingState.loading: AudioProcessingState.loading, ProcessingState.loading => AudioProcessingState.loading,
ProcessingState.buffering: AudioProcessingState.buffering, ProcessingState.buffering => AudioProcessingState.buffering,
ProcessingState.ready: AudioProcessingState.ready, ProcessingState.ready => AudioProcessingState.ready,
ProcessingState.completed: AudioProcessingState.completed, ProcessingState.completed => AudioProcessingState.completed,
}[processingState]!; };
} }
//Replace current queue //Replace current queue
@ -699,6 +690,8 @@ class AudioPlayerTask extends BaseAudioHandler {
case 'setIndex': case 'setIndex':
_queueIndex = extras!['index']; _queueIndex = extras!['index'];
break; break;
case 'favorite':
toggleFavoriteCurrent();
//Start visualizer //Start visualizer
// case 'startVisualizer': // case 'startVisualizer':
// if (_visualizerSubscription != null) break; // if (_visualizerSubscription != null) break;

View File

@ -166,8 +166,8 @@ class MenuSheet {
title: option.label, title: option.label,
leading: option.icon, leading: option.icon,
onTap: () { onTap: () {
option.onTap.call();
Navigator.pop(context); Navigator.pop(context);
option.onTap.call();
}, },
)) ))
.toList(growable: false)), .toList(growable: false)),
@ -367,10 +367,7 @@ class MenuSheet {
onTap: () { onTap: () {
navigatorKey.currentState! navigatorKey.currentState!
.push(MaterialPageRoute(builder: (context) => ArtistDetails(a))); .push(MaterialPageRoute(builder: (context) => ArtistDetails(a)));
navigateCallback?.call();
if (navigateCallback != null) {
navigateCallback!();
}
}, },
); );
@ -385,9 +382,7 @@ class MenuSheet {
navigatorKey.currentState! navigatorKey.currentState!
.push(MaterialPageRoute(builder: (context) => AlbumDetails(a))); .push(MaterialPageRoute(builder: (context) => AlbumDetails(a)));
if (navigateCallback != null) { navigateCallback?.call();
navigateCallback!();
}
}, },
); );
@ -686,7 +681,9 @@ class MenuSheet {
); );
MenuSheetOption wakelock() => MenuSheetOption( MenuSheetOption wakelock() => MenuSheetOption(
Text('Keep the screen on'.i18n), Text(cache.wakelock
? 'Don\'t keep screen on'.i18n
: 'Keep the screen on'.i18n),
icon: const Icon(Icons.screen_lock_portrait), icon: const Icon(Icons.screen_lock_portrait),
onTap: () async { onTap: () async {
//Enable //Enable

View File

@ -31,6 +31,7 @@ import 'package:marquee/marquee.dart';
import 'package:palette_generator/palette_generator.dart'; import 'package:palette_generator/palette_generator.dart';
import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
const _blurStrength = 90.0; const _blurStrength = 90.0;
@ -949,11 +950,19 @@ class _BigAlbumArtState extends State<BigAlbumArt> with WidgetsBindingObserver {
super.dispose(); super.dispose();
} }
void _pushLyrics() { void _pushLyrics() async {
// enable wakelock if not already enabled
final wakelockChanged = !(await WakelockPlus.enabled);
if (wakelockChanged) {
WakelockPlus.enable();
}
builder(ctx) => ChangeNotifierProvider<BackgroundProvider>.value( builder(ctx) => ChangeNotifierProvider<BackgroundProvider>.value(
value: Provider.of<BackgroundProvider>(context), value: Provider.of<BackgroundProvider>(context),
child: const LyricsScreen()); child: const LyricsScreen());
Navigator.of(context).pushRoute(builder: builder); final pushed = Navigator.of(context).pushRoute(builder: builder);
if (wakelockChanged) {
pushed.then((_) => WakelockPlus.disable());
}
} }
@override @override
@ -1044,9 +1053,9 @@ class _BigAlbumArtState extends State<BigAlbumArt> with WidgetsBindingObserver {
)), )),
); );
return Center( return AspectRatio(
child: AspectRatio( aspectRatio: 1.0,
aspectRatio: 1.0, child: Center(
child: settings.playerAlbumArtDropShadow child: settings.playerAlbumArtDropShadow
? Consumer<BackgroundProvider>( ? Consumer<BackgroundProvider>(
builder: (context, background, child) => AnimatedContainer( builder: (context, background, child) => AnimatedContainer(

View File

@ -1538,13 +1538,15 @@ class _GeneralSettingsState extends State<GeneralSettings> {
ScaffoldMessenger.of(context).snack('Copied'.i18n); ScaffoldMessenger.of(context).snack('Copied'.i18n);
}, },
), ),
// ListTile( if (kDebugMode) ...[
// title: const Text('DEBUG: stop audioHandler'), ListTile(
// onTap: () => audioHandler.stop()), title: const Text('DEBUG: stop audioHandler'),
// ListTile( onTap: () => audioHandler.stop()),
// title: const Text('DEBUG: show login screen'), ListTile(
// onTap: () => Navigator.of(context, rootNavigator: true) title: const Text('DEBUG: show login screen'),
// .pushRoute(builder: (ctx) => LoginWidget())), onTap: () => Navigator.of(context, rootNavigator: true)
.pushRoute(builder: (ctx) => LoginWidget())),
],
], ],
), ),
); );

View File

@ -73,7 +73,7 @@ apply_standard_settings(${BINARY_NAME})
# Add dependency libraries. Add any application-specific dependencies here. # Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
target_link_libraries(${BINARY_NAME} PRIVATE ${MIMALLOC_LIB})
# Run the Flutter tool portions of the build. This must not be removed. # Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble) add_dependencies(${BINARY_NAME} flutter_assemble)

View File

@ -19,7 +19,7 @@ if [ ! -w "$APPLICATIONS_DIR" ]; then
exit 1 exit 1
fi fi
cat <<EOF cat <<EOF > "$APPLICATIONS_DIR/freezer.desktop"
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=freezer Name=freezer
@ -30,5 +30,5 @@ Icon=$ICON
Categories=Audio;Music;Player;AudioVideo; Categories=Audio;Music;Player;AudioVideo;
Keywords=Music;Player;Streaming;Online; Keywords=Music;Player;Streaming;Online;
Terminal=false Terminal=false
EOF > "$APPLICATIONS_DIR/freezer.desktop" EOF

File diff suppressed because it is too large Load Diff