use of com.simplecity.amp_library.model.AdaptableItem in project Shuttle by timusus.
the class DialogUtils method showColorPickerDialog.
public static void showColorPickerDialog(SettingsFragment fragment, int selectedColor, int[] mainColors, int[][] subColors, ColorSelectionListener listener) {
View customView = LayoutInflater.from(fragment.getActivity()).inflate(R.layout.dialog_color_picker, null);
RecyclerView recyclerView = (RecyclerView) customView.findViewById(R.id.recyclerView);
GridLayoutManager gridLayoutManager = new GridLayoutManager(fragment.getActivity(), 5);
recyclerView.setLayoutManager(gridLayoutManager);
ThemeUtils.themeRecyclerView(recyclerView);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
ThemeUtils.themeRecyclerView(recyclerView);
super.onScrollStateChanged(recyclerView, newState);
}
});
ColorAdapter colorAdapter = new ColorAdapter();
List<AdaptableItem> colorViews = new ArrayList<>();
for (int i = 0, length = mainColors.length; i < length; i++) {
ColorView colorView = new ColorView(mainColors[i]);
boolean selected = false;
//If the sub colors array contains our selected color, then we set this colorView to selected.
for (int j = 0, jLength = subColors[i].length; j < jLength; j++) {
if (subColors[i][j] == selectedColor) {
selected = true;
}
}
colorView.selected = selected;
colorViews.add(colorView);
}
colorAdapter.setItems(colorViews);
recyclerView.setAdapter(colorAdapter);
colorAdapter.setColorListener((position, color, isSubColor) -> {
if (isSubColor) {
colorAdapter.setSelectedPosition(position);
} else {
List<AdaptableItem> subColorViews = new ArrayList<>();
for (int i = 0, length = subColors[position].length; i < length; i++) {
ColorView colorView = new ColorView(subColors[position][i]);
colorView.selected = colorView.color == selectedColor;
subColorViews.add(colorView);
colorAdapter.isSubColor = true;
}
colorAdapter.setItems(subColorViews);
}
});
int neutralTextResId;
TextView textView = (TextView) customView.findViewById(R.id.text1);
if (ShuttleUtils.isUpgraded()) {
textView.setVisibility(View.GONE);
neutralTextResId = R.string.dialog_custom;
} else {
textView.setVisibility(View.VISIBLE);
if (ShuttleUtils.isAmazonBuild()) {
neutralTextResId = R.string.get_pro_button_amazon;
} else {
neutralTextResId = R.string.btn_upgrade;
}
}
getBuilder(fragment.getActivity()).title(fragment.getActivity().getString(R.string.color_pick)).negativeText(R.string.cancel).onNegative((dialog, which) -> dialog.dismiss()).positiveText(R.string.button_done).onPositive((dialog, which) -> {
int color = selectedColor;
for (AdaptableItem item : colorAdapter.items) {
if (((ColorView) item).selected) {
color = ((ColorView) item).color;
break;
}
}
listener.colorSelected(color);
dialog.dismiss();
}).neutralText(neutralTextResId).autoDismiss(false).onNeutral((dialog, which) -> {
if (ShuttleUtils.isUpgraded()) {
showCustomColorPickerDialog(fragment.getActivity(), selectedColor, listener);
dialog.dismiss();
} else {
showUpgradeDialog(fragment.getActivity(), (upgradeDialog, which1) -> {
if (ShuttleUtils.isAmazonBuild()) {
ShuttleUtils.openShuttleLink(fragment.getActivity(), "com.simplecity.amp_pro");
} else {
AnalyticsManager.logUpgrade(AnalyticsManager.UpgradeType.COLORS);
((SettingsActivity) fragment.getActivity()).purchasePremiumUpgrade();
}
});
}
}).customView(customView, false).show();
}
use of com.simplecity.amp_library.model.AdaptableItem in project Shuttle by timusus.
the class ArtworkDialog method showDialog.
public static void showDialog(Context context, ArtworkProvider artworkProvider) {
View customView = LayoutInflater.from(context).inflate(R.layout.dialog_artwork, null);
ArtworkAdapter artworkAdapter = new ArtworkAdapter();
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = (RecyclerView) customView.findViewById(R.id.recyclerView);
recyclerView.addItemDecoration(new SpacesItemDecoration(16));
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(0);
recyclerView.setRecyclerListener(holder -> {
if (holder.getAdapterPosition() != -1) {
artworkAdapter.items.get(holder.getAdapterPosition()).recycle(holder);
}
});
artworkAdapter.items.add(0, new LoadingView());
artworkAdapter.notifyDataSetChanged();
recyclerView.setAdapter(artworkAdapter);
ArtworkView.GlideListener glideListener = artworkView -> {
int index = artworkAdapter.items.indexOf(artworkView);
if (index != -1) {
artworkAdapter.removeItem(index);
}
};
List<AdaptableItem> adaptableItems = 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);
adaptableItems.add(artworkView);
}
if (userSelectedArtwork == null || userSelectedArtwork.type != ArtworkProvider.Type.MEDIA_STORE) {
adaptableItems.add(new ArtworkView(ArtworkProvider.Type.MEDIA_STORE, artworkProvider, glideListener));
}
if (userSelectedArtwork == null || userSelectedArtwork.type != ArtworkProvider.Type.TAG) {
adaptableItems.add(new ArtworkView(ArtworkProvider.Type.TAG, artworkProvider, glideListener));
}
if (userSelectedArtwork == null || userSelectedArtwork.type != ArtworkProvider.Type.LAST_FM) {
adaptableItems.add(new ArtworkView(ArtworkProvider.Type.LAST_FM, artworkProvider, glideListener));
}
if (userSelectedArtwork == null || userSelectedArtwork.type != ArtworkProvider.Type.ITUNES) {
adaptableItems.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);
adaptableItems.add(folderView);
artworkAdapter.setItems(adaptableItems);
Observable.fromCallable(artworkProvider::getFolderArtworkFiles).subscribeOn(Schedulers.io()).subscribeOn(AndroidSchedulers.mainThread()).subscribe(files -> {
artworkAdapter.removeItem(artworkAdapter.items.indexOf(folderView));
if (files != null) {
Stream.of(files).filter(file -> userSelectedArtwork == null || !file.getPath().equals(userSelectedArtwork.path)).forEach(file -> {
artworkAdapter.addItem(new ArtworkView(ArtworkProvider.Type.FOLDER, artworkProvider, glideListener, file, false));
});
}
}, error -> {
Log.e(TAG, "Error getting folder artwork files.. " + error.toString());
});
DialogUtils.getBuilder(context).title(context.getString(R.string.artwork_edit)).customView(customView, false).autoDismiss(false).positiveText(context.getString(R.string.save)).onPositive((dialog, which) -> {
if (artworkAdapter.checkedItem != null) {
ContentValues values = new ContentValues();
values.put(CustomArtworkTable.COLUMN_KEY, artworkProvider.getArtworkKey());
values.put(CustomArtworkTable.COLUMN_TYPE, artworkAdapter.checkedItem.type);
values.put(CustomArtworkTable.COLUMN_PATH, artworkAdapter.checkedItem.file == null ? null : artworkAdapter.checkedItem.file.getPath());
context.getContentResolver().insert(CustomArtworkTable.URI, values);
ShuttleApplication.getInstance().userSelectedArtwork.put(artworkProvider.getArtworkKey(), new UserSelectedArtwork(artworkAdapter.checkedItem.type, artworkAdapter.checkedItem.file == null ? null : artworkAdapter.checkedItem.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 -> {
File dir = new File(ShuttleApplication.getInstance().getFilesDir() + "/shuttle/custom_artwork/" + artworkProvider.getArtworkKey().hashCode() + "/");
if (!dir.exists()) {
dir.mkdirs();
} else {
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 (artworkAdapter.getItemCount() != 0) {
File aFile = ((ArtworkView) artworkAdapter.items.get(0)).file;
if (aFile != null && aFile.getPath().contains(artworkProvider.getArtworkKey())) {
artworkAdapter.removeItem(0);
}
}
ArtworkView artworkView = new ArtworkView(ArtworkProvider.Type.FOLDER, artworkProvider, glideListener, file, true);
artworkAdapter.addItem(0, artworkView);
artworkAdapter.selectItem(0);
recyclerView.scrollToPosition(0);
})).cancelable(false).show();
}
use of com.simplecity.amp_library.model.AdaptableItem in project Shuttle by timusus.
the class DetailFragment method onCreateView.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_detail, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
if (canEdit()) {
itemTouchHelper = new ItemTouchHelper(new ItemTouchHelperCallback((from, to) -> {
long songViewCount = Stream.of(adapter.items).filter(adaptableItem -> adaptableItem instanceof SongView).count();
int offset = (int) (adapter.getItemCount() - songViewCount);
if (to >= offset) {
adapter.moveItem(from, to);
}
}, (from, to) -> {
// The 'offset' here is the number of items in the list which are not
// SongViews. We need this to determine the actual playlist positions of the items.
long songViewCount = Stream.of(adapter.items).filter(adaptableItem -> adaptableItem instanceof SongView).count();
int offset = (int) (adapter.getItemCount() - songViewCount);
from -= offset;
to -= offset;
try {
MediaStore.Audio.Playlists.Members.moveItem(getActivity().getContentResolver(), playlist.id, from, to);
} catch (IllegalArgumentException e) {
CrashlyticsCore.getInstance().log(String.format("Failed to move playlist item from %s to %s. Adapter count: %s. Error:%s", from, to, adapter.getItemCount(), e.getMessage()));
}
}, null));
itemTouchHelper.attachToRecyclerView(recyclerView);
}
fab = (FloatingActionButton) rootView.findViewById(R.id.fab);
fab.setOnClickListener(this);
lineOne = (TextView) rootView.findViewById(R.id.line_one);
lineTwo = (TextView) rootView.findViewById(R.id.line_two);
overflowButton = (NonScrollImageButton) rootView.findViewById(R.id.btn_overflow);
overflowButton.setOnClickListener(this);
if (albumArtist != null) {
lineOne.setText(albumArtist.name);
overflowButton.setContentDescription(getString(R.string.btn_options, albumArtist.name));
} else if (album != null) {
lineOne.setText(album.name);
overflowButton.setContentDescription(getString(R.string.btn_options, album.name));
} else if (genre != null) {
lineOne.setText(genre.name);
overflowButton.setVisibility(View.GONE);
} else if (playlist != null) {
lineOne.setText(playlist.name);
overflowButton.setContentDescription(getString(R.string.btn_options, playlist.name));
}
textProtectionScrim = rootView.findViewById(R.id.textProtectionScrim);
headerImageView = (ImageView) rootView.findViewById(R.id.background);
String transitionName = getArguments().getString(ARG_TRANSITION_NAME);
ViewCompat.setTransitionName(headerImageView, transitionName);
if (transitionName != null) {
textProtectionScrim.setVisibility(View.GONE);
fab.setVisibility(View.GONE);
}
int width = ResourceUtils.getScreenSize().width + ResourceUtils.toPixels(60);
int height = getResources().getDimensionPixelSize(R.dimen.header_view_height);
if (albumArtist != null || album != null) {
requestManager.load(albumArtist == null ? album : albumArtist).override(width, height).diskCacheStrategy(DiskCacheStrategy.SOURCE).priority(Priority.HIGH).placeholder(GlideUtils.getPlaceHolderDrawable(albumArtist == null ? album.name : albumArtist.name, false)).centerCrop().animate(new AlwaysCrossFade(false)).into(headerImageView);
}
actionMode = null;
//Set the RecyclerView HeaderView height equal to the headerItem height
headerView = rootView.findViewById(R.id.headerView);
headerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
headerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
DetailFragment.this.headerItem.height = headerView.getHeight();
}
});
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
headerTranslation = headerView.getTranslationY() - dy;
headerImageTranslation = headerImageView.getTranslationY() + dy / 2;
//the header translation.
if (headerTranslation == 0) {
headerImageTranslation = 0;
}
float ratio = Math.min(1, -headerTranslation / headerView.getHeight());
headerView.setTranslationY(headerTranslation);
headerImageView.setTranslationY(headerImageTranslation);
//when recreating this fragment.
if (getActivity() != null) {
if (((MainActivity) getActivity()).canSetAlpha()) {
((MainActivity) getActivity()).setActionBarAlpha(ratio, true);
}
}
}
});
themeUIComponents();
headerView.setTranslationY(headerTranslation);
headerImageView.setTranslationY(headerImageTranslation);
return rootView;
}
use of com.simplecity.amp_library.model.AdaptableItem in project Shuttle by timusus.
the class SuggestedFragment method refreshAdapterItems.
void refreshAdapterItems() {
PermissionUtils.RequestStoragePermissions(() -> {
if (getActivity() != null && isAdded()) {
subscription = new CompositeSubscription();
Observable<Playlist> mostPlayedPlaylistObservable = Observable.fromCallable(Playlist::mostPlayedPlaylist).subscribeOn(Schedulers.io()).cache();
Observable<List<Song>> mostPlayedSongsObservable = mostPlayedPlaylistObservable.filter(playlist -> playlist != null).flatMap(playlist -> playlist.getSongsObservable(getContext())).cache();
Observable<List<AdaptableItem>> mostPlayedItemsObservable = mostPlayedPlaylistObservable.flatMap(playlist -> {
SuggestedHeader mostPlayedHeader = new SuggestedHeader(getString(R.string.mostplayed), getString(R.string.suggested_most_played_songs_subtitle), playlist);
SuggestedHeaderView mostPlayedHeaderView = new SuggestedHeaderView(mostPlayedHeader);
return mostPlayedSongsObservable.map(songs -> {
List<AdaptableItem> items = new ArrayList<>();
if (!songs.isEmpty()) {
items.add(mostPlayedHeaderView);
items.add(mostPlayedRecyclerView);
}
return items;
});
}).switchIfEmpty(Observable.just(Collections.emptyList()));
Observable<List<AdaptableItem>> recentlyPlayedAlbums = Observable.fromCallable(Playlist::recentlyPlayedPlaylist).subscribeOn(Schedulers.io()).filter(playlist -> playlist != null).flatMap(playlist -> {
SuggestedHeader recentlyPlayedHeader = new SuggestedHeader(getString(R.string.suggested_recent_title), getString(R.string.suggested_recent_subtitle), playlist);
SuggestedHeaderView recentlyPlayedHeaderView = new SuggestedHeaderView(recentlyPlayedHeader);
return playlist.getSongsObservable(getContext()).flatMap(songs -> Observable.just(Operators.songsToAlbums(songs))).flatMap(Observable::from).sorted((a, b) -> ComparisonUtils.compareLong(b.lastPlayed, a.lastPlayed)).limit(6).flatMap(album -> album.getSongsObservable().map(songs -> {
album.numSongs = songs.size();
return album;
})).sorted((a, b) -> ComparisonUtils.compareLong(b.lastPlayed, a.lastPlayed)).filter(album -> album.numSongs > 0).map(album -> (AdaptableItem) new AlbumView(album, ViewType.ALBUM_LIST_SMALL, requestManager)).toList().map(adaptableItems -> {
if (!adaptableItems.isEmpty()) {
adaptableItems.add(0, recentlyPlayedHeaderView);
}
return adaptableItems;
});
}).switchIfEmpty(Observable.just(Collections.emptyList()));
Observable<Playlist> favouritesPlaylistObservable = Observable.fromCallable(Playlist::favoritesPlaylist).subscribeOn(Schedulers.io()).cache();
Observable<List<Song>> favouritesSongsObservable = favouritesPlaylistObservable.filter(playlist -> playlist != null).flatMap(playlist -> playlist.getSongsObservable(getContext())).cache();
Observable<List<AdaptableItem>> favoriteSongsItemsObservable = favouritesPlaylistObservable.flatMap(playlist -> {
SuggestedHeader favoriteHeader = new SuggestedHeader(getString(R.string.fav_title), getString(R.string.suggested_favorite_subtitle), playlist);
SuggestedHeaderView favoriteHeaderView = new SuggestedHeaderView(favoriteHeader);
return favouritesSongsObservable.map(songs -> {
List<AdaptableItem> items = new ArrayList<>();
if (!songs.isEmpty()) {
items.add(favoriteHeaderView);
items.add(favoriteRecyclerView);
}
return items;
});
}).switchIfEmpty(Observable.just(Collections.emptyList()));
Observable<List<AdaptableItem>> recentlyAddedAlbums = Observable.fromCallable(Playlist::recentlyAddedPlaylist).subscribeOn(Schedulers.io()).filter(playlist -> playlist != null).flatMap(playlist -> {
SuggestedHeader recentlyAddedHeader = new SuggestedHeader(getString(R.string.recentlyadded), getString(R.string.suggested_recently_added_subtitle), playlist);
SuggestedHeaderView recentlyAddedHeaderView = new SuggestedHeaderView(recentlyAddedHeader);
return playlist.getSongsObservable(getContext()).flatMap(songs -> Observable.just(Operators.songsToAlbums(songs))).flatMap(Observable::from).sorted((a, b) -> ComparisonUtils.compareLong(b.dateAdded, a.dateAdded)).limit(4).flatMap(album -> album.getSongsObservable().map(songs -> {
album.numSongs = songs.size();
return album;
})).sorted((a, b) -> ComparisonUtils.compareLong(b.dateAdded, a.dateAdded)).filter(album -> album.numSongs > 0).map(album -> (AdaptableItem) new AlbumView(album, ViewType.ALBUM_LIST_SMALL, requestManager)).toList().map(adaptableItems -> {
if (!adaptableItems.isEmpty()) {
adaptableItems.add(0, recentlyAddedHeaderView);
}
return adaptableItems;
});
}).switchIfEmpty(Observable.just(Collections.emptyList()));
Observable.merge(mostPlayedItemsObservable, recentlyPlayedAlbums, favoriteSongsItemsObservable, recentlyAddedAlbums);
subscription.add(Observable.combineLatest(mostPlayedItemsObservable, recentlyPlayedAlbums, favoriteSongsItemsObservable, recentlyAddedAlbums, (mostPlayedSongs1, recentlyPlayedAlbums1, favoriteSongs1, recentlyAddedAlbums1) -> {
List<AdaptableItem> items = new ArrayList<>();
items.addAll(mostPlayedSongs1);
items.addAll(recentlyPlayedAlbums1);
items.addAll(favoriteSongs1);
items.addAll(recentlyAddedAlbums1);
return items;
}).debounce(250, TimeUnit.MILLISECONDS).switchIfEmpty(Observable.just(new ArrayList<>())).observeOn(AndroidSchedulers.mainThread()).subscribe(adaptableItems -> {
if (adaptableItems.isEmpty()) {
suggestedAdapter.setEmpty(new EmptyView(R.string.empty_suggested));
} else {
suggestedAdapter.setItems(adaptableItems);
}
}));
subscription.add(mostPlayedSongsObservable.map(songs -> {
Collections.sort(songs, (a, b) -> ComparisonUtils.compareInt(b.playCount, a.playCount));
return Stream.of(songs).map(song -> (AdaptableItem) new SuggestedSongView(song, requestManager)).limit(20).collect(Collectors.toList());
}).observeOn(AndroidSchedulers.mainThread()).subscribe(adaptableItems -> {
mostPlayedRecyclerView.itemAdapter.setItems(adaptableItems);
}));
subscription.add(favouritesSongsObservable.map(songs -> Stream.of(songs).map(song -> (AdaptableItem) new SuggestedSongView(song, requestManager)).limit(20).collect(Collectors.toList())).observeOn(AndroidSchedulers.mainThread()).subscribe(adaptableItems -> {
favoriteRecyclerView.itemAdapter.setItems(adaptableItems);
}));
}
});
}
use of com.simplecity.amp_library.model.AdaptableItem in project Shuttle by timusus.
the class AlbumFragment method refreshAdapterItems.
void refreshAdapterItems() {
PermissionUtils.RequestStoragePermissions(() -> {
if (getActivity() != null && isAdded()) {
int albumDisplayType = SettingsManager.getInstance().getAlbumDisplayType();
boolean ascending = SortManager.getInstance().getAlbumsAscending();
subscription = DataManager.getInstance().getAlbumsRelay().flatMap(albums -> {
SortManager.getInstance().sortAlbums(albums);
if (!ascending) {
Collections.reverse(albums);
}
return Observable.from(albums).map(album -> (AdaptableItem) new AlbumView(album, albumDisplayType, requestManager, multiSelector)).toList();
}).observeOn(AndroidSchedulers.mainThread()).subscribe(items -> {
if (items.isEmpty()) {
albumAdapter.setEmpty(new EmptyView(R.string.empty_albums));
} else {
albumAdapter.setItems(items);
}
if (sortOrderChanged) {
recyclerView.scrollToPosition(0);
}
sortOrderChanged = false;
});
}
});
}
Aggregations