Animated emoji support (#2064)
* Animated emoji support * Try to query preference only once * Revert to using SpannableStringBuilder
This commit is contained in:
parent
c685192d49
commit
9580870445
38 changed files with 225 additions and 120 deletions
|
|
@ -42,7 +42,8 @@ interface AnnouncementActionListener: LinkListener {
|
|||
class AnnouncementAdapter(
|
||||
private var items: List<Announcement> = emptyList(),
|
||||
private val listener: AnnouncementActionListener,
|
||||
private val wellbeingEnabled: Boolean = false
|
||||
private val wellbeingEnabled: Boolean = false,
|
||||
private val animateEmojis: Boolean = false
|
||||
) : RecyclerView.Adapter<AnnouncementAdapter.AnnouncementViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AnnouncementViewHolder {
|
||||
|
|
@ -99,7 +100,8 @@ class AnnouncementAdapter(
|
|||
reaction.staticUrl ?: "",
|
||||
null
|
||||
)),
|
||||
this
|
||||
this,
|
||||
animateEmojis
|
||||
)
|
||||
|
||||
isChecked = reaction.me
|
||||
|
|
|
|||
|
|
@ -82,8 +82,9 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
|
|||
|
||||
val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
val wellbeingEnabled = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
|
||||
val animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
|
||||
adapter = AnnouncementAdapter(emptyList(), this, wellbeingEnabled)
|
||||
adapter = AnnouncementAdapter(emptyList(), this, wellbeingEnabled, animateEmojis)
|
||||
|
||||
announcementsList.adapter = adapter
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ import com.keylesspalace.tusky.entity.Attachment
|
|||
import com.keylesspalace.tusky.entity.Emoji
|
||||
import com.keylesspalace.tusky.entity.NewPoll
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.util.*
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
|
|
@ -160,7 +161,7 @@ class ComposeActivity : BaseActivity(),
|
|||
composeScheduleView.setDateTime(composeOptions?.scheduledAt)
|
||||
}
|
||||
|
||||
setupComposeField(viewModel.startingText)
|
||||
setupComposeField(preferences, viewModel.startingText)
|
||||
setupContentWarningField(composeOptions?.contentWarning)
|
||||
setupPollView()
|
||||
applyShareIntent(intent, savedInstanceState)
|
||||
|
|
@ -245,13 +246,18 @@ class ComposeActivity : BaseActivity(),
|
|||
composeContentWarningField.onTextChanged { _, _, _, _ -> updateVisibleCharactersLeft() }
|
||||
}
|
||||
|
||||
private fun setupComposeField(startingText: String?) {
|
||||
private fun setupComposeField(preferences: SharedPreferences, startingText: String?) {
|
||||
composeEditField.setOnCommitContentListener(this)
|
||||
|
||||
composeEditField.setOnKeyListener { _, keyCode, event -> this.onKeyDown(keyCode, event) }
|
||||
|
||||
composeEditField.setAdapter(
|
||||
ComposeAutoCompleteAdapter(this))
|
||||
ComposeAutoCompleteAdapter(
|
||||
this,
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false),
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
)
|
||||
)
|
||||
composeEditField.setTokenizer(ComposeTokenizer())
|
||||
|
||||
composeEditField.setText(startingText)
|
||||
|
|
|
|||
|
|
@ -53,11 +53,15 @@ public class ComposeAutoCompleteAdapter extends BaseAdapter
|
|||
|
||||
private final ArrayList<AutocompleteResult> resultList;
|
||||
private final AutocompletionProvider autocompletionProvider;
|
||||
private final boolean animateAvatar;
|
||||
private final boolean animateEmojis;
|
||||
|
||||
public ComposeAutoCompleteAdapter(AutocompletionProvider autocompletionProvider) {
|
||||
public ComposeAutoCompleteAdapter(AutocompletionProvider autocompletionProvider, boolean animateAvatar, boolean animateEmojis) {
|
||||
super();
|
||||
resultList = new ArrayList<>();
|
||||
this.autocompletionProvider = autocompletionProvider;
|
||||
this.animateAvatar = animateAvatar;
|
||||
this.animateEmojis = animateEmojis;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -147,15 +151,12 @@ public class ComposeAutoCompleteAdapter extends BaseAdapter
|
|||
);
|
||||
accountViewHolder.username.setText(formattedUsername);
|
||||
CharSequence emojifiedName = CustomEmojiHelper.emojify(account.getName(),
|
||||
account.getEmojis(), accountViewHolder.displayName);
|
||||
account.getEmojis(), accountViewHolder.displayName, animateEmojis);
|
||||
accountViewHolder.displayName.setText(emojifiedName);
|
||||
|
||||
int avatarRadius = accountViewHolder.avatar.getContext().getResources()
|
||||
.getDimensionPixelSize(R.dimen.avatar_radius_42dp);
|
||||
|
||||
boolean animateAvatar = PreferenceManager.getDefaultSharedPreferences(accountViewHolder.avatar.getContext())
|
||||
.getBoolean("animateGifAvatars", false);
|
||||
|
||||
ImageLoadingHelper.loadAvatar(
|
||||
account.getAvatar(),
|
||||
accountViewHolder.avatar,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public class ConversationViewHolder extends StatusBaseViewHolder {
|
|||
|
||||
setupCollapsedState(status.getCollapsible(), status.getCollapsed(), status.getExpanded(), status.getSpoilerText(), listener);
|
||||
|
||||
setDisplayName(account.getDisplayName(), account.getEmojis());
|
||||
setDisplayName(account.getDisplayName(), account.getEmojis(), statusDisplayOptions);
|
||||
setUsername(account.getUsername());
|
||||
setCreatedAt(status.getCreatedAt(), statusDisplayOptions);
|
||||
setIsReply(status.getInReplyToId() != null);
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ class ConversationsFragment : SFragment(), StatusActionListener, Injectable, Res
|
|||
useBlurhash = preferences.getBoolean("useBlurhash", true),
|
||||
cardViewMode = CardViewMode.NONE,
|
||||
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
|
||||
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
)
|
||||
|
||||
adapter = ConversationAdapter(statusDisplayOptions, this, ::onTopLoaded, viewModel::retry)
|
||||
|
|
|
|||
|
|
@ -174,6 +174,13 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable {
|
|||
setTitle(R.string.pref_title_enable_swipe_for_tabs)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(false)
|
||||
key = PrefKeys.ANIMATE_CUSTOM_EMOJIS
|
||||
setTitle(R.string.pref_title_animate_custom_emojis)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_browser_settings) {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class StatusViewHolder(
|
|||
sensitive, previewListener, viewState.isMediaShow(status.id, status.sensitive),
|
||||
mediaViewHeight)
|
||||
|
||||
statusViewHelper.setupPollReadonly(status.poll.toViewData(), status.emojis, statusDisplayOptions.useAbsoluteTime)
|
||||
statusViewHelper.setupPollReadonly(status.poll.toViewData(), status.emojis, statusDisplayOptions)
|
||||
setCreatedAt(status.createdAt)
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ class StatusViewHolder(
|
|||
itemView.statusContentWarningButton.hide()
|
||||
itemView.statusContentWarningDescription.hide()
|
||||
} else {
|
||||
val emojiSpoiler = status.spoilerText.emojify(status.emojis, itemView.statusContentWarningDescription)
|
||||
val emojiSpoiler = status.spoilerText.emojify(status.emojis, itemView.statusContentWarningDescription, statusDisplayOptions.animateEmojis)
|
||||
itemView.statusContentWarningDescription.text = emojiSpoiler
|
||||
itemView.statusContentWarningDescription.show()
|
||||
itemView.statusContentWarningButton.show()
|
||||
|
|
@ -122,7 +122,7 @@ class StatusViewHolder(
|
|||
emojis: List<Emoji>,
|
||||
listener: LinkListener) {
|
||||
if (expanded) {
|
||||
val emojifiedText = content.emojify(emojis, itemView.statusContent)
|
||||
val emojifiedText = content.emojify(emojis, itemView.statusContent, statusDisplayOptions.animateEmojis)
|
||||
LinkHelper.setClickableText(itemView.statusContent, emojifiedText, mentions, listener)
|
||||
} else {
|
||||
LinkHelper.setClickableMentions(itemView.statusContent, mentions, listener)
|
||||
|
|
|
|||
|
|
@ -111,7 +111,8 @@ class ReportStatusesFragment : Fragment(R.layout.fragment_report_statuses), Inje
|
|||
useBlurhash = preferences.getBoolean("useBlurhash", true),
|
||||
cardViewMode = CardViewMode.NONE,
|
||||
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
)
|
||||
|
||||
adapter = StatusesAdapter(statusDisplayOptions,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import com.keylesspalace.tusky.adapter.AccountViewHolder
|
|||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.interfaces.LinkListener
|
||||
|
||||
class SearchAccountsAdapter(private val linkListener: LinkListener)
|
||||
class SearchAccountsAdapter(private val linkListener: LinkListener, private val animateAvatars: Boolean, private val animateEmojis: Boolean)
|
||||
: PagedListAdapter<Account, RecyclerView.ViewHolder>(ACCOUNT_COMPARATOR) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
|
|
@ -37,7 +37,7 @@ class SearchAccountsAdapter(private val linkListener: LinkListener)
|
|||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
getItem(position)?.let { item ->
|
||||
(holder as AccountViewHolder).apply {
|
||||
setupWithAccount(item)
|
||||
setupWithAccount(item, animateAvatars, animateEmojis)
|
||||
setupLinkListener(linkListener)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,23 @@ package com.keylesspalace.tusky.components.search.fragments
|
|||
import androidx.lifecycle.LiveData
|
||||
import androidx.paging.PagedList
|
||||
import androidx.paging.PagedListAdapter
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.keylesspalace.tusky.components.search.adapter.SearchAccountsAdapter
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.util.NetworkState
|
||||
import kotlinx.android.synthetic.main.fragment_search.*
|
||||
|
||||
class SearchAccountsFragment : SearchFragment<Account>() {
|
||||
override fun createAdapter(): PagedListAdapter<Account, *> = SearchAccountsAdapter(this)
|
||||
override fun createAdapter(): PagedListAdapter<Account, *> {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(searchRecyclerView.context)
|
||||
|
||||
return SearchAccountsAdapter(
|
||||
this,
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false),
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
)
|
||||
}
|
||||
|
||||
override val networkStateRefresh: LiveData<NetworkState>
|
||||
get() = viewModel.networkStateAccountRefresh
|
||||
|
|
|
|||
|
|
@ -87,7 +87,8 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
|
|||
useBlurhash = preferences.getBoolean("useBlurhash", true),
|
||||
cardViewMode = CardViewMode.NONE,
|
||||
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
)
|
||||
|
||||
searchRecyclerView.addItemDecoration(DividerItemDecoration(searchRecyclerView.context, DividerItemDecoration.VERTICAL))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue