diff --git a/.gitignore b/.gitignore index 59943657..35c349a7 100644 --- a/.gitignore +++ b/.gitignore @@ -509,3 +509,4 @@ Thumbs.db !/gradle/wrapper/gradle-wrapper.jar # End of https://www.gitignore.io/api/java,swift,kotlin,android,flutter,intellij,objective-c,androidstudio +*.sh diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..055b1bc5 --- /dev/null +++ b/Makefile @@ -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 diff --git a/packages/mediascanner/example/test/widget_test.dart b/packages/mediascanner/example/test/widget_test.dart index e365e93a..d9adc263 100644 --- a/packages/mediascanner/example/test/widget_test.dart +++ b/packages/mediascanner/example/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mediascanner_example/main.dart'; +import '../lib/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { @@ -18,8 +18,7 @@ void main() { // Verify that platform version is retrieved. expect( find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + (Widget widget) => widget is Text && widget.data!.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/packages/migration/example/test/widget_test.dart b/packages/migration/example/test/widget_test.dart index bf3d0013..d9adc263 100644 --- a/packages/migration/example/test/widget_test.dart +++ b/packages/migration/example/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:migration_example/main.dart'; +import '../lib/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { @@ -18,8 +18,7 @@ void main() { // Verify that platform version is retrieved. expect( find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + (Widget widget) => widget is Text && widget.data!.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/packages/player/lib/src/player.dart b/packages/player/lib/src/player.dart index f73f7f22..8d2e4494 100644 --- a/packages/player/lib/src/player.dart +++ b/packages/player/lib/src/player.dart @@ -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? _stream; @@ -102,9 +103,10 @@ class Player { } Future enqueue( - Media media, - ) async { - _queue.add(media); + Media media, [ + bool enqueueAfterCurrent = false, + ]) async { + _queue.add(media, enqueueAfterCurrent); return Ok; } @@ -112,19 +114,25 @@ class Player { List 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 positionsToDelete, required bool isShuffle}) { + int removeByPosition({ + required List positionsToDelete, + required bool isShuffle, + }) { return _queue.removeByPosition( - positionsToDelete: positionsToDelete, isShuffle: isShuffle); + positionsToDelete: positionsToDelete, + isShuffle: isShuffle, + ); } Future removeAll() async { @@ -216,8 +224,11 @@ class Player { return media; } - Future reorder(int oldIndex, int newIndex, - [bool isShuffle = false]) async { + Future 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 load(Media media) async => _doPlay( - _queue.current!, - shouldLoadOnly: true, - ); + _queue.current!, + shouldLoadOnly: true, + ); Future 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; diff --git a/packages/player/lib/src/queue.dart b/packages/player/lib/src/queue.dart index 4a4847d5..b0334581 100644 --- a/packages/player/lib/src/queue.dart +++ b/packages/player/lib/src/queue.dart @@ -67,22 +67,22 @@ class Queue { } Future> get previousItems async { - previousPlaylistMusics = - await IsarService.instance.getPreviousPlaylistMusics(); + previousPlaylistMusics = await IsarService.instance + .getPreviousPlaylistMusics(); return previousPlaylistMusics?.musics?.toListMedia ?? []; } Future get _previousPlaylistPosition async { - final previousPlaylistPosition = - await IsarService.instance.getPreviousPlaylistPosition(); + final previousPlaylistPosition = await IsarService.instance + .getPreviousPlaylistPosition(); return previousPlaylistPosition?.position != null ? previousPlaylistPosition : null; } Future get previousPlaylistIndex async { - final previousPlaylistCurrentIndex = - await IsarService.instance.getPreviousPlaylistCurrentIndex(); + final previousPlaylistCurrentIndex = await IsarService.instance + .getPreviousPlaylistCurrentIndex(); return previousPlaylistCurrentIndex?.currentIndex ?? 0; } @@ -112,9 +112,23 @@ class Queue { } } - add(Media media) async { + add( + Media media, [ + bool enqueueAfterCurrent = false, + ]) async { int pos = _nextPosition(); - storage.add(QueueItem(pos, pos, media)); + + if (enqueueAfterCurrent && storage.isNotEmpty) { + final position = _index + 1; + storage.insert(position, QueueItem(pos, pos, media)); + + for (var i = 0; i < storage.length; ++i) { + storage[i].position = i; + } + } else { + storage.add(QueueItem(pos, pos, media)); + } + await _save(medias: [media]); } @@ -131,21 +145,31 @@ class Queue { List items, { bool shouldRemoveFirst = false, bool saveOnTop = false, + bool enqueueAfterCurrent = false, }) async { final medias = shouldRemoveFirst ? items.sublist(1) : items; int i = storage.length == 1 ? 0 : storage.length - 1; - if (saveOnTop) { + if (enqueueAfterCurrent && storage.isNotEmpty) { + final insertAt = _index + 1; + storage.insertAll(insertAt, _toQueueItems(medias, i)); + + for (var j = 0; j < storage.length; j++) { + storage[j].position = j; + } + } else if (saveOnTop) { storage.insertAll(0, _toQueueItems(medias, i)); } else { storage.addAll(_toQueueItems(medias, i)); } - await _save(medias: items, saveOnTop: saveOnTop); + await _save(medias: items, saveOnTop: enqueueAfterCurrent || saveOnTop); } - Future _save( - {required List medias, bool saveOnTop = false}) async { + Future _save({ + required List medias, + bool saveOnTop = false, + }) async { final items = await previousItems; debugPrint( '[TESTE] itemsFromStorage: ${items.length} - mediasToSave: ${medias.length}', @@ -166,12 +190,14 @@ class Queue { return [ ...topList.toListStringCompressed, - ...bottomList.toListStringCompressed + ...bottomList.toListStringCompressed, ]; } - int removeByPosition( - {required List positionsToDelete, required bool isShuffle}) { + int removeByPosition({ + required List positionsToDelete, + required bool isShuffle, + }) { try { int lastLength = storage.length; for (var i = 0; i < positionsToDelete.length; ++i) { @@ -189,7 +215,8 @@ class Queue { if (kDebugMode) { for (var e in storage) { debugPrint( - '=====> storage remove: ${e.item.name} - ${e.position} | ${e.originalPosition}'); + '=====> storage remove: ${e.item.name} - ${e.position} | ${e.originalPosition}', + ); } } return lastLength - storage.length; @@ -229,7 +256,8 @@ class Queue { if (kDebugMode) { for (var e in storage) { debugPrint( - '=====> storage unshuffle: ${e.item.name} - ${e.position} | ${e.originalPosition}'); + '=====> storage unshuffle: ${e.item.name} - ${e.position} | ${e.originalPosition}', + ); } } setIndex = current.position; diff --git a/packages/snowplow/example/test/widget_test.dart b/packages/snowplow/example/test/widget_test.dart index a899e1b7..d9adc263 100644 --- a/packages/snowplow/example/test/widget_test.dart +++ b/packages/snowplow/example/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:snowplow_example/main.dart'; +import '../lib/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { @@ -18,8 +18,7 @@ void main() { // Verify that platform version is retrieved. expect( find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + (Widget widget) => widget is Text && widget.data!.startsWith('Running on:'), ), findsOneWidget, );