Skip to content

Commit

Permalink
feat: individual shuffle and repeat/loop button of player
Browse files Browse the repository at this point in the history
  • Loading branch information
KRTirtho committed Jan 6, 2023
1 parent e7f3f4e commit f79223c
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 83 deletions.
7 changes: 4 additions & 3 deletions lib/components/library/user_albums.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ class UserAlbums extends HookConsumerWidget {
final searchText = useState('');

final albums = useMemoized(() {
if (searchText.value.isEmpty) {
return albumsQuery.data?.toList() ?? [];
}
return albumsQuery.data
?.map((e) => Tuple2(
searchText.value.isEmpty
? 100
: weightedRatio(e.name!, searchText.value),
weightedRatio(e.name!, searchText.value),
e,
))
.sorted((a, b) => b.item1.compareTo(a.item1))
Expand Down
13 changes: 8 additions & 5 deletions lib/components/library/user_artists.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ class UserArtists extends HookConsumerWidget {
final searchText = useState('');

final filteredArtists = useMemoized(() {
return artistQuery.pages
.expand<Artist>((page) => page?.items ?? const Iterable.empty())
final artists = artistQuery.pages
.expand<Artist>((page) => page?.items ?? const Iterable.empty());

if (searchText.value.isEmpty) {
return artists.toList();
}
return artists
.map((e) => Tuple2(
searchText.value.isEmpty
? 100
: weightedRatio(e.name!, searchText.value),
weightedRatio(e.name!, searchText.value),
e,
))
.sorted((a, b) => b.item1.compareTo(a.item1))
Expand Down
13 changes: 7 additions & 6 deletions lib/components/library/user_local_tracks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,15 @@ class UserLocalTracks extends HookConsumerWidget {
}, [sortBy.value, tracks]);

final filteredTracks = useMemoized(() {
if (searchText.value.isEmpty) {
return sortedTracks;
}
return sortedTracks
.map((e) => Tuple2(
searchText.value.isEmpty
? 100
: weightedRatio(
"${e.name} - ${TypeConversionUtils.artists_X_String<Artist>(e.artists ?? [])}",
searchText.value,
),
weightedRatio(
"${e.name} - ${TypeConversionUtils.artists_X_String<Artist>(e.artists ?? [])}",
searchText.value,
),
e,
))
.toList()
Expand Down
34 changes: 20 additions & 14 deletions lib/components/library/user_playlists.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,26 @@ class UserPlaylists extends HookConsumerWidget {
likedTracksPlaylist.images = [image];

final playlists = useMemoized(
() => [
likedTracksPlaylist,
...?playlistsQuery.data,
]
.map((e) => Tuple2(
searchText.value.isEmpty
? 100
: weightedRatio(e.name!, searchText.value),
e,
))
.sorted((a, b) => b.item1.compareTo(a.item1))
.where((e) => e.item1 > 50)
.map((e) => e.item2)
.toList(),
() {
if (searchText.value.isEmpty) {
return [
likedTracksPlaylist,
...?playlistsQuery.data,
];
}
return [
likedTracksPlaylist,
...?playlistsQuery.data,
]
.map((e) => Tuple2(
weightedRatio(e.name!, searchText.value),
e,
))
.sorted((a, b) => b.item1.compareTo(a.item1))
.where((e) => e.item1 > 50)
.map((e) => e.item2)
.toList();
},
[playlistsQuery.data, searchText.value],
);

Expand Down
43 changes: 28 additions & 15 deletions lib/components/player/player_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,22 +139,20 @@ class PlayerControls extends HookConsumerWidget {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
PlatformIconButton(
tooltip: playback.isLoop
? "Repeat playlist"
: playback.isShuffled
? "Loop track"
: "Shuffle playlist",
tooltip: playback.isShuffled
? "Unshuffle playlist"
: "Shuffle playlist",
icon: Icon(
playback.isLoop
? Icons.repeat_one_rounded
: playback.isShuffled
? Icons.shuffle_rounded
: Icons.repeat_rounded,
Icons.shuffle_rounded,
color: playback.isShuffled
? PlatformTheme.of(context).primaryColor
: null,
),
onPressed:
playback.track == null || playback.playlist == null
? null
: playback.cyclePlaybackMode,
onPressed: playback.playlist == null
? null
: () {
playback.setIsShuffled(!playback.isShuffled);
},
),
PlatformIconButton(
tooltip: "Previous track",
Expand Down Expand Up @@ -209,7 +207,22 @@ class PlayerControls extends HookConsumerWidget {
}
}
: null,
)
),
PlatformIconButton(
tooltip:
!playback.isLoop ? "Loop Track" : "Repeat playlist",
icon: Icon(
playback.isLoop
? Icons.repeat_one_rounded
: Icons.repeat_rounded,
),
onPressed:
playback.track == null || playback.playlist == null
? null
: () {
playback.setIsLoop(!playback.isLoop);
},
),
],
),
const SizedBox(height: 5)
Expand Down
13 changes: 7 additions & 6 deletions lib/components/shared/track_table/track_collection_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,15 @@ class TrackCollectionView<T> extends HookConsumerWidget {
final searchText = useState("");

final filteredTracks = useMemoized(() {
if (searchText.value.isEmpty) {
return tracksSnapshot.data;
}
return tracksSnapshot.data
?.map((e) => Tuple2(
searchText.value.isEmpty
? 100
: weightedRatio(
"${e.name} - ${TypeConversionUtils.artists_X_String<Artist>(e.artists ?? [])}",
searchText.value,
),
weightedRatio(
"${e.name} - ${TypeConversionUtils.artists_X_String<Artist>(e.artists ?? [])}",
searchText.value,
),
e,
))
.toList()
Expand Down
2 changes: 1 addition & 1 deletion lib/models/current_playlist.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class CurrentPlaylist {
// won't shuffle if already shuffled
if (_tempTrack == null) {
_tempTrack = [...tracks];
tracks.shuffle();
tracks = List.from(tracks)..shuffle();
if (topTrack != null) {
tracks.remove(topTrack);
tracks.insert(0, topTrack);
Expand Down
41 changes: 14 additions & 27 deletions lib/provider/playback_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,10 @@ enum AudioQuality {
low,
}

enum PlaybackMode {
repeat,
shuffle,
normal,
}

class Playback extends PersistedChangeNotifier {
// player properties
PlaybackMode playbackMode;
bool isShuffled;
bool isLoop;
bool isPlaying;
Duration currentDuration;
double volume;
Expand Down Expand Up @@ -83,7 +78,8 @@ class Playback extends PersistedChangeNotifier {
this.mobileAudioService,
}) : volume = 1,
isPlaying = false,
playbackMode = PlaybackMode.normal,
isShuffled = false,
isLoop = false,
currentDuration = Duration.zero,
_subscriptions = [],
status = PlaybackStatus.idle,
Expand Down Expand Up @@ -287,25 +283,18 @@ class Playback extends PersistedChangeNotifier {
isPlaying ? await pause() : await resume();
}

void cyclePlaybackMode() {
switch (playbackMode) {
case PlaybackMode.normal:
playbackMode = PlaybackMode.shuffle;
playlist?.shuffle(track);
break;
case PlaybackMode.shuffle:
playbackMode = PlaybackMode.repeat;
playlist?.unshuffle();
break;
case PlaybackMode.repeat:
playbackMode = PlaybackMode.normal;
break;
void setIsShuffled(bool shuffle) {
isShuffled = shuffle;
if (isShuffled) {
playlist?.shuffle(track);
} else {
playlist?.unshuffle();
}
notifyListeners();
}

void setPlaybackMode(PlaybackMode mode) {
playbackMode = mode;
void setIsLoop(bool loop) {
isLoop = loop;
notifyListeners();
}

Expand All @@ -325,7 +314,8 @@ class Playback extends PersistedChangeNotifier {
await player.stop();
await player.release();
isPlaying = false;
playbackMode = PlaybackMode.normal;
isShuffled = false;
isLoop = false;
playlist = null;
track = null;
status = PlaybackStatus.idle;
Expand Down Expand Up @@ -685,9 +675,6 @@ class Playback extends PersistedChangeNotifier {
};
}

bool get isLoop => playbackMode == PlaybackMode.repeat;
bool get isShuffled => playbackMode == PlaybackMode.shuffle;
bool get isNormal => playbackMode == PlaybackMode.normal;
UnmodifiableListView<Video> get siblingYtVideos =>
UnmodifiableListView(_siblingYtVideos);
}
Expand Down
12 changes: 6 additions & 6 deletions lib/services/linux_audio_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,15 @@ class _MprisMediaPlayer2Player extends DBusObject {

/// Gets value of property org.mpris.MediaPlayer2.Player.LoopStatus
Future<DBusMethodResponse> getLoopStatus() async {
return DBusMethodSuccessResponse([const DBusString("Playlist")]);
return DBusMethodSuccessResponse([
playback.isLoop ? const DBusString("Track") : const DBusString("None"),
]);
}

/// Sets property org.mpris.MediaPlayer2.Player.LoopStatus
Future<DBusMethodResponse> setLoopStatus(String value) async {
return DBusMethodErrorResponse.failed(
'Set org.mpris.MediaPlayer2.Player.LoopStatus not implemented');
playback.setIsLoop(value == "Track");
return DBusMethodSuccessResponse();
}

/// Gets value of property org.mpris.MediaPlayer2.Player.Rate
Expand All @@ -275,9 +277,7 @@ class _MprisMediaPlayer2Player extends DBusObject {

/// Sets property org.mpris.MediaPlayer2.Player.Shuffle
Future<DBusMethodResponse> setShuffle(bool value) async {
playback.setPlaybackMode(
value ? PlaybackMode.shuffle : PlaybackMode.normal,
);
playback.setIsShuffled(value);
return DBusMethodSuccessResponse();
}

Expand Down

0 comments on commit f79223c

Please sign in to comment.