Make it more likely 8 emoji fit on a row, fix emoji search emoticons.
This commit is contained in:
parent
a1c8573fad
commit
b85c5eb54a
14 changed files with 101 additions and 86 deletions
|
@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.util.InsetItemDecoration
|
|||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
|
||||
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)
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.util.MappingModel;
|
|||
import org.thoughtcrime.securesms.util.MappingModelList;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class EmojiPageView extends RecyclerView implements VariationSelectorListener {
|
||||
|
@ -59,26 +60,26 @@ public class EmojiPageView extends RecyclerView implements VariationSelectorList
|
|||
@NonNull VariationSelectorListener variationSelectorListener,
|
||||
boolean allowVariations,
|
||||
@NonNull LinearLayoutManager layoutManager,
|
||||
@LayoutRes int displayItemLayoutResId)
|
||||
@LayoutRes int displayEmojiLayoutResId,
|
||||
@LayoutRes int displayEmoticonLayoutResId)
|
||||
{
|
||||
super(context);
|
||||
initialize(emojiSelectionListener, variationSelectorListener, allowVariations, layoutManager, displayItemLayoutResId);
|
||||
initialize(emojiSelectionListener, variationSelectorListener, allowVariations, layoutManager, displayEmojiLayoutResId, displayEmoticonLayoutResId);
|
||||
}
|
||||
|
||||
public void initialize(@NonNull EmojiEventListener emojiSelectionListener,
|
||||
@NonNull VariationSelectorListener variationSelectorListener,
|
||||
boolean allowVariations)
|
||||
{
|
||||
initialize(emojiSelectionListener, variationSelectorListener, allowVariations, new GridLayoutManager(getContext(), 8), R.layout.emoji_display_item);
|
||||
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));
|
||||
initialize(emojiSelectionListener, variationSelectorListener, allowVariations, new GridLayoutManager(getContext(), 8), R.layout.emoji_display_item_grid, R.layout.emoji_text_display_item_grid);
|
||||
}
|
||||
|
||||
public void initialize(@NonNull EmojiEventListener emojiSelectionListener,
|
||||
@NonNull VariationSelectorListener variationSelectorListener,
|
||||
boolean allowVariations,
|
||||
@NonNull LinearLayoutManager layoutManager,
|
||||
@LayoutRes int displayItemLayoutResId)
|
||||
@LayoutRes int displayEmojiLayoutResId,
|
||||
@LayoutRes int displayEmoticonLayoutResId)
|
||||
{
|
||||
this.variationSelectorListener = variationSelectorListener;
|
||||
|
||||
|
@ -89,7 +90,8 @@ public class EmojiPageView extends RecyclerView implements VariationSelectorList
|
|||
emojiSelectionListener,
|
||||
this,
|
||||
allowVariations,
|
||||
displayItemLayoutResId);
|
||||
displayEmojiLayoutResId,
|
||||
displayEmoticonLayoutResId);
|
||||
|
||||
if (this.layoutManager instanceof GridLayoutManager) {
|
||||
GridLayoutManager gridLayout = (GridLayoutManager) this.layoutManager;
|
||||
|
@ -108,6 +110,9 @@ public class EmojiPageView extends RecyclerView implements VariationSelectorList
|
|||
}
|
||||
|
||||
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() {
|
||||
|
@ -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;
|
||||
EmojiPageViewGridAdapter adapter = adapterFactory.create();
|
||||
setAdapter(adapter);
|
||||
|
|
|
@ -22,15 +22,16 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
|
|||
@NonNull EmojiEventListener emojiEventListener,
|
||||
@NonNull VariationSelectorListener variationSelectorListener,
|
||||
boolean allowVariations,
|
||||
@LayoutRes int displayItemLayoutResId)
|
||||
@LayoutRes int displayEmojiLayoutResId,
|
||||
@LayoutRes int displayEmoticonLayoutResId)
|
||||
{
|
||||
this.variationSelectorListener = variationSelectorListener;
|
||||
|
||||
popup.setOnDismissListener(this);
|
||||
|
||||
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(EmojiTextModel.class, new LayoutFactory<>(v -> new EmojiTextViewHolder(v, emojiEventListener), R.layout.emoji_text_display_item));
|
||||
registerFactory(EmojiModel.class, new LayoutFactory<>(v -> new EmojiViewHolder(v, emojiEventListener, variationSelectorListener, popup, allowVariations), displayEmojiLayoutResId));
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -118,7 +119,6 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
|
|||
private final boolean allowVariations;
|
||||
|
||||
private final ImageView imageView;
|
||||
private final ImageView hintCorner;
|
||||
|
||||
public EmojiViewHolder(@NonNull View itemView,
|
||||
@NonNull EmojiEventListener emojiEventListener,
|
||||
|
@ -134,7 +134,6 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
|
|||
this.allowVariations = allowVariations;
|
||||
|
||||
this.imageView = itemView.findViewById(R.id.emoji_image);
|
||||
this.hintCorner = itemView.findViewById(R.id.emoji_variation_hint);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -151,9 +150,6 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
|
|||
});
|
||||
|
||||
if (allowVariations && model.emoji.hasMultipleVariations()) {
|
||||
if (hintCorner != null) {
|
||||
hintCorner.setVisibility(View.VISIBLE);
|
||||
}
|
||||
itemView.setOnLongClickListener(v -> {
|
||||
popup.dismiss();
|
||||
popup.setVariations(model.emoji.getVariations());
|
||||
|
@ -162,9 +158,6 @@ public class EmojiPageViewGridAdapter extends MappingAdapter implements PopupWin
|
|||
return true;
|
||||
});
|
||||
} else {
|
||||
if (hintCorner != null) {
|
||||
hintCorner.setVisibility(View.GONE);
|
||||
}
|
||||
itemView.setOnLongClickListener(null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,16 +7,12 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.thoughtcrime.securesms.R
|
||||
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.RecentEmojiPageModel
|
||||
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiTree
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
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.util.DefaultValueLiveData
|
||||
import org.thoughtcrime.securesms.util.MappingModel
|
||||
import org.thoughtcrime.securesms.util.MappingModelList
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,17 +40,25 @@ class EmojiSearchFragment : Fragment(R.layout.emoji_search_fragment), EmojiPageV
|
|||
val searchBar: KeyboardPageSearchView = view.findViewById(R.id.emoji_search_view)
|
||||
val resultsContainer: FrameLayout = view.findViewById(R.id.emoji_search_results_container)
|
||||
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)
|
||||
|
||||
searchBar.presentForEmojiSearch()
|
||||
searchBar.callbacks = SearchCallbacks()
|
||||
|
||||
viewModel.pageModel.observe(viewLifecycleOwner) { pageModel ->
|
||||
emojiPageView.setModel(pageModel)
|
||||
viewModel.emojiList.observe(viewLifecycleOwner) { results ->
|
||||
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
|
||||
noResults.visibility = View.GONE
|
||||
} else {
|
||||
|
|
|
@ -5,21 +5,29 @@ import androidx.lifecycle.MutableLiveData
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
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() {
|
||||
|
||||
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 {
|
||||
onQueryChanged("")
|
||||
}
|
||||
|
||||
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 {
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return requireNotNull(modelClass.cast(EmojiSearchViewModel(repository)))
|
||||
|
|
18
app/src/main/res/layout/emoji_display_item_list.xml
Normal file
18
app/src/main/res/layout/emoji_display_item_list.xml
Normal file
|
@ -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>
|
|
@ -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>
|
16
app/src/main/res/layout/emoji_text_display_item_list.xml
Normal file
16
app/src/main/res/layout/emoji_text_display_item_list.xml
Normal file
|
@ -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>
|
|
@ -34,8 +34,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingBottom="?actionBarSize"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<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_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_date_text_size">12sp</dimen>
|
||||
<dimen name="transport_selection_popup_width">200sp</dimen>
|
||||
|
|
Loading…
Add table
Reference in a new issue