Fix selected option not updated after applying color (1/2)

The issue comes from the diffing utils that we use to compare 2
OptionItemViewModels and update the recycler view. In
OptionItemViewModel, the equality check is overridden to check that the
flow values are equal, and not whether the flows are the same instance,
but flow values of the old items could be updated to match new items,
causing no view update. This was done to fix the original grid picker's
selection animation, which was janky because options were applied and
reloaded mid-animation (b/273336388). This will no longer be an issue
in the new picker UI, which uses the preview and apply pattern.
Therefore create a new OptionItemViewModel2 without overriding the
equality check.

Flag: com.android.systemui.shared.new_customization_picker_ui
Test: manually verified & unit tests
Bug: 350718581
Change-Id: If1afb2792855e9efbc8619b126c5841cf624d38c
diff --git a/src/com/android/wallpaper/picker/option/ui/adapter/OptionItemAdapter2.kt b/src/com/android/wallpaper/picker/option/ui/adapter/OptionItemAdapter2.kt
index 49bab8b..32f854b 100644
--- a/src/com/android/wallpaper/picker/option/ui/adapter/OptionItemAdapter2.kt
+++ b/src/com/android/wallpaper/picker/option/ui/adapter/OptionItemAdapter2.kt
@@ -26,7 +26,7 @@
 import androidx.recyclerview.widget.DiffUtil
 import androidx.recyclerview.widget.RecyclerView
 import com.android.wallpaper.picker.option.ui.binder.OptionItemBinder2
-import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.DisposableHandle
@@ -41,9 +41,9 @@
     private val bindPayload: (View, T) -> DisposableHandle?,
 ) : RecyclerView.Adapter<OptionItemAdapter2.ViewHolder>() {
 
-    private val items = mutableListOf<OptionItemViewModel<T>>()
+    private val items = mutableListOf<OptionItemViewModel2<T>>()
 
-    fun setItems(items: List<OptionItemViewModel<T>>, callback: (() -> Unit)? = null) {
+    fun setItems(items: List<OptionItemViewModel2<T>>, callback: (() -> Unit)? = null) {
         lifecycleOwner.lifecycleScope.launch {
             val oldItems = this@OptionItemAdapter2.items
             val newItems = items
diff --git a/src/com/android/wallpaper/picker/option/ui/binder/OptionItemBinder2.kt b/src/com/android/wallpaper/picker/option/ui/binder/OptionItemBinder2.kt
index 2291e37..741d09d 100644
--- a/src/com/android/wallpaper/picker/option/ui/binder/OptionItemBinder2.kt
+++ b/src/com/android/wallpaper/picker/option/ui/binder/OptionItemBinder2.kt
@@ -35,6 +35,7 @@
 import com.android.wallpaper.picker.common.text.ui.viewbinder.TextViewBinder
 import com.android.wallpaper.picker.option.ui.view.OptionItemBackground
 import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flatMapLatest
@@ -66,7 +67,7 @@
      */
     fun bind(
         view: View,
-        viewModel: OptionItemViewModel<*>,
+        viewModel: OptionItemViewModel2<*>,
         lifecycleOwner: LifecycleOwner,
         animationSpec: AnimationSpec = AnimationSpec(),
     ): DisposableHandle {
diff --git a/src/com/android/wallpaper/picker/option/ui/viewmodel/OptionItemViewModel2.kt b/src/com/android/wallpaper/picker/option/ui/viewmodel/OptionItemViewModel2.kt
new file mode 100644
index 0000000..9b2c561
--- /dev/null
+++ b/src/com/android/wallpaper/picker/option/ui/viewmodel/OptionItemViewModel2.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.wallpaper.picker.option.ui.viewmodel
+
+import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+
+/** Models UI state for an item in a list of selectable options. */
+data class OptionItemViewModel2<Payload>(
+    /**
+     * A stable key that uniquely identifies this option amongst all other options in the same list
+     * of options.
+     */
+    val key: StateFlow<String>,
+
+    /**
+     * The view model representing additional details needed for binding the icon of an option item
+     */
+    val payload: Payload? = null,
+
+    /**
+     * A text to show to the user (or attach as content description on the icon, if there's no
+     * dedicated view for it).
+     */
+    val text: Text,
+
+    /** Hides text and places the provided text in the content description instead */
+    val isTextUserVisible: Boolean = true,
+
+    /** Whether this option is selected. */
+    val isSelected: StateFlow<Boolean>,
+
+    /** Whether this option is enabled. */
+    val isEnabled: Boolean = true,
+
+    /** Notifies that the option has been clicked by the user. */
+    val onClicked: Flow<(() -> Unit)?>,
+
+    /** Notifies that the option has been long-clicked by the user. */
+    val onLongClicked: (() -> Unit)? = null,
+)