Commit 89b5646f authored by Geoffrey Métais's avatar Geoffrey Métais

Code cleaning

parent 23d4cd0d
......@@ -28,6 +28,7 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import kotlinx.android.synthetic.main.history_list.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
......@@ -47,7 +48,7 @@ private const val TAG = "VLC/HistoryFragment"
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
class HistoryFragment : MediaBrowserFragment<HistoryModel>(), IRefreshable, IHistory, androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener, IEventsHandler {
class HistoryFragment : MediaBrowserFragment<HistoryModel>(), IRefreshable, IHistory, SwipeRefreshLayout.OnRefreshListener, IEventsHandler {
private val historyAdapter: HistoryAdapter = HistoryAdapter(this)
......
......@@ -89,15 +89,15 @@ class InfoActivity : AudioPlayerContainerActivity(), View.OnClickListener {
model.cover.observe(this, Observer {
if (it != null) {
binding.cover = BitmapDrawable(this@InfoActivity.resources, it)
runOnMainThread(Runnable {
launch {
ViewCompat.setNestedScrollingEnabled(binding.container, true)
binding.appbar.setExpanded(true, true)
if (fabVisibility != -1) binding.fab.visibility = fabVisibility
})
}
} else noCoverFallback()
})
if (model.cover.value === null) model.getCover(item.artworkMrl, getScreenWidth())
AppScope.launch { updateMeta() }
launch { updateMeta() }
}
private fun updateMeta() {
......
......@@ -47,8 +47,7 @@ import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.*
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.medialibrary.media.Playlist
......@@ -72,6 +71,7 @@ import org.videolan.vlc.media.PlaylistManager
import org.videolan.vlc.util.*
import org.videolan.vlc.viewmodels.paged.MLPagedModel
import org.videolan.vlc.viewmodels.paged.PagedTracksModel
import java.lang.Runnable
import java.util.*
@ObsoleteCoroutinesApi
......@@ -81,7 +81,7 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
private lateinit var audioBrowserAdapter: AudioBrowserAdapter
private var playlist: MediaLibraryItem? = null
private val mediaLibrary = VLCApplication.mlInstance
private var binding: PlaylistActivityBinding? = null
private lateinit var binding: PlaylistActivityBinding
private var actionMode: ActionMode? = null
private var isPlaylist: Boolean = false
private var tracksModel: PagedTracksModel? = null
......@@ -93,16 +93,16 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
binding = DataBindingUtil.setContentView(this, R.layout.playlist_activity)
initAudioPlayerContainerActivity()
fragmentContainer = binding!!.songs
fragmentContainer = binding.songs
originalBottomPadding = fragmentContainer!!.paddingBottom
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
playlist = if (savedInstanceState != null)
savedInstanceState.getParcelable<Parcelable>(AudioBrowserFragment.TAG_ITEM) as MediaLibraryItem?
else
intent.getParcelableExtra<Parcelable>(AudioBrowserFragment.TAG_ITEM) as MediaLibraryItem?
isPlaylist = playlist!!.itemType == MediaLibraryItem.TYPE_PLAYLIST
binding!!.playlist = playlist
binding.playlist = playlist
tracksModel = ViewModelProviders.of(this, PagedTracksModel.Factory(this, playlist)).get(PagedTracksModel::class.java)
(tracksModel as MLPagedModel<MediaLibraryItem>).pagedList.observe(this, Observer<PagedList<MediaLibraryItem>> { tracks ->
if (tracks != null) {
......@@ -114,42 +114,40 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
})
audioBrowserAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_MEDIA, this, this, isPlaylist)
itemTouchHelper = ItemTouchHelper(SwipeDragItemTouchHelperCallback(audioBrowserAdapter))
itemTouchHelper!!.attachToRecyclerView(binding!!.songs)
itemTouchHelper!!.attachToRecyclerView(binding.songs)
binding!!.songs.layoutManager = LinearLayoutManager(this)
binding!!.songs.adapter = audioBrowserAdapter
binding.songs.layoutManager = LinearLayoutManager(this)
binding.songs.adapter = audioBrowserAdapter
val fabVisibility = savedInstanceState != null && savedInstanceState.getBoolean(TAG_FAB_VISIBILITY)
if (!TextUtils.isEmpty(playlist!!.artworkMrl)) {
runIO(Runnable {
val cover = AudioUtil.readCoverBitmap(Uri.decode(playlist!!.artworkMrl), resources.getDimensionPixelSize(R.dimen.audio_browser_item_size))
if (cover != null) {
binding!!.cover = BitmapDrawable(this@PlaylistActivity.resources, cover)
runOnMainThread(Runnable {
binding!!.appbar.setExpanded(true, true)
if (savedInstanceState != null) {
if (fabVisibility)
binding!!.fab.show()
else
binding!!.fab.hide()
}
})
} else
runOnMainThread(Runnable { fabFallback() })
})
} else
fabFallback()
binding!!.fab.setOnClickListener(this)
if (!TextUtils.isEmpty(playlist!!.artworkMrl)) launch {
val cover = withContext(Dispatchers.IO) {
AudioUtil.readCoverBitmap(Uri.decode(playlist!!.artworkMrl), resources.getDimensionPixelSize(R.dimen.audio_browser_item_size))
}
if (cover != null) {
binding.cover = BitmapDrawable(this@PlaylistActivity.resources, cover)
launch {
binding.appbar.setExpanded(true, true)
if (savedInstanceState != null) {
if (fabVisibility)
binding.fab.show()
else
binding.fab.hide()
}
}
} else fabFallback()
} else fabFallback()
binding.fab.setOnClickListener(this)
}
private fun fabFallback() {
binding!!.appbar.setExpanded(false)
val lp = binding!!.fab.layoutParams as CoordinatorLayout.LayoutParams
binding.appbar.setExpanded(false)
val lp = binding.fab.layoutParams as CoordinatorLayout.LayoutParams
lp.anchorId = R.id.songs
lp.anchorGravity = Gravity.BOTTOM or Gravity.END
lp.behavior = FloatingActionButtonBehavior(this@PlaylistActivity, null)
binding!!.fab.layoutParams = lp
binding!!.fab.show()
binding.fab.layoutParams = lp
binding.fab.show()
}
override fun onStop() {
......@@ -159,7 +157,7 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
public override fun onSaveInstanceState(outState: Bundle) {
outState.putParcelable(AudioBrowserFragment.TAG_ITEM, playlist)
outState.putBoolean(TAG_FAB_VISIBILITY, binding!!.fab.visibility == View.VISIBLE)
outState.putBoolean(TAG_FAB_VISIBILITY, binding.fab.visibility == View.VISIBLE)
super.onSaveInstanceState(outState)
}
......@@ -215,11 +213,11 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
}
override fun onPlayerStateChanged(bottomSheet: View, newState: Int) {
val visibility = binding!!.fab.visibility
val visibility = binding.fab.visibility
if (visibility == View.VISIBLE && newState != BottomSheetBehavior.STATE_COLLAPSED && newState != BottomSheetBehavior.STATE_HIDDEN)
binding!!.fab.hide()
binding.fab.hide()
else if (visibility == View.INVISIBLE && (newState == BottomSheetBehavior.STATE_COLLAPSED || newState == BottomSheetBehavior.STATE_HIDDEN))
binding!!.fab.show()
binding.fab.show()
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
......@@ -322,26 +320,24 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
private fun removeItem(position: Int, media: MediaWrapper) {
val resId = if (isPlaylist) R.string.confirm_remove_from_playlist else R.string.confirm_delete
if (isPlaylist) {
UiTools.snackerConfirm(binding!!.root, getString(resId, media.title), Runnable { (playlist as Playlist).remove(position) })
UiTools.snackerConfirm(binding.root, getString(resId, media.title), Runnable { (playlist as Playlist).remove(position) })
} else {
val deleteAction = Runnable { deleteMedia(media) }
UiTools.snackerConfirm(binding!!.root, getString(resId, media.title), Runnable { if (Util.checkWritePermission(this@PlaylistActivity, media, deleteAction)) deleteAction.run() })
UiTools.snackerConfirm(binding.root, getString(resId, media.title), Runnable { if (Util.checkWritePermission(this@PlaylistActivity, media, deleteAction)) deleteAction.run() })
}
}
private fun deleteMedia(mw: MediaLibraryItem) {
runIO(Runnable {
val foldersToReload = LinkedList<String>()
for (media in mw.tracks) {
val path = media.uri.path
val parentPath = FileUtils.getParent(path)
if (parentPath != null && FileUtils.deleteFile(path) && media.id > 0L && !foldersToReload.contains(parentPath)) {
foldersToReload.add(parentPath)
} else
UiTools.snacker(binding!!.root, getString(R.string.msg_delete_failed, media.title))
}
for (folder in foldersToReload) mediaLibrary.reload(folder)
})
private fun deleteMedia(mw: MediaLibraryItem) = launch(Dispatchers.IO) {
val foldersToReload = LinkedList<String>()
for (media in mw.tracks) {
val path = media.uri.path
val parentPath = FileUtils.getParent(path)
if (parentPath != null && FileUtils.deleteFile(path) && media.id > 0L && !foldersToReload.contains(parentPath)) {
foldersToReload.add(parentPath)
} else
UiTools.snacker(binding.root, getString(R.string.msg_delete_failed, media.title))
}
for (folder in foldersToReload) mediaLibrary.reload(folder)
}
override fun onClick(v: View) {
......@@ -350,24 +346,21 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
private fun removeFromPlaylist(list: List<MediaWrapper>, indexes: List<Int>) {
val itemsRemoved = HashMap<Int, Long>()
val playlist = this.playlist as Playlist?
val playlist = this.playlist as? Playlist ?: return
for (mediaItem in list) {
for (i in 0 until playlist!!.tracks.size) {
for (i in 0 until playlist.tracks.size) {
if (playlist.tracks[i].id == mediaItem.id) {
itemsRemoved[i] = mediaItem.id
}
}
}
for (index in indexes) {
playlist!!.remove(index)
}
for (index in indexes) playlist.remove(index)
UiTools.snackerWithCancel(binding!!.root, getString(R.string.removed_from_playlist_anonymous), null, Runnable {
UiTools.snackerWithCancel(binding.root, getString(R.string.removed_from_playlist_anonymous), null, Runnable {
for ((key, value) in itemsRemoved) {
playlist!!.add(value, key)
playlist.add(value, key)
}
})
}
......
......@@ -51,7 +51,6 @@ import org.videolan.vlc.gui.audio.BaseAudioBrowser
import org.videolan.vlc.gui.view.FastScroller
import org.videolan.vlc.gui.view.RecyclerSectionItemGridDecoration
import org.videolan.vlc.reloadLibrary
import org.videolan.vlc.util.AppScope
import org.videolan.vlc.util.getScreenWidth
import org.videolan.vlc.viewmodels.paged.PagedPlaylistsModel
......@@ -122,7 +121,7 @@ class PlaylistFragment : BaseAudioBrowser(), SwipeRefreshLayout.OnRefreshListene
binding.empty.visibility = if (it.isNullOrEmpty()) View.VISIBLE else View.GONE
})
viewModel.loading.observe(this, Observer<Boolean> { loading ->
AppScope.launch { binding.swipeLayout.isRefreshing = loading == true }
launch { binding.swipeLayout.isRefreshing = loading == true }
})
fastScroller.setRecyclerView(getCurrentRV(), viewModel)
......
......@@ -35,6 +35,7 @@ import androidx.lifecycle.ViewModelProviders
import androidx.paging.PagedList
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.viewpager.widget.ViewPager
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
......@@ -58,7 +59,7 @@ import org.videolan.vlc.viewmodels.paged.PagedTracksModel
/* All subclasses of Fragment must include a public empty constructor. */
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
class AudioAlbumsSongsFragment : BaseAudioBrowser(), androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener {
class AudioAlbumsSongsFragment : BaseAudioBrowser(), SwipeRefreshLayout.OnRefreshListener {
private var handler = Handler(Looper.getMainLooper())
private lateinit var albumModel: PagedAlbumsModel
......@@ -70,33 +71,30 @@ class AudioAlbumsSongsFragment : BaseAudioBrowser(), androidx.swiperefreshlayout
private lateinit var albumsAdapter: AudioBrowserAdapter
private lateinit var fastScroller: FastScroller
private lateinit var mItem: MediaLibraryItem
private lateinit var item: MediaLibraryItem
override val hasTabs = true
/*
* Disable Swipe Refresh while scrolling horizontally
*/
private val mSwipeFilter = View.OnTouchListener { v, event ->
private val swipeFilter = View.OnTouchListener { _, event ->
swipeRefreshLayout?.isEnabled = event.action == MotionEvent.ACTION_UP
false
}
override fun hasTabs(): Boolean {
return true
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mItem = if (savedInstanceState != null)
item = if (savedInstanceState != null)
savedInstanceState.getParcelable<Parcelable>(AudioBrowserFragment.TAG_ITEM) as MediaLibraryItem
else
arguments!!.getParcelable<Parcelable>(AudioBrowserFragment.TAG_ITEM) as MediaLibraryItem
albumModel = ViewModelProviders.of(this, PagedAlbumsModel.Factory(requireContext(), mItem)).get(PagedAlbumsModel::class.java)
tracksModel = ViewModelProviders.of(this, PagedTracksModel.Factory(requireContext(), mItem)).get(PagedTracksModel::class.java)
albumModel = ViewModelProviders.of(this, PagedAlbumsModel.Factory(requireContext(), item)).get(PagedAlbumsModel::class.java)
tracksModel = ViewModelProviders.of(this, PagedTracksModel.Factory(requireContext(), item)).get(PagedTracksModel::class.java)
audioModels = arrayOf(albumModel as MLPagedModel<MediaLibraryItem>, tracksModel as MLPagedModel<MediaLibraryItem>)
}
override fun getTitle(): String = mItem.title
override fun getTitle(): String = item.title
......@@ -127,7 +125,7 @@ class AudioAlbumsSongsFragment : BaseAudioBrowser(), androidx.swiperefreshlayout
fastScroller = view.rootView.findViewById<View>(R.id.songs_fast_scroller) as FastScroller
fastScroller.attachToCoordinator(view.rootView.findViewById<View>(R.id.appbar) as AppBarLayout, view.rootView.findViewById<View>(R.id.coordinator) as CoordinatorLayout, view.rootView.findViewById<View>(R.id.fab) as FloatingActionButton)
viewPager!!.setOnTouchListener(mSwipeFilter)
viewPager!!.setOnTouchListener(swipeFilter)
viewModel = audioModels[viewPager!!.currentItem]
viewPager!!.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {}
......@@ -172,7 +170,7 @@ class AudioAlbumsSongsFragment : BaseAudioBrowser(), androidx.swiperefreshlayout
}
override fun onSaveInstanceState(outState: Bundle) {
outState.putParcelable(AudioBrowserFragment.TAG_ITEM, mItem)
outState.putParcelable(AudioBrowserFragment.TAG_ITEM, item)
super.onSaveInstanceState(outState)
}
......
......@@ -78,6 +78,7 @@ class AudioBrowserFragment : BaseAudioBrowser(), SwipeRefreshLayout.OnRefreshLis
private lateinit var models: Array<MLPagedModel<MediaLibraryItem>>
private lateinit var settings: SharedPreferences
private lateinit var fastScroller: FastScroller
override val hasTabs = true
/**
* Handle changes on the list
......@@ -92,10 +93,6 @@ class AudioBrowserFragment : BaseAudioBrowser(), SwipeRefreshLayout.OnRefreshLis
false
}
override fun hasTabs(): Boolean {
return true
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (!::settings.isInitialized) settings = Settings.getInstance(requireContext())
......
......@@ -34,6 +34,7 @@ import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.R
......@@ -177,7 +178,7 @@ abstract class BaseAudioBrowser : MediaBrowserFragment<MLPagedModel<*>>(), IEven
val tracks = ArrayList<MediaWrapper>()
for (mediaItem in list)
tracks.addAll(Arrays.asList(*mediaItem.tracks))
runOnMainThread(Runnable {
launch {
when (item.itemId) {
R.id.action_mode_audio_play -> MediaUtils.openList(activity, tracks, 0)
R.id.action_mode_audio_append -> MediaUtils.appendMedia(activity, tracks)
......@@ -185,7 +186,7 @@ abstract class BaseAudioBrowser : MediaBrowserFragment<MLPagedModel<*>>(), IEven
R.id.action_mode_audio_info -> showInfoDialog(list[0])
R.id.action_mode_audio_set_song -> AudioUtil.setRingtone(list[0] as MediaWrapper, requireActivity())
}
})
}
})
return true
}
......
......@@ -40,7 +40,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import kotlinx.coroutines.*
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.tools.coroutineScope
import org.videolan.vlc.R
import org.videolan.vlc.databinding.DirectoryBrowserBinding
import org.videolan.vlc.gui.AudioPlayerContainerActivity
......@@ -367,7 +366,7 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
}
}
private fun toggleFavorite() = coroutineScope.launch {
private fun toggleFavorite() = launch {
val mw = currentMedia ?: return@launch
withContext(Dispatchers.IO) {
when {
......@@ -409,7 +408,7 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
}
override fun onCtxClick(v: View, position: Int, item: MediaLibraryItem) {
if (actionMode == null && item.itemType == MediaLibraryItem.TYPE_MEDIA) coroutineScope.launch {
if (actionMode == null && item.itemType == MediaLibraryItem.TYPE_MEDIA) launch {
val mw = item as MediaWrapper
if (mw.uri.scheme == "content" || mw.uri.scheme == OTG_SCHEME) return@launch
var flags = if (!isRootDirectory && this@BaseBrowserFragment is FileBrowserFragment) CTX_DELETE else 0
......@@ -457,7 +456,7 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
}
CTX_ADD_TO_PLAYLIST -> UiTools.addToPlaylist(requireActivity(), mw.tracks, SavePlaylistDialog.KEY_NEW_TRACKS)
CTX_DOWNLOAD_SUBTITLES -> MediaUtils.getSubs(requireActivity(), mw)
CTX_FAV_REMOVE -> coroutineScope.launch(Dispatchers.IO) { browserFavRepository.deleteBrowserFav(mw.uri) }
CTX_FAV_REMOVE -> launch(Dispatchers.IO) { browserFavRepository.deleteBrowserFav(mw.uri) }
}
}
......
......@@ -34,6 +34,7 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.ExternalMonitor
......@@ -150,13 +151,13 @@ open class FileBrowserFragment : BaseBrowserFragment() {
item.isVisible = !isRootDirectory && mrl!!.startsWith("file")
runIO(Runnable {
val isFavorite = mrl != null && browserFavRepository.browserFavExists(Uri.parse(mrl))
runOnMainThread(Runnable {
launch {
item.setIcon(if (isFavorite)
R.drawable.ic_menu_bookmark_w
else
R.drawable.ic_menu_bookmark_outline_w)
item.setTitle(if (isFavorite) R.string.favorites_remove else R.string.favorites_add)
})
}
})
}
......
......@@ -37,8 +37,7 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.TransitionManager
import com.google.android.material.floatingactionbutton.FloatingActionButton
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.*
import org.videolan.medialibrary.Medialibrary
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
......@@ -54,13 +53,14 @@ import org.videolan.vlc.interfaces.Filterable
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.util.*
import org.videolan.vlc.viewmodels.SortableModel
import java.lang.Runnable
import java.util.*
private const val TAG = "VLC/MediaBrowserFragment"
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
abstract class MediaBrowserFragment<T : SortableModel> : Fragment(), ActionMode.Callback, Filterable {
abstract class MediaBrowserFragment<T : SortableModel> : Fragment(), ActionMode.Callback, Filterable, CoroutineScope by MainScope() {
private lateinit var searchButtonView: View
var swipeRefreshLayout: SwipeRefreshLayout? = null
......@@ -69,6 +69,7 @@ abstract class MediaBrowserFragment<T : SortableModel> : Fragment(), ActionMode.
var fabPlay: FloatingActionButton? = null
open lateinit var viewModel: T
protected set
open val hasTabs = false
abstract fun getTitle(): String
......@@ -80,8 +81,6 @@ abstract class MediaBrowserFragment<T : SortableModel> : Fragment(), ActionMode.
return (activity as? AudioPlayerContainerActivity)?.menu
}
protected open fun hasTabs() = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mediaLibrary = VLCApplication.mlInstance
......@@ -127,7 +126,7 @@ abstract class MediaBrowserFragment<T : SortableModel> : Fragment(), ActionMode.
it.subtitle = subTitle
activity.invalidateOptionsMenu()
}
if (activity is ContentActivity) activity.setTabLayoutVisibility(hasTabs())
if (activity is ContentActivity) activity.setTabLayoutVisibility(hasTabs)
}
override fun onPause() {
......@@ -179,13 +178,13 @@ abstract class MediaBrowserFragment<T : SortableModel> : Fragment(), ActionMode.
}
for (folder in foldersToReload) mediaLibrary.reload(folder)
if (activity != null) {
runOnMainThread(Runnable {
launch {
if (mediaPaths.isEmpty()) {
failCB?.run()
return@Runnable
return@launch
}
if (refresh) onRefresh()
})
}
}
})
}
......
......@@ -39,13 +39,17 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.ExternalMonitor
import org.videolan.vlc.R
import org.videolan.vlc.VLCApplication
import org.videolan.vlc.gui.dialogs.NetworkServerDialog
import org.videolan.vlc.gui.dialogs.VlcLoginDialog
import org.videolan.vlc.util.*
import org.videolan.vlc.util.CTX_FAV_ADD
import org.videolan.vlc.util.CTX_FAV_EDIT
import org.videolan.vlc.util.Util
import org.videolan.vlc.util.runIO
import org.videolan.vlc.viewmodels.browser.NetworkModel
@ExperimentalCoroutinesApi
......@@ -85,13 +89,13 @@ class NetworkBrowserFragment : BaseBrowserFragment() {
item.isVisible = !isRootDirectory
runIO(Runnable {
val isFavorite = mrl != null && browserFavRepository.browserFavExists(Uri.parse(mrl))
runOnMainThread(Runnable {
launch {
item.setIcon(if (isFavorite)
R.drawable.ic_menu_bookmark_w
else
R.drawable.ic_menu_bookmark_outline_w)
item.setTitle(if (isFavorite) R.string.favorites_remove else R.string.favorites_add)
})
}
})
}
......
......@@ -63,14 +63,14 @@ internal class StorageBrowserAdapter(fragment: StorageBrowserFragment) : BaseBro
vh.binding.item = storage
job?.join()
val hasContextMenu = customDirsLocation.contains(storagePath)
val checked = (fragment as StorageBrowserFragment).mScannedDirectory || mediaDirsLocation.containsPath(storagePath)
val checked = (fragment as StorageBrowserFragment).scannedDirectory || mediaDirsLocation.containsPath(storagePath)
vh.binding.hasContextMenu = hasContextMenu
when {
checked -> vh.binding.browserCheckbox.state = ThreeStatesCheckbox.STATE_CHECKED
hasDiscoveredChildren(storagePath) -> vh.binding.browserCheckbox.state = ThreeStatesCheckbox.STATE_PARTIAL
else -> vh.binding.browserCheckbox.state = ThreeStatesCheckbox.STATE_UNCHECKED
}
vh.binding.checkEnabled = !(fragment as StorageBrowserFragment).mScannedDirectory
vh.binding.checkEnabled = !(fragment as StorageBrowserFragment).scannedDirectory
}
}
......
......@@ -38,13 +38,15 @@ import androidx.collection.SimpleArrayMap
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.interfaces.EntryPointsEventsCb
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.medialibrary.media.Storage
import org.videolan.tools.coroutineScope
import org.videolan.vlc.MediaParsingService
import org.videolan.vlc.R
import org.videolan.vlc.VLCApplication
......@@ -64,12 +66,12 @@ const val KEY_IN_MEDIALIB = "key_in_medialib"
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
class StorageBrowserFragment : FileBrowserFragment(), EntryPointsEventsCb, CoroutineScope by MainScope() {
class StorageBrowserFragment : FileBrowserFragment(), EntryPointsEventsCb {
internal var mScannedDirectory = false
private val mProcessingFolders = SimpleArrayMap<String, CheckBox>()
private var mSnack: com.google.android.material.snackbar.Snackbar? = null
private var mAlertDialog: AlertDialog? = null
internal var scannedDirectory = false
private val processingFolders = SimpleArrayMap<String, CheckBox>()
private var snack: com.google.android.material.snackbar.Snackbar? = null
private var alertDialog: AlertDialog? = null
override val categoryTitle: String
get() = getString(R.string.directories_summary)
......@@ -83,15 +85,15 @@ class StorageBrowserFragment : FileBrowserFragment(), EntryPointsEventsCb, Corou
super.onCreate(bundle)
adapter = StorageBrowserAdapter(this)
if (bundle == null) bundle = arguments
if (bundle != null) mScannedDirectory = bundle.getBoolean(KEY_IN_MEDIALIB)
if (bundle != null) scannedDirectory = bundle.getBoolean(KEY_IN_MEDIALIB)
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (isRootDirectory && AndroidDevices.showTvUi(view.context)) {
mSnack = com.google.android.material.snackbar.Snackbar.make(view, R.string.tv_settings_hint, com.google.android.material.snackbar.Snackbar.LENGTH_INDEFINITE)
if (AndroidUtil.isLolliPopOrLater) mSnack?.view?.elevation = view.resources.getDimensionPixelSize(R.dimen.audio_player_elevation).toFloat()
snack = com.google.android.material.snackbar.Snackbar.make(view, R.string.tv_settings_hint, com.google.android.material.snackbar.Snackbar.LENGTH_INDEFINITE)
if (AndroidUtil.isLolliPopOrLater) snack?.view?.elevation = view.resources.getDimensionPixelSize(R.dimen.audio_player_elevation).toFloat()
}
}
......@@ -102,20 +104,20 @@ class StorageBrowserFragment : FileBrowserFragment(), EntryPointsEventsCb, Corou
override fun onStart() {
super.onStart()
VLCApplication.mlInstance.addEntryPointsEventsCb(this)
mSnack?.show()
snack?.show()
launch { if (isAdded) (adapter as StorageBrowserAdapter).updateListState(requireContext()) }
}
override fun onStop() {
super.onStop()
VLCApplication.mlInstance.removeEntryPointsEventsCb(this)
mSnack?.dismiss()
mAlertDialog?.let { if (it.isShowing) it.dismiss() }
snack?.dismiss()
alertDialog?.let { if (it.isShowing) it.dismiss() }
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(KEY_IN_MEDIALIB, mScannedDirectory)
outState.putBoolean(KEY_IN_MEDIALIB, scannedDirectory)
}
override fun onPrepareOptionsMenu(menu: Menu) {
......@@ -137,7 +139,7 @@ class StorageBrowserFragment : FileBrowserFragment(), EntryPointsEventsCb, Corou
val next = createFragment()
val args = Bundle()
args.putParcelable(KEY_MEDIA, media)
args.putBoolean(KEY_IN_MEDIALIB, mScannedDirectory || scanned)
args.putBoolean(KEY_IN_MEDIALIB, scannedDirectory || scanned)
next.arguments = args
ft?.replace(R.id.fragment_placeholder, next, media.location)
ft?.addToBackStack(if (isRootDirectory) "root" else currentMedia?.title
......@@ -196,7 +198,7 @@ class StorageBrowserFragment : FileBrowserFragment(), EntryPointsEventsCb, Corou
internal fun processEvent(cbp: CheckBox, mrl: String) {
cbp.isEnabled = false
mProcessingFolders.put(mrl, cbp)
processingFolders.put(mrl, cbp)
}
override fun onEntryPointBanned(entryPoint: String, success: Boolean) {}
......@@ -207,8 +209,8 @@ class StorageBrowserFragment : FileBrowserFragment(), EntryPointsEventsCb, Corou
var entryPoint = entryPoint
if (entryPoint.endsWith("/"))
entryPoint = entryPoint.substring(0, entryPoint.length - 1)
if (mProcessingFolders.containsKey(entryPoint)) {
mProcessingFolders.remove(entryPoint)?.let {
if (processingFolders.containsKey(entryPoint)) {
processingFolders.remove(entryPoint)?.let {
handler.post {
it.isEnabled = true
if (success) {
......@@ -228,9 +230,9 @@ class StorageBrowserFragment : FileBrowserFragment(), EntryPointsEventsCb, Corou
override fun onDiscoveryCompleted(entryPoint: String) {
var path = entryPoint
if (path.endsWith("/")) path = path.dropLast(1)
if (mProcessingFolders.containsKey(path)) {
if (processingFolders.containsKey(path)) {
val finalPath = path
handler.post { mProcessingFolders.get(finalPath)?.isEnabled = true }
handler.post { processingFolders.get