Make it more likely 8 emoji fit on a row, fix emoji search emoticons.

fork-5.53.8
Cody Henthorne 2021-06-29 20:29:34 -04:00 zatwierdzone przez Alex Hart
rodzic a1c8573fad
commit b85c5eb54a
14 zmienionych plików z 101 dodań i 86 usunięć

Wyświetl plik

@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.util.InsetItemDecoration
import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.ViewUtil
private val EDGE_LENGTH: Int = ViewUtil.dpToPx(7) private val EDGE_LENGTH: Int = ViewUtil.dpToPx(7)
private val HORIZONTAL_INSET: Int = ViewUtil.dpToPx(11) private val HORIZONTAL_INSET: Int = ViewUtil.dpToPx(8)
private val VERTICAL_INSET: Int = ViewUtil.dpToPx(8) private val VERTICAL_INSET: Int = ViewUtil.dpToPx(8)
/** /**

Wyświetl plik

@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.util.MappingModel;
import org.thoughtcrime.securesms.util.MappingModelList; import org.thoughtcrime.securesms.util.MappingModelList;
import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.List;
import java.util.Optional; import java.util.Optional;
public class EmojiPageView extends RecyclerView implements VariationSelectorListener { public class EmojiPageView extends RecyclerView implements VariationSelectorListener {
@ -59,26 +60,26 @@ public class EmojiPageView extends RecyclerView implements VariationSelectorList
@NonNull VariationSelectorListener variationSelectorListener, @NonNull VariationSelectorListener variationSelectorListener,
boolean allowVariations, boolean allowVariations,
@NonNull LinearLayoutManager layoutManager, @NonNull LinearLayoutManager layoutManager,
@LayoutRes int displayItemLayoutResId) @LayoutRes int displayEmojiLayoutResId,
@LayoutRes int displayEmoticonLayoutResId)
{ {
super(context); super(context);
initialize(emojiSelectionListener, variationSelectorListener, allowVariations, layoutManager, displayItemLayoutResId); initialize(emojiSelectionListener, variationSelectorListener, allowVariations, layoutManager, displayEmojiLayoutResId, displayEmoticonLayoutResId);
} }
public void initialize(@NonNull EmojiEventListener emojiSelectionListener, public void initialize(@NonNull EmojiEventListener emojiSelectionListener,
@NonNull VariationSelectorListener variationSelectorListener, @NonNull VariationSelectorListener variationSelectorListener,
boolean allowVariations) boolean allowVariations)
{ {
initialize(emojiSelectionListener, variationSelectorListener, allowVariations, new GridLayoutManager(getContext(), 8), R.layout.emoji_display_item); initialize(emojiSelectionListener, variationSelectorListener, allowVariations, new GridLayoutManager(getContext(), 8), R.layout.emoji_display_item_grid, R.layout.emoji_text_display_item_grid);
Drawable drawable = DrawableUtil.tint(ContextUtil.requireDrawable(getContext(), R.drawable.triangle_bottom_right_corner), ContextCompat.getColor(getContext(), R.color.signal_button_secondary_text_disabled));
addItemDecoration(new EmojiItemDecoration(allowVariations, drawable));
} }
public void initialize(@NonNull EmojiEventListener emojiSelectionListener, public void initialize(@NonNull EmojiEventListener emojiSelectionListener,
@NonNull VariationSelectorListener variationSelectorListener, @NonNull VariationSelectorListener variationSelectorListener,
boolean allowVariations, boolean allowVariations,
@NonNull LinearLayoutManager layoutManager, @NonNull LinearLayoutManager layoutManager,
@LayoutRes int displayItemLayoutResId) @LayoutRes int displayEmojiLayoutResId,
@LayoutRes int displayEmoticonLayoutResId)
{ {
this.variationSelectorListener = variationSelectorListener; this.variationSelectorListener = variationSelectorListener;
@ -89,7 +90,8 @@ public class EmojiPageView extends RecyclerView implements VariationSelectorList
emojiSelectionListener, emojiSelectionListener,
this, this,
allowVariations, allowVariations,
displayItemLayoutResId); displayEmojiLayoutResId,
displayEmoticonLayoutResId);
if (this.layoutManager instanceof GridLayoutManager) { if (this.layoutManager instanceof GridLayoutManager) {
GridLayoutManager gridLayout = (GridLayoutManager) this.layoutManager; GridLayoutManager gridLayout = (GridLayoutManager) this.layoutManager;
@ -108,6 +110,9 @@ public class EmojiPageView extends RecyclerView implements VariationSelectorList
} }
setLayoutManager(layoutManager); setLayoutManager(layoutManager);
Drawable drawable = DrawableUtil.tint(ContextUtil.requireDrawable(getContext(), R.drawable.triangle_bottom_right_corner), ContextCompat.getColor(getContext(), R.color.signal_button_secondary_text_disabled));
addItemDecoration(new EmojiItemDecoration(allowVariations, drawable));
} }
public void presentForEmojiKeyboard() { public void presentForEmojiKeyboard() {
@ -125,7 +130,7 @@ public class EmojiPageView extends RecyclerView implements VariationSelectorList
} }
} }
public void setList(@NonNull MappingModelList list) { public void setList(@NonNull List<MappingModel<?>> list) {
this.model = null; this.model = null;
EmojiPageViewGridAdapter adapter = adapterFactory.create(); EmojiPageViewGridAdapter adapter = adapterFactory.create();
setAdapter(adapter); setAdapter(adapter);

Wyświetl plik

@ -22,15 +22,16 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
@NonNull EmojiEventListener emojiEventListener, @NonNull EmojiEventListener emojiEventListener,
@NonNull VariationSelectorListener variationSelectorListener, @NonNull VariationSelectorListener variationSelectorListener,
boolean allowVariations, boolean allowVariations,
@LayoutRes int displayItemLayoutResId) @LayoutRes int displayEmojiLayoutResId,
@LayoutRes int displayEmoticonLayoutResId)
{ {
this.variationSelectorListener = variationSelectorListener; this.variationSelectorListener = variationSelectorListener;
popup.setOnDismissListener(this); popup.setOnDismissListener(this);
registerFactory(EmojiHeader.class, new LayoutFactory<>(EmojiHeaderViewHolder::new, R.layout.emoji_grid_header)); registerFactory(EmojiHeader.class, new LayoutFactory<>(EmojiHeaderViewHolder::new, R.layout.emoji_grid_header));
registerFactory(EmojiModel.class, new LayoutFactory<>(v -> new EmojiViewHolder(v, emojiEventListener, variationSelectorListener, popup, allowVariations), displayItemLayoutResId)); registerFactory(EmojiModel.class, new LayoutFactory<>(v -> new EmojiViewHolder(v, emojiEventListener, variationSelectorListener, popup, allowVariations), displayEmojiLayoutResId));
registerFactory(EmojiTextModel.class, new LayoutFactory<>(v -> new EmojiTextViewHolder(v, emojiEventListener), R.layout.emoji_text_display_item)); registerFactory(EmojiTextModel.class, new LayoutFactory<>(v -> new EmojiTextViewHolder(v, emojiEventListener), displayEmoticonLayoutResId));
registerFactory(EmojiNoResultsModel.class, new LayoutFactory<>(MappingViewHolder.SimpleViewHolder::new, R.layout.emoji_grid_no_results)); registerFactory(EmojiNoResultsModel.class, new LayoutFactory<>(MappingViewHolder.SimpleViewHolder::new, R.layout.emoji_grid_no_results));
} }
@ -118,7 +119,6 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
private final boolean allowVariations; private final boolean allowVariations;
private final ImageView imageView; private final ImageView imageView;
private final ImageView hintCorner;
public EmojiViewHolder(@NonNull View itemView, public EmojiViewHolder(@NonNull View itemView,
@NonNull EmojiEventListener emojiEventListener, @NonNull EmojiEventListener emojiEventListener,
@ -134,7 +134,6 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
this.allowVariations = allowVariations; this.allowVariations = allowVariations;
this.imageView = itemView.findViewById(R.id.emoji_image); this.imageView = itemView.findViewById(R.id.emoji_image);
this.hintCorner = itemView.findViewById(R.id.emoji_variation_hint);
} }
@Override @Override
@ -151,9 +150,6 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
}); });
if (allowVariations && model.emoji.hasMultipleVariations()) { if (allowVariations && model.emoji.hasMultipleVariations()) {
if (hintCorner != null) {
hintCorner.setVisibility(View.VISIBLE);
}
itemView.setOnLongClickListener(v -> { itemView.setOnLongClickListener(v -> {
popup.dismiss(); popup.dismiss();
popup.setVariations(model.emoji.getVariations()); popup.setVariations(model.emoji.getVariations());
@ -162,9 +158,6 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
return true; return true;
}); });
} else { } else {
if (hintCorner != null) {
hintCorner.setVisibility(View.GONE);
}
itemView.setOnLongClickListener(null); itemView.setOnLongClickListener(null);
} }
} }

Wyświetl plik

@ -7,16 +7,12 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.emoji.EmojiPageModel import org.thoughtcrime.securesms.components.emoji.EmojiPageModel
import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter
import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.EmojiHeader import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.EmojiHeader
import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiTree
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.emoji.EmojiCategory import org.thoughtcrime.securesms.emoji.EmojiCategory
import org.thoughtcrime.securesms.emoji.EmojiSource.Companion.latest
import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardPageCategoryMappingModel.EmojiCategoryMappingModel import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardPageCategoryMappingModel.EmojiCategoryMappingModel
import org.thoughtcrime.securesms.util.DefaultValueLiveData import org.thoughtcrime.securesms.util.DefaultValueLiveData
import org.thoughtcrime.securesms.util.MappingModel
import org.thoughtcrime.securesms.util.MappingModelList import org.thoughtcrime.securesms.util.MappingModelList
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil import org.thoughtcrime.securesms.util.livedata.LiveDataUtil
@ -92,17 +88,3 @@ class EmojiKeyboardPageViewModel(repository: EmojiKeyboardPageRepository) : View
} }
} }
} }
private fun EmojiPageModel.toMappingModels(): List<MappingModel<*>> {
val emojiTree: EmojiTree = latest.emojiTree
return displayEmoji.map {
val isTextEmoji = EmojiCategory.EMOTICONS.key == key || (RecentEmojiPageModel.KEY == key && emojiTree.getEmoji(it.value, 0, it.value.length) == null)
if (isTextEmoji) {
EmojiPageViewGridAdapter.EmojiTextModel(key, it)
} else {
EmojiPageViewGridAdapter.EmojiModel(key, it)
}
}
}

Wyświetl plik

@ -0,0 +1,23 @@
package org.thoughtcrime.securesms.keyboard.emoji
import org.thoughtcrime.securesms.components.emoji.EmojiPageModel
import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter
import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiTree
import org.thoughtcrime.securesms.emoji.EmojiCategory
import org.thoughtcrime.securesms.emoji.EmojiSource
import org.thoughtcrime.securesms.util.MappingModel
fun EmojiPageModel.toMappingModels(): List<MappingModel<*>> {
val emojiTree: EmojiTree = EmojiSource.latest.emojiTree
return displayEmoji.map {
val isTextEmoji = EmojiCategory.EMOTICONS.key == key || (RecentEmojiPageModel.KEY == key && emojiTree.getEmoji(it.value, 0, it.value.length) == null)
if (isTextEmoji) {
EmojiPageViewGridAdapter.EmojiTextModel(key, it)
} else {
EmojiPageViewGridAdapter.EmojiModel(key, it)
}
}
}

Wyświetl plik

@ -40,17 +40,25 @@ class EmojiSearchFragment : Fragment(R.layout.emoji_search_fragment), EmojiPageV
val searchBar: KeyboardPageSearchView = view.findViewById(R.id.emoji_search_view) val searchBar: KeyboardPageSearchView = view.findViewById(R.id.emoji_search_view)
val resultsContainer: FrameLayout = view.findViewById(R.id.emoji_search_results_container) val resultsContainer: FrameLayout = view.findViewById(R.id.emoji_search_results_container)
val noResults: TextView = view.findViewById(R.id.emoji_search_empty) val noResults: TextView = view.findViewById(R.id.emoji_search_empty)
val emojiPageView = EmojiPageView(requireContext(), eventListener, this, true, LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false), R.layout.emoji_search_result_display_item) val emojiPageView = EmojiPageView(
requireContext(),
eventListener,
this,
true,
LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false),
R.layout.emoji_display_item_list,
R.layout.emoji_text_display_item_list
)
resultsContainer.addView(emojiPageView) resultsContainer.addView(emojiPageView)
searchBar.presentForEmojiSearch() searchBar.presentForEmojiSearch()
searchBar.callbacks = SearchCallbacks() searchBar.callbacks = SearchCallbacks()
viewModel.pageModel.observe(viewLifecycleOwner) { pageModel -> viewModel.emojiList.observe(viewLifecycleOwner) { results ->
emojiPageView.setModel(pageModel) emojiPageView.setList(results.emojiList)
if (pageModel.emoji.isNotEmpty() || pageModel.iconAttr == R.attr.emoji_category_recent) { if (results.emojiList.isNotEmpty() || results.isRecents) {
emojiPageView.visibility = View.VISIBLE emojiPageView.visibility = View.VISIBLE
noResults.visibility = View.GONE noResults.visibility = View.GONE
} else { } else {

Wyświetl plik

@ -5,21 +5,29 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import org.thoughtcrime.securesms.components.emoji.EmojiPageModel import org.thoughtcrime.securesms.components.emoji.EmojiPageModel
import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel
import org.thoughtcrime.securesms.keyboard.emoji.toMappingModels
import org.thoughtcrime.securesms.util.MappingModel
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil
class EmojiSearchViewModel(private val repository: EmojiSearchRepository) : ViewModel() { class EmojiSearchViewModel(private val repository: EmojiSearchRepository) : ViewModel() {
private val internalPageModel = MutableLiveData<EmojiPageModel>() private val pageModel = MutableLiveData<EmojiPageModel>()
val pageModel: LiveData<EmojiPageModel> = internalPageModel val emojiList: LiveData<EmojiSearchResults> = LiveDataUtil.mapAsync(pageModel) { page ->
EmojiSearchResults(page.toMappingModels(), page.key == RecentEmojiPageModel.KEY)
}
init { init {
onQueryChanged("") onQueryChanged("")
} }
fun onQueryChanged(query: String) { fun onQueryChanged(query: String) {
repository.submitQuery(query = query, includeRecents = true, consumer = internalPageModel::postValue) repository.submitQuery(query = query, includeRecents = true, consumer = pageModel::postValue)
} }
data class EmojiSearchResults(val emojiList: List<MappingModel<*>>, val isRecents: Boolean)
class Factory(private val repository: EmojiSearchRepository) : ViewModelProvider.Factory { class Factory(private val repository: EmojiSearchRepository) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T { override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return requireNotNull(modelClass.cast(EmojiSearchViewModel(repository))) return requireNotNull(modelClass.cast(EmojiSearchViewModel(repository)))

Wyświetl plik

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless"
tools:layout_height="60dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/emoji_image"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
tools:src="@drawable/ic_emoji_smiley_24" />
</FrameLayout>

Wyświetl plik

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/emoji_drawer_item_width"
android:layout_height="@dimen/emoji_drawer_item_width"
android:padding="2dp"
android:background="?selectableItemBackground">
<ImageView
android:id="@+id/emoji_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:paddingTop="6dp"
android:paddingEnd="6dp"
android:paddingStart="6dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
<org.thoughtcrime.securesms.components.emoji.AsciiEmojiView
android:id="@+id/emoji_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
android:paddingEnd="6dp"
android:paddingStart="6dp"
android:visibility="gone"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/emoji_variation_hint"
android:layout_width="7dp"
android:layout_height="7dp"
android:layout_gravity="bottom|right|end"
app:srcCompat="@drawable/triangle_bottom_right_corner"
android:tint="@color/core_grey_25"/>
</FrameLayout>

Wyświetl plik

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless"
tools:layout_height="60dp">
<org.thoughtcrime.securesms.components.emoji.AsciiEmojiView
android:id="@+id/emoji_text"
android:layout_width="32dp"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>

Wyświetl plik

@ -34,8 +34,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:paddingStart="5dp" android:paddingStart="8dp"
android:paddingEnd="5dp" android:paddingEnd="8dp"
android:paddingBottom="?actionBarSize" android:paddingBottom="?actionBarSize"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Wyświetl plik

@ -6,7 +6,7 @@
<dimen name="min_custom_keyboard_size">110dp</dimen> <dimen name="min_custom_keyboard_size">110dp</dimen>
<dimen name="min_custom_keyboard_top_margin_portrait">170dp</dimen> <dimen name="min_custom_keyboard_top_margin_portrait">170dp</dimen>
<dimen name="min_custom_keyboard_top_margin_landscape_bubble">56dp</dimen> <dimen name="min_custom_keyboard_top_margin_landscape_bubble">56dp</dimen>
<dimen name="emoji_drawer_item_width">54dp</dimen> <dimen name="emoji_drawer_item_width">48dp</dimen>
<dimen name="conversation_item_body_text_size">16sp</dimen> <dimen name="conversation_item_body_text_size">16sp</dimen>
<dimen name="conversation_item_date_text_size">12sp</dimen> <dimen name="conversation_item_date_text_size">12sp</dimen>
<dimen name="transport_selection_popup_width">200sp</dimen> <dimen name="transport_selection_popup_width">200sp</dimen>