diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt index ae378a42..c81a2614 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt @@ -175,7 +175,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) { - CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist!!, data!!.data!!) + data?.data?.let { CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, it) } } else -> if (resultCode == Activity.RESULT_OK) { reload() diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt index 0e3add24..8a70a830 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt @@ -24,7 +24,6 @@ import code.name.monkey.retromusic.loaders.AlbumLoader import code.name.monkey.retromusic.loaders.ArtistLoader import code.name.monkey.retromusic.loaders.PlaylistSongsLoader import code.name.monkey.retromusic.service.MusicService -import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.PreferenceUtil import io.reactivex.disposables.CompositeDisposable import java.util.* @@ -62,12 +61,17 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP setDrawUnderStatusBar() super.onCreate(savedInstanceState) + getBottomNavigationView().selectedItemId = PreferenceUtil.getInstance().lastPage + getBottomNavigationView().setOnNavigationItemSelectedListener { PreferenceUtil.getInstance().lastPage = it.itemId selectedFragment(it.itemId) + true + } + if (savedInstanceState == null) { selectedFragment(PreferenceUtil.getInstance().lastPage) } else { @@ -254,8 +258,10 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP key == PreferenceUtil.ALBUM_COVER_STYLE || key == PreferenceUtil.HOME_ARTIST_GRID_STYLE || key == PreferenceUtil.ALBUM_COVER_TRANSFORM || - key == PreferenceUtil.TAB_TEXT_MODE) + key == PreferenceUtil.TAB_TEXT_MODE || + key == PreferenceUtil.LIBRARY_CATEGORIES) postRecreate() + } private fun showPromotionalOffer() { @@ -277,6 +283,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP R.id.action_album, R.id.action_artist, R.id.action_playlist, + R.id.action_genre, R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), false) R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), false) R.id.action_folder -> setCurrentFragment(FoldersFragment.newInstance(this), false) @@ -296,8 +303,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP companion object { const val APP_INTRO_REQUEST = 2323 - const val LIBRARY = 1 - const val FOLDERS = 3 const val HOME = 0 private const val TAG = "MainActivity" private const val APP_USER_INFO_REQUEST = 9003 diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt index dae87bef..613c986f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt @@ -61,6 +61,8 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), Sliding chooseFragmentForTheme() setupSlidingUpPanel() + + updateTabs() } override fun onResume() { @@ -307,4 +309,16 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), Sliding } } + + fun updateTabs() { + bottomNavigationView.menu.clear() + val currentTabs = PreferenceUtil.getInstance().libraryCategoryInfos + for (tab in currentTabs) { + if (tab.visible) { + val menu = tab.category; + bottomNavigationView.menu.add(0, menu.id, 0, menu.stringRes) + .setIcon(menu.icon) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.java b/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.java new file mode 100644 index 00000000..2310f613 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2019 Hemanth Savarala. + * + * Licensed under the GNU General Public License v3 + * + * This is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by + * the Free Software Foundation either version 3 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + */ + +package code.name.monkey.retromusic.adapter; + +import android.annotation.SuppressLint; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import code.name.monkey.retromusic.R; +import code.name.monkey.retromusic.model.CategoryInfo; +import code.name.monkey.retromusic.util.SwipeAndDragHelper; + +public class CategoryInfoAdapter extends RecyclerView.Adapter implements SwipeAndDragHelper.ActionCompletionContract { + private List categoryInfos; + private ItemTouchHelper touchHelper; + + public CategoryInfoAdapter(@NonNull List categoryInfos) { + this.categoryInfos = categoryInfos; + SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(this); + touchHelper = new ItemTouchHelper(swipeAndDragHelper); + } + + @Override + @NonNull + public CategoryInfoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.preference_dialog_library_categories_listitem, parent, false); + return new ViewHolder(view); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void onBindViewHolder(@NonNull CategoryInfoAdapter.ViewHolder holder, int position) { + CategoryInfo categoryInfo = categoryInfos.get(position); + + holder.checkBox.setChecked(categoryInfo.visible); + holder.title.setText(holder.title.getResources().getString(categoryInfo.category.stringRes)); + + holder.itemView.setOnClickListener(v -> { + if (!(categoryInfo.visible && isLastCheckedCategory(categoryInfo))) { + categoryInfo.visible = !categoryInfo.visible; + holder.checkBox.setChecked(categoryInfo.visible); + } else { + Toast.makeText(holder.itemView.getContext(), R.string.you_have_to_select_at_least_one_category, Toast.LENGTH_SHORT).show(); + } + }); + + holder.dragView.setOnTouchListener((view, event) -> { + if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { + touchHelper.startDrag(holder); + } + return false; + } + ); + } + + @Override + public int getItemCount() { + return categoryInfos.size(); + } + + @Override + public void onViewMoved(int oldPosition, int newPosition) { + CategoryInfo categoryInfo = categoryInfos.get(oldPosition); + categoryInfos.remove(oldPosition); + categoryInfos.add(newPosition, categoryInfo); + notifyItemMoved(oldPosition, newPosition); + } + + public void attachToRecyclerView(RecyclerView recyclerView) { + touchHelper.attachToRecyclerView(recyclerView); + } + + @NonNull + public List getCategoryInfos() { + return categoryInfos; + } + + public void setCategoryInfos(@NonNull List categoryInfos) { + this.categoryInfos = categoryInfos; + notifyDataSetChanged(); + } + + private boolean isLastCheckedCategory(CategoryInfo categoryInfo) { + if (categoryInfo.visible) { + for (CategoryInfo c : categoryInfos) { + if (c != categoryInfo && c.visible) return false; + } + } + return true; + } + + static class ViewHolder extends RecyclerView.ViewHolder { + CheckBox checkBox; + TextView title; + View dragView; + + ViewHolder(View view) { + super(view); + checkBox = view.findViewById(R.id.checkbox); + title = view.findViewById(R.id.title); + dragView = view.findViewById(R.id.drag_view); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt index 1e70dc29..e4d6febb 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt @@ -4,14 +4,12 @@ import android.app.Activity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup - -import java.util.ArrayList -import java.util.Locale import androidx.recyclerview.widget.RecyclerView import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder +import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.util.NavigationUtil +import java.util.* /** * @author Hemanth S (h4h13). @@ -40,10 +38,6 @@ class GenreAdapter(private val mActivity: Activity, dataSet: ArrayList, p else mActivity.getString(R.string.song)) } - - if (holder.separator != null) { - holder.separator!!.visibility = View.GONE - } } override fun getItemCount(): Int { @@ -56,14 +50,6 @@ class GenreAdapter(private val mActivity: Activity, dataSet: ArrayList, p } inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) { - init { - if (menu != null) { - menu!!.visibility = View.GONE - } - assert(imageContainer != null) - imageContainer!!.visibility = View.GONE - } - override fun onClick(v: View?) { super.onClick(v) val genre = dataSet[adapterPosition] diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt index 28f2ea3a..53a157ae 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt @@ -32,7 +32,6 @@ class HomeAdapter(private val activity: AppCompatActivity, private var homes: Li val layout = LayoutInflater.from(activity).inflate(R.layout.section_recycler_view, parent, false) return when (viewType) { RECENT_ARTISTS, TOP_ARTISTS -> ArtistViewHolder(layout) - GENRES -> GenreViewHolder(layout) PLAYLISTS -> PlaylistViewHolder(layout) else -> { AlbumViewHolder(LayoutInflater.from(activity).inflate(R.layout.metal_section_recycler_view, parent, false)) @@ -52,10 +51,6 @@ class HomeAdapter(private val activity: AppCompatActivity, private var homes: Li val viewHolder = holder as ArtistViewHolder viewHolder.bindView(home) } - GENRES -> { - val viewHolder = holder as GenreViewHolder - viewHolder.bindView(home) - } PLAYLISTS -> { val viewHolder = holder as PlaylistViewHolder viewHolder.bindView(home) @@ -108,20 +103,6 @@ class HomeAdapter(private val activity: AppCompatActivity, private var homes: Li chip.setChipIconResource(home.icon) } } - - private inner class GenreViewHolder(view: View) : AbsHomeViewItem(view) { - fun bindView(home: Home) { - recyclerView.apply { - val genreAdapter = GenreAdapter(activity, home.arrayList as ArrayList, R.layout.item_list) - layoutManager = LinearLayoutManager(context) - adapter = genreAdapter - - } - chip.text = activity.getString(home.title) - chip.setChipIconResource(home.icon) - } - } - private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) { fun bindView(home: Home) { val songs = PlaylistSongsLoader.getPlaylistSongList(activity, home.arrayList[0] as Playlist).blockingFirst() diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/AlbumsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/AlbumsFragment.kt index 2cf5c322..01cc1639 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/AlbumsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/AlbumsFragment.kt @@ -3,11 +3,11 @@ package code.name.monkey.retromusic.fragments.mainactivity import android.os.Bundle import androidx.recyclerview.widget.GridLayoutManager import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.adapter.album.AlbumAdapter +import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.mvp.contract.AlbumContract import code.name.monkey.retromusic.mvp.presenter.AlbumPresenter -import code.name.monkey.retromusic.adapter.album.AlbumAdapter -import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment import code.name.monkey.retromusic.util.PreferenceUtil open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment(), AlbumContract.AlbumView { @@ -95,23 +95,9 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment(), GenreContract.GenreView { + override fun loading() { + + } + + override fun showData(list: ArrayList) { + adapter?.swapDataSet(list) + } + + override fun showEmptyView() { + + } + + override fun completed() { + + } + + override fun createLayoutManager(): LinearLayoutManager { + return LinearLayoutManager(activity) + } + + override fun createAdapter(): GenreAdapter { + val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet + return GenreAdapter(libraryFragment.mainActivity, dataSet, R.layout.item_list_no_image) + } + + override val emptyMessage: Int + get() = R.string.no_genres + + private lateinit var presenter: GenrePresenter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + presenter = GenrePresenter(this) + } + + override fun onResume() { + super.onResume() + if (adapter!!.dataSet.isEmpty()) { + presenter.subscribe() + } + } + + override fun onDestroy() { + presenter.unsubscribe() + super.onDestroy() + } + + override fun onMediaStoreChanged() { + presenter.loadGenre() + } + + companion object { + + fun newInstance(): GenresFragment { + return GenresFragment() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java index c92d7260..326c7d47 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java @@ -1,7 +1,6 @@ package code.name.monkey.retromusic.fragments.mainactivity; import android.app.Activity; -import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; @@ -26,10 +25,11 @@ import com.google.android.material.card.MaterialCardView; import org.jetbrains.annotations.NotNull; +import java.util.Objects; + import code.name.monkey.appthemehelper.ThemeStore; import code.name.monkey.appthemehelper.common.ATHToolbarActivity; import code.name.monkey.appthemehelper.util.ATHUtil; -import code.name.monkey.appthemehelper.util.ColorUtil; import code.name.monkey.appthemehelper.util.TintHelper; import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper; import code.name.monkey.retromusic.R; @@ -137,6 +137,9 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde case R.id.action_playlist: selectedFragment(PlaylistsFragment.Companion.newInstance()); break; + case R.id.action_genre: + selectedFragment(GenresFragment.Companion.newInstance()); + break; } } @@ -144,13 +147,13 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde private void setupToolbar() { int primaryColor = ThemeStore.Companion.primaryColor(getContext()); TintHelper.setTintAuto(contentContainer, primaryColor, true); + appBarLayout.setBackgroundColor(primaryColor); toolbar.setBackgroundColor(RetroColorUtil.toolbarColor(getMainActivity())); toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp); toolbar.setOnClickListener(v -> { Pair pair = new Pair<>(toolbarContainer, getString(R.string.transition_toolbar)); NavigationUtil.goToSearch(getMainActivity(), pair); }); - appBarLayout.setBackgroundColor(primaryColor); appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> getMainActivity().setLightStatusbar(!ATHUtil.INSTANCE.isWindowBackgroundDark(getContext()))); getMainActivity().setSupportActionBar(toolbar); @@ -187,12 +190,12 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde if (cab != null && cab.isActive()) { cab.finish(); } - //noinspection ConstantConditions + cab = new MaterialCab(getMainActivity(), R.id.cab_stub) .setMenu(menuRes) .setCloseDrawableRes(R.drawable.ic_close_white_24dp) .setBackgroundColor( - RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.Companion.primaryColor(getActivity()))) + RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.Companion.primaryColor(Objects.requireNonNull(getActivity())))) .start(callback); return cab; } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/PlaylistsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/PlaylistsFragment.kt index 9f266d06..44d172cb 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/PlaylistsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/PlaylistsFragment.kt @@ -5,12 +5,11 @@ import android.view.Menu import android.view.MenuInflater import androidx.recyclerview.widget.LinearLayoutManager import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter +import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewFragment import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.mvp.contract.PlaylistContract import code.name.monkey.retromusic.mvp.presenter.PlaylistPresenter -import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter -import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewFragment -import code.name.monkey.retromusic.util.PreferenceUtil import java.util.* @@ -36,16 +35,8 @@ class PlaylistsFragment : AbsLibraryPagerRecyclerViewFragment dialogFragment = NowPlayingScreenPreferenceDialog.newInstance(preference.key) - is AlbumCoverStylePreference -> dialogFragment = AlbumCoverStylePreferenceDialog.newInstance(preference.key) + is LibraryPreference -> dialogFragment = LibraryPreferenceDialog.newInstance() + is NowPlayingScreenPreference -> dialogFragment = NowPlayingScreenPreferenceDialog.newInstance( ) + is AlbumCoverStylePreference -> dialogFragment = AlbumCoverStylePreferenceDialog.newInstance() is MaterialListPreference -> { preference.entries dialogFragment = MaterialListPreferenceDialog.newInstance(preference) diff --git a/app/src/main/java/code/name/monkey/retromusic/model/CategoryInfo.java b/app/src/main/java/code/name/monkey/retromusic/model/CategoryInfo.java new file mode 100644 index 00000000..3916f1f9 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/model/CategoryInfo.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019 Hemanth Savarala. + * + * Licensed under the GNU General Public License v3 + * + * This is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by + * the Free Software Foundation either version 3 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + */ + +package code.name.monkey.retromusic.model; + +import android.os.Parcel; +import android.os.Parcelable; + +import code.name.monkey.retromusic.R; + + +public class CategoryInfo implements Parcelable { + public static final Creator CREATOR = new Creator() { + public CategoryInfo createFromParcel(Parcel source) { + return new CategoryInfo(source); + } + + public CategoryInfo[] newArray(int size) { + return new CategoryInfo[size]; + } + }; + public Category category; + public boolean visible; + + public CategoryInfo(Category category, boolean visible) { + this.category = category; + this.visible = visible; + } + + + private CategoryInfo(Parcel source) { + category = (Category) source.readSerializable(); + visible = source.readInt() == 1; + } + + @Override + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeSerializable(category); + dest.writeInt(visible ? 1 : 0); + } + + public enum Category { + HOME(R.id.action_home, R.string.home, R.drawable.toggle_home), + SONGS(R.id.action_song, R.string.songs, R.drawable.toggle_audiotrack), + ALBUMS(R.id.action_album, R.string.albums, R.drawable.toggle_album), + ARTISTS(R.id.action_artist, R.string.artists, R.drawable.toggle_artist), + PLAYLISTS(R.id.action_playlist, R.string.playlists, R.drawable.toggle_queue_music), + GENRES(R.id.action_genre, R.string.genres, R.drawable.toggle_guitar); + + public final int stringRes; + public final int id; + public final int icon; + + Category(int id, int stringRes, int icon) { + this.stringRes = stringRes; + this.id = id; + this.icon = icon; + } + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/HomePresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/HomePresenter.kt index 83cb6f54..7b837ce0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/HomePresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/HomePresenter.kt @@ -42,7 +42,6 @@ class HomePresenter(private val view: HomeContract.HomeView) : Presenter(), Home loadTopArtists() loadATopAlbums() loadFavorite() - if (PreferenceUtil.getInstance().isGenreShown) loadGenre() } override fun subscribe() { @@ -102,14 +101,4 @@ class HomePresenter(private val view: HomeContract.HomeView) : Presenter(), Home view.showEmptyView() }) } - - private fun loadGenre() { - disposable += repository.allGenres - .subscribe({ - if (it.isNotEmpty()) hashSet.add(Home(6, R.string.genres, 0, it, GENRES, R.drawable.ic_guitar_acoustic_white_24dp)) - view.showData(ArrayList(hashSet)) - }, { - view.showEmptyView() - }) - } } diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/AlbumCoverStylePreferenceDialog.kt b/app/src/main/java/code/name/monkey/retromusic/preferences/AlbumCoverStylePreferenceDialog.kt index 59e5c8e3..33b4a57a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/preferences/AlbumCoverStylePreferenceDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/preferences/AlbumCoverStylePreferenceDialog.kt @@ -33,7 +33,6 @@ import code.name.monkey.retromusic.fragments.AlbumCoverStyle import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.ViewUtil import com.afollestad.materialdialogs.MaterialDialog -import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.customview.customView import com.bumptech.glide.Glide @@ -131,14 +130,8 @@ class AlbumCoverStylePreferenceDialog : PreferenceDialogFragmentCompat(), ViewPa companion object { val TAG: String = AlbumCoverStylePreferenceDialog::class.java.simpleName - private const val EXTRA_KEY = "key" - - fun newInstance(key: String): AlbumCoverStylePreferenceDialog { - val args = Bundle() - args.putString(EXTRA_KEY, key) - val fragment = AlbumCoverStylePreferenceDialog() - fragment.arguments = args - return fragment + fun newInstance(): AlbumCoverStylePreferenceDialog { + return AlbumCoverStylePreferenceDialog() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/BlacklistPreferenceDialog.kt b/app/src/main/java/code/name/monkey/retromusic/preferences/BlacklistPreferenceDialog.kt index 31bcd508..788b2606 100644 --- a/app/src/main/java/code/name/monkey/retromusic/preferences/BlacklistPreferenceDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/preferences/BlacklistPreferenceDialog.kt @@ -23,6 +23,7 @@ import android.util.AttributeSet import androidx.fragment.app.DialogFragment import androidx.preference.DialogPreference import code.name.monkey.appthemehelper.ThemeStore +import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference import code.name.monkey.retromusic.R import code.name.monkey.retromusic.dialogs.BlacklistFolderChooserDialog import code.name.monkey.retromusic.providers.BlacklistStore @@ -32,7 +33,7 @@ import com.afollestad.materialdialogs.list.listItems import java.io.File import java.util.* -class BlacklistPreference : DialogPreference { +class BlacklistPreference : ATEDialogPreference { constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet) : super(context, attrs) diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/LibraryPreference.kt b/app/src/main/java/code/name/monkey/retromusic/preferences/LibraryPreference.kt new file mode 100644 index 00000000..8dd8d7e8 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/preferences/LibraryPreference.kt @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019 Hemanth Savarala. + * + * Licensed under the GNU General Public License v3 + * + * This is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by + * the Free Software Foundation either version 3 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + */ + +package code.name.monkey.retromusic.preferences + +import android.app.Dialog +import android.content.Context +import android.graphics.PorterDuff +import android.os.Bundle +import android.util.AttributeSet +import android.widget.Toast +import androidx.fragment.app.DialogFragment +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import code.name.monkey.appthemehelper.ThemeStore +import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference +import code.name.monkey.retromusic.adapter.CategoryInfoAdapter +import code.name.monkey.retromusic.model.CategoryInfo +import code.name.monkey.retromusic.util.PreferenceUtil +import com.afollestad.materialdialogs.MaterialDialog +import com.afollestad.materialdialogs.bottomsheets.BottomSheet +import com.afollestad.materialdialogs.customview.customView +import java.util.* + + +class LibraryPreference : ATEDialogPreference { + constructor(context: Context) : super(context) {} + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {} + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {} + + init { + icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN) + } +} + +class LibraryPreferenceDialog : DialogFragment() { + lateinit var adapter: CategoryInfoAdapter + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val view = activity!!.layoutInflater.inflate(code.name.monkey.retromusic.R.layout.preference_dialog_library_categories, null) + + val categoryInfos: List + if (savedInstanceState != null) { + categoryInfos = savedInstanceState.getParcelableArrayList(PreferenceUtil.LIBRARY_CATEGORIES) + } else { + categoryInfos = PreferenceUtil.getInstance().getLibraryCategoryInfos() + } + adapter = CategoryInfoAdapter(categoryInfos) + + val recyclerView = view.findViewById(code.name.monkey.retromusic.R.id.recycler_view) + recyclerView.layoutManager = LinearLayoutManager(activity) + recyclerView.adapter = adapter + + adapter.attachToRecyclerView(recyclerView) + + + return MaterialDialog(context!!, BottomSheet()) + .title(code.name.monkey.retromusic.R.string.library_categories) + .customView(view = view) + .positiveButton(android.R.string.ok) { + updateCategories(adapter.categoryInfos) + dismiss() + } + .negativeButton(android.R.string.cancel) { + dismiss() + } + .neutralButton(code.name.monkey.retromusic.R.string.reset_action) { + adapter.categoryInfos = PreferenceUtil.getInstance().defaultLibraryCategoryInfos + } + .noAutoDismiss() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putParcelableArrayList(PreferenceUtil.LIBRARY_CATEGORIES, ArrayList(adapter.categoryInfos)) + } + + private fun updateCategories(categories: List) { + if (getSelected(categories) == 0) return + if (getSelected(categories) > 5) { + Toast.makeText(context, "Not more than 5 items", Toast.LENGTH_SHORT).show() + return + } + PreferenceUtil.getInstance().libraryCategoryInfos = categories + } + + private fun getSelected(categories: List): Int { + var selected = 0 + for (categoryInfo in categories) { + if (categoryInfo.visible) + selected++ + } + return selected + } + + companion object { + + fun newInstance(): LibraryPreferenceDialog { + return LibraryPreferenceDialog() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.kt b/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.kt index aa4110c6..d234d335 100644 --- a/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.kt @@ -124,14 +124,10 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP } companion object { - private const val EXTRA_KEY = "key" - fun newInstance(key: String): NowPlayingScreenPreferenceDialog { - val args = Bundle() - args.putString(EXTRA_KEY, key) - val fragment = NowPlayingScreenPreferenceDialog() - fragment.arguments = args - return fragment + + fun newInstance(): NowPlayingScreenPreferenceDialog { + return NowPlayingScreenPreferenceDialog() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt index 829e170d..559568b8 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt +++ b/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt @@ -58,6 +58,7 @@ class CustomArtistImageUtil private constructor(context: Context) { @SuppressLint("ApplySharedPref") override fun doInBackground(vararg params: Void): Void? { val dir = File(App.context.filesDir, FOLDER_NAME) + println(dir.absolutePath) if (!dir.exists()) { if (!dir.mkdirs()) { // create the folder return null diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java index 591e0204..56105406 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java @@ -27,8 +27,14 @@ import androidx.annotation.StyleRes; import androidx.viewpager.widget.ViewPager; import com.google.android.material.bottomnavigation.LabelVisibilityMode; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; import java.io.File; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import code.name.monkey.retromusic.App; @@ -38,6 +44,7 @@ import code.name.monkey.retromusic.fragments.AlbumCoverStyle; import code.name.monkey.retromusic.fragments.NowPlayingScreen; import code.name.monkey.retromusic.fragments.mainactivity.folders.FoldersFragment; import code.name.monkey.retromusic.helper.SortOrder; +import code.name.monkey.retromusic.model.CategoryInfo; import code.name.monkey.retromusic.transform.CascadingPageTransformer; import code.name.monkey.retromusic.transform.DepthTransformation; import code.name.monkey.retromusic.transform.HingeTransformation; @@ -47,7 +54,7 @@ import code.name.monkey.retromusic.transform.VerticalFlipTransformation; import code.name.monkey.retromusic.transform.VerticalStackTransformer; public final class PreferenceUtil { - + public static final String LIBRARY_CATEGORIES = "library_categories"; public static final String KEEP_SCREEN_ON = "keep_screen_on"; public static final String TOGGLE_HOME_BANNER = "toggle_home_banner"; public static final String NOW_PLAYING_SCREEN_ID = "now_playing_screen_id"; @@ -812,4 +819,44 @@ public final class PreferenceUtil { public boolean isClickOrSave() { return mPreferences.getBoolean(NOW_PLAYING_SCREEN, false); } + + @NonNull + public List getLibraryCategoryInfos() { + String data = mPreferences.getString(LIBRARY_CATEGORIES, null); + if (data != null) { + Gson gson = new Gson(); + Type collectionType = new TypeToken>() { + }.getType(); + + try { + return gson.fromJson(data, collectionType); + } catch (JsonSyntaxException e) { + e.printStackTrace(); + } + } + + return getDefaultLibraryCategoryInfos(); + } + + public void setLibraryCategoryInfos(List categories) { + Gson gson = new Gson(); + Type collectionType = new TypeToken>() { + }.getType(); + + final SharedPreferences.Editor editor = mPreferences.edit(); + editor.putString(LIBRARY_CATEGORIES, gson.toJson(categories, collectionType)); + editor.apply(); + } + + @NonNull + public List getDefaultLibraryCategoryInfos() { + List defaultCategoryInfos = new ArrayList<>(6); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.HOME, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.SONGS, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.ALBUMS, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.ARTISTS, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.PLAYLISTS, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.GENRES, false)); + return defaultCategoryInfos; + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/util/RetroColorUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/RetroColorUtil.java index 220b4fc3..8eab3524 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/RetroColorUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/RetroColorUtil.java @@ -195,6 +195,13 @@ public class RetroColorUtil { return backgroundColor; } + @ColorInt + public static int shiftBackgroundColorForDarkText(@ColorInt int backgroundColor) { + while (!ColorUtil.INSTANCE.isColorLight(backgroundColor)) { + backgroundColor = ColorUtil.INSTANCE.lightenColor(backgroundColor); + } + return backgroundColor; + } private static class SwatchComparator implements Comparator { diff --git a/app/src/main/java/code/name/monkey/retromusic/util/SwipeAndDragHelper.java b/app/src/main/java/code/name/monkey/retromusic/util/SwipeAndDragHelper.java new file mode 100644 index 00000000..1e2c82ba --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/util/SwipeAndDragHelper.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2019 Hemanth Savarala. + * + * Licensed under the GNU General Public License v3 + * + * This is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by + * the Free Software Foundation either version 3 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + */ + +package code.name.monkey.retromusic.util; + +import android.graphics.Canvas; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.ItemTouchHelper; + +public class SwipeAndDragHelper extends ItemTouchHelper.Callback { + + private ActionCompletionContract contract; + + public SwipeAndDragHelper(ActionCompletionContract contract) { + this.contract = contract; + } + + @Override + public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; + return makeMovementFlags(dragFlags, 0); + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { + contract.onViewMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition()); + return true; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + } + + @Override + public boolean isLongPressDragEnabled() { + return false; + } + + @Override + public void onChildDraw(Canvas c, + RecyclerView recyclerView, + RecyclerView.ViewHolder viewHolder, + float dX, + float dY, + int actionState, + boolean isCurrentlyActive) { + if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { + float alpha = 1 - (Math.abs(dX) / recyclerView.getWidth()); + viewHolder.itemView.setAlpha(alpha); + } + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + } + + public interface ActionCompletionContract { + void onViewMoved(int oldPosition, int newPosition); + } + +} + diff --git a/app/src/main/res/drawable/ic_guitar_acoustic_white_24dp.xml b/app/src/main/res/drawable/ic_guitar_acoustic_white_24dp.xml index 01d22f1e..ee5d963b 100644 --- a/app/src/main/res/drawable/ic_guitar_acoustic_white_24dp.xml +++ b/app/src/main/res/drawable/ic_guitar_acoustic_white_24dp.xml @@ -1,10 +1,17 @@ - + + android:viewportWidth="511.999" + android:viewportHeight="511.999"> + + android:pathData="M276.503 421.573c5.687-26.889 21.401-49.915 44.245-64.834 19.137-12.495 30.74-29.04 33.555-47.846 3.149-21.04-4.592-44.418-23.022-69.629l64.952-64.949-58.682-58.682-65.311 65.315c-24.124-16.967-46.712-24.068-67.286-21.117-18.947 2.72-35.843 14.104-48.864 32.926-15.481 22.39-38.441 37.471-64.657 42.467-25.764 4.921-43.684 12.515-54.784 23.212-23.097 22.258-36.062 54.037-36.506 89.484-0.53 42.25 16.932 85.486 46.71 115.656 29.794 30.185 72.705 48.286 114.787 48.421 0.162 0.001 0.318 0 0.48 0 35.187-0.001 67.001-12.443 89.616-35.062 11.137-11.137 19.239-29.245 24.767-55.362zm-127.857 1.924c-3.839 0-7.678-1.464-10.607-4.393l-45.276-45.276c-5.858-5.858-5.858-15.355 0-21.213 5.857-5.858 15.355-5.858 21.213 0l45.276 45.276c5.858 5.858 5.858 15.355 0 21.213-2.929 2.929-6.768 4.393-10.606 4.393zm64.261-74.466c-12.827 0-25.653-4.88-35.422-14.641-19.529-19.544-19.527-51.322-0.004-70.847 8.539-8.539 19.875-13.705 31.921-14.547 14.474-1.02 28.658 4.281 38.923 14.547 10.266 10.265 15.567 24.455 14.546 38.932-0.834 12.032-5.999 23.364-14.547 31.911-9.762 9.763-22.59 14.645-35.417 14.645z" /> + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_guitar_white_24dp.xml b/app/src/main/res/drawable/ic_guitar_white_24dp.xml new file mode 100644 index 00000000..e5ca181e --- /dev/null +++ b/app/src/main/res/drawable/ic_guitar_white_24dp.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/toggle_album.xml b/app/src/main/res/drawable/toggle_album.xml index 71a54f73..d4838d2d 100644 --- a/app/src/main/res/drawable/toggle_album.xml +++ b/app/src/main/res/drawable/toggle_album.xml @@ -1,4 +1,17 @@ - + + diff --git a/app/src/main/res/drawable/toggle_artist.xml b/app/src/main/res/drawable/toggle_artist.xml index bcdcde7f..46802416 100644 --- a/app/src/main/res/drawable/toggle_artist.xml +++ b/app/src/main/res/drawable/toggle_artist.xml @@ -1,4 +1,18 @@ + + diff --git a/app/src/main/res/drawable/toggle_audiotrack.xml b/app/src/main/res/drawable/toggle_audiotrack.xml index 3f400c6c..57e16d19 100644 --- a/app/src/main/res/drawable/toggle_audiotrack.xml +++ b/app/src/main/res/drawable/toggle_audiotrack.xml @@ -1,4 +1,18 @@ + + diff --git a/app/src/main/res/drawable/toggle_guitar.xml b/app/src/main/res/drawable/toggle_guitar.xml new file mode 100644 index 00000000..954adb12 --- /dev/null +++ b/app/src/main/res/drawable/toggle_guitar.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/toggle_home.xml b/app/src/main/res/drawable/toggle_home.xml index b97748a6..0574dc92 100644 --- a/app/src/main/res/drawable/toggle_home.xml +++ b/app/src/main/res/drawable/toggle_home.xml @@ -1,4 +1,18 @@ + + diff --git a/app/src/main/res/drawable/toggle_queue_music.xml b/app/src/main/res/drawable/toggle_queue_music.xml index 391986f0..7e9fbf2b 100644 --- a/app/src/main/res/drawable/toggle_queue_music.xml +++ b/app/src/main/res/drawable/toggle_queue_music.xml @@ -1,4 +1,18 @@ + + diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml index 536c19ac..7fc5b06d 100644 --- a/app/src/main/res/layout/fragment_library.xml +++ b/app/src/main/res/layout/fragment_library.xml @@ -50,12 +50,13 @@ android:id="@+id/toolbar" style="@style/Toolbar" app:titleMarginStart="0dp" + app:title="@string/library" tools:ignore="UnusedAttribute" /> + android:layout_height="48dp" /> diff --git a/app/src/main/res/layout/item_list_no_image.xml b/app/src/main/res/layout/item_list_no_image.xml new file mode 100644 index 00000000..1047979e --- /dev/null +++ b/app/src/main/res/layout/item_list_no_image.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/preference_dialog_library_categories.xml b/app/src/main/res/layout/preference_dialog_library_categories.xml new file mode 100644 index 00000000..1b758214 --- /dev/null +++ b/app/src/main/res/layout/preference_dialog_library_categories.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml new file mode 100644 index 00000000..fee28556 --- /dev/null +++ b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index dbd81b7f..9f93a55c 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -2,8 +2,7 @@ - - + @@ -17,7 +16,6 @@ - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 66b740c4..f5f10d4a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,6 @@ + You have to select at least one category. Small album Accent color The theme accent color, defaults to teal @@ -601,6 +602,7 @@ Pick image Set a profile photo Edit + Library Swipe to unlock Add lyrics Paste lyrics here @@ -625,4 +627,7 @@ Play all Start playing music. Keyboard + Reset + Library categories + Configure visibility and order of library categories. diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7cd659e7..d32fe0da 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -28,7 +28,7 @@