diff --git a/application/resources/src/main/res/color/standard_selection_control_normal_primary.xml b/application/resources/src/main/res/color/standard_selection_control_normal_primary.xml index af92bfd04abcc7919fb5065675d1e8b2ea485250..c926fb5ed777e3819b11e440e13002fe2b1e93ed 100644 --- a/application/resources/src/main/res/color/standard_selection_control_normal_primary.xml +++ b/application/resources/src/main/res/color/standard_selection_control_normal_primary.xml @@ -26,5 +26,6 @@ <item android:state_selected="true" android:color="?attr/colorPrimary" /> <item android:state_pressed="true" android:color="?attr/colorPrimary" /> <item android:state_focused="true" android:color="?attr/colorPrimary" /> + <item android:state_enabled="false" android:color="?attr/font_disabled" /> <item android:color="?attr/colorControlNormal" /> </selector> \ No newline at end of file diff --git a/application/resources/src/main/res/values/attrs.xml b/application/resources/src/main/res/values/attrs.xml index b5a9024ccd59d0f8892fd1a1a2b6f672c4278954..4f6b2a89c934b4671f16defa1825868578c72905 100644 --- a/application/resources/src/main/res/values/attrs.xml +++ b/application/resources/src/main/res/values/attrs.xml @@ -41,6 +41,7 @@ <attr name="font_default" format="reference|color" /> <attr name="font_audio_light" format="reference|color" /> <attr name="font_light" format="reference|color" /> + <attr name="font_disabled" format="reference|color" /> <attr name="audio_browser_separator" format="reference|color" /> <attr name="list_subtitle" format="reference|color" /> <attr name="list_title" format="reference|color" /> diff --git a/application/resources/src/main/res/values/colors.xml b/application/resources/src/main/res/values/colors.xml index 102457477ff48a5982b655ab844174480313594b..cc958a21c0c03c6091f9d9b18c67b1fc03663188 100644 --- a/application/resources/src/main/res/values/colors.xml +++ b/application/resources/src/main/res/values/colors.xml @@ -69,8 +69,10 @@ <color name="grey50transparent">#b9fafafa</color> <color name="grey50transparent_ea">#eafafafa</color> + <color name="grey300transparent">#80e0e0e0</color> <color name="grey400transparent">#80bdbdbd</color> <color name="grey600transparent">#80757575</color> + <color name="grey700transparent">#80616161</color> <color name="grey900transparent_bb">#bb212121</color> <color name="grey900transparent_dd">#dd212121</color> <color name="grey900transparent">#80212121</color> diff --git a/application/vlc-android/res/layout/sort_display_setting.xml b/application/vlc-android/res/layout/sort_display_setting.xml index 30267159cd543f79ce7ad9b19e23355b02f7f3b6..1e4b6c77272f718c605601060df151596084a68a 100644 --- a/application/vlc-android/res/layout/sort_display_setting.xml +++ b/application/vlc-android/res/layout/sort_display_setting.xml @@ -40,6 +40,7 @@ android:id="@+id/sort_icon" android:layout_width="24dp" android:layout_height="24dp" + app:tint="@color/standard_selection_control_normal_primary" android:layout_marginStart="24dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/sort_title" @@ -51,7 +52,7 @@ android:layout_height="wrap_content" android:layout_marginStart="24dp" android:layout_weight="1" - android:textColor="?attr/font_default" + android:textColor="@color/standard_selection_control_normal_primary" android:textSize="16sp" app:layout_constraintBaseline_toBaselineOf="@id/sort_asc" app:layout_constraintEnd_toStartOf="@+id/guideline15" diff --git a/application/vlc-android/res/values/styles.xml b/application/vlc-android/res/values/styles.xml index 949573289866c6d7069718398b3ad3a61cb16b87..6588b2b1f86ede599e8874dfe918fb19e8f3719c 100644 --- a/application/vlc-android/res/values/styles.xml +++ b/application/vlc-android/res/values/styles.xml @@ -62,6 +62,7 @@ <item name="dialog_circle_background">@color/dialog_circle_background</item> <item name="font_default">@color/grey900</item> <item name="font_light">@color/grey700</item> + <item name="font_disabled">@color/grey700transparent</item> <item name="font_audio_light">@color/grey700</item> <item name="list_subtitle">@color/list_subtitle</item> <item name="list_title">@color/list_title</item> @@ -151,6 +152,7 @@ <item name="background_default_darker">@color/grey875</item> <item name="font_default">@color/grey50</item> <item name="font_light">@color/grey600</item> + <item name="font_disabled">@color/grey600transparent</item> <item name="list_subtitle">@color/grey400</item> <item name="list_title">@color/white</item> <item name="ariane_text_color">@color/grey50</item> @@ -173,6 +175,7 @@ <item name="background_default_darker">@color/grey200</item> <item name="font_default">@color/black</item> <item name="font_light">@color/grey300</item> + <item name="font_disabled">@color/grey300transparent</item> <item name="list_subtitle">@color/grey600</item> <item name="list_title">@color/black</item> <item name="ariane_text_color">@color/grey900</item> @@ -256,6 +259,7 @@ <item name="dialog_circle_background">@color/dialog_circle_background_dark</item> <item name="font_default">@color/grey50</item> <item name="font_light">@color/grey600</item> + <item name="font_disabled">@color/grey600transparent</item> <item name="font_audio_light">@color/grey400</item> <item name="list_subtitle">@color/list_subtitle_dark</item> <item name="list_title">@color/list_title_dark</item> @@ -518,6 +522,7 @@ <item name="ic_passthrough">@drawable/ic_passthrough</item> <item name="font_default">@color/grey50</item> <item name="font_light">@color/grey600</item> + <item name="font_disabled">@color/grey600transparent</item> <item name="font_audio_light">@color/grey600</item> <item name="dialog_circle_background">@color/dialog_circle_background_dark</item> <item name="bookmark_background">@color/black_transparent_80</item> diff --git a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt index a2267b79e4ed4c99e0fc9b8ec20d2d15a232cc14..61e4cce00c9cf8d46e3540cc0f1f20ba548ee675 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt @@ -213,6 +213,9 @@ class AudioBrowserFragment : BaseAudioBrowser<AudioBrowserViewModel>() { updateTabs() } CURRENT_SORT -> { + lifecycleScope.launch { + displaySettingsViewModel.lockSorts(true) + } @Suppress("UNCHECKED_CAST") val sort = value as Pair<Int, Boolean> viewModel.providers[currentTab].sort = sort.first viewModel.providers[currentTab].desc = sort.second diff --git a/application/vlc-android/src/org/videolan/vlc/gui/audio/BaseAudioBrowser.kt b/application/vlc-android/src/org/videolan/vlc/gui/audio/BaseAudioBrowser.kt index 243a0c1373a4d494482bcafdf84d20b3cf4e39ba..9c608900b9491050251490bd0515b484655e4c6e 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/audio/BaseAudioBrowser.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/audio/BaseAudioBrowser.kt @@ -176,7 +176,14 @@ abstract class BaseAudioBrowser<T : MedialibraryViewModel> : MediaBrowserFragmen } fun displayListInGrid(list: RecyclerView, adapter: AudioBrowserAdapter, provider: MedialibraryProvider<MediaLibraryItem>, spacing: Int) { - val gridLayoutManager = GridLayoutManager(requireActivity(), nbColumns) + val gridLayoutManager = object: GridLayoutManager(requireActivity(), nbColumns) { + override fun onLayoutCompleted(state: RecyclerView.State?) { + super.onLayoutCompleted(state) + lifecycleScope.launch { + displaySettingsViewModel.lockSorts(false) + } + } + } gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { if (position == adapter.itemCount - 1) return 1 @@ -258,7 +265,14 @@ abstract class BaseAudioBrowser<T : MedialibraryViewModel> : MediaBrowserFragmen provider ) ) - list.layoutManager = LinearLayoutManager(activity) + list.layoutManager = object: LinearLayoutManager(activity) { + override fun onLayoutCompleted(state: RecyclerView.State?) { + super.onLayoutCompleted(state) + lifecycleScope.launch { + displaySettingsViewModel.lockSorts(false) + } + } + } } } val lp = list.layoutParams @@ -490,6 +504,7 @@ abstract class BaseAudioBrowser<T : MedialibraryViewModel> : MediaBrowserFragmen if (adapter == getCurrentAdapter()) { restoreMultiSelectHelper() } + displaySettingsViewModel.waitForUpdate = false } override fun onItemFocused(v: View, item: MediaLibraryItem) {} diff --git a/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt index 13716ea7f72e654441fb43407e856ec39326a002..39ead5c4e0076813a033bd4a39cd538fa75a843b 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt @@ -39,7 +39,6 @@ import androidx.core.net.toUri import androidx.core.os.bundleOf import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager -import androidx.fragment.app.activityViewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.MutableLiveData import androidx.lifecycle.asFlow @@ -152,7 +151,6 @@ import org.videolan.vlc.util.SchedulerCallback import org.videolan.vlc.util.isSchemeSupported import org.videolan.vlc.util.isTalkbackIsEnabled import org.videolan.vlc.util.launchWhenStarted -import org.videolan.vlc.viewmodels.DisplaySettingsViewModel import org.videolan.vlc.viewmodels.PlaylistModel import org.videolan.vlc.viewmodels.browser.BrowserModel import java.io.File @@ -194,8 +192,6 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr private var enqueuingSnackbar: Snackbar? = null private lateinit var startedScope: CoroutineScope - private val displaySettingsViewModel: DisplaySettingsViewModel by activityViewModels() - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) scheduler = LifecycleAwareScheduler(this) diff --git a/application/vlc-android/src/org/videolan/vlc/gui/browser/MediaBrowserFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/browser/MediaBrowserFragment.kt index 9053a31f4efc01617436aa4c18ccd7a136be56e3..14c78c1a4befee92ff14650c29d8aed0b72bb17e 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/browser/MediaBrowserFragment.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/browser/MediaBrowserFragment.kt @@ -30,7 +30,6 @@ 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 @@ -40,7 +39,6 @@ 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 @@ -53,8 +51,11 @@ 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.* +import org.videolan.vlc.viewmodels.DisplaySettingsViewModel +import org.videolan.vlc.viewmodels.MedialibraryViewModel +import org.videolan.vlc.viewmodels.SortableModel +import org.videolan.vlc.viewmodels.prepareOptionsMenu +import org.videolan.vlc.viewmodels.sortMenuTitles private const val TAG = "VLC/MediaBrowserFragment" private const val KEY_SELECTION = "key_selection" @@ -69,7 +70,7 @@ abstract class MediaBrowserFragment<T : SortableModel> : BaseFragment(), Filtera duration = 300 } - private val displaySettingsViewModel: DisplaySettingsViewModel by activityViewModels() + val displaySettingsViewModel: DisplaySettingsViewModel by activityViewModels() /** * Triggered when a display setting is changed diff --git a/application/vlc-android/src/org/videolan/vlc/gui/dialogs/DisplaySettingsDialog.kt b/application/vlc-android/src/org/videolan/vlc/gui/dialogs/DisplaySettingsDialog.kt index 5b27184be177bd11bb2fa07b43421da25dd24299..f68dc8b5741f61c2753b476f7c9ce533b746c50c 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/dialogs/DisplaySettingsDialog.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/dialogs/DisplaySettingsDialog.kt @@ -37,8 +37,11 @@ import androidx.annotation.StringRes import androidx.core.content.ContextCompat import androidx.core.os.bundleOf import androidx.core.view.children +import androidx.core.view.isEmpty import androidx.databinding.DataBindingUtil import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED import kotlinx.coroutines.launch @@ -51,7 +54,6 @@ import org.videolan.tools.setGone import org.videolan.vlc.R import org.videolan.vlc.databinding.DialogDisplaySettingsBinding import org.videolan.vlc.databinding.SortDisplaySettingBinding -import org.videolan.vlc.gui.dialogs.DisplaySettingsDialog.VideoGroup.values import org.videolan.vlc.gui.helpers.DefaultPlaybackAction import org.videolan.vlc.gui.helpers.UiTools.showPinIfNeeded import org.videolan.vlc.viewmodels.DisplaySettingsViewModel @@ -154,6 +156,19 @@ class DisplaySettingsDialog : VLCBottomSheetDialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewLifecycleOwner.lifecycleScope.launch { + //listen to display settings changes + displaySettingsViewModel.lockSortFlow + .flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED) + .collect { + if (isResumed) { + lockSorts(it) + } + } + } + + updateDisplayMode() updateShowAllArtists() updateShowOnlyFavs() @@ -269,6 +284,13 @@ class DisplaySettingsDialog : VLCBottomSheetDialogFragment() { } } + fun lockSorts(lock: Boolean) { + binding.sortsContainer.children.forEach { + it.isEnabled = !lock + if (it is ViewGroup) it.children.forEach { child -> child.isEnabled = !lock } + } + } + /** * Update the view for the "display in list / grid" item * @@ -376,7 +398,7 @@ class DisplaySettingsDialog : VLCBottomSheetDialogFragment() { */ private fun updateSorts() { //first time: create all the views - if (binding.sortsContainer.childCount == 0) + if (binding.sortsContainer.isEmpty()) sorts.forEach { sort -> val binding: SortDisplaySettingBinding = DataBindingUtil.inflate(LayoutInflater.from(requireActivity()), R.layout.sort_display_setting, binding.sortsContainer, true) @@ -422,6 +444,7 @@ class DisplaySettingsDialog : VLCBottomSheetDialogFragment() { (it as TextView).setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, if (selected) ContextCompat.getDrawable(requireActivity(), R.drawable.ic_check_large) else null, null) } } + lockSorts(displaySettingsViewModel.lockSortFlow.value) } /** diff --git a/application/vlc-android/src/org/videolan/vlc/viewmodels/DisplaySettingsViewModel.kt b/application/vlc-android/src/org/videolan/vlc/viewmodels/DisplaySettingsViewModel.kt index 8ba633ba1432dc94277cb83a744fa3a7f54664f1..b67d0e5569d312078d7a5e9c686f9900b99103c5 100644 --- a/application/vlc-android/src/org/videolan/vlc/viewmodels/DisplaySettingsViewModel.kt +++ b/application/vlc-android/src/org/videolan/vlc/viewmodels/DisplaySettingsViewModel.kt @@ -49,6 +49,11 @@ class DisplaySettingsViewModel: ViewModel() { private val _settingChangeFlow = MutableStateFlow(SettingChange()) val settingChangeFlow = _settingChangeFlow.asStateFlow() + private val _lockSortFlow = MutableStateFlow(false) + val lockSortFlow = _lockSortFlow.asStateFlow() + + var waitForUpdate = false + /** * Send a new event when a setting is changed * @@ -67,4 +72,11 @@ class DisplaySettingsViewModel: ViewModel() { _settingChangeFlow.emit(SettingChange()) } + suspend fun lockSorts(locked: Boolean) { + if (locked) + waitForUpdate = true + if (locked || !waitForUpdate) + _lockSortFlow.emit(locked) + } + } \ No newline at end of file