diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt index 0c4e3498d..6d07f7817 100644 --- a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt +++ b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt @@ -38,6 +38,7 @@ import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.text.TextUtils import android.view.* +import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.withContext import org.videolan.medialibrary.media.MediaLibraryItem import org.videolan.medialibrary.media.MediaWrapper @@ -81,7 +82,7 @@ abstract class BaseBrowserFragment : MediaBrowserFragment(), IRefr protected abstract val categoryTitle: String protected lateinit var binding: DirectoryBrowserBinding - private lateinit var browserFavRepository: BrowserFavRepository + protected lateinit var browserFavRepository: BrowserFavRepository protected abstract fun createFragment(): Fragment @@ -351,6 +352,29 @@ abstract class BaseBrowserFragment : MediaBrowserFragment(), IRefr adapter.resetSelectionCount() } + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + when (item!!.itemId) { + R.id.ml_menu_save -> { + toggleFavorite() + onPrepareOptionsMenu(menu) + return true + } + else -> return super.onOptionsItemSelected(item) + } + } + + private fun toggleFavorite() = uiJob(false) { + val mw = currentMedia ?: return@uiJob + withContext(VLCIO) { + when { + browserFavRepository.browserFavExists(mw.uri) -> browserFavRepository.deleteBrowserFav(mw.uri) + mw.uri.scheme == "file" -> browserFavRepository.addLocalFavItem(mw.uri, mw.title, mw.artworkURL) + else -> browserFavRepository.addNetworkFavItem(mw.uri, mw.title, mw.artworkURL) + } + } + activity?.invalidateOptionsMenu() + } + override fun onClick(v: View, position: Int, item: MediaLibraryItem) { val mediaWrapper = item as MediaWrapper if (mActionMode != null) { @@ -393,10 +417,14 @@ abstract class BaseBrowserFragment : MediaBrowserFragment(), IRefr if (mw.type == MediaWrapper.TYPE_DIR) { val isEmpty = viewModel.isFolderEmpty(mw) if (!isEmpty) flags = flags or Constants.CTX_PLAY - if (this@BaseBrowserFragment is NetworkBrowserFragment) { + val isFileBrowser = this@BaseBrowserFragment is FileBrowserFragment && item.uri.scheme == "file" + val isNetworkBrowser = this@BaseBrowserFragment is NetworkBrowserFragment + if (isFileBrowser || isNetworkBrowser) { val favExists = withContext(VLCIO) { browserFavRepository.browserFavExists(mw.uri) } - flags = if (favExists) flags or Constants.CTX_NETWORK_EDIT or Constants.CTX_NETWORK_REMOVE - else flags or Constants.CTX_NETWORK_ADD + flags = if (favExists) { + if (isNetworkBrowser) flags or Constants.CTX_FAV_EDIT or Constants.CTX_FAV_REMOVE + else flags or Constants.CTX_FAV_REMOVE + } else flags or Constants.CTX_FAV_ADD } } else { val isVideo = mw.type == MediaWrapper.TYPE_VIDEO @@ -412,10 +440,7 @@ abstract class BaseBrowserFragment : MediaBrowserFragment(), IRefr override fun onCtxAction(position: Int, option: Int) { if (adapter.getItem(position) !is MediaWrapper) return - val uri = (adapter.getItem(position) as MediaWrapper).uri - val mwFromMl = if ("file" == uri.scheme) mMediaLibrary.getMedia(uri) else null - val mw = mwFromMl ?: adapter.getItem(position) as MediaWrapper - + val mw = adapter.getItem(position) as MediaWrapper when (option) { Constants.CTX_PLAY -> MediaUtils.openMedia(activity, mw) Constants.CTX_PLAY_ALL -> { @@ -432,6 +457,7 @@ abstract class BaseBrowserFragment : MediaBrowserFragment(), IRefr } Constants.CTX_ADD_TO_PLAYLIST -> UiTools.addToPlaylist(requireActivity(), mw.tracks, SavePlaylistDialog.KEY_NEW_TRACKS) Constants.CTX_DOWNLOAD_SUBTITLES -> MediaUtils.getSubs(requireActivity(), mw) + Constants.CTX_FAV_REMOVE -> launch(VLCIO) { browserFavRepository.deleteBrowserFav(mw.uri) } } } diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java index 9e4fcab4b..7d67e3ef0 100644 --- a/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java +++ b/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java @@ -31,6 +31,9 @@ import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import org.jetbrains.annotations.NotNull; @@ -40,8 +43,10 @@ import org.videolan.vlc.ExternalMonitor; import org.videolan.vlc.R; import org.videolan.vlc.gui.helpers.hf.OtgAccess; import org.videolan.vlc.util.AndroidDevices; +import org.videolan.vlc.util.Constants; import org.videolan.vlc.util.FileUtils; import org.videolan.vlc.util.Strings; +import org.videolan.vlc.util.WorkersKt; import org.videolan.vlc.viewmodels.browser.BrowserModel; import org.videolan.vlc.viewmodels.browser.BrowserModelKt; @@ -114,6 +119,48 @@ public class FileBrowserFragment extends BaseBrowserFragment { super.onClick(v, position, item); } + @Override + public void onCtxAction(int position, int option) { + final MediaWrapper mw = (MediaWrapper) getAdapter().getItem(position); + switch (option) { + case Constants.CTX_FAV_ADD: + getBrowserFavRepository().addLocalFavItem(mw.getUri(), mw.getTitle(), mw.getArtworkURL()); + break; + default: + super.onCtxAction(position, option); + } + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + if (!(this instanceof FilePickerFragment || this instanceof StorageBrowserFragment)) + inflater.inflate(R.menu.fragment_option_network, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + final MenuItem item = menu.findItem(R.id.ml_menu_save); + if (item == null) return; + item.setVisible(!isRootDirectory() && getMrl().startsWith("file")); + WorkersKt.runBackground(new Runnable() { + @Override + public void run() { + final boolean isFavorite = getMrl() != null && getBrowserFavRepository().browserFavExists(Uri.parse(getMrl())); + WorkersKt.runOnMainThread(new Runnable() { + @Override + public void run() { + item.setIcon(isFavorite ? + R.drawable.ic_menu_bookmark_w : + R.drawable.ic_menu_bookmark_outline_w); + item.setTitle(isFavorite ? R.string.favorites_remove : R.string.favorites_add); + } + }); + } + }); + } + private void browseOtgDevice(@NotNull Uri uri, @NotNull String title) { final MediaWrapper mw = new MediaWrapper(uri); mw.setType(MediaWrapper.TYPE_DIR); diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java index 5daebf389..7f918e918 100644 --- a/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java +++ b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java @@ -23,7 +23,6 @@ package org.videolan.vlc.gui.browser; -import android.app.Activity; import android.arch.lifecycle.Observer; import android.arch.lifecycle.ViewModelProviders; import android.content.BroadcastReceiver; @@ -50,7 +49,6 @@ import org.videolan.vlc.VLCApplication; import org.videolan.vlc.gui.SimpleAdapter; import org.videolan.vlc.gui.dialogs.NetworkServerDialog; import org.videolan.vlc.gui.dialogs.VlcLoginDialog; -import org.videolan.vlc.repository.BrowserFavRepository; import org.videolan.vlc.util.Constants; import org.videolan.vlc.util.Util; import org.videolan.vlc.util.WorkersKt; @@ -58,7 +56,6 @@ import org.videolan.vlc.viewmodels.browser.NetworkModel; public class NetworkBrowserFragment extends BaseBrowserFragment implements SimpleAdapter.FavoritesHandler { - BrowserFavRepository mBrowserFavRepository; @Override public void onClick(@NotNull MediaLibraryItem item) { browse((MediaWrapper) item, true); @@ -68,7 +65,6 @@ public class NetworkBrowserFragment extends BaseBrowserFragment implements Simpl public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); viewModel = ViewModelProviders.of(this, new NetworkModel.Factory(getMrl(), getShowHiddenFiles())).get(NetworkModel.class); - mBrowserFavRepository = new BrowserFavRepository(requireContext()); } @Override @@ -96,7 +92,7 @@ public class NetworkBrowserFragment extends BaseBrowserFragment implements Simpl WorkersKt.runBackground(new Runnable() { @Override public void run() { - final boolean isFavorite = getMrl() != null && mBrowserFavRepository.browserFavExists(Uri.parse(getMrl())); + final boolean isFavorite = getMrl() != null && getBrowserFavRepository().browserFavExists(Uri.parse(getMrl())); WorkersKt.runOnMainThread(new Runnable() { @Override public void run() { @@ -131,18 +127,6 @@ public class NetworkBrowserFragment extends BaseBrowserFragment implements Simpl } } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.ml_menu_save: - toggleFavorite(); - onPrepareOptionsMenu(getMenu()); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - @Override protected Fragment createFragment() { return new NetworkBrowserFragment(); @@ -161,20 +145,12 @@ public class NetworkBrowserFragment extends BaseBrowserFragment implements Simpl public void onCtxAction(int position, int option) { final MediaWrapper mw = (MediaWrapper) getAdapter().getItem(position); switch (option) { - case Constants.CTX_NETWORK_ADD: - mBrowserFavRepository.addNetworkFavItem(mw.getUri(), mw.getTitle(), mw.getArtworkURL()); + case Constants.CTX_FAV_ADD: + getBrowserFavRepository().addNetworkFavItem(mw.getUri(), mw.getTitle(), mw.getArtworkURL()); break; - case Constants.CTX_NETWORK_EDIT: + case Constants.CTX_FAV_EDIT: showAddServerDialog(mw); break; - case Constants.CTX_NETWORK_REMOVE: - WorkersKt.runBackground(new Runnable() { - @Override - public void run() { - mBrowserFavRepository.deleteBrowserFav(mw.getUri()); - } - }); - break; default: super.onCtxAction(position, option); } @@ -192,25 +168,6 @@ public class NetworkBrowserFragment extends BaseBrowserFragment implements Simpl return getString(R.string.network_browsing); } - public void toggleFavorite() { - WorkersKt.runBackground(new Runnable() { - @Override - public void run() { - if (mBrowserFavRepository.browserFavExists(getCurrentMedia().getUri())) - mBrowserFavRepository.deleteBrowserFav(getCurrentMedia().getUri()); - else - mBrowserFavRepository.addNetworkFavItem(getCurrentMedia().getUri(), getCurrentMedia().getTitle(), getCurrentMedia().getArtworkURL()); - WorkersKt.runOnMainThread(new Runnable() { - @Override - public void run() { - final Activity activity = getActivity(); - if (activity!= null) activity.invalidateOptionsMenu(); - } - }); - } - }); - } - /** * Update views visibility and emptiness info */ diff --git a/vlc-android/src/org/videolan/vlc/gui/dialogs/ContextSheet.kt b/vlc-android/src/org/videolan/vlc/gui/dialogs/ContextSheet.kt index 75b519913..6415df9ee 100644 --- a/vlc-android/src/org/videolan/vlc/gui/dialogs/ContextSheet.kt +++ b/vlc-android/src/org/videolan/vlc/gui/dialogs/ContextSheet.kt @@ -92,9 +92,9 @@ class ContextSheet : BottomSheetDialogFragment() { if (flags and Constants.CTX_PLAY_NEXT != 0) add(Simple(Constants.CTX_PLAY_NEXT, getString(R.string.insert_next), R.drawable.ic_ctx_play_next_normal)) if (flags and Constants.CTX_ADD_TO_PLAYLIST != 0) add(Simple(Constants.CTX_ADD_TO_PLAYLIST, getString(R.string.add_to_playlist), R.drawable.ic_ctx_add_to_playlist_normal)) if (flags and Constants.CTX_SET_RINGTONE != 0 && AndroidDevices.isPhone) add(Simple(Constants.CTX_SET_RINGTONE, getString(R.string.set_song), R.drawable.ic_ctx_set_ringtone_normal)) - if (flags and Constants.CTX_NETWORK_ADD != 0) add(Simple(Constants.CTX_NETWORK_ADD, getString(R.string.favorites_add), R.drawable.ic_menu_network)) - if (flags and Constants.CTX_NETWORK_EDIT != 0) add(Simple(Constants.CTX_NETWORK_EDIT, getString(R.string.favorites_edit), R.drawable.ic_menu_network)) - if (flags and Constants.CTX_NETWORK_REMOVE != 0) add(Simple(Constants.CTX_NETWORK_REMOVE, getString(R.string.favorites_remove), R.drawable.ic_menu_network)) + if (flags and Constants.CTX_FAV_ADD != 0) add(Simple(Constants.CTX_FAV_ADD, getString(R.string.favorites_add), R.drawable.ic_menu_network)) + if (flags and Constants.CTX_FAV_EDIT != 0) add(Simple(Constants.CTX_FAV_EDIT, getString(R.string.favorites_edit), R.drawable.ic_menu_network)) + if (flags and Constants.CTX_FAV_REMOVE != 0) add(Simple(Constants.CTX_FAV_REMOVE, getString(R.string.favorites_remove), R.drawable.ic_menu_network)) } inner class ContextAdapter : RecyclerView.Adapter() { diff --git a/vlc-android/src/org/videolan/vlc/providers/FileBrowserProvider.kt b/vlc-android/src/org/videolan/vlc/providers/FileBrowserProvider.kt index f5697d827..b5d5e6190 100644 --- a/vlc-android/src/org/videolan/vlc/providers/FileBrowserProvider.kt +++ b/vlc-android/src/org/videolan/vlc/providers/FileBrowserProvider.kt @@ -39,10 +39,16 @@ import org.videolan.vlc.repository.BrowserFavRepository import org.videolan.vlc.util.* import java.io.File -open class FileBrowserProvider(dataset: LiveDataset, url: String?, private val filePicker: Boolean = false, showHiddenFiles: Boolean) : BrowserProvider(dataset, url, showHiddenFiles), Observer> { +open class FileBrowserProvider( + dataset: LiveDataset, + url: String?, private val filePicker: Boolean = false, + showHiddenFiles: Boolean) : BrowserProvider(dataset, + url, showHiddenFiles +), Observer> { private var storagePosition = -1 private var otgPosition = -1 + private val showFavorites : Boolean private val favorites = if (url == null && !filePicker) BrowserFavRepository(VLCApplication.getAppContext()).localFavorites else null private val favoritesObserver by lazy { Observer> { @@ -66,9 +72,10 @@ open class FileBrowserProvider(dataset: LiveDataset, url: Stri } } init { + showFavorites = url == null && !filePicker && this !is StorageProvider if (url == null) { ExternalMonitor.devices.observeForever(this) - favorites?.observeForever(favoritesObserver) + if (showFavorites) favorites?.observeForever(favoritesObserver) } } @@ -116,7 +123,7 @@ open class FileBrowserProvider(dataset: LiveDataset, url: Stri override fun release(): Job { if (url == null) { ExternalMonitor.devices.removeObserver(this) - favorites?.removeObserver(favoritesObserver) + if (showFavorites) favorites?.removeObserver(favoritesObserver) } return super.release() } diff --git a/vlc-android/src/org/videolan/vlc/util/Constants.java b/vlc-android/src/org/videolan/vlc/util/Constants.java index 9d15fc365..795010e3a 100644 --- a/vlc-android/src/org/videolan/vlc/util/Constants.java +++ b/vlc-android/src/org/videolan/vlc/util/Constants.java @@ -144,9 +144,9 @@ public class Constants { public final static int CTX_PLAY_NEXT = 1 << 9; public final static int CTX_ADD_TO_PLAYLIST = 1 << 10; public final static int CTX_SET_RINGTONE = 1 << 11; - public final static int CTX_NETWORK_ADD = 1 << 12; - public final static int CTX_NETWORK_EDIT = 1 << 13; - public final static int CTX_NETWORK_REMOVE = 1 << 14; + public final static int CTX_FAV_ADD = 1 << 12; + public final static int CTX_FAV_EDIT = 1 << 13; + public final static int CTX_FAV_REMOVE = 1 << 14; public final static int CTX_CUSTOM_REMOVE = 1 << 15; public final static int CTX_ITEM_DL = 1 << 16;