diff --git a/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/CustomEmojiPickerPage.kt b/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/CustomEmojiPickerPage.kt index a2d5746b..1dc5acfb 100644 --- a/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/CustomEmojiPickerPage.kt +++ b/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/CustomEmojiPickerPage.kt @@ -1,6 +1,7 @@ package com.keylesspalace.tusky.view.emojireactions import android.content.Context +import android.content.SharedPreferences import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -10,12 +11,14 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.GridLayoutManager -import com.keylesspalace.tusky.adapter.EmojiAdapter import com.keylesspalace.tusky.adapter.OnEmojiSelectedListener import com.keylesspalace.tusky.core.extensions.afterTextChanged +import com.keylesspalace.tusky.core.extensions.gone import com.keylesspalace.tusky.databinding.LayoutEmojiCustomBinding import com.keylesspalace.tusky.entity.Emoji +import com.keylesspalace.tusky.settings.PrefKeys import kotlinx.coroutines.launch +import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel class CustomEmojiPickerPage( @@ -24,7 +27,18 @@ class CustomEmojiPickerPage( ) : Fragment() { private lateinit var binding: LayoutEmojiCustomBinding + private val preferences: SharedPreferences by inject() private val customEmojiViewModel by viewModel() + private val adapter by lazy { + ListEmojiAdapter( + object : OnEmojiSelectedListener { + override fun onEmojiSelected(shortcode: String) { + onReactionCallback(shortcode) + } + }, + animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false) + ) + } override fun onCreateView( inflater: LayoutInflater, @@ -51,15 +65,10 @@ class CustomEmojiPickerPage( viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { customEmojiViewModel.emojis.collect { emojis -> - binding.emojiGrid.adapter = EmojiAdapter( - emojis, - object : OnEmojiSelectedListener { - override fun onEmojiSelected(shortcode: String) { - onReactionCallback(shortcode) - } - }, - animateEmojis = false // TODO - ) + binding.emojiGrid.adapter = adapter + adapter.submitList(emojis) + + binding.loadingOverlay.gone() } } } diff --git a/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/CustomEmojiPickerViewModel.kt b/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/CustomEmojiPickerViewModel.kt index b0c57be6..408abf8c 100644 --- a/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/CustomEmojiPickerViewModel.kt +++ b/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/CustomEmojiPickerViewModel.kt @@ -36,7 +36,9 @@ class CustomEmojiPickerViewModel : ViewModel() { ) fun setEmojis(list: List) { - allEmojis.value = list + allEmojis.value = list.filter { emoji -> + emoji.visibleInPicker == null || emoji.visibleInPicker + }.sortedBy { it.shortcode.lowercase() } } fun updateQuery(newQuery: String) { diff --git a/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/ListEmojiAdapter.kt b/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/ListEmojiAdapter.kt new file mode 100644 index 00000000..92fe5838 --- /dev/null +++ b/husky/app/src/main/java/com/keylesspalace/tusky/view/emojireactions/ListEmojiAdapter.kt @@ -0,0 +1,67 @@ +package com.keylesspalace.tusky.view.emojireactions + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.github.penfeizhou.animation.glide.AnimationDecoderOption +import com.keylesspalace.tusky.adapter.OnEmojiSelectedListener +import com.keylesspalace.tusky.databinding.ItemEmojiButtonBinding +import com.keylesspalace.tusky.entity.Emoji + +class ListEmojiAdapter( + private val onEmojiSelectedListener: OnEmojiSelectedListener, + private var animateEmojis: Boolean +) : ListAdapter(EmojiDiffer) { + + private object EmojiDiffer : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Emoji, newItem: Emoji): Boolean { + return oldItem == newItem + } + + override fun areContentsTheSame(oldItem: Emoji, newItem: Emoji): Boolean { + return ((oldItem.category == newItem.category) && + (oldItem.shortcode == newItem.shortcode) && + (oldItem.url == newItem.url) && + (oldItem.staticUrl == newItem.staticUrl) && + (oldItem.visibleInPicker == newItem.visibleInPicker)) + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ListEmojiHolder { + return ListEmojiHolder( + ItemEmojiButtonBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder( + holder: ListEmojiHolder, + position: Int + ) { + val emoji = getItem(position) + + Glide.with(holder.layout.composeEmojiButton) + .load(emoji.url) + .set(AnimationDecoderOption.DISABLE_ANIMATION_GIF_DECODER, !animateEmojis) + .set(AnimationDecoderOption.DISABLE_ANIMATION_WEBP_DECODER, !animateEmojis) + .set(AnimationDecoderOption.DISABLE_ANIMATION_APNG_DECODER, !animateEmojis) + .into(holder.layout.composeEmojiButton) + + holder.layout.composeEmojiButton.setOnClickListener { + onEmojiSelectedListener.onEmojiSelected(emoji.shortcode) + } + + holder.layout.composeEmojiButton.contentDescription = emoji.shortcode + } + + inner class ListEmojiHolder(val layout: ItemEmojiButtonBinding) : RecyclerView.ViewHolder(layout.composeEmojiButton) +} diff --git a/husky/app/src/main/res/layout/layout_emoji_custom.xml b/husky/app/src/main/res/layout/layout_emoji_custom.xml index 32d013fb..1ac88ff6 100644 --- a/husky/app/src/main/res/layout/layout_emoji_custom.xml +++ b/husky/app/src/main/res/layout/layout_emoji_custom.xml @@ -1,24 +1,51 @@ - + android:layout_height="match_parent"> - + android:layout_height="match_parent" + android:orientation="vertical"> - + + + + + + + android:layout_height="300dp" + android:background="?android:attr/colorBackground" + android:gravity="center" + android:orientation="vertical"> + + + + + + - +