-
Notifications
You must be signed in to change notification settings - Fork 1
Feature/3580 add music next queue #161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| .PHONY: pub-get | ||
|
|
||
| PUBSPEC_DIRS := $(sort $(dir $(wildcard packages/*/pubspec.yaml))) | ||
|
|
||
| ## Run flutter pub get in all packages containing pubspec.yaml | ||
| pub-get: | ||
| @failed=""; \ | ||
| for dir in $(PUBSPEC_DIRS); do \ | ||
| echo "=> pub get: $$dir"; \ | ||
| (cd $$dir && flutter pub get) || failed="$$failed $$dir"; \ | ||
| done; \ | ||
| echo ""; \ | ||
| if [ -n "$$failed" ]; then \ | ||
| echo "FAILED in:$$failed"; \ | ||
| exit 1; \ | ||
| else \ | ||
| echo "All packages updated!"; \ | ||
| fi |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,19 +1,20 @@ | ||||||||||||||||||||||||
| import 'dart:async'; | ||||||||||||||||||||||||
| import 'dart:io'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import 'package:flutter/foundation.dart'; | ||||||||||||||||||||||||
| import 'package:smaws/aws.dart'; | ||||||||||||||||||||||||
| import 'package:flutter/services.dart'; | ||||||||||||||||||||||||
| import 'package:mutex/mutex.dart'; | ||||||||||||||||||||||||
| import 'package:smaws/aws.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/before_play_event.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/duration_change_event.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/event.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/event_type.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/isar_service.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/media.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/duration_change_event.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/position_change_event.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/previous_playlist_model.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/queue.dart'; | ||||||||||||||||||||||||
| import 'package:smplayer/src/repeat_mode.dart'; | ||||||||||||||||||||||||
| import 'package:mutex/mutex.dart'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import 'player_state.dart'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -66,7 +67,7 @@ class Player { | |||||||||||||||||||||||
| EventType.PAUSED, | ||||||||||||||||||||||||
| EventType.PLAYING, | ||||||||||||||||||||||||
| EventType.EXTERNAL_RESUME_REQUESTED, | ||||||||||||||||||||||||
| EventType.EXTERNAL_PAUSE_REQUESTED | ||||||||||||||||||||||||
| EventType.EXTERNAL_PAUSE_REQUESTED, | ||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Stream<Event>? _stream; | ||||||||||||||||||||||||
|
|
@@ -102,29 +103,36 @@ class Player { | |||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Future<int> enqueue( | ||||||||||||||||||||||||
| Media media, | ||||||||||||||||||||||||
| ) async { | ||||||||||||||||||||||||
| _queue.add(media); | ||||||||||||||||||||||||
| Media media, [ | ||||||||||||||||||||||||
| bool enqueueAfterCurrent = false, | ||||||||||||||||||||||||
| ]) async { | ||||||||||||||||||||||||
| _queue.add(media, enqueueAfterCurrent); | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# First, check the Queue.add and Queue.addAll signatures
echo "=== Checking Queue.add/addAll signatures ==="
rg -n --type=dart '^\s*(Future|async).*\s+(add|addAll)\s*\(' packages/player/lib/src/queue.dart -B1 -A5
echo -e "\n=== Checking Player._queue.add/addAll calls ==="
rg -n --type=dart '_queue\.(add|addAll)\s*\(' packages/player/lib/src/player.dart -B2 -A2Repository: SuaMusica/flutter_plugins Length of output: 446 🏁 Script executed: #!/bin/bash
# Get file sizes to determine if we should read them entirely
echo "=== File sizes ==="
wc -l packages/player/lib/src/queue.dart packages/player/lib/src/player.dart
echo -e "\n=== Check specific lines 109 and 119 in player.dart ==="
sed -n '105,125p' packages/player/lib/src/player.dartRepository: SuaMusica/flutter_plugins Length of output: 736 🏁 Script executed: #!/bin/bash
# Search for Queue class and its add/addAll method definitions
echo "=== Full search for add/addAll methods in Queue ==="
ast-grep --pattern 'class Queue {
$$$
$_* add$_* $$$
$$$
}'
ast-grep --pattern 'class Queue {
$$$
$_* addAll$_* $$$
$$$
}'Repository: SuaMusica/flutter_plugins Length of output: 120 🏁 Script executed: #!/bin/bash
# Read queue.dart to see the full implementation
cat -n packages/player/lib/src/queue.dartRepository: SuaMusica/flutter_plugins Length of output: 14415 🏁 Script executed: #!/bin/bash
# Search for add and addAll method definitions specifically
echo "=== Searching for add method definition ==="
rg -n 'add\s*\(' packages/player/lib/src/queue.dart -B1 -A3
echo -e "\n=== Searching for addAll method definition ==="
rg -n 'addAll\s*\(' packages/player/lib/src/queue.dart -B1 -A3Repository: SuaMusica/flutter_plugins Length of output: 1023 🏁 Script executed: #!/bin/bash
# Verify the _save method signature to confirm persistence is truly async
rg -n '_save\(' packages/player/lib/src/queue.dart -B2 -A8Repository: SuaMusica/flutter_plugins Length of output: 1076 Add
Suggested fix- _queue.add(media, enqueueAfterCurrent);
+ await _queue.add(media, enqueueAfterCurrent);- _queue.addAll(
+ await _queue.addAll(
items,
shouldRemoveFirst: shouldRemoveFirst,
saveOnTop: saveOnTop,
enqueueAfterCurrent: enqueueAfterCurrent,
);🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| return Ok; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Future<int> enqueueAll( | ||||||||||||||||||||||||
| List<Media> items, { | ||||||||||||||||||||||||
| bool shouldRemoveFirst = false, | ||||||||||||||||||||||||
| bool saveOnTop = false, | ||||||||||||||||||||||||
| bool enqueueAfterCurrent = false, | ||||||||||||||||||||||||
| }) async { | ||||||||||||||||||||||||
| _queue.addAll( | ||||||||||||||||||||||||
| items, | ||||||||||||||||||||||||
| shouldRemoveFirst: shouldRemoveFirst, | ||||||||||||||||||||||||
| saveOnTop: saveOnTop, | ||||||||||||||||||||||||
| enqueueAfterCurrent: enqueueAfterCurrent, | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| return Ok; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| int removeByPosition( | ||||||||||||||||||||||||
| {required List<int> positionsToDelete, required bool isShuffle}) { | ||||||||||||||||||||||||
| int removeByPosition({ | ||||||||||||||||||||||||
| required List<int> positionsToDelete, | ||||||||||||||||||||||||
| required bool isShuffle, | ||||||||||||||||||||||||
| }) { | ||||||||||||||||||||||||
| return _queue.removeByPosition( | ||||||||||||||||||||||||
| positionsToDelete: positionsToDelete, isShuffle: isShuffle); | ||||||||||||||||||||||||
| positionsToDelete: positionsToDelete, | ||||||||||||||||||||||||
| isShuffle: isShuffle, | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Future<int> removeAll() async { | ||||||||||||||||||||||||
|
|
@@ -216,8 +224,11 @@ class Player { | |||||||||||||||||||||||
| return media; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Future<int> reorder(int oldIndex, int newIndex, | ||||||||||||||||||||||||
| [bool isShuffle = false]) async { | ||||||||||||||||||||||||
| Future<int> reorder( | ||||||||||||||||||||||||
| int oldIndex, | ||||||||||||||||||||||||
| int newIndex, [ | ||||||||||||||||||||||||
| bool isShuffle = false, | ||||||||||||||||||||||||
| ]) async { | ||||||||||||||||||||||||
| _queue.reorder(oldIndex, newIndex, isShuffle); | ||||||||||||||||||||||||
| return Ok; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
@@ -241,9 +252,9 @@ class Player { | |||||||||||||||||||||||
| Media? get top => _queue.top; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Future<int> load(Media media) async => _doPlay( | ||||||||||||||||||||||||
| _queue.current!, | ||||||||||||||||||||||||
| shouldLoadOnly: true, | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| _queue.current!, | ||||||||||||||||||||||||
| shouldLoadOnly: true, | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
|
Comment on lines
254
to
+257
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Line 255 loads 🔧 Suggested fix- Future<int> load(Media media) async => _doPlay(
- _queue.current!,
+ Future<int> load(Media media) async => _doPlay(
+ media,
shouldLoadOnly: true,
);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Future<int> play( | ||||||||||||||||||||||||
| Media media, { | ||||||||||||||||||||||||
|
|
@@ -333,7 +344,7 @@ class Player { | |||||||||||||||||||||||
| 'position': position?.inMilliseconds, | ||||||||||||||||||||||||
| 'respectSilence': respectSilence, | ||||||||||||||||||||||||
| 'stayAwake': stayAwake, | ||||||||||||||||||||||||
| 'isFavorite': media.isFavorite | ||||||||||||||||||||||||
| 'isFavorite': media.isFavorite, | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| } else if (autoPlay) { | ||||||||||||||||||||||||
| _notifyBeforePlayEvent((loadOnly) => {}); | ||||||||||||||||||||||||
|
|
@@ -352,7 +363,7 @@ class Player { | |||||||||||||||||||||||
| 'position': position?.inMilliseconds, | ||||||||||||||||||||||||
| 'respectSilence': respectSilence, | ||||||||||||||||||||||||
| 'stayAwake': stayAwake, | ||||||||||||||||||||||||
| 'isFavorite': media.isFavorite | ||||||||||||||||||||||||
| 'isFavorite': media.isFavorite, | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||
| _notifyBeforePlayEvent((loadOnly) { | ||||||||||||||||||||||||
|
|
@@ -370,7 +381,7 @@ class Player { | |||||||||||||||||||||||
| 'position': position?.inMilliseconds, | ||||||||||||||||||||||||
| 'respectSilence': respectSilence, | ||||||||||||||||||||||||
| 'stayAwake': stayAwake, | ||||||||||||||||||||||||
| 'isFavorite': media.isFavorite | ||||||||||||||||||||||||
| 'isFavorite': media.isFavorite, | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -694,14 +705,16 @@ class Player { | |||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| case PlayerState.ERROR: | ||||||||||||||||||||||||
| final error = callArgs['error'] ?? "Unknown from Source"; | ||||||||||||||||||||||||
| final isPermissionError = | ||||||||||||||||||||||||
| (error as String).contains('Permission denied'); | ||||||||||||||||||||||||
| final isPermissionError = (error as String).contains( | ||||||||||||||||||||||||
| 'Permission denied', | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| _notifyPlayerErrorEvent( | ||||||||||||||||||||||||
| player: player, | ||||||||||||||||||||||||
| error: error, | ||||||||||||||||||||||||
| errorType: isPermissionError | ||||||||||||||||||||||||
| ? PlayerErrorType.PERMISSION_DENIED | ||||||||||||||||||||||||
| : null); | ||||||||||||||||||||||||
| player: player, | ||||||||||||||||||||||||
| error: error, | ||||||||||||||||||||||||
| errorType: isPermissionError | ||||||||||||||||||||||||
| ? PlayerErrorType.PERMISSION_DENIED | ||||||||||||||||||||||||
| : null, | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -773,7 +786,10 @@ class Player { | |||||||||||||||||||||||
| case 'externalPlayback.play': | ||||||||||||||||||||||||
| print("Player: externalPlayback : Play"); | ||||||||||||||||||||||||
| _notifyPlayerStateChangeEvent( | ||||||||||||||||||||||||
| player, EventType.EXTERNAL_RESUME_REQUESTED, ""); | ||||||||||||||||||||||||
| player, | ||||||||||||||||||||||||
| EventType.EXTERNAL_RESUME_REQUESTED, | ||||||||||||||||||||||||
| "", | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||
| case 'externalPlayback.pause': | ||||||||||||||||||||||||
| print("Player: externalPlayback : Pause"); | ||||||||||||||||||||||||
|
|
@@ -800,61 +816,77 @@ class Player { | |||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _notifyChangeToNext(Media media) { | ||||||||||||||||||||||||
| _add( | ||||||||||||||||||||||||
| Event(type: EventType.NEXT, media: media, queuePosition: _queue.index)); | ||||||||||||||||||||||||
| Event(type: EventType.NEXT, media: media, queuePosition: _queue.index), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _notifyChangeToPrevious(Media media) { | ||||||||||||||||||||||||
| _add(Event( | ||||||||||||||||||||||||
| type: EventType.PREVIOUS, media: media, queuePosition: _queue.index)); | ||||||||||||||||||||||||
| _add( | ||||||||||||||||||||||||
| Event( | ||||||||||||||||||||||||
| type: EventType.PREVIOUS, | ||||||||||||||||||||||||
| media: media, | ||||||||||||||||||||||||
| queuePosition: _queue.index, | ||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _notifyRewind(Media media) async { | ||||||||||||||||||||||||
| final positionInMilli = await getCurrentPosition(); | ||||||||||||||||||||||||
| final durationInMilli = await getDuration(); | ||||||||||||||||||||||||
| _add(Event( | ||||||||||||||||||||||||
| type: EventType.REWIND, | ||||||||||||||||||||||||
| media: media, | ||||||||||||||||||||||||
| queuePosition: _queue.index, | ||||||||||||||||||||||||
| position: Duration(milliseconds: positionInMilli), | ||||||||||||||||||||||||
| duration: Duration(milliseconds: durationInMilli), | ||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||
| _add( | ||||||||||||||||||||||||
| Event( | ||||||||||||||||||||||||
| type: EventType.REWIND, | ||||||||||||||||||||||||
| media: media, | ||||||||||||||||||||||||
| queuePosition: _queue.index, | ||||||||||||||||||||||||
| position: Duration(milliseconds: positionInMilli), | ||||||||||||||||||||||||
| duration: Duration(milliseconds: durationInMilli), | ||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _notifyForward(Media media) async { | ||||||||||||||||||||||||
| final positionInMilli = await getCurrentPosition(); | ||||||||||||||||||||||||
| final durationInMilli = await getDuration(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _add(Event( | ||||||||||||||||||||||||
| type: EventType.FORWARD, | ||||||||||||||||||||||||
| media: media, | ||||||||||||||||||||||||
| queuePosition: _queue.index, | ||||||||||||||||||||||||
| position: Duration(milliseconds: positionInMilli), | ||||||||||||||||||||||||
| duration: Duration(milliseconds: durationInMilli), | ||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||
| _add( | ||||||||||||||||||||||||
| Event( | ||||||||||||||||||||||||
| type: EventType.FORWARD, | ||||||||||||||||||||||||
| media: media, | ||||||||||||||||||||||||
| queuePosition: _queue.index, | ||||||||||||||||||||||||
| position: Duration(milliseconds: positionInMilli), | ||||||||||||||||||||||||
| duration: Duration(milliseconds: durationInMilli), | ||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _notifyPlayerStatusChangeEvent(EventType type) { | ||||||||||||||||||||||||
| if (_queue.current != null) { | ||||||||||||||||||||||||
| _add(Event( | ||||||||||||||||||||||||
| type: type, media: _queue.current!, queuePosition: _queue.index)); | ||||||||||||||||||||||||
| _add( | ||||||||||||||||||||||||
| Event(type: type, media: _queue.current!, queuePosition: _queue.index), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _notifyBeforePlayEvent(Function(bool) operation) { | ||||||||||||||||||||||||
| _add(BeforePlayEvent( | ||||||||||||||||||||||||
| _add( | ||||||||||||||||||||||||
| BeforePlayEvent( | ||||||||||||||||||||||||
| media: _queue.current!, | ||||||||||||||||||||||||
| queuePosition: _queue.index, | ||||||||||||||||||||||||
| operation: operation)); | ||||||||||||||||||||||||
| operation: operation, | ||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| static _notifyDurationChangeEvent(Player player, Duration newDuration) { | ||||||||||||||||||||||||
| if (player._queue.current != null) { | ||||||||||||||||||||||||
| _addUsingPlayer( | ||||||||||||||||||||||||
| player, | ||||||||||||||||||||||||
| DurationChangeEvent( | ||||||||||||||||||||||||
| media: player._queue.current!, | ||||||||||||||||||||||||
| queuePosition: player._queue.index, | ||||||||||||||||||||||||
| duration: newDuration)); | ||||||||||||||||||||||||
| player, | ||||||||||||||||||||||||
| DurationChangeEvent( | ||||||||||||||||||||||||
| media: player._queue.current!, | ||||||||||||||||||||||||
| queuePosition: player._queue.index, | ||||||||||||||||||||||||
| duration: newDuration, | ||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -902,7 +934,10 @@ class Player { | |||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| static _notifyPositionChangeEvent( | ||||||||||||||||||||||||
| Player player, Duration newPosition, Duration newDuration) { | ||||||||||||||||||||||||
| Player player, | ||||||||||||||||||||||||
| Duration newPosition, | ||||||||||||||||||||||||
| Duration newDuration, | ||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||
| final media = player.current; | ||||||||||||||||||||||||
| if (media != null) { | ||||||||||||||||||||||||
| final position = newPosition.inSeconds; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid a global
*.shignore pattern.Line 512 will ignore all shell scripts, including valid repo automation scripts (CI, release, tooling), which can silently block commits. Prefer ignoring only generated/script-specific paths.
Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents