diff --git a/app/build.gradle b/app/build.gradle index f12388f0..741823af 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -133,8 +133,8 @@ dependencies { implementation "com.afollestad.material-dialogs:input:$material_dialog_version" implementation "com.afollestad.material-dialogs:color:$material_dialog_version" implementation "com.afollestad.material-dialogs:bottomsheets:$material_dialog_version" - //noinspection GradleDependency - implementation 'com.afollestad:material-cab:0.1.12' + + implementation 'com.afollestad:material-cab:2.0.1' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" @@ -159,6 +159,7 @@ dependencies { implementation 'com.heinrichreimersoftware:material-intro:2.0.0' implementation 'com.github.dhaval2404:imagepicker:1.7.1' implementation 'me.zhanghai.android.fastscroll:library:1.1.7' + implementation "com.github.YvesCheung.RollingText:RollingText:1.2.10" implementation 'cat.ereza:customactivityoncrash:2.3.0' debugImplementation 'com.amitshekhar.android:debug-db:1.0.6' } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/base/AbsMultiSelectAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/base/AbsMultiSelectAdapter.kt index ccffec7e..486a8b97 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/base/AbsMultiSelectAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/base/AbsMultiSelectAdapter.kt @@ -8,46 +8,38 @@ import androidx.fragment.app.FragmentActivity import androidx.recyclerview.widget.RecyclerView import code.name.monkey.retromusic.R import code.name.monkey.retromusic.extensions.surfaceColor +import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.util.ColorAnimUtil import code.name.monkey.retromusic.util.RetroColorUtil -import com.afollestad.materialcab.MaterialCab +import com.afollestad.materialcab.attached.AttachedCab +import com.afollestad.materialcab.attached.destroy +import com.afollestad.materialcab.attached.isActive import java.util.* abstract class AbsMultiSelectAdapter( open val activity: FragmentActivity, private val ICabHolder: ICabHolder?, @MenuRes menuRes: Int -) : RecyclerView.Adapter(), MaterialCab.Callback { - private var cab: MaterialCab? = null +) : RecyclerView.Adapter(), ICabCallback { + private var cab: AttachedCab? = null private val checked: MutableList private var menuRes: Int - override fun onCabCreated(materialCab: MaterialCab, menu: Menu): Boolean { - // Animate the color change - ColorAnimUtil.createColorAnimator( - activity.surfaceColor(), - RetroColorUtil.shiftBackgroundColor(activity.surfaceColor()) - ).apply { - addUpdateListener { - // Change color of status bar too - activity.window.statusBarColor = animatedValue as Int - materialCab.setBackgroundColor(animatedValue as Int) - } - start() - } + override fun onCabCreated(cab: AttachedCab, menu: Menu): Boolean { + return true } - override fun onCabFinished(materialCab: MaterialCab): Boolean { + override fun onCabFinished(cab: AttachedCab): Boolean { clearChecked() activity.window.statusBarColor = Color.TRANSPARENT return true } - override fun onCabItemClicked(menuItem: MenuItem): Boolean { - if (menuItem.itemId == R.id.action_multi_select_adapter_check_all) { + override fun onCabItemClicked(item: MenuItem): Boolean { + if (item.itemId == R.id.action_multi_select_adapter_check_all) { checkAll() } else { - onMultipleItemAction(menuItem, ArrayList(checked)) - cab?.finish() + onMultipleItemAction(item, ArrayList(checked)) + cab?.destroy() clearChecked() } return true @@ -77,7 +69,7 @@ abstract class AbsMultiSelectAdapter( } protected val isInQuickSelectMode: Boolean - get() = cab != null && cab!!.isActive + get() = cab != null && cab!!.isActive() protected abstract fun onMultipleItemAction(menuItem: MenuItem, selection: List) protected fun setMultiSelectMenuRes(@MenuRes menuRes: Int) { @@ -104,19 +96,19 @@ abstract class AbsMultiSelectAdapter( private fun updateCab() { if (ICabHolder != null) { - if (cab == null || !cab!!.isActive) { + if (cab == null || !cab!!.isActive()) { cab = ICabHolder.openCab(menuRes, this) } val size = checked.size when { size <= 0 -> { - cab?.finish() + cab?.destroy() } size == 1 -> { - cab?.setTitle(getName(checked[0])) + cab?.title(literal = getName(checked[0])) } else -> { - cab?.setTitle(activity.getString(R.string.x_selected, size)) + cab?.title(literal = activity.getString(R.string.x_selected, size)) } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt index bab50620..eeef000f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt @@ -37,12 +37,12 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.helper.menu.SongMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper +import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.color.MediaNotificationProcessor -import com.afollestad.materialcab.MaterialCab import me.zhanghai.android.fastscroll.PopupTextProvider /** @@ -59,7 +59,7 @@ open class SongAdapter( activity, ICabHolder, R.menu.menu_media_selection -), MaterialCab.Callback, PopupTextProvider { +), ICabCallback, PopupTextProvider { private var showSectionName = true diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt index c9291185..7956880c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt @@ -57,6 +57,7 @@ import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder.Companion import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder.Companion.SONG_TRACK_LIST import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder.Companion.SONG_Z_A import code.name.monkey.retromusic.interfaces.IAlbumClickListener +import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Artist @@ -68,7 +69,10 @@ import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.color.MediaNotificationProcessor -import com.afollestad.materialcab.MaterialCab +import com.afollestad.materialcab.attached.AttachedCab +import com.afollestad.materialcab.attached.destroy +import com.afollestad.materialcab.attached.isActive +import com.afollestad.materialcab.createCab import com.google.android.material.transition.MaterialArcMotion import com.google.android.material.transition.MaterialContainerTransform import kotlinx.coroutines.Dispatchers @@ -450,28 +454,34 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det private fun handleBackPress(): Boolean { cab?.let { - if (it.isActive) { - it.finish() + if (it.isActive()) { + it.destroy() return true } } return false } - private var cab: MaterialCab? = null + private var cab: AttachedCab? = null - override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab { + override fun openCab(menuRes: Int, callback: ICabCallback): AttachedCab { cab?.let { - if (it.isActive) { - it.finish() + if (it.isActive()) { + it.destroy() } } - cab = MaterialCab(mainActivity, R.id.cab_stub) - .setMenu(menuRes) - .setCloseDrawableRes(R.drawable.ic_close) - .setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor())) - .start(callback) - return cab as MaterialCab + cab = createCab(R.id.cab_stub) { + menu(menuRes) + closeDrawable(R.drawable.ic_close) + backgroundColor(literal = RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor())) + slideDown() + onCreate { cab, menu -> callback.onCabCreated(cab, menu) } + onSelection { + callback.onCabItemClicked(it) + } + onDestroy { callback.onCabFinished(it) } + } + return cab as AttachedCab } override fun onDestroyView() { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt index 92a372fe..cd7b1baa 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt @@ -29,11 +29,15 @@ import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment import code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder import code.name.monkey.retromusic.interfaces.IAlbumClickListener +import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroUtil -import com.afollestad.materialcab.MaterialCab +import com.afollestad.materialcab.attached.AttachedCab +import com.afollestad.materialcab.attached.destroy +import com.afollestad.materialcab.attached.isActive +import com.afollestad.materialcab.createCab import com.google.android.gms.cast.framework.CastButtonFactory class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment(), @@ -325,28 +329,34 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment callback.onCabCreated(cab, menu) } + onSelection { + callback.onCabItemClicked(it) + } + onDestroy { callback.onCabFinished(it) } + } + return cab as AttachedCab } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt index e02cbb31..fc8e398c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt @@ -33,6 +33,7 @@ import code.name.monkey.retromusic.glide.RetroGlideExtension import code.name.monkey.retromusic.glide.SingleColorTarget import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.interfaces.IAlbumClickListener +import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.network.Result @@ -42,7 +43,10 @@ import code.name.monkey.retromusic.util.CustomArtistImageUtil import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroUtil -import com.afollestad.materialcab.MaterialCab +import com.afollestad.materialcab.attached.AttachedCab +import com.afollestad.materialcab.attached.destroy +import com.afollestad.materialcab.attached.isActive +import com.afollestad.materialcab.createCab import com.google.android.material.transition.MaterialContainerTransform import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -306,28 +310,34 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm private fun handleBackPress(): Boolean { cab?.let { - if (it.isActive) { - it.finish() + if (it.isActive()) { + it.destroy() return true } } return false } - private var cab: MaterialCab? = null + private var cab: AttachedCab? = null - override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab { + override fun openCab(menuRes: Int, callback: ICabCallback): AttachedCab { cab?.let { - if (it.isActive) { - it.finish() + if (it.isActive()) { + it.destroy() } } - cab = MaterialCab(mainActivity, R.id.cab_stub) - .setMenu(menuRes) - .setCloseDrawableRes(R.drawable.ic_close) - .setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor())) - .start(callback) - return cab as MaterialCab + cab = createCab(R.id.cab_stub) { + menu(menuRes) + closeDrawable(R.drawable.ic_close) + backgroundColor(literal = RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor())) + slideDown() + onCreate { cab, menu -> callback.onCabCreated(cab, menu) } + onSelection { + callback.onCabItemClicked(it) + } + onDestroy { callback.onCabFinished(it) } + } + return cab as AttachedCab } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistsFragment.kt index 8275c526..9bec93f4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistsFragment.kt @@ -31,11 +31,15 @@ import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeF import code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder import code.name.monkey.retromusic.interfaces.IAlbumArtistClickListener import code.name.monkey.retromusic.interfaces.IArtistClickListener +import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroUtil -import com.afollestad.materialcab.MaterialCab +import com.afollestad.materialcab.attached.AttachedCab +import com.afollestad.materialcab.attached.destroy +import com.afollestad.materialcab.attached.isActive +import com.afollestad.materialcab.createCab import com.google.android.gms.cast.framework.CastButtonFactory class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment(), @@ -324,28 +328,34 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment callback.onCabCreated(cab, menu) } + onSelection { + callback.onCabItemClicked(it) + } + onDestroy { callback.onCabFinished(it) } + } + return cab as AttachedCab } override fun onResume() { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt index d9803ac7..620432c1 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt @@ -11,932 +11,805 @@ * 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.fragments.folder -package code.name.monkey.retromusic.fragments.folder; +import android.app.Dialog +import android.content.Context +import android.media.MediaScannerConnection +import android.os.Bundle +import android.os.Environment +import android.text.Html +import android.view.* +import android.webkit.MimeTypeMap +import android.widget.PopupMenu +import android.widget.Toast +import androidx.activity.OnBackPressedCallback +import androidx.loader.app.LoaderManager +import androidx.loader.content.Loader +import androidx.navigation.Navigation.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor +import code.name.monkey.appthemehelper.common.ATHToolbarActivity +import code.name.monkey.appthemehelper.util.ATHUtil.resolveColor +import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper +import code.name.monkey.retromusic.App +import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.adapter.SongFileAdapter +import code.name.monkey.retromusic.adapter.Storage +import code.name.monkey.retromusic.adapter.StorageAdapter +import code.name.monkey.retromusic.adapter.StorageClickListener +import code.name.monkey.retromusic.databinding.FragmentFolderBinding +import code.name.monkey.retromusic.extensions.surfaceColor +import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment +import code.name.monkey.retromusic.fragments.folder.FoldersFragment.ListPathsAsyncTask.OnPathsListedCallback +import code.name.monkey.retromusic.fragments.folder.FoldersFragment.ListSongsAsyncTask.OnSongsListedCallback +import code.name.monkey.retromusic.helper.MusicPlayerRemote.openQueue +import code.name.monkey.retromusic.helper.MusicPlayerRemote.playingQueue +import code.name.monkey.retromusic.helper.menu.SongMenuHelper.handleMenuClick +import code.name.monkey.retromusic.helper.menu.SongsMenuHelper +import code.name.monkey.retromusic.interfaces.ICabCallback +import code.name.monkey.retromusic.interfaces.ICabHolder +import code.name.monkey.retromusic.interfaces.ICallbacks +import code.name.monkey.retromusic.interfaces.IMainActivityFragmentCallbacks +import code.name.monkey.retromusic.misc.DialogAsyncTask +import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener +import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.providers.BlacklistStore +import code.name.monkey.retromusic.util.* +import code.name.monkey.retromusic.util.DensityUtil.dip2px +import code.name.monkey.retromusic.util.PreferenceUtil.startDirectory +import code.name.monkey.retromusic.util.ThemedFastScroller.create +import code.name.monkey.retromusic.views.BreadCrumbLayout.Crumb +import code.name.monkey.retromusic.views.BreadCrumbLayout.SelectionCallback +import code.name.monkey.retromusic.views.ScrollingViewOnApplyWindowInsetsListener +import com.afollestad.materialcab.attached.AttachedCab +import com.afollestad.materialcab.attached.destroy +import com.afollestad.materialcab.attached.isActive +import com.afollestad.materialcab.createCab +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar +import com.google.android.material.transition.MaterialFadeThrough +import com.google.android.material.transition.MaterialSharedAxis +import java.io.* +import java.lang.ref.WeakReference +import java.util.* -import static code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor; - -import android.app.Dialog; -import android.content.Context; -import android.media.MediaScannerConnection; -import android.os.Bundle; -import android.os.Environment; -import android.text.Html; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.MarginLayoutParams; -import android.webkit.MimeTypeMap; -import android.widget.PopupMenu; -import android.widget.Toast; - -import androidx.activity.OnBackPressedCallback; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.loader.app.LoaderManager; -import androidx.loader.content.Loader; -import androidx.navigation.Navigation; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.afollestad.materialcab.MaterialCab; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; -import com.google.android.material.transition.MaterialFadeThrough; -import com.google.android.material.transition.MaterialSharedAxis; - -import org.jetbrains.annotations.NotNull; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileFilter; -import java.io.FileReader; -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.StringTokenizer; - -import code.name.monkey.appthemehelper.ThemeStore; -import code.name.monkey.appthemehelper.util.ATHUtil; -import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper; -import code.name.monkey.retromusic.App; -import code.name.monkey.retromusic.R; -import code.name.monkey.retromusic.adapter.SongFileAdapter; -import code.name.monkey.retromusic.adapter.Storage; -import code.name.monkey.retromusic.adapter.StorageAdapter; -import code.name.monkey.retromusic.adapter.StorageClickListener; -import code.name.monkey.retromusic.databinding.FragmentFolderBinding; -import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment; -import code.name.monkey.retromusic.helper.MusicPlayerRemote; -import code.name.monkey.retromusic.helper.menu.SongMenuHelper; -import code.name.monkey.retromusic.helper.menu.SongsMenuHelper; -import code.name.monkey.retromusic.interfaces.ICabHolder; -import code.name.monkey.retromusic.interfaces.ICallbacks; -import code.name.monkey.retromusic.interfaces.IMainActivityFragmentCallbacks; -import code.name.monkey.retromusic.misc.DialogAsyncTask; -import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener; -import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader; -import code.name.monkey.retromusic.model.Song; -import code.name.monkey.retromusic.providers.BlacklistStore; -import code.name.monkey.retromusic.util.DensityUtil; -import code.name.monkey.retromusic.util.FileUtil; -import code.name.monkey.retromusic.util.PreferenceUtil; -import code.name.monkey.retromusic.util.RetroColorUtil; -import code.name.monkey.retromusic.util.ThemedFastScroller; -import code.name.monkey.retromusic.views.BreadCrumbLayout; -import code.name.monkey.retromusic.views.ScrollingViewOnApplyWindowInsetsListener; -import me.zhanghai.android.fastscroll.FastScroller; - -public class FoldersFragment extends AbsMainActivityFragment - implements IMainActivityFragmentCallbacks, - ICabHolder, - BreadCrumbLayout.SelectionCallback, - ICallbacks, - LoaderManager.LoaderCallbacks>, StorageClickListener { - - private FragmentFolderBinding binding; - public static final String TAG = FoldersFragment.class.getSimpleName(); - public static final FileFilter AUDIO_FILE_FILTER = - file -> - !file.isHidden() - && (file.isDirectory() - || FileUtil.fileIsMimeType(file, "audio/*", MimeTypeMap.getSingleton()) - || FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton()) - || FileUtil.fileIsMimeType(file, "application/ogg", MimeTypeMap.getSingleton())); - - private static final String CRUMBS = "crumbs"; - private static final int LOADER_ID = 5; - private SongFileAdapter adapter; - private StorageAdapter storageAdapter; - private MaterialCab cab; - private final Comparator fileComparator = - (lhs, rhs) -> { - if (lhs.isDirectory() && !rhs.isDirectory()) { - return -1; - } else if (!lhs.isDirectory() && rhs.isDirectory()) { - return 1; - } else { - return lhs.getName().compareToIgnoreCase(rhs.getName()); - } - }; - private final ArrayList storageItems = new ArrayList<>(); - - public FoldersFragment() { - super(R.layout.fragment_folder); - } - - public static File getDefaultStartDirectory() { - File musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); - File startFolder; - if (musicDir.exists() && musicDir.isDirectory()) { - startFolder = musicDir; +class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder), + IMainActivityFragmentCallbacks, ICabHolder, SelectionCallback, ICallbacks, + LoaderManager.LoaderCallbacks>, StorageClickListener { + private var _binding: FragmentFolderBinding? = null + private val binding get() = _binding!! + private var adapter: SongFileAdapter? = null + private var storageAdapter: StorageAdapter? = null + private var cab: AttachedCab? = null + private val fileComparator = Comparator { lhs: File, rhs: File -> + if (lhs.isDirectory && !rhs.isDirectory) { + return@Comparator -1 + } else if (!lhs.isDirectory && rhs.isDirectory) { + return@Comparator 1 } else { - File externalStorage = Environment.getExternalStorageDirectory(); - if (externalStorage.exists() && externalStorage.isDirectory()) { - startFolder = externalStorage; - } else { - startFolder = new File("/"); // root - } - } - return startFolder; - } - - private static File tryGetCanonicalFile(File file) { - try { - return file.getCanonicalFile(); - } catch (IOException e) { - e.printStackTrace(); - return file; + return@Comparator lhs.name.compareTo(rhs.name, ignoreCase = true) } } - - @NonNull - @Override - public View onCreateView( - @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - binding = FragmentFolderBinding.inflate(inflater, container, false); - return binding.getRoot(); + private val storageItems = ArrayList() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View { + _binding = FragmentFolderBinding.inflate(inflater, container, false) + return binding.root } - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - setEnterTransition(new MaterialFadeThrough()); - setExitTransition(new MaterialFadeThrough()); - getMainActivity().addMusicServiceEventListener(getLibraryViewModel()); - getMainActivity().setSupportActionBar(binding.toolbar); - getMainActivity().getSupportActionBar().setTitle(null); - setStatusBarColorAuto(view); - setUpAppbarColor(); - setUpBreadCrumbs(); - setUpRecyclerView(); - listRoots(); - setUpAdapter(); - setUpTitle(); - requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { - @Override - public void handleOnBackPressed() { - if (!handleBackPress()) { - remove(); - requireActivity().onBackPressed(); + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + enterTransition = MaterialFadeThrough() + exitTransition = MaterialFadeThrough() + mainActivity.addMusicServiceEventListener(libraryViewModel) + mainActivity.setSupportActionBar(binding.toolbar) + mainActivity.supportActionBar?.title = null + setStatusBarColorAuto(view) + setUpAppbarColor() + setUpBreadCrumbs() + setUpRecyclerView() + setUpAdapter() + setUpTitle() + requireActivity().onBackPressedDispatcher.addCallback( + viewLifecycleOwner, + object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + if (!handleBackPress()) { + remove() + requireActivity().onBackPressed() + } } - } - }); + }) } - private void setUpTitle() { - binding.toolbar.setNavigationOnClickListener( - v -> { - setExitTransition(new MaterialSharedAxis(MaterialSharedAxis.Z, true).setDuration(300)); - setReenterTransition(new MaterialSharedAxis(MaterialSharedAxis.Z, false).setDuration(300)); - Navigation.findNavController(v).navigate(R.id.searchFragment, null, getNavOptions()); - }); - binding.appNameText.setText(getResources().getString(R.string.folders)); + private fun setUpTitle() { + binding.toolbar.setNavigationOnClickListener { v: View? -> + exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).setDuration(300) + reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).setDuration(300) + findNavController(v!!).navigate(R.id.searchFragment, null, navOptions) + } + binding.appNameText.text = resources.getString(R.string.folders) } - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - setHasOptionsMenu(true); + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + setHasOptionsMenu(true) if (savedInstanceState == null) { - switchToFileAdapter(); + switchToFileAdapter() setCrumb( - new BreadCrumbLayout.Crumb( - FileUtil.safeGetCanonicalFile(PreferenceUtil.INSTANCE.getStartDirectory())), - true); - + Crumb( + FileUtil.safeGetCanonicalFile(startDirectory) + ), + true + ) } else { - binding.breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS)); - LoaderManager.getInstance(this).initLoader(LOADER_ID, null, this); + binding.breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS)) + LoaderManager.getInstance(this).initLoader(LOADER_ID, null, this) } } - @Override - public void onPause() { - super.onPause(); - saveScrollPosition(); + override fun onPause() { + super.onPause() + saveScrollPosition() } - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - if (binding != null) { - outState.putParcelable(CRUMBS, binding.breadCrumbs.getStateWrapper()); + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + if (_binding != null) { + outState.putParcelable(CRUMBS, binding.breadCrumbs.stateWrapper) } } - @Override - public boolean handleBackPress() { - if (cab != null && cab.isActive()) { - cab.finish(); - return true; + override fun handleBackPress(): Boolean { + if (cab != null && cab!!.isActive()) { + cab?.destroy() + return true } if (binding.breadCrumbs.popHistory()) { - setCrumb(binding.breadCrumbs.lastHistory(), false); - return true; + setCrumb(binding.breadCrumbs.lastHistory(), false) + return true } - return false; + return false } - @NonNull - @Override - public Loader> onCreateLoader(int id, Bundle args) { - return new AsyncFileLoader(this); + override fun onCreateLoader(id: Int, args: Bundle?): Loader> { + return AsyncFileLoader(this) } - @Override - public void onCrumbSelection(BreadCrumbLayout.Crumb crumb, int index) { - setCrumb(crumb, true); + override fun onCrumbSelection(crumb: Crumb, index: Int) { + setCrumb(crumb, true) } - @Override - public void onFileMenuClicked(final File file, @NotNull View view) { - PopupMenu popupMenu = new PopupMenu(getActivity(), view); - if (file.isDirectory()) { - popupMenu.inflate(R.menu.menu_item_directory); - popupMenu.setOnMenuItemClickListener( - item -> { - final int itemId = item.getItemId(); - switch (itemId) { - case R.id.action_play_next: - case R.id.action_add_to_current_playing: - case R.id.action_add_to_playlist: - case R.id.action_delete_from_device: - new ListSongsAsyncTask( - getActivity(), - null, - (songs, extra) -> { - if (!songs.isEmpty()) { - SongsMenuHelper.INSTANCE.handleMenuClick( - requireActivity(), songs, itemId); - } - }) - .execute( - new ListSongsAsyncTask.LoadingInfo( - toList(file), AUDIO_FILE_FILTER, getFileComparator())); - return true; - case R.id.action_add_to_blacklist: - BlacklistStore.getInstance(App.Companion.getContext()).addPath(file); - return true; - case R.id.action_set_as_start_directory: - PreferenceUtil.INSTANCE.setStartDirectory(file); - Toast.makeText( - getActivity(), - String.format(getString(R.string.new_start_directory), file.getPath()), - Toast.LENGTH_SHORT) - .show(); - return true; - case R.id.action_scan: - new ListPathsAsyncTask(getActivity(), this::scanPaths) - .execute(new ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER)); - return true; - } - return false; - }); + override fun onFileMenuClicked(file: File, view: View) { + val popupMenu = PopupMenu(activity, view) + if (file.isDirectory) { + popupMenu.inflate(R.menu.menu_item_directory) + popupMenu.setOnMenuItemClickListener { item: MenuItem -> + when (val itemId = item.itemId) { + R.id.action_play_next, R.id.action_add_to_current_playing, R.id.action_add_to_playlist, R.id.action_delete_from_device -> { + ListSongsAsyncTask( + activity, + null, + object : OnSongsListedCallback { + override fun onSongsListed(songs: List, extra: Any?) { + if (songs.isNotEmpty()) { + SongsMenuHelper.handleMenuClick( + requireActivity(), songs, itemId + ) + } + } + }) + .execute( + ListSongsAsyncTask.LoadingInfo( + toList(file), AUDIO_FILE_FILTER, fileComparator + ) + ) + return@setOnMenuItemClickListener true + } + R.id.action_add_to_blacklist -> { + BlacklistStore.getInstance(App.getContext()).addPath(file) + return@setOnMenuItemClickListener true + } + R.id.action_set_as_start_directory -> { + startDirectory = file + Toast.makeText( + activity, + String.format(getString(R.string.new_start_directory), file.path), + Toast.LENGTH_SHORT + ) + .show() + return@setOnMenuItemClickListener true + } + R.id.action_scan -> { + ListPathsAsyncTask( + activity, + object : OnPathsListedCallback { + override fun onPathsListed(paths: Array) { + scanPaths(paths) + } + }) + .execute(ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER)) + return@setOnMenuItemClickListener true + } + } + false + } } else { - popupMenu.inflate(R.menu.menu_item_file); - popupMenu.setOnMenuItemClickListener( - item -> { - final int itemId = item.getItemId(); - switch (itemId) { - case R.id.action_play_next: - case R.id.action_add_to_current_playing: - case R.id.action_add_to_playlist: - case R.id.action_go_to_album: - case R.id.action_go_to_artist: - case R.id.action_share: - case R.id.action_tag_editor: - case R.id.action_details: - case R.id.action_set_as_ringtone: - case R.id.action_delete_from_device: - new ListSongsAsyncTask( - getActivity(), - null, - (songs, extra) -> - SongMenuHelper.INSTANCE.handleMenuClick( - requireActivity(), songs.get(0), itemId)) - .execute( - new ListSongsAsyncTask.LoadingInfo( - toList(file), AUDIO_FILE_FILTER, getFileComparator())); - return true; - case R.id.action_scan: - new ListPathsAsyncTask(getActivity(), this::scanPaths) - .execute(new ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER)); - return true; - } - return false; - }); + popupMenu.inflate(R.menu.menu_item_file) + popupMenu.setOnMenuItemClickListener { item: MenuItem -> + when (val itemId = item.itemId) { + R.id.action_play_next, R.id.action_add_to_current_playing, R.id.action_add_to_playlist, R.id.action_go_to_album, R.id.action_go_to_artist, R.id.action_share, R.id.action_tag_editor, R.id.action_details, R.id.action_set_as_ringtone, R.id.action_delete_from_device -> { + ListSongsAsyncTask( + activity, + null, + object : OnSongsListedCallback { + override fun onSongsListed(songs: List, extra: Any?) { + handleMenuClick( + requireActivity(), songs[0], itemId + ) + } + }) + .execute( + ListSongsAsyncTask.LoadingInfo( + toList(file), AUDIO_FILE_FILTER, fileComparator + ) + ) + return@setOnMenuItemClickListener true + } + R.id.action_scan -> { + ListPathsAsyncTask( + activity, + object : OnPathsListedCallback { + override fun onPathsListed(paths: Array) { + scanPaths(paths) + } + }) + .execute(ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER)) + return@setOnMenuItemClickListener true + } + } + false + } } - popupMenu.show(); + popupMenu.show() } - @Override - public void onFileSelected(@NotNull File file) { - file = tryGetCanonicalFile(file); // important as we compare the path value later - if (file.isDirectory()) { - setCrumb(new BreadCrumbLayout.Crumb(file), true); + override fun onFileSelected(file: File) { + var mFile = file + mFile = tryGetCanonicalFile(mFile) // important as we compare the path value later + if (mFile.isDirectory) { + setCrumb(Crumb(mFile), true) } else { - FileFilter fileFilter = - pathname -> !pathname.isDirectory() && AUDIO_FILE_FILTER.accept(pathname); - new ListSongsAsyncTask( - getActivity(), - file, - (songs, extra) -> { - File file1 = (File) extra; - int startIndex = -1; - for (int i = 0; i < songs.size(); i++) { + val fileFilter = FileFilter { pathname: File -> + !pathname.isDirectory && AUDIO_FILE_FILTER.accept(pathname) + } + ListSongsAsyncTask( + activity, + mFile, + object : OnSongsListedCallback { + override fun onSongsListed(songs: List, extra: Any?) { + val file1 = extra as File + var startIndex = -1 + for (i in songs.indices) { if (file1 - .getPath() - .equals(songs.get(i).getData())) { // path is already canonical here - startIndex = i; - break; + .path + == songs[i].data + ) { // path is already canonical here + startIndex = i + break } } if (startIndex > -1) { - MusicPlayerRemote.openQueue(songs, startIndex, true); + openQueue(songs, startIndex, true) } else { - final File finalFile = file1; Snackbar.make( - binding.coordinatorLayout, - Html.fromHtml( - String.format( - getString(R.string.not_listed_in_media_store), file1.getName())), - Snackbar.LENGTH_LONG) - .setAction( - R.string.action_scan, - v -> - new ListPathsAsyncTask(requireActivity(), this::scanPaths) - .execute( - new ListPathsAsyncTask.LoadingInfo( - finalFile, AUDIO_FILE_FILTER))) - .setActionTextColor(ThemeStore.Companion.accentColor(requireActivity())) - .show(); + binding.coordinatorLayout, + Html.fromHtml( + String.format( + getString(R.string.not_listed_in_media_store), file1.name + ) + ), + Snackbar.LENGTH_LONG + ) + .setAction( + R.string.action_scan + ) { + ListPathsAsyncTask( + requireActivity(), + object : OnPathsListedCallback { + override fun onPathsListed(paths: Array) { + scanPaths(paths) + } + }) + .execute( + ListPathsAsyncTask.LoadingInfo( + file1, AUDIO_FILE_FILTER + ) + ) + } + .setActionTextColor(accentColor(requireActivity())) + .show() } - }) - .execute( - new ListSongsAsyncTask.LoadingInfo( - toList(file.getParentFile()), fileFilter, getFileComparator())); + } + }) + .execute( + ListSongsAsyncTask.LoadingInfo( + toList(mFile.parentFile), fileFilter, fileComparator + ) + ) } } - @Override - public void onLoadFinished(@NonNull Loader> loader, List data) { - updateAdapter(data); + override fun onLoadFinished(loader: Loader>, data: List) { + updateAdapter(data) } - @Override - public void onLoaderReset(@NonNull Loader> loader) { - updateAdapter(new LinkedList<>()); + override fun onLoaderReset(loader: Loader>) { + updateAdapter(LinkedList()) } - @Override - public void onMultipleItemAction(MenuItem item, @NotNull ArrayList files) { - final int itemId = item.getItemId(); - new ListSongsAsyncTask( - getActivity(), - null, - (songs, extra) -> - SongsMenuHelper.INSTANCE.handleMenuClick(requireActivity(), songs, itemId)) - .execute(new ListSongsAsyncTask.LoadingInfo(files, AUDIO_FILE_FILTER, getFileComparator())); - } - - @Override - public void onPrepareOptionsMenu(@NonNull Menu menu) { - super.onPrepareOptionsMenu(menu); - ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - menu.add(0, R.id.action_scan, 0, R.string.scan_media) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - menu.add(0, R.id.action_go_to_start_directory, 1, R.string.action_go_to_start_directory) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - menu.removeItem(R.id.action_grid_size); - menu.removeItem(R.id.action_layout_type); - menu.removeItem(R.id.action_sort_order); - ToolbarContentTintHelper.handleOnCreateOptionsMenu( - requireContext(), binding.toolbar, menu, getToolbarBackgroundColor(binding.toolbar)); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.action_go_to_start_directory: - setCrumb( - new BreadCrumbLayout.Crumb( - tryGetCanonicalFile(PreferenceUtil.INSTANCE.getStartDirectory())), - true); - return true; - case R.id.action_scan: - BreadCrumbLayout.Crumb crumb = getActiveCrumb(); - if (crumb != null) { - //noinspection Convert2MethodRef - new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths)) - .execute(new ListPathsAsyncTask.LoadingInfo(crumb.getFile(), AUDIO_FILE_FILTER)); + override fun onMultipleItemAction(item: MenuItem, files: ArrayList) { + val itemId = item.itemId + ListSongsAsyncTask( + activity, + null, + object : OnSongsListedCallback { + override fun onSongsListed(songs: List, extra: Any?) { + SongsMenuHelper.handleMenuClick( + requireActivity(), + songs, + itemId + ) } - return true; + }) + .execute(ListSongsAsyncTask.LoadingInfo(files, AUDIO_FILE_FILTER, fileComparator)) + } + + override fun onPrepareOptionsMenu(menu: Menu) { + super.onPrepareOptionsMenu(menu) + ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + super.onCreateOptionsMenu(menu, inflater) + menu.add(0, R.id.action_scan, 0, R.string.scan_media) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER) + menu.add(0, R.id.action_go_to_start_directory, 1, R.string.action_go_to_start_directory) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER) + menu.removeItem(R.id.action_grid_size) + menu.removeItem(R.id.action_layout_type) + menu.removeItem(R.id.action_sort_order) + ToolbarContentTintHelper.handleOnCreateOptionsMenu( + requireContext(), binding.toolbar, menu, ATHToolbarActivity.getToolbarBackgroundColor( + binding.toolbar + ) + ) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.action_go_to_start_directory -> { + setCrumb( + Crumb( + tryGetCanonicalFile(startDirectory) + ), + true + ) + return true + } + R.id.action_scan -> { + val crumb = activeCrumb + if (crumb != null) { + ListPathsAsyncTask( + activity, + object : OnPathsListedCallback { + override fun onPathsListed(paths: Array) { + scanPaths(paths) + } + }) + .execute(ListPathsAsyncTask.LoadingInfo(crumb.file, AUDIO_FILE_FILTER)) + } + return true + } } - return super.onOptionsItemSelected(item); + return super.onOptionsItemSelected(item) } - @Override - public void onQueueChanged() { - super.onQueueChanged(); - checkForPadding(); + override fun onQueueChanged() { + super.onQueueChanged() + checkForPadding() } - @Override - public void onServiceConnected() { - super.onServiceConnected(); - checkForPadding(); + override fun onServiceConnected() { + super.onServiceConnected() + checkForPadding() } - @NonNull - @Override - public MaterialCab openCab(int menuRes, @NotNull MaterialCab.Callback callback) { - if (cab != null && cab.isActive()) { - cab.finish(); + override fun openCab(menuRes: Int, callback: ICabCallback): AttachedCab { + if (cab != null && cab!!.isActive()) { + cab?.destroy() } - cab = - new MaterialCab(getMainActivity(), R.id.cab_stub) - .setMenu(menuRes) - .setCloseDrawableRes(R.drawable.ic_close) - .setBackgroundColor( - RetroColorUtil.shiftBackgroundColorForLightText( - ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorSurface))) - .start(callback); - return cab; + cab = createCab(R.id.cab_stub) { + menu(menuRes) + closeDrawable(R.drawable.ic_close) + backgroundColor(literal = RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor())) + slideDown() + onCreate { cab, menu -> callback.onCabCreated(cab, menu) } + onSelection { + callback.onCabItemClicked(it) + } + onDestroy { callback.onCabFinished(it) } + } + return cab as AttachedCab } - private void checkForPadding() { - final int count = adapter.getItemCount(); - if (binding != null) { - final MarginLayoutParams params = (MarginLayoutParams) binding.coordinatorLayout.getLayoutParams(); - params.bottomMargin = - count > 0 && !MusicPlayerRemote.getPlayingQueue().isEmpty() - ? DensityUtil.dip2px(requireContext(), 104f) - : DensityUtil.dip2px(requireContext(), 54f); - binding.coordinatorLayout.setLayoutParams(params); + private fun checkForPadding() { + val count = adapter?.itemCount ?: 0 + if (_binding != null) { + val params = binding.coordinatorLayout.layoutParams as ViewGroup.MarginLayoutParams + params.bottomMargin = if (count > 0 && playingQueue.isNotEmpty()) dip2px( + requireContext(), + 104f + ) else dip2px(requireContext(), 54f) + binding.coordinatorLayout.layoutParams = params } } - private void checkIsEmpty() { - if (binding != null) { - binding.emptyEmoji.setText(getEmojiByUnicode(0x1F631)); - binding.empty.setVisibility( - adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); + private fun checkIsEmpty() { + if (_binding != null) { + binding.emptyEmoji.text = getEmojiByUnicode(0x1F631) + binding.empty.visibility = + if (adapter == null || adapter!!.itemCount == 0) View.VISIBLE else View.GONE } } - @Nullable - private BreadCrumbLayout.Crumb getActiveCrumb() { - if (binding != null) { - return binding.breadCrumbs.size() > 0 - ? binding.breadCrumbs.getCrumb(binding.breadCrumbs.getActiveIndex()) - : null; - } - return null; + private val activeCrumb: Crumb? + get() = if (_binding != null) { + if (binding.breadCrumbs.size() > 0) binding.breadCrumbs.getCrumb(binding.breadCrumbs.activeIndex) else null + } else null + + private fun getEmojiByUnicode(unicode: Int): String { + return String(Character.toChars(unicode)) } - private String getEmojiByUnicode(int unicode) { - return new String(Character.toChars(unicode)); - } - - private Comparator getFileComparator() { - return fileComparator; - } - - private void saveScrollPosition() { - BreadCrumbLayout.Crumb crumb = getActiveCrumb(); + private fun saveScrollPosition() { + val crumb = activeCrumb if (crumb != null) { - crumb.setScrollPosition( - ((LinearLayoutManager) binding.recyclerView.getLayoutManager()).findFirstVisibleItemPosition()); + crumb.scrollPosition = + (binding.recyclerView.layoutManager as LinearLayoutManager?)!!.findFirstVisibleItemPosition() } } - private void scanPaths(@Nullable String[] toBeScanned) { - if (getActivity() == null) { - return; + private fun scanPaths(toBeScanned: Array) { + if (activity == null) { + return } - if (toBeScanned == null || toBeScanned.length < 1) { - Toast.makeText(getActivity(), R.string.nothing_to_scan, Toast.LENGTH_SHORT).show(); + if (toBeScanned.isEmpty()) { + Toast.makeText(activity, R.string.nothing_to_scan, Toast.LENGTH_SHORT).show() } else { MediaScannerConnection.scanFile( - getActivity().getApplicationContext(), - toBeScanned, - null, - new UpdateToastMediaScannerCompletionListener(getActivity(), Arrays.asList(toBeScanned))); + requireContext(), + toBeScanned, + null, + UpdateToastMediaScannerCompletionListener(activity, listOf(*toBeScanned)) + ) } } - private void setCrumb(BreadCrumbLayout.Crumb crumb, boolean addToHistory) { + private fun setCrumb(crumb: Crumb?, addToHistory: Boolean) { if (crumb == null) { - return; + return } - String path = crumb.getFile().getPath(); - if (path.equals("/") || path.equals("/storage") || path.equals("/storage/emulated")) { - switchToStorageAdapter(); + val path = crumb.file.path + if (path == "/" || path == "/storage" || path == "/storage/emulated") { + switchToStorageAdapter() } else { - saveScrollPosition(); - binding.breadCrumbs.setActiveOrAdd(crumb, false); + saveScrollPosition() + binding.breadCrumbs.setActiveOrAdd(crumb, false) if (addToHistory) { - binding.breadCrumbs.addHistory(crumb); + binding.breadCrumbs.addHistory(crumb) } - LoaderManager.getInstance(this).restartLoader(LOADER_ID, null, this); + LoaderManager.getInstance(this).restartLoader(LOADER_ID, null, this) } } - private void setUpAdapter() { - switchToFileAdapter(); + private fun setUpAdapter() { + switchToFileAdapter() } - private void setUpAppbarColor() { + private fun setUpAppbarColor() { binding.breadCrumbs.setActivatedContentColor( - ATHUtil.INSTANCE.resolveColor(requireContext(), android.R.attr.textColorPrimary)); + resolveColor(requireContext(), android.R.attr.textColorPrimary) + ) binding.breadCrumbs.setDeactivatedContentColor( - ATHUtil.INSTANCE.resolveColor(requireContext(), android.R.attr.textColorSecondary)); + resolveColor(requireContext(), android.R.attr.textColorSecondary) + ) } - private void setUpBreadCrumbs() { - binding.breadCrumbs.setCallback(this); + private fun setUpBreadCrumbs() { + binding.breadCrumbs.setCallback(this) } - private void setUpRecyclerView() { - binding.recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); - FastScroller fastScroller = ThemedFastScroller.INSTANCE.create(binding.recyclerView); + private fun setUpRecyclerView() { + binding.recyclerView.layoutManager = LinearLayoutManager( + activity + ) + val fastScroller = create( + binding.recyclerView + ) binding.recyclerView.setOnApplyWindowInsetsListener( - new ScrollingViewOnApplyWindowInsetsListener(binding.recyclerView, fastScroller)); + ScrollingViewOnApplyWindowInsetsListener(binding.recyclerView, fastScroller) + ) } - private ArrayList toList(File file) { - ArrayList files = new ArrayList<>(1); - files.add(file); - return files; + private fun toList(file: File): ArrayList { + val files = ArrayList(1) + files.add(file) + return files } - private void updateAdapter(@NonNull List files) { - adapter.swapDataSet(files); - BreadCrumbLayout.Crumb crumb = getActiveCrumb(); + private fun updateAdapter(files: List) { + adapter?.swapDataSet(files) + val crumb = activeCrumb if (crumb != null) { - ((LinearLayoutManager) binding.recyclerView.getLayoutManager()) - .scrollToPositionWithOffset(crumb.getScrollPosition(), 0); + (binding.recyclerView.layoutManager as LinearLayoutManager?) + ?.scrollToPositionWithOffset(crumb.scrollPosition, 0) } } - @Override - public void onDestroyView() { - super.onDestroyView(); - binding = null; + override fun onDestroyView() { + super.onDestroyView() + _binding = null } - public static class ListPathsAsyncTask - extends ListingFilesDialogAsyncTask { + class ListPathsAsyncTask(context: Context?, callback: OnPathsListedCallback) : + ListingFilesDialogAsyncTask>( + context + ) { + private val onPathsListedCallbackWeakReference: WeakReference = + WeakReference(callback) - private final WeakReference onPathsListedCallbackWeakReference; - - public ListPathsAsyncTask(Context context, OnPathsListedCallback callback) { - super(context); - onPathsListedCallbackWeakReference = new WeakReference<>(callback); - } - - @Override - protected String[] doInBackground(LoadingInfo... params) { - try { - if (isCancelled() || checkCallbackReference() == null) { - return null; + override fun doInBackground(vararg params: LoadingInfo): Array { + return try { + if (isCancelled || checkCallbackReference() == null) { + return arrayOf() } - - LoadingInfo info = params[0]; - - final String[] paths; - - if (info.file.isDirectory()) { - List files = FileUtil.listFilesDeep(info.file, info.fileFilter); - - if (isCancelled() || checkCallbackReference() == null) { - return null; + val info = params[0] + val paths: Array + if (info.file.isDirectory) { + val files = FileUtil.listFilesDeep(info.file, info.fileFilter) + if (isCancelled || checkCallbackReference() == null) { + return arrayOf() } - - paths = new String[files.size()]; - for (int i = 0; i < files.size(); i++) { - File f = files.get(i); - paths[i] = FileUtil.safeGetCanonicalPath(f); - - if (isCancelled() || checkCallbackReference() == null) { - return null; + paths = arrayOfNulls(files.size) + for (i in files.indices) { + val f = files[i] + paths[i] = FileUtil.safeGetCanonicalPath(f) + if (isCancelled || checkCallbackReference() == null) { + return arrayOf() } } } else { - paths = new String[1]; - paths[0] = info.file.getPath(); + paths = arrayOfNulls(1) + paths[0] = info.file.path } - - return paths; - } catch (Exception e) { - e.printStackTrace(); - cancel(false); - return null; + paths + } catch (e: Exception) { + e.printStackTrace() + cancel(false) + arrayOf() } } - @Override - protected void onPostExecute(String[] paths) { - super.onPostExecute(paths); - OnPathsListedCallback callback = checkCallbackReference(); - if (callback != null && paths != null) { - callback.onPathsListed(paths); - } + override fun onPostExecute(paths: Array) { + super.onPostExecute(paths) + checkCallbackReference()?.onPathsListed(paths) } - @Override - protected void onPreExecute() { - super.onPreExecute(); - checkCallbackReference(); + override fun onPreExecute() { + super.onPreExecute() + checkCallbackReference() } - private OnPathsListedCallback checkCallbackReference() { - OnPathsListedCallback callback = onPathsListedCallbackWeakReference.get(); + private fun checkCallbackReference(): OnPathsListedCallback? { + val callback = onPathsListedCallbackWeakReference.get() if (callback == null) { - cancel(false); + cancel(false) } - return callback; + return callback } - public interface OnPathsListedCallback { - - void onPathsListed(@NonNull String[] paths); + interface OnPathsListedCallback { + fun onPathsListed(paths: Array) } - public static class LoadingInfo { + class LoadingInfo(val file: File, val fileFilter: FileFilter) - public final File file; - - final FileFilter fileFilter; - - public LoadingInfo(File file, FileFilter fileFilter) { - this.file = file; - this.fileFilter = fileFilter; - } - } } - private static class AsyncFileLoader extends WrappedAsyncTaskLoader> { + private class AsyncFileLoader(foldersFragment: FoldersFragment) : + WrappedAsyncTaskLoader>(foldersFragment.requireActivity()) { + private val fragmentWeakReference: WeakReference = + WeakReference(foldersFragment) - private final WeakReference fragmentWeakReference; - - AsyncFileLoader(FoldersFragment foldersFragment) { - super(foldersFragment.requireActivity()); - fragmentWeakReference = new WeakReference<>(foldersFragment); - } - - @Override - public List loadInBackground() { - FoldersFragment foldersFragment = fragmentWeakReference.get(); - File directory = null; + override fun loadInBackground(): List { + val foldersFragment = fragmentWeakReference.get() + var directory: File? = null if (foldersFragment != null) { - BreadCrumbLayout.Crumb crumb = foldersFragment.getActiveCrumb(); + val crumb = foldersFragment.activeCrumb if (crumb != null) { - directory = crumb.getFile(); + directory = crumb.file } } - if (directory != null) { - List files = FileUtil.listFiles(directory, AUDIO_FILE_FILTER); - Collections.sort(files, foldersFragment.getFileComparator()); - return files; + return if (directory != null) { + val files = FileUtil.listFiles( + directory, + AUDIO_FILE_FILTER + ) + Collections.sort(files, foldersFragment!!.fileComparator) + files } else { - return new LinkedList<>(); + LinkedList() } } + } - private static class ListSongsAsyncTask - extends ListingFilesDialogAsyncTask> { - - private final Object extra; - private final WeakReference callbackWeakReference; - private final WeakReference contextWeakReference; - - ListSongsAsyncTask(Context context, Object extra, OnSongsListedCallback callback) { - super(context); - this.extra = extra; - contextWeakReference = new WeakReference<>(context); - callbackWeakReference = new WeakReference<>(callback); - } - - @Override - protected List doInBackground(LoadingInfo... params) { - try { - LoadingInfo info = params[0]; - List files = FileUtil.listFilesDeep(info.files, info.fileFilter); - - if (isCancelled() || checkContextReference() == null || checkCallbackReference() == null) { - return null; + private open class ListSongsAsyncTask( + context: Context?, + private val extra: Any?, + callback: OnSongsListedCallback + ) : ListingFilesDialogAsyncTask>(context) { + private val callbackWeakReference = WeakReference(callback) + private val contextWeakReference = WeakReference(context) + override fun doInBackground(vararg params: LoadingInfo): List { + return try { + val info = params[0] + val files = FileUtil.listFilesDeep(info.files, info.fileFilter) + if (isCancelled || checkContextReference() == null || checkCallbackReference() == null) { + return emptyList() } - - Collections.sort(files, info.fileComparator); - - Context context = checkContextReference(); - if (isCancelled() || context == null || checkCallbackReference() == null) { - return null; - } - - return FileUtil.matchFilesWithMediaStore(context, files); - } catch (Exception e) { - e.printStackTrace(); - cancel(false); - return null; + Collections.sort(files, info.fileComparator) + val context = checkContextReference() + if (isCancelled || context == null || checkCallbackReference() == null) { + emptyList() + } else FileUtil.matchFilesWithMediaStore(context, files) + } catch (e: Exception) { + e.printStackTrace() + cancel(false) + emptyList() } } - @Override - protected void onPostExecute(List songs) { - super.onPostExecute(songs); - OnSongsListedCallback callback = checkCallbackReference(); - if (songs != null && callback != null) { - callback.onSongsListed(songs, extra); - } + override fun onPostExecute(songs: List) { + super.onPostExecute(songs) + checkCallbackReference()?.onSongsListed(songs, extra) } - @Override - protected void onPreExecute() { - super.onPreExecute(); - checkCallbackReference(); - checkContextReference(); + override fun onPreExecute() { + super.onPreExecute() + checkCallbackReference() + checkContextReference() } - private OnSongsListedCallback checkCallbackReference() { - OnSongsListedCallback callback = callbackWeakReference.get(); + private fun checkCallbackReference(): OnSongsListedCallback? { + val callback = callbackWeakReference.get() if (callback == null) { - cancel(false); + cancel(false) } - return callback; + return callback } - private Context checkContextReference() { - Context context = contextWeakReference.get(); + private fun checkContextReference(): Context? { + val context = contextWeakReference.get() if (context == null) { - cancel(false); + cancel(false) } - return context; + return context } - public interface OnSongsListedCallback { - - void onSongsListed(@NonNull List songs, Object extra); + interface OnSongsListedCallback { + fun onSongsListed(songs: List, extra: Any?) } - static class LoadingInfo { + class LoadingInfo( + val files: List, + val fileFilter: FileFilter, + val fileComparator: Comparator + ) - final Comparator fileComparator; + } - final FileFilter fileFilter; + abstract class ListingFilesDialogAsyncTask : + DialogAsyncTask { + internal constructor(context: Context?) : super(context) - final List files; - - LoadingInfo( - @NonNull List files, - @NonNull FileFilter fileFilter, - @NonNull Comparator fileComparator) { - this.fileComparator = fileComparator; - this.fileFilter = fileFilter; - this.files = files; - } + override fun createDialog(context: Context): Dialog { + return MaterialAlertDialogBuilder(context) + .setTitle(R.string.listing_files) + .setCancelable(false) + .setView(R.layout.loading) + .setOnCancelListener { cancel(false) } + .setOnDismissListener { cancel(false) } + .create() } } - private abstract static class ListingFilesDialogAsyncTask - extends DialogAsyncTask { - - ListingFilesDialogAsyncTask(Context context) { - super(context); - } - - public ListingFilesDialogAsyncTask(Context context, int showDelay) { - super(context, showDelay); - } - - @Override - protected Dialog createDialog(@NonNull Context context) { - return new MaterialAlertDialogBuilder(context) - .setTitle(R.string.listing_files) - .setCancelable(false) - .setView(R.layout.loading) - .setOnCancelListener(dialog -> cancel(false)) - .setOnDismissListener(dialog -> cancel(false)) - .create(); - } - } - - // https://github.com/DrKLO/Telegram/blob/ab221dafadbc17459d78d9ea3e643ae18e934b16/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertDocumentLayout.java#L939 - private void listRoots() { - storageItems.clear(); - HashSet paths = new HashSet<>(); - String defaultPath = Environment.getExternalStorageDirectory().getPath(); - String defaultPathState = Environment.getExternalStorageState(); - if (defaultPathState.equals(Environment.MEDIA_MOUNTED) || defaultPathState.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) { - Storage ext = new Storage(); - if (Environment.isExternalStorageRemovable()) { - ext.title = "SD Card"; - } else { - ext.title = "Internal Storage"; - } - ext.file = Environment.getExternalStorageDirectory(); - storageItems.add(ext); - paths.add(defaultPath); - } - - BufferedReader bufferedReader = null; - try { - bufferedReader = new BufferedReader(new FileReader("/proc/mounts")); - String line; - while ((line = bufferedReader.readLine()) != null) { - if (line.contains("vfat") || line.contains("/mnt")) { - StringTokenizer tokens = new StringTokenizer(line, " "); - tokens.nextToken(); - String path = tokens.nextToken(); - if (paths.contains(path)) { - continue; - } - if (line.contains("/dev/block/vold")) { - if (!line.contains("/mnt/secure") && !line.contains("/mnt/asec") && !line.contains("/mnt/obb") && !line.contains("/dev/mapper") && !line.contains("tmpfs")) { - if (!new File(path).isDirectory()) { - int index = path.lastIndexOf('/'); - if (index != -1) { - String newPath = "/storage/" + path.substring(index + 1); - if (new File(newPath).isDirectory()) { - path = newPath; - } - } - } - paths.add(path); - try { - Storage item = new Storage(); - if (path.toLowerCase().contains("sd")) { - item.title = "SD Card"; - } else { - item.title = "External Storage"; - } - item.file = new File(path); - storageItems.add(item); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (bufferedReader != null) { - try { - bufferedReader.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - - @Override - public void onStorageClicked(@NonNull Storage storage) { - switchToFileAdapter(); + override fun onStorageClicked(storage: Storage) { + switchToFileAdapter() setCrumb( - new BreadCrumbLayout.Crumb( - FileUtil.safeGetCanonicalFile(storage.file)), - true); + Crumb( + FileUtil.safeGetCanonicalFile(storage.file) + ), + true + ) } - public void switchToFileAdapter() { - adapter = - new SongFileAdapter(getMainActivity(), new LinkedList<>(), R.layout.item_list, this, this); - adapter.registerAdapterDataObserver( - new RecyclerView.AdapterDataObserver() { - @Override - public void onChanged() { - super.onChanged(); - checkIsEmpty(); - checkForPadding(); + private fun switchToFileAdapter() { + adapter = SongFileAdapter(mainActivity, LinkedList(), R.layout.item_list, this, this) + adapter!!.registerAdapterDataObserver( + object : RecyclerView.AdapterDataObserver() { + override fun onChanged() { + super.onChanged() + checkIsEmpty() + checkForPadding() + } + }) + binding.recyclerView.adapter = adapter + checkIsEmpty() + } + + private fun switchToStorageAdapter() { + FileUtil.listRoots() + storageAdapter = StorageAdapter(storageItems, this) + binding.recyclerView.adapter = storageAdapter + binding.breadCrumbs.clearCrumbs() + } + + companion object { + val TAG: String = FoldersFragment::class.java.simpleName + val AUDIO_FILE_FILTER = FileFilter { file: File -> + (!file.isHidden + && (file.isDirectory + || FileUtil.fileIsMimeType(file, "audio/*", MimeTypeMap.getSingleton()) + || FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton()) + || FileUtil.fileIsMimeType( + file, + "application/ogg", + MimeTypeMap.getSingleton() + ))) + } + private const val CRUMBS = "crumbs" + private const val LOADER_ID = 5 + + // root + val defaultStartDirectory: File + get() { + val musicDir = + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) + val startFolder = if (musicDir.exists() && musicDir.isDirectory) { + musicDir + } else { + val externalStorage = Environment.getExternalStorageDirectory() + if (externalStorage.exists() && externalStorage.isDirectory) { + externalStorage + } else { + File("/") // root } - }); - binding.recyclerView.setAdapter(adapter); - checkIsEmpty(); - } + } + return startFolder + } - public void switchToStorageAdapter() { - listRoots(); - storageAdapter = new StorageAdapter(storageItems, this); - binding.recyclerView.setAdapter(storageAdapter); - binding.breadCrumbs.clearCrumbs(); + private fun tryGetCanonicalFile(file: File): File { + return try { + file.canonicalFile + } catch (e: IOException) { + e.printStackTrace() + file + } + } } -} +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt index 320f9a88..a251757e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt @@ -22,10 +22,14 @@ import code.name.monkey.retromusic.extensions.dipToPix import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper +import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.RetroColorUtil -import com.afollestad.materialcab.MaterialCab +import com.afollestad.materialcab.attached.AttachedCab +import com.afollestad.materialcab.attached.destroy +import com.afollestad.materialcab.attached.isActive +import com.afollestad.materialcab.createCab import com.google.android.material.transition.MaterialSharedAxis import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator @@ -158,29 +162,35 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli private fun handleBackPress(): Boolean { cab?.let { - if (it.isActive) { - it.finish() + if (it.isActive()) { + it.destroy() return true } } return false } - private var cab: MaterialCab? = null + private var cab: AttachedCab? = null - override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab { + override fun openCab(menuRes: Int, callback: ICabCallback): AttachedCab { cab?.let { println("Cab") - if (it.isActive) { - it.finish() + if (it.isActive()) { + it.destroy() } } - cab = MaterialCab(mainActivity, R.id.cab_stub) - .setMenu(menuRes) - .setCloseDrawableRes(R.drawable.ic_close) - .setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor())) - .start(callback) - return cab as MaterialCab + cab = createCab(R.id.cab_stub) { + menu(menuRes) + closeDrawable(R.drawable.ic_close) + backgroundColor(literal = RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor())) + slideDown() + onCreate { cab, menu -> callback.onCabCreated(cab, menu) } + onSelection { + callback.onCabItemClicked(it) + } + onDestroy { callback.onCabFinished(it) } + } + return cab as AttachedCab } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/songs/SongsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/songs/SongsFragment.kt index 022b4999..afab7103 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/songs/SongsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/songs/SongsFragment.kt @@ -26,11 +26,15 @@ import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment import code.name.monkey.retromusic.helper.SortOrder.SongSortOrder +import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroUtil -import com.afollestad.materialcab.MaterialCab +import com.afollestad.materialcab.attached.AttachedCab +import com.afollestad.materialcab.attached.destroy +import com.afollestad.materialcab.attached.isActive +import com.afollestad.materialcab.createCab import com.google.android.gms.cast.framework.CastButtonFactory class SongsFragment : AbsRecyclerViewCustomGridSizeFragment(), @@ -348,30 +352,36 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment callback.onCabCreated(cab, menu) } + onSelection { + callback.onCabItemClicked(it) + } + onDestroy { callback.onCabFinished(it) } + } + return cab as AttachedCab } } diff --git a/app/src/main/java/code/name/monkey/retromusic/interfaces/ICabCallback.kt b/app/src/main/java/code/name/monkey/retromusic/interfaces/ICabCallback.kt new file mode 100644 index 00000000..76750ff0 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/interfaces/ICabCallback.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Hemanth Savarla. + * + * 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.interfaces + +import android.view.Menu +import android.view.MenuItem +import com.afollestad.materialcab.attached.AttachedCab + +interface ICabCallback { + fun onCabCreated(cab: AttachedCab, menu: Menu): Boolean + + fun onCabItemClicked(item: MenuItem): Boolean + + fun onCabFinished(cab: AttachedCab): Boolean +} diff --git a/app/src/main/java/code/name/monkey/retromusic/interfaces/ICabHolder.kt b/app/src/main/java/code/name/monkey/retromusic/interfaces/ICabHolder.kt index 81052035..e04a4c32 100644 --- a/app/src/main/java/code/name/monkey/retromusic/interfaces/ICabHolder.kt +++ b/app/src/main/java/code/name/monkey/retromusic/interfaces/ICabHolder.kt @@ -14,9 +14,9 @@ */ package code.name.monkey.retromusic.interfaces -import com.afollestad.materialcab.MaterialCab +import com.afollestad.materialcab.attached.AttachedCab interface ICabHolder { - fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab + fun openCab(menuRes: Int, callback: ICabCallback): AttachedCab } diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt index 60f09831..e7a10dda 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt +++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt @@ -544,7 +544,7 @@ object PreferenceUtil { var startDirectory: File get() { - val folderPath = FoldersFragment.getDefaultStartDirectory().path + val folderPath = FoldersFragment.defaultStartDirectory.path val filePath: String = sharedPreferences.getStringOrDefault(START_DIRECTORY, folderPath) return File(filePath) } diff --git a/app/src/main/res/values-night-v27/styles.xml b/app/src/main/res/values-night-v27/styles.xml index f110231a..696621d6 100644 --- a/app/src/main/res/values-night-v27/styles.xml +++ b/app/src/main/res/values-night-v27/styles.xml @@ -19,7 +19,6 @@ true true @style/ThemeOverlay.AppCompat.Dark - @style/ThemeOverlay.AppCompat.Dark true @style/PreferenceThemeOverlay.v14.Material @style/MaterialAlertDialogTheme diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index f2fbebc1..545d17a8 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -19,7 +19,6 @@ true true @style/ThemeOverlay.AppCompat.Dark - @style/ThemeOverlay.AppCompat.Dark true @style/PreferenceThemeOverlay.v14.Material @style/MaterialAlertDialogTheme diff --git a/app/src/main/res/values-v27/styles_parents.xml b/app/src/main/res/values-v27/styles_parents.xml index b91f2857..b2fcc3ab 100644 --- a/app/src/main/res/values-v27/styles_parents.xml +++ b/app/src/main/res/values-v27/styles_parents.xml @@ -19,7 +19,6 @@ true true @style/ThemeOverlay.AppCompat.Light - @style/ThemeOverlay.AppCompat.Light @style/PreferenceThemeOverlay.v14.Material @drawable/round_selector @drawable/rect_selector @@ -37,7 +36,6 @@ true true @style/ThemeOverlay.AppCompat.Dark - @style/ThemeOverlay.AppCompat.Dark @drawable/round_selector @drawable/rect_selector @style/Widget.ActionButton.Overflow diff --git a/app/src/main/res/values/styles_parents.xml b/app/src/main/res/values/styles_parents.xml index f4b5fbcf..1cdf495f 100644 --- a/app/src/main/res/values/styles_parents.xml +++ b/app/src/main/res/values/styles_parents.xml @@ -6,7 +6,6 @@ true true @style/ThemeOverlay.AppCompat.Light - @style/ThemeOverlay.AppCompat.Light @style/PreferenceThemeOverlay.v14.Material @drawable/round_selector @drawable/rect_selector @@ -25,7 +24,6 @@ true true @style/ThemeOverlay.AppCompat.Dark - @style/ThemeOverlay.AppCompat.Dark @drawable/round_selector @drawable/rect_selector @style/Widget.ActionButton.Overflow @@ -53,7 +51,6 @@ @color/blackColorSurface @color/blackColorSurface @style/ThemeOverlay.AppCompat.Dark - @style/ThemeOverlay.AppCompat.Dark @style/MaterialPopupMenuStyle @style/Widget.Material3.CardView.Elevated @color/bottomSheetColorBlack