Browse Source

Add a permission changed listener on the dialog and listen it in the ML fragments

merge-requests/2174/head
Nicolas Pomepuy 2 years ago
parent
commit
2c74565815
  1. 26
      application/television/src/main/java/org/videolan/television/ui/MediaItemDetailsFragment.kt
  2. 1
      application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesAdvanced.kt
  3. 85
      application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt
  4. 10
      application/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.kt
  5. 30
      application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt
  6. 20
      application/vlc-android/src/org/videolan/vlc/gui/browser/MediaBrowserFragment.kt
  7. 18
      application/vlc-android/src/org/videolan/vlc/gui/dialogs/ConfirmDeleteDialog.kt
  8. 129
      application/vlc-android/src/org/videolan/vlc/gui/preferences/PreferencesAdvanced.kt

26
application/television/src/main/java/org/videolan/television/ui/MediaItemDetailsFragment.kt

@ -27,10 +27,12 @@ import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.setFragmentResultListener
import androidx.leanback.app.BackgroundManager
import androidx.leanback.app.DetailsSupportFragment
import androidx.leanback.widget.*
@ -55,6 +57,7 @@ import org.videolan.resources.FAVORITE_TITLE
import org.videolan.resources.HEADER_DIRECTORIES
import org.videolan.resources.HEADER_NETWORK
import org.videolan.resources.util.parcelable
import org.videolan.resources.util.parcelableList
import org.videolan.television.ui.browser.VerticalGridActivity
import org.videolan.tools.HttpImageLoader
import org.videolan.tools.retrieveParent
@ -62,6 +65,8 @@ import org.videolan.vlc.BuildConfig
import org.videolan.vlc.R
import org.videolan.vlc.gui.DialogActivity
import org.videolan.vlc.gui.DialogActivity.Companion.EXTRA_MEDIA
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_MEDIALIST
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_RESULT
import org.videolan.vlc.gui.dialogs.ConfirmDeleteDialog
import org.videolan.vlc.gui.helpers.AudioUtil
import org.videolan.vlc.gui.helpers.UiTools
@ -172,6 +177,18 @@ class MediaItemDetailsFragment : DetailsSupportFragment(), CoroutineScope by Mai
onItemViewClickedListener = this
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
requireActivity().supportFragmentManager.setFragmentResultListener(CONFIRM_DELETE_DIALOG_RESULT, viewLifecycleOwner) { requestKey, bundle ->
var preventFinish = false
MediaUtils.deleteItem(requireActivity(), viewModel.media) {
onDeleteFailed(it)
preventFinish = true
}
if (!preventFinish) requireActivity().finish()
}
}
override fun onResume() {
super.onResume()
// buildDetails()
@ -480,15 +497,6 @@ class MediaItemDetailsFragment : DetailsSupportFragment(), CoroutineScope by Mai
private fun delete() {
val dialog = ConfirmDeleteDialog.newInstance(arrayListOf(viewModel.media))
dialog.show(requireActivity().supportFragmentManager, ConfirmDeleteDialog::class.simpleName)
dialog.setListener {
dialog.dismiss()
var preventFinish = false
MediaUtils.deleteItem(requireActivity(), viewModel.media) {
onDeleteFailed(it)
preventFinish = true
}
if (!preventFinish) requireActivity().finish()
}
}
}

1
application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesAdvanced.kt

@ -62,7 +62,6 @@ import org.videolan.resources.KEY_MEDIA_LAST_PLAYLIST_RESUME
import org.videolan.resources.ROOM_DATABASE
import org.videolan.resources.SCHEME_PACKAGE
import org.videolan.resources.VLCInstance
import org.videolan.television.ui.dialogs.ConfirmationTvActivity
import org.videolan.tools.BitmapCache
import org.videolan.tools.DAV1D_THREAD_NUMBER
import org.videolan.tools.Settings

85
application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt

@ -51,18 +51,36 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.videolan.medialibrary.interfaces.Medialibrary
import org.videolan.medialibrary.interfaces.media.*
import org.videolan.medialibrary.interfaces.media.Album
import org.videolan.medialibrary.interfaces.media.MediaWrapper
import org.videolan.medialibrary.interfaces.media.Playlist
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.resources.*
import org.videolan.resources.AndroidDevices
import org.videolan.resources.MEDIALIBRARY_PAGE_SIZE
import org.videolan.resources.TAG_ITEM
import org.videolan.resources.UPDATE_REORDER
import org.videolan.resources.util.parcelable
import org.videolan.tools.*
import org.videolan.resources.util.parcelableList
import org.videolan.tools.ALBUMS_SHOW_TRACK_NUMBER
import org.videolan.tools.PLAYLIST_MODE_AUDIO
import org.videolan.tools.Settings
import org.videolan.tools.copy
import org.videolan.tools.dp
import org.videolan.tools.isStarted
import org.videolan.tools.putSingle
import org.videolan.vlc.BuildConfig
import org.videolan.vlc.R
import org.videolan.vlc.databinding.HeaderMediaListActivityBinding
import org.videolan.vlc.gui.audio.AudioAlbumTracksAdapter
import org.videolan.vlc.gui.audio.AudioBrowserAdapter
import org.videolan.vlc.gui.audio.AudioBrowserFragment
import org.videolan.vlc.gui.dialogs.*
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_MEDIALIST
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_RESULT
import org.videolan.vlc.gui.dialogs.ConfirmDeleteDialog
import org.videolan.vlc.gui.dialogs.CtxActionReceiver
import org.videolan.vlc.gui.dialogs.RenameDialog
import org.videolan.vlc.gui.dialogs.SavePlaylistDialog
import org.videolan.vlc.gui.dialogs.showContext
import org.videolan.vlc.gui.helpers.AudioUtil
import org.videolan.vlc.gui.helpers.AudioUtil.setRingtone
import org.videolan.vlc.gui.helpers.ExpandStateAppBarLayoutBehavior
@ -77,15 +95,35 @@ import org.videolan.vlc.interfaces.IEventsHandler
import org.videolan.vlc.interfaces.IListEventsHandler
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.media.PlaylistManager
import org.videolan.vlc.util.*
import org.videolan.vlc.util.ContextOption.*
import org.videolan.vlc.util.ContextOption
import org.videolan.vlc.util.ContextOption.CTX_ADD_SHORTCUT
import org.videolan.vlc.util.ContextOption.CTX_ADD_TO_PLAYLIST
import org.videolan.vlc.util.ContextOption.CTX_APPEND
import org.videolan.vlc.util.ContextOption.CTX_COPY
import org.videolan.vlc.util.ContextOption.CTX_DELETE
import org.videolan.vlc.util.ContextOption.CTX_FAV_ADD
import org.videolan.vlc.util.ContextOption.CTX_FAV_REMOVE
import org.videolan.vlc.util.ContextOption.CTX_GO_TO_ALBUM_ARTIST
import org.videolan.vlc.util.ContextOption.CTX_GO_TO_ARTIST
import org.videolan.vlc.util.ContextOption.CTX_INFORMATION
import org.videolan.vlc.util.ContextOption.CTX_PLAY_ALL
import org.videolan.vlc.util.ContextOption.CTX_PLAY_NEXT
import org.videolan.vlc.util.ContextOption.CTX_RENAME
import org.videolan.vlc.util.ContextOption.CTX_SET_RINGTONE
import org.videolan.vlc.util.ContextOption.CTX_SHARE
import org.videolan.vlc.util.ContextOption.Companion.createCtxPlaylistItemFlags
import org.videolan.vlc.util.FileUtils
import org.videolan.vlc.util.Permissions
import org.videolan.vlc.util.ThumbnailsProvider
import org.videolan.vlc.util.getScreenWidth
import org.videolan.vlc.util.isSchemeHttpOrHttps
import org.videolan.vlc.util.launchWhenStarted
import org.videolan.vlc.util.share
import org.videolan.vlc.viewmodels.PlaylistModel
import org.videolan.vlc.viewmodels.mobile.PlaylistViewModel
import org.videolan.vlc.viewmodels.mobile.getViewModel
import java.security.SecureRandom
import java.util.*
import java.util.LinkedList
import kotlin.math.min
open class HeaderMediaListActivity : AudioPlayerContainerActivity(), IEventsHandler<MediaLibraryItem>, IListEventsHandler, ActionMode.Callback, View.OnClickListener, CtxActionReceiver, Filterable, SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener {
@ -229,6 +267,24 @@ open class HeaderMediaListActivity : AudioPlayerContainerActivity(), IEventsHand
audioBrowserAdapter.areSectionsEnabled = false
binding.browserFastScroller.attachToCoordinator(binding.appbar, binding.coordinator, null)
binding.browserFastScroller.setRecyclerView(binding.songs, viewModel.tracksProvider)
supportFragmentManager.setFragmentResultListener(CONFIRM_DELETE_DIALOG_RESULT, this) { key, bundle ->
// Any type can be passed via to the bundle
val items: List<MediaWrapper> = bundle.parcelableList(CONFIRM_DELETE_DIALOG_MEDIALIST) ?: listOf()
lifecycleScope.launch {
for (item in items) {
val deleteAction = kotlinx.coroutines.Runnable {
lifecycleScope.launch {
MediaUtils.deleteItem(this@HeaderMediaListActivity, item) {
UiTools.snacker(this@HeaderMediaListActivity, getString(R.string.msg_delete_failed, it.title))
}
if (isStarted()) viewModel.refresh()
}
}
if (Permissions.checkWritePermission(this@HeaderMediaListActivity, item, deleteAction)) deleteAction.run()
}
}
}
}
override fun onResume() {
@ -544,21 +600,6 @@ open class HeaderMediaListActivity : AudioPlayerContainerActivity(), IEventsHand
private fun removeItems(items: List<MediaWrapper>) {
val dialog = ConfirmDeleteDialog.newInstance(ArrayList(items))
dialog.show(supportFragmentManager, ConfirmDeleteDialog::class.simpleName)
dialog.setListener {
lifecycleScope.launch {
for (item in items) {
val deleteAction = kotlinx.coroutines.Runnable {
lifecycleScope.launch {
MediaUtils.deleteItem(this@HeaderMediaListActivity, item) {
UiTools.snacker(this@HeaderMediaListActivity, getString(R.string.msg_delete_failed, it.title))
}
if (isStarted()) viewModel.refresh()
}
}
if (Permissions.checkWritePermission(this@HeaderMediaListActivity, item, deleteAction)) deleteAction.run()
}
}
}
}
private fun deleteMedia(mw: MediaLibraryItem) = lifecycleScope.launch(Dispatchers.IO) {

10
application/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.kt

@ -24,6 +24,7 @@ import android.view.*
import android.widget.TextView
import androidx.appcompat.view.ActionMode
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.setFragmentResultListener
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper
@ -40,6 +41,7 @@ import org.videolan.resources.KEY_MEDIA_LAST_PLAYLIST
import org.videolan.tools.*
import org.videolan.vlc.R
import org.videolan.vlc.gui.browser.MediaBrowserFragment
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_RESULT
import org.videolan.vlc.gui.dialogs.ConfirmDeleteDialog
import org.videolan.vlc.gui.dialogs.RenameDialog
import org.videolan.vlc.gui.helpers.*
@ -108,6 +110,10 @@ class HistoryFragment : MediaBrowserFragment<HistoryModel>(), IRefreshable, IHis
list.requestFocus()
registerForContextMenu(list)
swipeRefreshLayout.setOnRefreshListener(this)
requireActivity().supportFragmentManager.setFragmentResultListener(CONFIRM_DELETE_DIALOG_RESULT, viewLifecycleOwner) { requestKey, bundle ->
clearHistory()
requireActivity().finish()
}
}
override fun onStart() {
@ -134,10 +140,6 @@ class HistoryFragment : MediaBrowserFragment<HistoryModel>(), IRefreshable, IHis
val dialog = ConfirmDeleteDialog.newInstance(title = getString(R.string.clear_playback_history), description = getString(R.string.clear_history_message), buttonText = getString(R.string.clear_history))
dialog.show((activity as FragmentActivity).supportFragmentManager, RenameDialog::class.simpleName)
dialog.setListener {
clearHistory()
requireActivity().finish()
}
true
}
else -> super.onOptionsItemSelected(item)

30
application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt

@ -77,13 +77,14 @@ import org.videolan.resources.MOVIEPEDIA_ACTIVITY
import org.videolan.resources.MOVIEPEDIA_MEDIA
import org.videolan.resources.util.getFromMl
import org.videolan.resources.util.parcelable
import org.videolan.resources.util.parcelableList
import org.videolan.tools.BROWSER_DISPLAY_IN_CARDS
import org.videolan.tools.BROWSER_SHOW_HIDDEN_FILES
import org.videolan.tools.BROWSER_SHOW_ONLY_MULTIMEDIA
import org.videolan.tools.PLAYLIST_MODE_AUDIO
import org.videolan.tools.PLAYLIST_MODE_VIDEO
import org.videolan.tools.KeyHelper
import org.videolan.tools.MultiSelectHelper
import org.videolan.tools.PLAYLIST_MODE_AUDIO
import org.videolan.tools.PLAYLIST_MODE_VIDEO
import org.videolan.tools.Settings
import org.videolan.tools.dp
import org.videolan.tools.isStarted
@ -95,6 +96,8 @@ import org.videolan.vlc.R
import org.videolan.vlc.databinding.DirectoryBrowserBinding
import org.videolan.vlc.gui.AudioPlayerContainerActivity
import org.videolan.vlc.gui.MainActivity
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_MEDIALIST
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_RESULT
import org.videolan.vlc.gui.dialogs.CURRENT_SORT
import org.videolan.vlc.gui.dialogs.ConfirmDeleteDialog
import org.videolan.vlc.gui.dialogs.CtxActionReceiver
@ -288,6 +291,19 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
}
}
}
requireActivity().supportFragmentManager.setFragmentResultListener(CONFIRM_DELETE_DIALOG_RESULT, viewLifecycleOwner) { requestKey, bundle ->
val items: List<MediaWrapper> = bundle.parcelableList(CONFIRM_DELETE_DIALOG_MEDIALIST) ?: listOf()
if (items.isNotEmpty()) {
val mw = items[0]
val deleteAction = Runnable {
lifecycleScope.launch {
MediaUtils.deleteItem(requireActivity(), mw) { viewModel.refresh() }
viewModel.remove(mw)
}
}
if (Permissions.checkWritePermission(requireActivity(), mw, deleteAction)) deleteAction.run()
}
}
}
override fun onDisplaySettingChanged(key: String, value: Any) {
@ -536,17 +552,9 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
override fun removeItem(item: MediaLibraryItem): Boolean {
val mw = item as? MediaWrapper
?: return false
val deleteAction = Runnable {
lifecycleScope.launch {
MediaUtils.deleteItem(requireActivity(), mw) { viewModel.refresh() }
viewModel.remove(mw)
}
}
val dialog = ConfirmDeleteDialog.newInstance(arrayListOf(mw))
dialog.show(requireActivity().supportFragmentManager, ConfirmDeleteDialog::class.simpleName)
dialog.setListener {
if (Permissions.checkWritePermission(requireActivity(), mw, deleteAction)) deleteAction.run()
}
return true
}

20
application/vlc-android/src/org/videolan/vlc/gui/browser/MediaBrowserFragment.kt

@ -30,6 +30,7 @@ import android.view.animation.AccelerateDecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.setFragmentResultListener
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
@ -39,15 +40,20 @@ import androidx.transition.TransitionManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.videolan.medialibrary.interfaces.Medialibrary
import org.videolan.medialibrary.interfaces.media.MediaWrapper
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.resources.util.parcelableList
import org.videolan.tools.MultiSelectHelper
import org.videolan.vlc.R
import org.videolan.vlc.gui.BaseFragment
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_MEDIALIST
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_RESULT
import org.videolan.vlc.gui.dialogs.ConfirmDeleteDialog
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.gui.helpers.fillActionMode
import org.videolan.vlc.interfaces.Filterable
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.util.Permissions
import org.videolan.vlc.viewmodels.*
private const val TAG = "VLC/MediaBrowserFragment"
@ -98,6 +104,12 @@ abstract class MediaBrowserFragment<T : SortableModel> : BaseFragment(), Filtera
}
}
}
requireActivity().supportFragmentManager.setFragmentResultListener(CONFIRM_DELETE_DIALOG_RESULT, viewLifecycleOwner) { requestKey, bundle ->
val items: List<MediaLibraryItem> = bundle.parcelableList(CONFIRM_DELETE_DIALOG_MEDIALIST) ?: listOf()
for (item in items) {
MediaUtils.deleteItem(requireActivity(), item) { onDeleteFailed(it)}
}
}
}
@ -152,19 +164,11 @@ abstract class MediaBrowserFragment<T : SortableModel> : BaseFragment(), Filtera
}
val dialog = ConfirmDeleteDialog.newInstance(ArrayList(items))
dialog.show(requireActivity().supportFragmentManager, ConfirmDeleteDialog::class.simpleName)
dialog.setListener {
for (item in items) {
MediaUtils.deleteItem(requireActivity(), item) { onDeleteFailed(it)}
}
}
}
protected open fun removeItem(item: MediaLibraryItem): Boolean {
val dialog = ConfirmDeleteDialog.newInstance(arrayListOf(item))
dialog.show(requireActivity().supportFragmentManager, ConfirmDeleteDialog::class.simpleName)
dialog.setListener {
MediaUtils.deleteItem(requireActivity(), item) { onDeleteFailed(it)}
}
return true
}

18
application/vlc-android/src/org/videolan/vlc/gui/dialogs/ConfirmDeleteDialog.kt

@ -30,6 +30,7 @@ import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.fragment.app.setFragmentResult
import androidx.lifecycle.lifecycleScope
import androidx.vectordrawable.graphics.drawable.Animatable2Compat
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
@ -43,13 +44,17 @@ import org.videolan.resources.util.parcelableList
import org.videolan.vlc.R
import org.videolan.vlc.gui.helpers.UiTools.showPinIfNeeded
const val CONFIRM_DELETE_DIALOG_RESULT_DEFAULT_VALUE = 0
const val CONFIRM_DELETE_DIALOG_RESULT = "CONFIRM_DELETE_DIALOG_RESULT"
const val CONFIRM_DELETE_DIALOG_MEDIALIST = "CONFIRM_DELETE_DIALOG_MEDIALIST"
const val CONFIRM_DELETE_DIALOG_TITLE = "CONFIRM_DELETE_DIALOG_TITLE"
const val CONFIRM_DELETE_DIALOG_DESCRIPTION = "CONFIRM_DELETE_DIALOG_DESCRIPTION"
const val CONFIRM_DELETE_DIALOG_BUTTON_TEXT = "CONFIRM_DELETE_DIALOG_BUTTON_TEXT"
const val CONFIRM_DELETE_DIALOG_RESULT_VALUE = "CONFIRM_DELETE_DIALOG_RESULT_VALUE"
class ConfirmDeleteDialog : VLCBottomSheetDialogFragment() {
private var resultValue: Int = CONFIRM_DELETE_DIALOG_RESULT_DEFAULT_VALUE
private lateinit var listener: () -> Unit
private lateinit var deleteAnimation: ImageView
private lateinit var title: TextView
@ -69,7 +74,7 @@ class ConfirmDeleteDialog : VLCBottomSheetDialogFragment() {
* @param description the description to be used
* @param buttonText the button's text to be used
*/
fun newInstance(medias: ArrayList<MediaLibraryItem> = arrayListOf(), title:String ="", description:String ="", buttonText:String=""): ConfirmDeleteDialog {
fun newInstance(medias: ArrayList<MediaLibraryItem> = arrayListOf(), title:String ="", description:String ="", buttonText:String="", resultValue:Int = CONFIRM_DELETE_DIALOG_RESULT_DEFAULT_VALUE): ConfirmDeleteDialog {
return ConfirmDeleteDialog().apply {
arguments = bundleOf(CONFIRM_DELETE_DIALOG_MEDIALIST to medias,CONFIRM_DELETE_DIALOG_TITLE to title,CONFIRM_DELETE_DIALOG_DESCRIPTION to description, CONFIRM_DELETE_DIALOG_BUTTON_TEXT to buttonText)
@ -77,6 +82,11 @@ class ConfirmDeleteDialog : VLCBottomSheetDialogFragment() {
}
}
/**
* Set the listener. Should be only used from leanback as it has no setFragmentResultListener
*
* @param listener
*/
fun setListener(listener: () -> Unit) {
this.listener = listener
}
@ -87,6 +97,9 @@ class ConfirmDeleteDialog : VLCBottomSheetDialogFragment() {
titleString = arguments?.getString(CONFIRM_DELETE_DIALOG_TITLE)
descriptionString = arguments?.getString(CONFIRM_DELETE_DIALOG_DESCRIPTION)
buttonText = arguments?.getString(CONFIRM_DELETE_DIALOG_BUTTON_TEXT)
arguments?.getInt(CONFIRM_DELETE_DIALOG_BUTTON_TEXT)?.let {
resultValue = it
}
super.onCreate(savedInstanceState)
}
@ -97,7 +110,8 @@ class ConfirmDeleteDialog : VLCBottomSheetDialogFragment() {
description = view.findViewById(R.id.message)
deleteButton = view.findViewById(R.id.delete_button)
view.findViewById<Button>(R.id.delete_button).setOnClickListener {
listener.invoke()
if (::listener.isInitialized) listener.invoke()
setFragmentResult(CONFIRM_DELETE_DIALOG_RESULT, bundleOf(CONFIRM_DELETE_DIALOG_MEDIALIST to mediaList, CONFIRM_DELETE_DIALOG_RESULT_VALUE to resultValue))
dismiss()
}
view.findViewById<Button>(R.id.cancel_button).setOnClickListener {

129
application/vlc-android/src/org/videolan/vlc/gui/preferences/PreferencesAdvanced.kt

@ -34,11 +34,13 @@ import android.os.Bundle
import android.text.InputFilter
import android.text.InputType
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.core.content.edit
import androidx.core.os.bundleOf
import androidx.core.text.isDigitsOnly
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.setFragmentResultListener
import androidx.lifecycle.lifecycleScope
import androidx.preference.EditTextPreference
import androidx.preference.Preference
@ -46,6 +48,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.videolan.medialibrary.interfaces.Medialibrary
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.resources.AndroidDevices
import org.videolan.resources.EXPORT_SETTINGS_FILE
import org.videolan.resources.KEY_AUDIO_LAST_PLAYLIST
@ -60,6 +63,7 @@ import org.videolan.resources.KEY_MEDIA_LAST_PLAYLIST_RESUME
import org.videolan.resources.ROOM_DATABASE
import org.videolan.resources.SCHEME_PACKAGE
import org.videolan.resources.VLCInstance
import org.videolan.resources.util.parcelableList
import org.videolan.tools.BitmapCache
import org.videolan.tools.DAV1D_THREAD_NUMBER
import org.videolan.tools.Settings
@ -70,6 +74,9 @@ import org.videolan.vlc.gui.DebugLogActivity
import org.videolan.vlc.gui.browser.EXTRA_MRL
import org.videolan.vlc.gui.browser.FilePickerActivity
import org.videolan.vlc.gui.browser.KEY_PICKER_TYPE
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_MEDIALIST
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_RESULT
import org.videolan.vlc.gui.dialogs.CONFIRM_DELETE_DIALOG_RESULT_VALUE
import org.videolan.vlc.gui.dialogs.ConfirmDeleteDialog
import org.videolan.vlc.gui.dialogs.NEW_INSTALL
import org.videolan.vlc.gui.dialogs.RenameDialog
@ -81,6 +88,7 @@ import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.gui.helpers.hf.StoragePermissionsDelegate.Companion.getWritePermission
import org.videolan.vlc.gui.helpers.restartMediaPlayer
import org.videolan.vlc.gui.preferences.search.PreferenceParser
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.providers.PickerType
import org.videolan.vlc.util.AutoUpdate
import org.videolan.vlc.util.FeatureFlag
@ -90,6 +98,9 @@ import java.io.File
import java.io.IOException
private const val FILE_PICKER_RESULT_CODE = 10000
private const val RESULT_VALUE_CLEAR_HISTORY = 1
private const val RESULT_VALUE_CLEAR_MEDIA_DATABASE = 2
private const val RESULT_VALUE_CLEAR_APP_DATA = 3
class PreferencesAdvanced : BasePreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
override fun getXml() = R.xml.preferences_adv
@ -110,6 +121,70 @@ class PreferencesAdvanced : BasePreferenceFragment(), SharedPreferences.OnShared
if (!BuildConfig.DEBUG) findPreference<Preference>("show_update")?.isVisible = false
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
requireActivity().supportFragmentManager.setFragmentResultListener(CONFIRM_DELETE_DIALOG_RESULT, viewLifecycleOwner) { requestKey, bundle ->
val reason = bundle.getInt(CONFIRM_DELETE_DIALOG_RESULT_VALUE)
when (reason) {
RESULT_VALUE_CLEAR_HISTORY -> {
Medialibrary.getInstance().clearHistory(Medialibrary.HISTORY_TYPE_GLOBAL)
Settings.getInstance(requireActivity()).edit()
.remove(KEY_AUDIO_LAST_PLAYLIST)
.remove(KEY_MEDIA_LAST_PLAYLIST)
.remove(KEY_MEDIA_LAST_PLAYLIST_RESUME)
.remove(KEY_CURRENT_AUDIO)
.remove(KEY_CURRENT_MEDIA)
.remove(KEY_CURRENT_MEDIA_RESUME)
.remove(KEY_CURRENT_AUDIO_RESUME_TITLE)
.remove(KEY_CURRENT_AUDIO_RESUME_ARTIST)
.remove(KEY_CURRENT_AUDIO_RESUME_THUMB)
.apply()
}
RESULT_VALUE_CLEAR_MEDIA_DATABASE -> {
val medialibrary = Medialibrary.getInstance()
if (medialibrary.isWorking) {
activity?.let {
Toast.makeText(
it,
R.string.settings_ml_block_scan,
Toast.LENGTH_LONG
).show()
}
} else {
lifecycleScope.launch {
val roots = medialibrary.foldersList
withContext((Dispatchers.IO)) {
medialibrary.clearDatabase(false)
//delete thumbnails
try {
requireActivity().getExternalFilesDir(null)?.let {
val files =
File(it.absolutePath + Medialibrary.MEDIALIB_FOLDER_NAME).listFiles()
files?.forEach { file ->
if (file.isFile) FileUtils.deleteFile(file)
}
}
BitmapCache.clear()
} catch (e: IOException) {
Log.e(this::class.java.simpleName, e.message, e)
}
}
for (root in roots) {
MedialibraryUtils.addDir(
root.removePrefix("file://"),
requireContext()
)
} }
}
}
RESULT_VALUE_CLEAR_APP_DATA -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
(requireActivity().getSystemService(ACTIVITY_SERVICE) as ActivityManager).clearApplicationUserData()
}
}
}
}
override fun onStart() {
super.onStart()
preferenceScreen.sharedPreferences!!.registerOnSharedPreferenceChangeListener(this)
@ -149,22 +224,8 @@ class PreferencesAdvanced : BasePreferenceFragment(), SharedPreferences.OnShared
return true
}
"clear_history" -> {
val dialog = ConfirmDeleteDialog.newInstance(title = getString(R.string.clear_playback_history), description = getString(R.string.clear_history_message), buttonText = getString(R.string.clear_history))
val dialog = ConfirmDeleteDialog.newInstance(title = getString(R.string.clear_playback_history), description = getString(R.string.clear_history_message), buttonText = getString(R.string.clear_history), resultValue = RESULT_VALUE_CLEAR_HISTORY)
dialog.show((activity as FragmentActivity).supportFragmentManager, RenameDialog::class.simpleName)
dialog.setListener {
Medialibrary.getInstance().clearHistory(Medialibrary.HISTORY_TYPE_GLOBAL)
Settings.getInstance(requireActivity()).edit()
.remove(KEY_AUDIO_LAST_PLAYLIST)
.remove(KEY_MEDIA_LAST_PLAYLIST)
.remove(KEY_MEDIA_LAST_PLAYLIST_RESUME)
.remove(KEY_CURRENT_AUDIO)
.remove(KEY_CURRENT_MEDIA)
.remove(KEY_CURRENT_MEDIA_RESUME)
.remove(KEY_CURRENT_AUDIO_RESUME_TITLE)
.remove(KEY_CURRENT_AUDIO_RESUME_ARTIST)
.remove(KEY_CURRENT_AUDIO_RESUME_THUMB)
.apply()
}
return true
}
"clear_media_db" -> {
@ -178,50 +239,28 @@ class PreferencesAdvanced : BasePreferenceFragment(), SharedPreferences.OnShared
).show()
}
} else {
val roots = medialibrary.foldersList
val dialog = ConfirmDeleteDialog.newInstance(
title = getString(R.string.clear_media_db),
description = getString(R.string.clear_media_db_message),
buttonText = getString(R.string.clear)
buttonText = getString(R.string.clear),
resultValue = RESULT_VALUE_CLEAR_MEDIA_DATABASE
)
dialog.show(
requireActivity().supportFragmentManager,
RenameDialog::class.simpleName
)
dialog.setListener {
lifecycleScope.launch {
withContext((Dispatchers.IO)) {
medialibrary.clearDatabase(false)
//delete thumbnails
try {
requireActivity().getExternalFilesDir(null)?.let {
val files =
File(it.absolutePath + Medialibrary.MEDIALIB_FOLDER_NAME).listFiles()
files?.forEach { file ->
if (file.isFile) FileUtils.deleteFile(file)
}
}
BitmapCache.clear()
} catch (e: IOException) {
Log.e(this::class.java.simpleName, e.message, e)
}
}
for (root in roots) {
MedialibraryUtils.addDir(
root.removePrefix("file://"),
requireContext()
)
}
}
}
return true
}
}
"clear_app_data" -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val dialog = ConfirmDeleteDialog.newInstance(title = getString(R.string.clear_app_data), description = getString(R.string.clear_app_data_message), buttonText = getString(R.string.clear))
val dialog = ConfirmDeleteDialog.newInstance(
title = getString(R.string.clear_app_data),
description = getString(R.string.clear_app_data_message),
buttonText = getString(R.string.clear),
resultValue = RESULT_VALUE_CLEAR_APP_DATA
)
dialog.show(requireActivity().supportFragmentManager, RenameDialog::class.simpleName)
dialog.setListener { (requireActivity().getSystemService(ACTIVITY_SERVICE) as ActivityManager).clearApplicationUserData() }
} else {
val i = Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
i.addCategory(Intent.CATEGORY_DEFAULT)

Loading…
Cancel
Save