diff --git a/app/build.gradle b/app/build.gradle
index b3edbe698..1e8b004f6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -104,11 +104,6 @@ dependencies {
// Material
implementation "com.google.android.material:material:1.3.0"
- // Dialogs
- // TODO: Eliminate these, would eliminate ~100kb from the app size
- implementation "com.afollestad.material-dialogs:core:3.3.0"
- implementation "com.afollestad.material-dialogs:files:3.3.0"
-
// --- DEBUG ---
// Lint
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c1f57fe6a..5a403aaab 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,10 +8,6 @@
-
0 && height > 0 && (lastWidth != width || lastHeight != height)) {
val totalSpace = width - paddingRight - paddingLeft
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistDialog.kt b/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistDialog.kt
index 42e286a9e..f2e9a3e76 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistDialog.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistDialog.kt
@@ -2,47 +2,39 @@ package org.oxycblt.auxio.settings.blacklist
import android.content.DialogInterface
import android.content.Intent
+import android.net.Uri
import android.os.Bundle
import android.os.Environment
+import android.provider.DocumentsContract
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.view.children
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
-import androidx.recyclerview.widget.RecyclerView
-import com.afollestad.materialdialogs.MaterialDialog
-import com.afollestad.materialdialogs.customview.getCustomView
-import com.afollestad.materialdialogs.files.folderChooser
-import com.afollestad.materialdialogs.files.selectedFolder
-import com.afollestad.materialdialogs.internal.list.DialogRecyclerView
-import com.afollestad.materialdialogs.utils.invalidateDividers
-import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.oxycblt.auxio.MainActivity
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.DialogBlacklistBinding
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.playback.PlaybackViewModel
+import org.oxycblt.auxio.settings.ui.LifecycleDialog
import org.oxycblt.auxio.ui.Accent
import org.oxycblt.auxio.ui.createToast
import org.oxycblt.auxio.ui.toColor
-import java.io.File
import kotlin.system.exitProcess
/**
* Dialog that manages the currently excluded directories.
* @author OxygenCobalt
*/
-class BlacklistDialog : BottomSheetDialogFragment() {
+class BlacklistDialog : LifecycleDialog() {
private val blacklistModel: BlacklistViewModel by viewModels {
BlacklistViewModel.Factory(requireContext())
}
private val playbackModel: PlaybackViewModel by activityViewModels()
- override fun getTheme() = R.style.Theme_BottomSheetFix
-
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -50,14 +42,16 @@ class BlacklistDialog : BottomSheetDialogFragment() {
): View {
val binding = DialogBlacklistBinding.inflate(inflater)
+ val launcher = registerForActivityResult(
+ ActivityResultContracts.OpenDocumentTree(), ::addDocTreePath
+ )
+
val accent = Accent.get().color.toColor(requireContext())
val adapter = BlacklistEntryAdapter { path ->
blacklistModel.removePath(path)
}
- requireContext().setTheme(Accent.get().theme)
-
// --- UI SETUP ---
binding.blacklistRecycler.adapter = adapter
@@ -68,7 +62,8 @@ class BlacklistDialog : BottomSheetDialogFragment() {
setTextColor(accent)
setOnClickListener {
- showFileDialog()
+ // showFileDialog()
+ launcher.launch(null)
}
}
@@ -112,48 +107,33 @@ class BlacklistDialog : BottomSheetDialogFragment() {
blacklistModel.loadDatabasePaths()
}
- private fun showFileDialog() {
- MaterialDialog(requireActivity()).show {
- positiveButton(R.string.label_add) {
- onFolderSelected()
- }
+ private fun addDocTreePath(uri: Uri) {
+ val path = parseDocTreePath(uri)
- negativeButton()
-
- folderChooser(
- requireContext(),
- initialDirectory = File(getRootPath()),
- emptyTextRes = R.string.label_no_dirs
- )
-
- // Once again remove the ugly dividers from the dialog, but now with an even
- // worse solution.
- invalidateDividers(showTop = false, showBottom = false)
-
- val recycler = (getCustomView() as ViewGroup)
- .children.filterIsInstance().firstOrNull()
-
- recycler?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
- override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
- invalidateDividers(showTop = false, showBottom = false)
- }
- })
+ if (path != null) {
+ blacklistModel.addPath(path)
+ } else {
+ getString(R.string.error_bad_dir).createToast(requireContext())
}
}
- private fun MaterialDialog.onFolderSelected() {
- selectedFolder()?.absolutePath?.let { path ->
- // Due to how Auxio's navigation flow works, dont allow the main root directory
- // to be excluded, as that would lead to the user being stuck at the "No Music Found"
- // screen.
- if (path == getRootPath()) {
- getString(R.string.error_brick_dir).createToast(requireContext())
+ private fun parseDocTreePath(uri: Uri): String? {
+ // Turn the raw URI into a document tree URI
+ val docUri = DocumentsContract.buildDocumentUriUsingTree(
+ uri, DocumentsContract.getTreeDocumentId(uri)
+ )
- return
- }
+ // Turn it into a semi-usable path
+ val typeAndPath = DocumentsContract.getTreeDocumentId(docUri).split(":")
- blacklistModel.addPath(path)
+ // We only support the main drive since that's all we can get from MediaColumns.DATA.
+ // We also check if this directory actually has multiple parts, if it isn't, then its
+ // the root directory and it shouldn't be supported.
+ if (typeAndPath[0] == "primary" && typeAndPath.size == 2) {
+ return getRootPath() + "/" + typeAndPath.last()
}
+
+ return null
}
private fun saveAndRestart() {
@@ -163,7 +143,7 @@ class BlacklistDialog : BottomSheetDialogFragment() {
}
private fun hardRestart() {
- logD("Performing hard-restart.")
+ logD("Performing hard restart.")
// Instead of having to do a ton of cleanup and horrible code changes
// to restart this application non-destructively, I just restart the UI task [There is only
@@ -176,6 +156,9 @@ class BlacklistDialog : BottomSheetDialogFragment() {
exitProcess(0)
}
+ /**
+ * Get *just* the root path, nothing else is really needed.
+ */
@Suppress("DEPRECATION")
private fun getRootPath(): String {
return Environment.getExternalStorageDirectory().absolutePath
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/ui/LifecycleDialog.kt b/app/src/main/java/org/oxycblt/auxio/settings/ui/LifecycleDialog.kt
new file mode 100644
index 000000000..929edcc59
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/settings/ui/LifecycleDialog.kt
@@ -0,0 +1,24 @@
+package org.oxycblt.auxio.settings.ui
+
+import android.app.Dialog
+import android.os.Bundle
+import android.view.View
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+
+/**
+ * [DialogFragment] that replicates the Fragment lifecycle in regards to [AlertDialog], which
+ * doesn't seem to set the view from onCreateView correctly.
+ */
+abstract class LifecycleDialog() : DialogFragment() {
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return MaterialAlertDialogBuilder(requireActivity(), theme).create()
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ (requireDialog() as AlertDialog).setView(view)
+ }
+}
diff --git a/app/src/main/res/layout/dialog_accent.xml b/app/src/main/res/layout/dialog_accent.xml
index 350feac6f..0c3808071 100644
--- a/app/src/main/res/layout/dialog_accent.xml
+++ b/app/src/main/res/layout/dialog_accent.xml
@@ -7,7 +7,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
- android:paddingBottom="@dimen/margin_medium"
+ android:paddingBottom="@dimen/padding_small"
android:theme="@style/Theme.Neutral">
@@ -47,7 +47,7 @@