Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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(
Expand All @@ -24,7 +27,18 @@ class CustomEmojiPickerPage(
) : Fragment() {

private lateinit var binding: LayoutEmojiCustomBinding
private val preferences: SharedPreferences by inject()
private val customEmojiViewModel by viewModel<CustomEmojiPickerViewModel>()
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,
Expand All @@ -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()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class CustomEmojiPickerViewModel : ViewModel() {
)

fun setEmojis(list: List<Emoji>) {
allEmojis.value = list
allEmojis.value = list.filter { emoji ->
emoji.visibleInPicker == null || emoji.visibleInPicker
}.sortedBy { it.shortcode.lowercase() }
}

fun updateQuery(newQuery: String) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Emoji, ListEmojiAdapter.ListEmojiHolder>(EmojiDiffer) {

private object EmojiDiffer : DiffUtil.ItemCallback<Emoji>() {
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)
}
61 changes: 44 additions & 17 deletions husky/app/src/main/res/layout/layout_emoji_custom.xml
Original file line number Diff line number Diff line change
@@ -1,24 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical">
android:layout_height="match_parent">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/emojiGrid"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipToPadding="false" />
android:layout_height="match_parent"
android:orientation="vertical">

<EditText
android:id="@+id/searchBox"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/emojiGrid"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipToPadding="false" />

<EditText
android:id="@+id/searchBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints="@null"
android:hint="@string/custom_emoji_page__placeholder"
android:imeOptions="actionDone"
android:inputType="text" />

</LinearLayout>

<LinearLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/custom_emoji_page__placeholder"
android:imeOptions="actionDone"
android:importantForAutofill="no"
android:inputType="text" />
android:layout_height="300dp"
android:background="?android:attr/colorBackground"
android:gravity="center"
android:orientation="vertical">

<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.6"
android:text="Cargando emojis..."
android:textAppearance="?android:attr/textAppearanceSmall" />

</LinearLayout>

</LinearLayout>
</FrameLayout>