[Android] Network browser: ViewModel observes network status

Geoffrey Métais git at videolan.org
Mon Sep 23 18:10:52 CEST 2019


vlc-android | branch: 3.2.x | Geoffrey Métais <geoffrey.metais at gmail.com> | Tue Sep 17 16:11:27 2019 +0200| [a170070d71ab5c8054e9f29e9b9fdb7eac205066] | committer: Geoffrey Métais

Network browser: ViewModel observes network status

(cherry picked from commit 0b1e6cddcdac1ada356dc5670999f0c8350adebf)

> https://code.videolan.org/videolan/vlc-android/commit/a170070d71ab5c8054e9f29e9b9fdb7eac205066
---

 .../vlc/gui/browser/NetworkBrowserFragment.kt      | 34 +++++++---------------
 .../vlc/gui/tv/browser/FileBrowserTvFragment.kt    |  8 ++---
 .../vlc/viewmodels/browser/BrowserModel.kt         |  5 +++-
 .../vlc/viewmodels/browser/NetworkModel.kt         | 12 ++++++++
 4 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.kt b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.kt
index 2ecadb57b..f001f66f6 100644
--- a/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.kt
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.kt
@@ -37,9 +37,7 @@ import androidx.lifecycle.Observer
 import androidx.lifecycle.ViewModelProviders
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import androidx.recyclerview.widget.RecyclerView
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.ObsoleteCoroutinesApi
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
 import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
 import org.videolan.tools.isStarted
 import org.videolan.vlc.ExternalMonitor
@@ -50,7 +48,6 @@ import org.videolan.vlc.gui.dialogs.VlcLoginDialog
 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
@@ -75,11 +72,6 @@ class NetworkBrowserFragment : BaseBrowserFragment() {
         if (isRootDirectory) swipeRefreshLayout.isEnabled = false
     }
 
-    override fun onActivityCreated(savedInstanceState: Bundle?) {
-        super.onActivityCreated(savedInstanceState)
-        ExternalMonitor.connected.observe(this, Observer { connected -> refresh(connected!!) })
-    }
-
     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
         inflater.inflate(R.menu.fragment_option_network, menu)
         super.onCreateOptionsMenu(menu, inflater)
@@ -89,16 +81,14 @@ class NetworkBrowserFragment : BaseBrowserFragment() {
         super.onPrepareOptionsMenu(menu)
         val item = menu.findItem(R.id.ml_menu_save)
         item.isVisible = !isRootDirectory
-        runIO(Runnable {
-            val isFavorite = mrl != null && browserFavRepository.browserFavExists(Uri.parse(mrl))
-            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)
-            }
-        })
+        launch {
+            val isFavorite = mrl != null && withContext(Dispatchers.IO) { browserFavRepository.browserFavExists(Uri.parse(mrl)) }
+            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)
+        }
     }
 
     override fun onStart() {
@@ -109,11 +99,7 @@ class NetworkBrowserFragment : BaseBrowserFragment() {
     }
 
     override fun refresh() {
-        refresh(ExternalMonitor.isConnected)
-    }
-
-    fun refresh(connected: Boolean) {
-        if (connected)
+        if (ExternalMonitor.isConnected)
             super.refresh()
         else {
             updateEmptyView()
diff --git a/vlc-android/src/org/videolan/vlc/gui/tv/browser/FileBrowserTvFragment.kt b/vlc-android/src/org/videolan/vlc/gui/tv/browser/FileBrowserTvFragment.kt
index 46b55b118..fead9d144 100644
--- a/vlc-android/src/org/videolan/vlc/gui/tv/browser/FileBrowserTvFragment.kt
+++ b/vlc-android/src/org/videolan/vlc/gui/tv/browser/FileBrowserTvFragment.kt
@@ -9,6 +9,7 @@ import android.view.View
 import androidx.core.content.ContextCompat
 import androidx.fragment.app.FragmentManager
 import androidx.lifecycle.Observer
+import androidx.lifecycle.ViewModelProviders
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager
@@ -33,10 +34,7 @@ import org.videolan.vlc.util.CATEGORY
 import org.videolan.vlc.util.FileUtils
 import org.videolan.vlc.util.ITEM
 import org.videolan.vlc.util.isSchemeSupported
-import org.videolan.vlc.viewmodels.browser.BrowserModel
-import org.videolan.vlc.viewmodels.browser.TYPE_FILE
-import org.videolan.vlc.viewmodels.browser.TYPE_NETWORK
-import org.videolan.vlc.viewmodels.browser.getBrowserModel
+import org.videolan.vlc.viewmodels.browser.*
 
 private const val TAG = "FileBrowserTvFragment"
 @UseExperimental(ObsoleteCoroutinesApi::class)
@@ -90,10 +88,10 @@ class FileBrowserTvFragment : BaseBrowserTvFragment(), PathAdapterListener {
         super.onCreate(savedInstanceState)
         item = if (savedInstanceState != null) savedInstanceState.getParcelable<Parcelable>(ITEM) as? MediaLibraryItem
         else arguments?.getParcelable(ITEM) as? MediaLibraryItem
-        viewModel = getBrowserModel(getCategory(), (item as? AbstractMediaWrapper)?.location, true, false)
 
         isRootLevel = arguments?.getBoolean("rootLevel") ?: false
         (item as? MediaWrapper)?.run { mrl = location }
+        viewModel = ViewModelProviders.of(this, NetworkModel.Factory(requireContext(), mrl, false)).get(NetworkModel::class.java)
 
         viewModel.currentItem = item
         browserFavRepository = BrowserFavRepository.getInstance(requireContext())
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/browser/BrowserModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/browser/BrowserModel.kt
index 30faa35aa..95b72acec 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/browser/BrowserModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/browser/BrowserModel.kt
@@ -120,4 +120,7 @@ private val descComp by lazy {
 }
 
 @ExperimentalCoroutinesApi
-fun Fragment.getBrowserModel(category: Long, url: String?, showHiddenFiles: Boolean, showDummyCategory: Boolean) = ViewModelProviders.of(this, BrowserModel.Factory(requireContext(), url, category, showHiddenFiles, showDummyCategory = showDummyCategory)).get(BrowserModel::class.java)
+fun Fragment.getBrowserModel(category: Long, url: String?, showHiddenFiles: Boolean, showDummyCategory: Boolean) = if (category == TYPE_NETWORK)
+    ViewModelProviders.of(this, NetworkModel.Factory(requireContext(), url, showHiddenFiles)).get(NetworkModel::class.java)
+else
+    ViewModelProviders.of(this, BrowserModel.Factory(requireContext(), url, category, showHiddenFiles, showDummyCategory = showDummyCategory)).get(BrowserModel::class.java)
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/browser/NetworkModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/browser/NetworkModel.kt
index 6871f1b52..b2d634fc8 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/browser/NetworkModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/browser/NetworkModel.kt
@@ -21,11 +21,23 @@
 package org.videolan.vlc.viewmodels.browser
 
 import android.content.Context
+import androidx.lifecycle.Observer
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
+import org.videolan.vlc.ExternalMonitor
 
 class NetworkModel(context: Context, url: String? = null, showHiddenFiles: Boolean) : BrowserModel(context, url, TYPE_NETWORK, showHiddenFiles, true) {
 
+    private val networkObs = Observer<Boolean> { if (it == true) refresh() }
+
+    init {
+        ExternalMonitor.connected.observeForever(networkObs)
+    }
+
+    override fun onCleared() {
+        ExternalMonitor.connected.removeObserver(networkObs)
+        super.onCleared()
+    }
     class Factory(val context: Context, val url: String?, private val showHiddenFiles: Boolean): ViewModelProvider.NewInstanceFactory() {
         override fun <T : ViewModel> create(modelClass: Class<T>): T {
             @Suppress("UNCHECKED_CAST")



More information about the Android mailing list