use of com.afollestad.materialdialogs.MaterialDialog in project Shuttle by timusus.
the class BiographyDialog method getBiographyDialog.
private static MaterialDialog getBiographyDialog(final Context context, @BioType int type, String artistName, String albumName) {
@SuppressLint("InflateParams") View customView = LayoutInflater.from(context).inflate(R.layout.dialog_biography, null, false);
final ProgressBar progressBar = customView.findViewById(R.id.progress);
final TextView message = customView.findViewById(R.id.message);
Callback<LastFmArtist> artistCallback = new Callback<LastFmArtist>() {
@Override
public void onResponse(Call<LastFmArtist> call, Response<LastFmArtist> response) {
progressBar.setVisibility(View.GONE);
if (response != null && response.isSuccessful()) {
if (response.body() != null && response.body().artist != null && response.body().artist.bio != null) {
String summary = response.body().artist.bio.summary;
if (ShuttleUtils.hasNougat()) {
message.setText(Html.fromHtml(summary, Html.FROM_HTML_MODE_COMPACT));
} else {
message.setText(Html.fromHtml(summary));
}
} else {
message.setText(R.string.no_artist_info);
}
}
}
@Override
public void onFailure(Call<LastFmArtist> call, Throwable t) {
progressBar.setVisibility(View.GONE);
switch(type) {
case BioType.ARTIST:
message.setText(R.string.no_artist_info);
break;
case BioType.ALBUM:
message.setText(R.string.no_album_info);
break;
}
}
};
Callback<LastFmAlbum> albumCallback = new Callback<LastFmAlbum>() {
@Override
public void onResponse(Call<LastFmAlbum> call, Response<LastFmAlbum> response) {
progressBar.setVisibility(View.GONE);
if (response != null && response.isSuccessful()) {
if (response.body() != null && response.body().album != null && response.body().album.wiki != null) {
String summary = response.body().album.wiki.summary;
if (ShuttleUtils.hasNougat()) {
message.setText(Html.fromHtml(summary, Html.FROM_HTML_MODE_COMPACT));
} else {
message.setText(Html.fromHtml(summary));
}
} else {
message.setText(R.string.no_album_info);
}
}
}
@Override
public void onFailure(Call<LastFmAlbum> call, Throwable t) {
progressBar.setVisibility(View.GONE);
switch(type) {
case BioType.ARTIST:
message.setText(R.string.no_artist_info);
break;
case BioType.ALBUM:
message.setText(R.string.no_album_info);
break;
}
}
};
switch(type) {
case BioType.ARTIST:
HttpClient.getInstance().lastFmService.getLastFmArtistResult(artistName).enqueue(artistCallback);
break;
case BioType.ALBUM:
HttpClient.getInstance().lastFmService.getLastFmAlbumResult(artistName, albumName).enqueue(albumCallback);
break;
}
MaterialDialog.Builder builder = DialogUtils.getBuilder(context).title(R.string.info).customView(customView, false).negativeText(R.string.close);
return builder.build();
}
use of com.afollestad.materialdialogs.MaterialDialog in project Shuttle by timusus.
the class ArtworkDialog method build.
public static MaterialDialog build(Context context, ArtworkProvider artworkProvider) {
@SuppressLint("InflateParams") View customView = LayoutInflater.from(context).inflate(R.layout.dialog_artwork, null);
ViewModelAdapter adapter = new ViewModelAdapter();
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = customView.findViewById(R.id.recyclerView);
recyclerView.addItemDecoration(new SpacesItemDecoration(16));
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(0);
recyclerView.setRecyclerListener(new RecyclerListener());
adapter.items.add(0, new ArtworkLoadingView());
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
ArtworkView.GlideListener glideListener = artworkView -> {
int index = adapter.items.indexOf(artworkView);
if (index != -1) {
adapter.removeItem(index);
}
};
List<ViewModel> viewModels = new ArrayList<>();
UserSelectedArtwork userSelectedArtwork = ShuttleApplication.getInstance().userSelectedArtwork.get(artworkProvider.getArtworkKey());
if (userSelectedArtwork != null) {
File file = null;
if (userSelectedArtwork.path != null) {
file = new File(userSelectedArtwork.path);
}
ArtworkView artworkView = new ArtworkView(userSelectedArtwork.type, artworkProvider, glideListener, file, true);
artworkView.setSelected(true);
viewModels.add(artworkView);
}
if (userSelectedArtwork == null || userSelectedArtwork.type != ArtworkProvider.Type.MEDIA_STORE) {
viewModels.add(new ArtworkView(ArtworkProvider.Type.MEDIA_STORE, artworkProvider, glideListener));
}
if (userSelectedArtwork == null || userSelectedArtwork.type != ArtworkProvider.Type.TAG) {
viewModels.add(new ArtworkView(ArtworkProvider.Type.TAG, artworkProvider, glideListener));
}
if (userSelectedArtwork == null || userSelectedArtwork.type != ArtworkProvider.Type.LAST_FM) {
viewModels.add(new ArtworkView(ArtworkProvider.Type.LAST_FM, artworkProvider, glideListener));
}
if (userSelectedArtwork == null || userSelectedArtwork.type != ArtworkProvider.Type.ITUNES) {
viewModels.add(new ArtworkView(ArtworkProvider.Type.ITUNES, artworkProvider, glideListener));
}
// Dummy Folder ArtworkView - will be replaced or removed depending on availability of folder images
ArtworkView folderView = new ArtworkView(ArtworkProvider.Type.FOLDER, null, null);
viewModels.add(folderView);
ArtworkView.ClickListener listener = artworkView -> {
Stream.of(viewModels).filter(viewModel -> viewModel instanceof ArtworkView).forEachIndexed((i, viewModel) -> ((ArtworkView) viewModel).setSelected(viewModel == artworkView));
adapter.notifyItemRangeChanged(0, adapter.getItemCount(), 0);
};
Stream.of(viewModels).filter(viewModel -> viewModel instanceof ArtworkView).forEach(viewModel -> ((ArtworkView) viewModel).setListener(listener));
adapter.setItems(viewModels);
Observable.fromCallable(artworkProvider::getFolderArtworkFiles).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(files -> {
adapter.removeItem(adapter.items.indexOf(folderView));
if (files != null) {
Stream.of(files).filter(file -> userSelectedArtwork == null || !file.getPath().equals(userSelectedArtwork.path)).forEach(file -> adapter.addItem(new ArtworkView(ArtworkProvider.Type.FOLDER, artworkProvider, glideListener, file, false)));
}
}, error -> LogUtils.logException(TAG, "Error getting artwork files", error));
return new MaterialDialog.Builder(context).title(R.string.artwork_edit).customView(customView, false).autoDismiss(false).positiveText(context.getString(R.string.save)).onPositive((dialog, which) -> {
ArtworkView checkedView = ArtworkDialog.getCheckedView(adapter.items);
if (checkedView != null) {
ArtworkModel artworkModel = checkedView.getItem();
ContentValues values = new ContentValues();
values.put(CustomArtworkTable.COLUMN_KEY, artworkProvider.getArtworkKey());
values.put(CustomArtworkTable.COLUMN_TYPE, artworkModel.type);
values.put(CustomArtworkTable.COLUMN_PATH, artworkModel.file == null ? null : artworkModel.file.getPath());
context.getContentResolver().insert(CustomArtworkTable.URI, values);
ShuttleApplication.getInstance().userSelectedArtwork.put(artworkProvider.getArtworkKey(), new UserSelectedArtwork(artworkModel.type, artworkModel.file == null ? null : artworkModel.file.getPath()));
} else {
context.getContentResolver().delete(CustomArtworkTable.URI, CustomArtworkTable.COLUMN_KEY + "='" + artworkProvider.getArtworkKey().replaceAll("'", "\''") + "'", null);
ShuttleApplication.getInstance().userSelectedArtwork.remove(artworkProvider.getArtworkKey());
}
dialog.dismiss();
}).negativeText(context.getString(R.string.close)).onNegative((dialog, which) -> dialog.dismiss()).neutralText(context.getString(R.string.artwork_gallery)).onNeutral((dialog, which) -> RxImagePicker.with(context).requestImage(Sources.GALLERY).flatMap(uri -> {
// The directory will be shuttle/custom_artwork/key_hashcode/currentSystemTime.artwork
// We want the directory to be based on the key, so we can delete old artwork, and the
// filename to be unique, because it's used for Glide caching.
File dir = new File(ShuttleApplication.getInstance().getFilesDir() + "/shuttle/custom_artwork/" + artworkProvider.getArtworkKey().hashCode() + "/");
// Create dir if necessary
if (!dir.exists()) {
dir.mkdirs();
} else {
// Delete any existing artwork for this key.
if (dir.isDirectory()) {
String[] children = dir.list();
for (String child : children) {
new File(dir, child).delete();
}
}
}
File file = new File(dir.getPath() + System.currentTimeMillis() + ".artwork");
try {
file.createNewFile();
if (file.exists()) {
return RxImageConverters.uriToFile(context, uri, file);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}).filter(file -> file != null && file.exists()).subscribe(file -> {
// If we've already got user-selected artwork in the adapter, remove it.
if (adapter.getItemCount() != 0) {
File aFile = ((ArtworkView) adapter.items.get(0)).file;
if (aFile != null && aFile.getPath().contains(artworkProvider.getArtworkKey())) {
adapter.removeItem(0);
}
}
ArtworkView artworkView = new ArtworkView(ArtworkProvider.Type.FOLDER, artworkProvider, glideListener, file, true);
artworkView.setSelected(true);
adapter.addItem(0, artworkView);
recyclerView.scrollToPosition(0);
}, error -> LogUtils.logException(TAG, "Error picking from gallery", error))).cancelable(false).build();
}
use of com.afollestad.materialdialogs.MaterialDialog in project Shuttle by timusus.
the class MenuUtils method deleteFile.
public static void deleteFile(Context context, BaseFileObject fileObject, UnsafeAction fileDeleted) {
MaterialDialog.Builder builder = DialogUtils.getBuilder(context).title(R.string.delete_item).iconRes(R.drawable.ic_warning_24dp);
if (fileObject.fileType == FileType.FILE) {
builder.content(String.format(context.getResources().getString(R.string.delete_file_confirmation_dialog), fileObject.name));
} else {
builder.content(String.format(context.getResources().getString(R.string.delete_folder_confirmation_dialog), fileObject.path));
}
builder.positiveText(R.string.button_ok).onPositive((materialDialog, dialogAction) -> {
if (FileHelper.deleteFile(new File(fileObject.path))) {
fileDeleted.run();
CustomMediaScanner.scanFiles(Collections.singletonList(fileObject.path), null);
} else {
Toast.makeText(context, fileObject.fileType == FileType.FOLDER ? R.string.delete_folder_failed : R.string.delete_file_failed, Toast.LENGTH_LONG).show();
}
});
builder.negativeText(R.string.cancel).show();
}
use of com.afollestad.materialdialogs.MaterialDialog in project Shuttle by timusus.
the class PlaylistUtils method createPlaylistDialog.
@SuppressLint("CheckResult")
private static void createPlaylistDialog(final Context context, final OnSavePlaylistListener listener) {
@SuppressLint("InflateParams") View customView = LayoutInflater.from(context).inflate(R.layout.dialog_playlist, null);
final EditText editText = customView.findViewById(R.id.editText);
Observable.fromCallable(() -> makePlaylistName(context)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(name -> {
editText.setText(name);
if (!TextUtils.isEmpty(name)) {
editText.setSelection(name.length());
}
}, error -> LogUtils.logException(TAG, "PlaylistUtils: Error Setting playlist name", error));
MaterialDialog.Builder builder = DialogUtils.getBuilder(context).customView(customView, false).title(R.string.menu_playlist).positiveText(R.string.create_playlist_create_text).onPositive((materialDialog, dialogAction) -> {
String name = editText.getText().toString();
if (!name.isEmpty()) {
idForPlaylistObservable(context, name).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(id -> {
Uri uri;
if (id >= 0) {
uri = ContentUris.withAppendedId(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, id);
clearPlaylist(id);
} else {
ContentValues values = new ContentValues(1);
values.put(MediaStore.Audio.Playlists.NAME, name);
try {
uri = context.getContentResolver().insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, values);
} catch (IllegalArgumentException | NullPointerException e) {
Toast.makeText(context, R.string.dialog_create_playlist_error, Toast.LENGTH_LONG).show();
uri = null;
}
}
if (uri != null) {
listener.onSave(new Playlist(Playlist.Type.USER_CREATED, Long.valueOf(uri.getLastPathSegment()), name, true, false, true, true, true));
}
}, error -> LogUtils.logException(TAG, "PlaylistUtils: Error Saving playlist", error));
}
}).negativeText(R.string.cancel);
final Dialog dialog = builder.build();
dialog.show();
TextWatcher textWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// don't care about this one
}
// Fixme:
// It's probably best to just query all playlist names first, and then check against
// that list, rather than requerying for each char change.
public void onTextChanged(CharSequence s, int start, int before, int count) {
String newText = editText.getText().toString();
if (newText.trim().length() == 0) {
((MaterialDialog) dialog).getActionButton(DialogAction.POSITIVE).setEnabled(false);
} else {
((MaterialDialog) dialog).getActionButton(DialogAction.POSITIVE).setEnabled(true);
// check if playlist with current name exists already, and warn the user if so.
idForPlaylistObservable(context, newText).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(id -> {
if (id >= 0) {
((MaterialDialog) dialog).getActionButton(DialogAction.POSITIVE).setText(R.string.create_playlist_overwrite_text);
} else {
((MaterialDialog) dialog).getActionButton(DialogAction.POSITIVE).setText(R.string.create_playlist_create_text);
}
}, error -> LogUtils.logException(TAG, "PlaylistUtils: Error handling text change", error));
}
}
public void afterTextChanged(Editable s) {
// don't care about this one
}
};
editText.addTextChangedListener(textWatcher);
}
use of com.afollestad.materialdialogs.MaterialDialog in project Shuttle by timusus.
the class SleepTimer method showMinutesDialog.
public void showMinutesDialog(Context context, UnsafeAction timerStarted) {
@SuppressLint("InflateParams") View customView = LayoutInflater.from(context).inflate(R.layout.dialog_minutes_picker, null);
EditText editText = customView.findViewById(R.id.editText);
new MaterialDialog.Builder(context).title(R.string.sleep_timer_set_minutes).customView(customView, false).positiveText(R.string.button_ok).negativeText(R.string.cancel).autoDismiss(false).onPositive((materialDialog, dialogAction) -> {
if (!TextUtils.isEmpty(editText.getText())) {
start(Integer.parseInt(editText.getText().toString()) * 60, playToEnd);
timerStarted.run();
materialDialog.dismiss();
}
}).onNegative((materialDialog, dialogAction) -> {
materialDialog.dismiss();
}).show();
new Handler().post(() -> {
InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
});
}
Aggregations