QueuePage working properly now

This commit is contained in:
Moritz Weber 2020-12-24 11:20:22 +01:00
parent 3afb25bdb1
commit 53112c2c1b
11 changed files with 89 additions and 69 deletions

View file

@ -19,6 +19,7 @@ abstract class AudioRepository {
Future<Either<Failure, void>> pause();
Future<Either<Failure, void>> skipToNext();
Future<Either<Failure, void>> skipToPrevious();
Future<void> setIndex(int index);
Future<Either<Failure, void>> setShuffleMode(ShuffleMode shuffleMode);
Future<void> setLoopMode(LoopMode loopMode);

View file

@ -1,7 +1,10 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:provider/provider.dart';
import 'package:reorderables/reorderables.dart';
import '../../domain/entities/song.dart';
import '../state/audio_store.dart';
@ -15,68 +18,59 @@ class QueuePage extends StatelessWidget {
print('QueuePage.build');
final AudioStore audioStore = Provider.of<AudioStore>(context);
final ObservableStream<int> queueIndexStream = audioStore.queueIndexStream;
final initialIndex = max(((queueIndexStream?.value) ?? 0) - 2, 0);
final ScrollController _scrollController = ScrollController(initialScrollOffset: initialIndex * 72.0);
return Scaffold(
body: SafeArea(
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) =>
Observer(
builder: (BuildContext context) {
print('QueuePage.build -> Observer.build');
final ObservableStream<List<Song>> queueStream =
audioStore.queueStream;
final ObservableStream<int> queueIndexStream =
audioStore.queueIndexStream;
child: Observer(
builder: (BuildContext context) {
print('QueuePage.build -> Observer.build');
final ObservableStream<List<Song>> queueStream = audioStore.queueStream;
switch (queueStream.status) {
case StreamStatus.active:
return ReorderableListView(
children: queueStream.value.asMap().entries.map((e) {
final index = e.key;
final song = e.value;
return Dismissible(
key: ValueKey(song.path),
child: AlbumArtListTile(
title: song.title,
subtitle: '${song.artist}${song.album}',
albumArtPath: song.albumArtPath,
highlight: index == queueIndexStream.value,
),
onDismissed: (direction) {
audioStore.removeQueueIndex(index);
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('${song.title} dismissed'),
switch (queueStream.status) {
case StreamStatus.active:
final int activeIndex = queueIndexStream.value;
return CustomScrollView(
controller: _scrollController,
slivers: [
ReorderableSliverList(
delegate: ReorderableSliverChildBuilderDelegate(
(context, int index) {
final song = queueStream.value[index];
return Dismissible(
key: ValueKey(song.path),
child: AlbumArtListTile(
title: song.title,
subtitle: '${song.artist}',
albumArtPath: song.albumArtPath,
highlight: index == activeIndex,
onTap: () => audioStore.setIndex(index),
),
onDismissed: (direction) {
audioStore.removeQueueIndex(index);
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('${song.title} removed'),
),
);
},
);
},
);
}).toList(),
onReorder: (oldIndex, newIndex) =>
audioStore.moveQueueItem(oldIndex, newIndex),
);
return ListView.separated(
itemCount: queueStream.value.length,
itemBuilder: (_, int index) {
final Song song = queueStream.value[index];
return AlbumArtListTile(
title: song.title,
subtitle: '${song.artist}${song.album}',
albumArtPath: song.albumArtPath,
highlight: index == queueIndexStream.value,
);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(
height: 4.0,
),
);
case StreamStatus.waiting:
case StreamStatus.done:
default:
return Container();
}
},
),
childCount: queueStream.value.length,
),
onReorder: (oldIndex, newIndex) =>
audioStore.moveQueueItem(oldIndex, newIndex),
)
],
);
case StreamStatus.waiting:
case StreamStatus.done:
default:
return Container();
}
},
),
),
);

View file

@ -75,31 +75,30 @@ abstract class _AudioStore with Store {
@observable
ObservableStream<LoopMode> loopModeStream;
@action
Future<void> playSong(int index, List<Song> songList) async {
_audioRepository.playSong(index, songList);
}
@action
Future<void> play() async {
_audioRepository.play();
}
@action
Future<void> pause() async {
_audioRepository.pause();
}
@action
Future<void> skipToNext() async {
_audioRepository.skipToNext();
}
@action
Future<void> skipToPrevious() async {
_audioRepository.skipToPrevious();
}
Future<void> setIndex(int index) async {
_audioRepository.setIndex(index);
}
Future<void> setShuffleMode(ShuffleMode shuffleMode) async {
_audioRepository.setShuffleMode(shuffleMode);
}

View file

@ -49,7 +49,8 @@ class MyAudioHandler extends BaseAudioHandler {
_audioPlayer.setShuffleMode(await _playerStateDataSource.shuffleModeStream.first, false);
}
if (_playerStateDataSource.queueStream != null && _playerStateDataSource.currentIndexStream != null) {
if (_playerStateDataSource.queueStream != null &&
_playerStateDataSource.currentIndexStream != null) {
_audioPlayer.loadQueue(
queue: await _playerStateDataSource.queueStream.first,
initialIndex: await _playerStateDataSource.currentIndexStream.first,
@ -95,6 +96,11 @@ class MyAudioHandler extends BaseAudioHandler {
_audioPlayer.addToQueue(SongModel.fromMediaItem(mediaItem));
}
@override
Future<void> removeQueueItemAt(int index) async {
_audioPlayer.removeQueueIndex(index);
}
@override
Future<void> customAction(String name, Map<String, dynamic> arguments) async {
switch (name) {
@ -112,8 +118,8 @@ class MyAudioHandler extends BaseAudioHandler {
return shuffleAll();
case MOVE_QUEUE_ITEM:
return moveQueueItem(arguments['OLD_INDEX'] as int, arguments['NEW_INDEX'] as int);
case REMOVE_QUEUE_ITEM:
return removeQueueIndex(arguments as int);
case SET_INDEX:
return setIndex(arguments['INDEX'] as int);
default:
}
}
@ -155,8 +161,8 @@ class MyAudioHandler extends BaseAudioHandler {
_audioPlayer.moveQueueItem(oldIndex, newIndex);
}
Future<void> removeQueueIndex(int index) async {
_audioPlayer.removeQueueIndex(index);
Future<void> setIndex(int index) async {
_audioPlayer.setIndex(index);
}
void _handleSetQueue(List<QueueItemModel> queueItems) {

View file

@ -111,6 +111,11 @@ class AudioManagerImpl implements AudioManager {
await _audioHandler.skipToPrevious();
}
@override
Future<void> setIndex(int index) async {
await _audioHandler.customAction(SET_INDEX, {'INDEX': index});
}
@override
Future<void> setShuffleMode(ShuffleMode shuffleMode) async {
await _audioHandler.customAction(SET_SHUFFLE_MODE, {'SHUFFLE_MODE': shuffleMode});
@ -178,6 +183,6 @@ class AudioManagerImpl implements AudioManager {
@override
Future<void> removeQueueIndex(int index) async {
await _audioHandler.customAction(REMOVE_QUEUE_ITEM, {'INDEX': index});
await _audioHandler.removeQueueItemAt(index);
}
}

View file

@ -17,6 +17,7 @@ abstract class AudioManager {
Future<void> pause();
Future<void> skipToNext();
Future<void> skipToPrevious();
Future<void> setIndex(int index);
Future<void> setShuffleMode(ShuffleMode shuffleMode);
Future<void> setLoopMode(LoopMode loopMode);
Future<void> shuffleAll();

View file

@ -98,6 +98,7 @@ class AudioPlayerImpl implements AudioPlayer {
if (queue == null || initialIndex >= queue.length) {
return;
}
_queue = queue;
_queueSubject.add(queue);
// final smallQueue = queue.sublist(max(initialIndex - 10, 0), min(initialIndex + 140, queue.length));

View file

@ -6,5 +6,5 @@ const String APP_LIFECYCLE_RESUMED = 'APP_LIFECYCLE_RESUMED';
const String SHUFFLE_ALL = 'SHUFFLE_ALL';
const String SET_SHUFFLE_MODE = 'SET_SHUFFLE_MODE';
const String SET_LOOP_MODE = 'SET_LOOP_MODE';
const String MOVE_QUEUE_ITEM = 'MOVE_QUEUE_ITEM';
const String REMOVE_QUEUE_ITEM = 'REMOVE_QUEUE_ITEM';
const String SET_INDEX = 'SET_INDEX';
const String MOVE_QUEUE_ITEM = 'MOVE_QUEUE_ITEM';

View file

@ -103,4 +103,9 @@ class AudioRepositoryImpl implements AudioRepository {
Future<void> setLoopMode(LoopMode loopMode) async {
await _audioManager.setLoopMode(loopMode);
}
@override
Future<void> setIndex(int index) async {
await _audioManager.setIndex(index);
}
}

View file

@ -578,6 +578,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
reorderables:
dependency: "direct main"
description:
name: reorderables
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.2"
rxdart:
dependency: transitive
description:

View file

@ -32,6 +32,7 @@ dependencies:
path:
path_provider: ^1.6.18
provider: ^4.0.4
reorderables: ^0.3.2
sqlite3_flutter_libs: ^0.3.0
dev_dependencies: