use of com.simplecity.amp_library.model.Song in project Shuttle by timusus.
the class DialogUtils method showBlacklistDialog.
public static void showBlacklistDialog(final Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.dialog_blacklist, null);
final MaterialDialog.Builder builder = getBuilder(context).title(R.string.blacklist_title).customView(view, false).positiveText(R.string.close).negativeText(R.string.pref_title_clear_blacklist).onNegative((materialDialog, dialogAction) -> {
BlacklistHelper.deleteAllSongs();
Toast.makeText(context, R.string.blacklist_deleted, Toast.LENGTH_SHORT).show();
});
final Dialog dialog = builder.build();
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
final BlacklistAdapter blacklistAdapter = new BlacklistAdapter();
blacklistAdapter.setBlackListListener((v, position, song) -> {
BlacklistHelper.deleteSong(song.id);
if (blacklistAdapter.items.size() == 0) {
dialog.dismiss();
}
});
recyclerView.setAdapter(blacklistAdapter);
Observable<List<Song>> songsObservable = SqlBriteUtils.createContinuousQuery(ShuttleApplication.getInstance(), Song::new, Song.getQuery()).first();
Observable<List<BlacklistedSong>> blacklistObservable = BlacklistHelper.getBlacklistSongsObservable();
Subscription subscription = Observable.combineLatest(songsObservable, blacklistObservable, (songs, blacklistedSongs) -> Stream.of(songs).filter(song -> Stream.of(blacklistedSongs).anyMatch(blacklistedSong -> blacklistedSong.songId == song.id)).sorted((a, b) -> ComparisonUtils.compare(a.albumArtistName, b.albumArtistName)).sorted((a, b) -> ComparisonUtils.compareInt(b.year, a.year)).sorted((a, b) -> ComparisonUtils.compareInt(a.track, b.track)).sorted((a, b) -> ComparisonUtils.compareInt(a.discNumber, b.discNumber)).sorted((a, b) -> ComparisonUtils.compare(a.albumName, b.albumName)).map(song -> (AdaptableItem) new BlacklistView(song)).collect(Collectors.toList())).observeOn(AndroidSchedulers.mainThread()).subscribe(blacklistViews -> {
if (blacklistViews.size() == 0) {
blacklistAdapter.addItem(0, new EmptyView(R.string.blacklist_empty));
} else {
blacklistAdapter.setItems(blacklistViews);
}
});
dialog.setOnDismissListener(dialogInterface -> subscription.unsubscribe());
dialog.show();
}
use of com.simplecity.amp_library.model.Song in project Shuttle by timusus.
the class ShuttleUtils method setRingtone.
/**
* Method setRingtone.
*
* @param context context
* @param song Song
*/
public static void setRingtone(final Context context, final Song song) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(context)) {
new AlertDialog.Builder(context).setTitle(R.string.dialog_title_set_ringtone).setMessage(R.string.dialog_message_set_ringtone).setPositiveButton(R.string.button_ok, (dialog, which) -> {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + ShuttleApplication.getInstance().getPackageName()));
context.startActivity(intent);
}).setNegativeButton(R.string.cancel, null).show();
return;
}
}
Observable.fromCallable(() -> {
boolean success = false;
final ContentResolver resolver = context.getContentResolver();
// Set the flag in the database to mark this as a ringtone
final Uri ringUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, song.id);
try {
final ContentValues values = new ContentValues(2);
values.put(MediaStore.Audio.AudioColumns.IS_RINGTONE, "1");
values.put(MediaStore.Audio.AudioColumns.IS_ALARM, "1");
if (ringUri != null) {
resolver.update(ringUri, values, null, null);
}
} catch (final UnsupportedOperationException ex) {
// most likely the card just got unmounted
Log.e(TAG, "couldn't set ringtone flag for song " + song);
return false;
}
Query query = new Query.Builder().uri(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI).projection(new String[] { BaseColumns._ID, MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.TITLE }).selection(BaseColumns._ID + "=" + song.id).build();
final Cursor cursor = SqlUtils.createQuery(context, query);
try {
if (cursor != null && cursor.getCount() == 1) {
// Set the system setting to make this the current ringtone
cursor.moveToFirst();
if (ringUri != null) {
Settings.System.putString(resolver, Settings.System.RINGTONE, ringUri.toString());
}
success = true;
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return success;
}).map(success -> success ? context.getString(R.string.ringtone_set, song.name) : context.getString(R.string.ringtone_set_failed)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(message -> Toast.makeText(context, message, Toast.LENGTH_SHORT).show());
}
use of com.simplecity.amp_library.model.Song in project Shuttle by timusus.
the class Operators method songsToAlbums.
public static List<Album> songsToAlbums(List<Song> songs) {
HashMap<Pair<Long, String>, Album> albumMap = new HashMap<>();
for (Song song : songs) {
//Create an album representing the album this song belongs to
Album album = song.getAlbum();
// We need to use the album id AND the albumArtistName as the key, to determine whether
// two albums are the same. This is because it's possible that the user doesn't have
// correct album tags for their songs. In that case, Android falls back to using the folder
// name for the album. So all songs with no album name, which share a folder will end up with
// the same album id. By using the albumArtistName in the key, we ensure that songs with the
// same album id but different albumArtistNames are not considered to be part of the same album.
Pair<Long, String> key = new Pair<>(album.id, album.albumArtistName);
//Now check if there's already an equivalent album in our albumMap
Album oldAlbum = albumMap.get(key);
if (oldAlbum != null) {
//Increment the number of songs.
oldAlbum.numSongs++;
//The number of discs is just the largest disc number for songs
oldAlbum.numDiscs = Math.max(song.discNumber, oldAlbum.numDiscs);
oldAlbum.songPlayCount += song.playCount;
//Add any new artists
Stream.of(album.artists).filter(artist -> !oldAlbum.artists.contains(artist)).forEach(artist -> oldAlbum.artists.add(artist));
//Add new paths
Stream.of(album.paths).filter(path -> !oldAlbum.paths.contains(path)).forEach(path -> oldAlbum.paths.add(path));
} else {
//Couldn't find an existing entry for this album. Add a new one.
albumMap.put(key, album);
}
}
return new ArrayList<>(albumMap.values());
}
use of com.simplecity.amp_library.model.Song in project Shuttle by timusus.
the class PlaylistUtils method removeFromFavorites.
public static void removeFromFavorites(Context context) {
Song song = MusicUtils.getSong();
if (song == null) {
return;
}
Observable.fromCallable(() -> {
Playlist favoritesPlaylist = Playlist.favoritesPlaylist();
if (favoritesPlaylist.id >= 0) {
final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", favoritesPlaylist.id);
return context.getContentResolver().delete(uri, MediaStore.Audio.Playlists.Members.AUDIO_ID + "=" + song.id, null);
}
return 0;
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(numTracksAdded -> {
if (numTracksAdded > 0) {
Toast.makeText(context, context.getResources().getString(R.string.song_removed_from_favourites, song.name), Toast.LENGTH_SHORT).show();
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(MusicService.InternalIntents.FAVORITE_CHANGED));
}
});
}
use of com.simplecity.amp_library.model.Song in project Shuttle by timusus.
the class SearchActivity method refreshAdapterItems.
private void refreshAdapterItems() {
subscriptions.add(DataManager.getInstance().getSongsRelay().first().map(songs -> {
char[] prefix = filterString.toUpperCase().toCharArray();
List<Album> albums = Operators.songsToAlbums(songs);
Collections.sort(albums, Album::compareTo);
List<AlbumArtist> albumArtists = Operators.albumsToAlbumArtists(albums);
Collections.sort(albumArtists, AlbumArtist::compareTo);
List<AdaptableItem> adaptableItems = Stream.of(albumArtists).filter(album -> album.name != null).map(albumArtist -> new SearchUtils.JaroWinklerObject<>(albumArtist, filterString, albumArtist.name)).filter(jaroWinklerObject -> jaroWinklerObject.score > SCORE_THRESHOLD || TextUtils.isEmpty(filterString)).sorted((a, b) -> a.object.compareTo(b.object)).sorted((a, b) -> Double.compare(b.score, a.score)).map(jaroWinklerObject -> jaroWinklerObject.object).map(albumArtist -> {
AlbumArtistView albumArtistView = new AlbumArtistView(albumArtist, ViewType.ARTIST_LIST, requestManager);
albumArtistView.setPrefix(prefixHighlighter, prefix);
return (AdaptableItem) albumArtistView;
}).collect(Collectors.toList());
if (!adaptableItems.isEmpty()) {
adaptableItems.add(0, artistsHeader);
}
List<AdaptableItem> albumItems = Stream.of(albums).filter(album -> album.name != null).map(album -> new SearchUtils.JaroWinklerObject<>(album, filterString, album.name, album.albumArtistName)).filter(jaroWinklerObject -> jaroWinklerObject.score > SCORE_THRESHOLD || TextUtils.isEmpty(filterString)).sorted((a, b) -> a.object.compareTo(b.object)).sorted((a, b) -> Double.compare(b.score, a.score)).map(jaroWinklerObject -> jaroWinklerObject.object).map(album -> {
AlbumView albumView = new AlbumView(album, ViewType.ALBUM_LIST, requestManager);
albumView.setPrefix(prefixHighlighter, prefix);
return albumView;
}).collect(Collectors.toList());
if (!albumItems.isEmpty()) {
albumItems.add(0, albumsHeader);
}
adaptableItems.addAll(albumItems);
songs = Stream.of(songs).filter(song -> song.name != null).map(song -> new SearchUtils.JaroWinklerObject<>(song, filterString, song.name, song.albumName, song.artistName, song.albumArtistName)).filter(jaroWinklerObject -> jaroWinklerObject.score > SCORE_THRESHOLD || TextUtils.isEmpty(filterString)).sorted((a, b) -> a.object.compareTo(b.object)).sorted((a, b) -> Double.compare(b.score, a.score)).map(jaroWinklerObject -> jaroWinklerObject.object).collect(Collectors.toList());
List<AdaptableItem> songItems = Stream.of(songs).map(song -> {
SongView songView = new SongView(song, dummySelector, requestManager);
songView.setPrefix(prefixHighlighter, prefix);
return songView;
}).collect(Collectors.toList());
if (!songItems.isEmpty()) {
songItems.add(0, songsHeader);
}
adaptableItems.addAll(songItems);
return adaptableItems;
}).observeOn(AndroidSchedulers.mainThread()).subscribe(adaptableItems -> {
if (setItemsSubscription != null) {
setItemsSubscription.unsubscribe();
}
setItemsSubscription = adapter.setItems(adaptableItems);
recyclerView.scrollToPosition(0);
}));
}
Aggregations