mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-16 19:57:31 +00:00
Allow reacting direct item with any emoji. Fixes austinhuang0131/barinsta#1137
This commit is contained in:
parent
5744a1a687
commit
2f4fe657e9
@ -406,6 +406,8 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter<RecyclerView.
|
|||||||
void onReactionClick(DirectItem item, int position);
|
void onReactionClick(DirectItem item, int position);
|
||||||
|
|
||||||
void onOptionSelect(DirectItem item, @IdRes int itemId, final Function<DirectItem, Void> callback);
|
void onOptionSelect(DirectItem item, @IdRes int itemId, final Function<DirectItem, Void> callback);
|
||||||
|
|
||||||
|
void onAddReactionListener(DirectItem item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface DirectItemInternalLongClickListener {
|
public interface DirectItemInternalLongClickListener {
|
||||||
|
@ -551,6 +551,10 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple
|
|||||||
menu.setOnDismissListener(() -> setSelected(false));
|
menu.setOnDismissListener(() -> setSelected(false));
|
||||||
menu.setOnReactionClickListener(emoji -> callback.onReaction(item, emoji));
|
menu.setOnReactionClickListener(emoji -> callback.onReaction(item, emoji));
|
||||||
menu.setOnOptionSelectListener((itemId, cb) -> callback.onOptionSelect(item, itemId, cb));
|
menu.setOnOptionSelectListener((itemId, cb) -> callback.onOptionSelect(item, itemId, cb));
|
||||||
|
menu.setOnAddReactionListener(() -> {
|
||||||
|
menu.dismiss();
|
||||||
|
itemView.postDelayed(() -> callback.onAddReactionListener(item), 300);
|
||||||
|
});
|
||||||
menu.show(itemView, location);
|
menu.show(itemView, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
package awais.instagrabber.customviews.emoji;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||||
|
|
||||||
|
import awais.instagrabber.R;
|
||||||
|
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
|
public class EmojiBottomSheetDialog extends BottomSheetDialogFragment {
|
||||||
|
public static final String TAG = EmojiBottomSheetDialog.class.getSimpleName();
|
||||||
|
|
||||||
|
private RecyclerView grid;
|
||||||
|
private EmojiPicker.OnEmojiClickListener callback;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static EmojiBottomSheetDialog newInstance() {
|
||||||
|
// Bundle args = new Bundle();
|
||||||
|
// fragment.setArguments(args);
|
||||||
|
return new EmojiBottomSheetDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setStyle(DialogFragment.STYLE_NORMAL, R.style.ThemeOverlay_Rounded_BottomSheetDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
|
||||||
|
final Context context = getContext();
|
||||||
|
if (context == null) return null;
|
||||||
|
grid = new RecyclerView(context);
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
final Dialog dialog = getDialog();
|
||||||
|
if (dialog == null) return;
|
||||||
|
final BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialog;
|
||||||
|
final View bottomSheetInternal = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
|
||||||
|
if (bottomSheetInternal == null) return;
|
||||||
|
bottomSheetInternal.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||||
|
bottomSheetInternal.requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull final Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
final Fragment parentFragment = getParentFragment();
|
||||||
|
if (parentFragment instanceof EmojiPicker.OnEmojiClickListener) {
|
||||||
|
callback = (EmojiPicker.OnEmojiClickListener) parentFragment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
grid = null;
|
||||||
|
super.onDestroyView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
final Context context = getContext();
|
||||||
|
if (context == null) return;
|
||||||
|
final GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 9);
|
||||||
|
grid.setLayoutManager(gridLayoutManager);
|
||||||
|
grid.setHasFixedSize(true);
|
||||||
|
grid.setClipToPadding(false);
|
||||||
|
grid.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(8)));
|
||||||
|
final EmojiGridAdapter adapter = new EmojiGridAdapter(null, (view, emoji) -> {
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onClick(view, emoji);
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}, null);
|
||||||
|
grid.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
@ -43,7 +43,7 @@ public class EmojiGridAdapter extends RecyclerView.Adapter<EmojiGridAdapter.Emoj
|
|||||||
private final EmojiVariantManager emojiVariantManager;
|
private final EmojiVariantManager emojiVariantManager;
|
||||||
private final AppExecutors appExecutors;
|
private final AppExecutors appExecutors;
|
||||||
|
|
||||||
public EmojiGridAdapter(@NonNull final EmojiCategoryType emojiCategoryType,
|
public EmojiGridAdapter(final EmojiCategoryType emojiCategoryType,
|
||||||
final OnEmojiClickListener onEmojiClickListener,
|
final OnEmojiClickListener onEmojiClickListener,
|
||||||
final OnEmojiLongClickListener onEmojiLongClickListener) {
|
final OnEmojiLongClickListener onEmojiLongClickListener) {
|
||||||
this.onEmojiClickListener = onEmojiClickListener;
|
this.onEmojiClickListener = onEmojiClickListener;
|
||||||
@ -55,6 +55,11 @@ public class EmojiGridAdapter extends RecyclerView.Adapter<EmojiGridAdapter.Emoj
|
|||||||
emojiVariantManager = EmojiVariantManager.getInstance();
|
emojiVariantManager = EmojiVariantManager.getInstance();
|
||||||
appExecutors = AppExecutors.getInstance();
|
appExecutors = AppExecutors.getInstance();
|
||||||
setHasStableIds(true);
|
setHasStableIds(true);
|
||||||
|
if (emojiCategoryType == null) {
|
||||||
|
// show all if type is null
|
||||||
|
differ.submitList(ImmutableList.copyOf(emojiParser.getAllEmojis().values()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
final EmojiCategory emojiCategory = categoryMap.get(emojiCategoryType);
|
final EmojiCategory emojiCategory = categoryMap.get(emojiCategoryType);
|
||||||
if (emojiCategory == null) {
|
if (emojiCategory == null) {
|
||||||
differ.submitList(Collections.emptyList());
|
differ.submitList(Collections.emptyList());
|
||||||
@ -105,7 +110,7 @@ public class EmojiGridAdapter extends RecyclerView.Adapter<EmojiGridAdapter.Emoj
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class EmojiViewHolder extends RecyclerView.ViewHolder {
|
public static class EmojiViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final AppExecutors appExecutors = AppExecutors.getInstance();
|
// private final AppExecutors appExecutors = AppExecutors.getInstance();
|
||||||
private final ItemEmojiGridBinding binding;
|
private final ItemEmojiGridBinding binding;
|
||||||
private final OnEmojiClickListener onEmojiClickListener;
|
private final OnEmojiClickListener onEmojiClickListener;
|
||||||
private final OnEmojiLongClickListener onEmojiLongClickListener;
|
private final OnEmojiLongClickListener onEmojiLongClickListener;
|
||||||
@ -123,17 +128,17 @@ public class EmojiGridAdapter extends RecyclerView.Adapter<EmojiGridAdapter.Emoj
|
|||||||
binding.image.setImageDrawable(null);
|
binding.image.setImageDrawable(null);
|
||||||
binding.indicator.setVisibility(View.GONE);
|
binding.indicator.setVisibility(View.GONE);
|
||||||
itemView.setOnLongClickListener(null);
|
itemView.setOnLongClickListener(null);
|
||||||
itemView.post(() -> {
|
// itemView.post(() -> {
|
||||||
binding.image.setImageDrawable(emoji.getDrawable());
|
binding.image.setImageDrawable(emoji.getDrawable());
|
||||||
final boolean hasVariants = !parent.getVariants().isEmpty();
|
final boolean hasVariants = !parent.getVariants().isEmpty();
|
||||||
binding.indicator.setVisibility(hasVariants ? View.VISIBLE : View.GONE);
|
binding.indicator.setVisibility(hasVariants ? View.VISIBLE : View.GONE);
|
||||||
if (onEmojiClickListener != null) {
|
if (onEmojiClickListener != null) {
|
||||||
itemView.setOnClickListener(v -> onEmojiClickListener.onClick(v, emoji));
|
itemView.setOnClickListener(v -> onEmojiClickListener.onClick(v, emoji));
|
||||||
}
|
}
|
||||||
if (hasVariants && onEmojiLongClickListener != null) {
|
if (hasVariants && onEmojiLongClickListener != null) {
|
||||||
itemView.setOnLongClickListener(v -> onEmojiLongClickListener.onLongClick(position, v, parent));
|
itemView.setOnLongClickListener(v -> onEmojiLongClickListener.onLongClick(position, v, parent));
|
||||||
}
|
}
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,163 +0,0 @@
|
|||||||
package awais.instagrabber.customviews.emoji;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager.LayoutParams;
|
|
||||||
import android.widget.PopupWindow;
|
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
|
||||||
import awais.instagrabber.customviews.emoji.EmojiPicker.OnBackspaceClickListener;
|
|
||||||
import awais.instagrabber.customviews.emoji.EmojiPicker.OnEmojiClickListener;
|
|
||||||
import awais.instagrabber.utils.Utils;
|
|
||||||
|
|
||||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* https://stackoverflow.com/a/33897583/1436766
|
|
||||||
*/
|
|
||||||
public class EmojiPopupWindow extends PopupWindow {
|
|
||||||
|
|
||||||
private int keyBoardHeight = 0;
|
|
||||||
private Boolean pendingOpen = false;
|
|
||||||
private Boolean isOpened = false;
|
|
||||||
private final View rootView;
|
|
||||||
private final Context context;
|
|
||||||
private final OnEmojiClickListener onEmojiClickListener;
|
|
||||||
private final OnBackspaceClickListener onBackspaceClickListener;
|
|
||||||
|
|
||||||
private OnSoftKeyboardOpenCloseListener onSoftKeyboardOpenCloseListener;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param rootView The top most layout in your view hierarchy. The difference of this view and the screen height will be used to calculate the keyboard height.
|
|
||||||
*/
|
|
||||||
public EmojiPopupWindow(final View rootView,
|
|
||||||
final OnEmojiClickListener onEmojiClickListener,
|
|
||||||
final OnBackspaceClickListener onBackspaceClickListener) {
|
|
||||||
super(rootView.getContext());
|
|
||||||
this.rootView = rootView;
|
|
||||||
this.context = rootView.getContext();
|
|
||||||
this.onEmojiClickListener = onEmojiClickListener;
|
|
||||||
this.onBackspaceClickListener = onBackspaceClickListener;
|
|
||||||
View customView = createCustomView();
|
|
||||||
setContentView(customView);
|
|
||||||
setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
|
|
||||||
//default size
|
|
||||||
setSize((int) context.getResources().getDimension(R.dimen.keyboard_height), MATCH_PARENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the listener for the event of keyboard opening or closing.
|
|
||||||
*/
|
|
||||||
public void setOnSoftKeyboardOpenCloseListener(OnSoftKeyboardOpenCloseListener listener) {
|
|
||||||
this.onSoftKeyboardOpenCloseListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this function to show the emoji popup.
|
|
||||||
* NOTE: Since, the soft keyboard sizes are variable on different android devices, the
|
|
||||||
* library needs you to open the soft keyboard atleast once before calling this function.
|
|
||||||
* If that is not possible see showAtBottomPending() function.
|
|
||||||
*/
|
|
||||||
public void showAtBottom() {
|
|
||||||
showAtLocation(rootView, Gravity.BOTTOM, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this function when the soft keyboard has not been opened yet. This
|
|
||||||
* will show the emoji popup after the keyboard is up next time.
|
|
||||||
* Generally, you will be calling InputMethodManager.showSoftInput function after
|
|
||||||
* calling this function.
|
|
||||||
*/
|
|
||||||
public void showAtBottomPending() {
|
|
||||||
if (isKeyBoardOpen())
|
|
||||||
showAtBottom();
|
|
||||||
else
|
|
||||||
pendingOpen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Returns true if the soft keyboard is open, false otherwise.
|
|
||||||
*/
|
|
||||||
public Boolean isKeyBoardOpen() {
|
|
||||||
return isOpened;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dismiss the popup
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void dismiss() {
|
|
||||||
super.dismiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call this function to resize the emoji popup according to your soft keyboard size
|
|
||||||
*/
|
|
||||||
public void setSizeForSoftKeyboard() {
|
|
||||||
rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
|
|
||||||
Rect r = new Rect();
|
|
||||||
rootView.getWindowVisibleDisplayFrame(r);
|
|
||||||
|
|
||||||
int screenHeight = getUsableScreenHeight();
|
|
||||||
int heightDifference = screenHeight - (r.bottom - r.top);
|
|
||||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
|
||||||
if (resourceId > 0) {
|
|
||||||
heightDifference -= context.getResources()
|
|
||||||
.getDimensionPixelSize(resourceId);
|
|
||||||
}
|
|
||||||
if (heightDifference > 100) {
|
|
||||||
keyBoardHeight = heightDifference;
|
|
||||||
setSize(MATCH_PARENT, keyBoardHeight);
|
|
||||||
if (!isOpened) {
|
|
||||||
if (onSoftKeyboardOpenCloseListener != null)
|
|
||||||
onSoftKeyboardOpenCloseListener.onKeyboardOpen(keyBoardHeight);
|
|
||||||
}
|
|
||||||
isOpened = true;
|
|
||||||
if (pendingOpen) {
|
|
||||||
showAtBottom();
|
|
||||||
pendingOpen = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
isOpened = false;
|
|
||||||
if (onSoftKeyboardOpenCloseListener != null)
|
|
||||||
onSoftKeyboardOpenCloseListener.onKeyboardClose();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getUsableScreenHeight() {
|
|
||||||
return Utils.displayMetrics.heightPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manually set the popup window size
|
|
||||||
*
|
|
||||||
* @param width Width of the popup
|
|
||||||
* @param height Height of the popup
|
|
||||||
*/
|
|
||||||
public void setSize(int width, int height) {
|
|
||||||
setWidth(width);
|
|
||||||
setHeight(height);
|
|
||||||
}
|
|
||||||
|
|
||||||
private View createCustomView() {
|
|
||||||
final EmojiPicker emojiPicker = new EmojiPicker(context);
|
|
||||||
final LayoutParams layoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
|
|
||||||
emojiPicker.setLayoutParams(layoutParams);
|
|
||||||
emojiPicker.init(rootView, onEmojiClickListener, onBackspaceClickListener);
|
|
||||||
return emojiPicker;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public interface OnSoftKeyboardOpenCloseListener {
|
|
||||||
void onKeyboardOpen(int keyBoardHeight);
|
|
||||||
|
|
||||||
void onKeyboardClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -25,7 +25,6 @@ import android.graphics.Rect;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.emoji.text.EmojiCompat;
|
import androidx.emoji.text.EmojiCompat;
|
||||||
|
@ -15,7 +15,6 @@ import android.net.Uri;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@ -33,7 +32,6 @@ import androidx.constraintlayout.widget.ConstraintLayout;
|
|||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MediatorLiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
@ -75,6 +73,8 @@ import awais.instagrabber.animations.CubicBezierInterpolator;
|
|||||||
import awais.instagrabber.customviews.RecordView;
|
import awais.instagrabber.customviews.RecordView;
|
||||||
import awais.instagrabber.customviews.Tooltip;
|
import awais.instagrabber.customviews.Tooltip;
|
||||||
import awais.instagrabber.customviews.emoji.Emoji;
|
import awais.instagrabber.customviews.emoji.Emoji;
|
||||||
|
import awais.instagrabber.customviews.emoji.EmojiBottomSheetDialog;
|
||||||
|
import awais.instagrabber.customviews.emoji.EmojiPicker;
|
||||||
import awais.instagrabber.customviews.helpers.HeaderItemDecoration;
|
import awais.instagrabber.customviews.helpers.HeaderItemDecoration;
|
||||||
import awais.instagrabber.customviews.helpers.HeightProvider;
|
import awais.instagrabber.customviews.helpers.HeightProvider;
|
||||||
import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtEdge;
|
import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtEdge;
|
||||||
@ -114,7 +114,8 @@ import awais.instagrabber.viewmodels.factories.DirectThreadViewModelFactory;
|
|||||||
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
|
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
|
||||||
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
|
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
|
||||||
|
|
||||||
public class DirectMessageThreadFragment extends Fragment implements DirectReactionsAdapter.OnReactionClickListener {
|
public class DirectMessageThreadFragment extends Fragment implements DirectReactionsAdapter.OnReactionClickListener,
|
||||||
|
EmojiPicker.OnEmojiClickListener {
|
||||||
private static final String TAG = DirectMessageThreadFragment.class.getSimpleName();
|
private static final String TAG = DirectMessageThreadFragment.class.getSimpleName();
|
||||||
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
|
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
|
||||||
private static final int AUDIO_RECORD_PERM_REQUEST_CODE = 1000;
|
private static final int AUDIO_RECORD_PERM_REQUEST_CODE = 1000;
|
||||||
@ -159,6 +160,9 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
private LiveData<Integer> pendingRequestsCountLiveData;
|
private LiveData<Integer> pendingRequestsCountLiveData;
|
||||||
private LiveData<List<User>> usersLiveData;
|
private LiveData<List<User>> usersLiveData;
|
||||||
private boolean autoMarkAsSeen = false;
|
private boolean autoMarkAsSeen = false;
|
||||||
|
private MenuItem markAsSeenMenuItem;
|
||||||
|
private Media tempMedia;
|
||||||
|
private DirectItem addReactionItem;
|
||||||
|
|
||||||
private final AppExecutors appExecutors = AppExecutors.getInstance();
|
private final AppExecutors appExecutors = AppExecutors.getInstance();
|
||||||
private final Animatable2Compat.AnimationCallback micToSendAnimationCallback = new Animatable2Compat.AnimationCallback() {
|
private final Animatable2Compat.AnimationCallback micToSendAnimationCallback = new Animatable2Compat.AnimationCallback() {
|
||||||
@ -291,6 +295,14 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
cb.apply(item);
|
cb.apply(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAddReactionListener(final DirectItem item) {
|
||||||
|
if (item == null) return;
|
||||||
|
addReactionItem = item;
|
||||||
|
final EmojiBottomSheetDialog emojiBottomSheetDialog = EmojiBottomSheetDialog.newInstance();
|
||||||
|
emojiBottomSheetDialog.show(getChildFragmentManager(), EmojiBottomSheetDialog.TAG);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final DirectItemLongClickListener directItemLongClickListener = position -> {
|
private final DirectItemLongClickListener directItemLongClickListener = position -> {
|
||||||
@ -321,8 +333,6 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
backStackSavedStateResultLiveData.postValue(null);
|
backStackSavedStateResultLiveData.postValue(null);
|
||||||
};
|
};
|
||||||
private final MutableLiveData<Integer> inputLength = new MutableLiveData<>(0);
|
private final MutableLiveData<Integer> inputLength = new MutableLiveData<>(0);
|
||||||
private MenuItem markAsSeenMenuItem;
|
|
||||||
private Media tempMedia;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
@ -1461,25 +1471,12 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(direction);
|
NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ItemsAdapterDataMerger extends MediatorLiveData<Pair<User, DirectThread>> {
|
@Override
|
||||||
private User user;
|
public void onClick(final View view, final Emoji emoji) {
|
||||||
private DirectThread thread;
|
if (addReactionItem == null) return;
|
||||||
|
final LiveData<Resource<Object>> resourceLiveData = viewModel.sendReaction(addReactionItem, emoji);
|
||||||
public ItemsAdapterDataMerger(final LiveData<User> userLiveData,
|
if (resourceLiveData != null) {
|
||||||
final LiveData<DirectThread> threadLiveData) {
|
resourceLiveData.observe(getViewLifecycleOwner(), directItemResource -> handleSentMessage(resourceLiveData));
|
||||||
addSource(userLiveData, user -> {
|
|
||||||
this.user = user;
|
|
||||||
combine();
|
|
||||||
});
|
|
||||||
addSource(threadLiveData, thread -> {
|
|
||||||
this.thread = thread;
|
|
||||||
combine();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void combine() {
|
|
||||||
if (user == null || thread == null) return;
|
|
||||||
setValue(new Pair<>(user, thread));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -585,8 +585,7 @@ public final class ThreadManager {
|
|||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
temp.add(0, reaction);
|
temp.add(0, reaction);
|
||||||
} else if (shouldReplaceIfAlreadyReacted) {
|
} else if (shouldReplaceIfAlreadyReacted) {
|
||||||
temp.add(0, reaction);
|
temp.set(index, reaction);
|
||||||
temp.remove(index);
|
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
@ -736,6 +735,7 @@ public final class ThreadManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public LiveData<Resource<Object>> sendReaction(final DirectItem item, final Emoji emoji) {
|
public LiveData<Resource<Object>> sendReaction(final DirectItem item, final Emoji emoji) {
|
||||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||||
final Long userId = getCurrentUserId(data);
|
final Long userId = getCurrentUserId(data);
|
||||||
|
@ -47,4 +47,14 @@ public class DirectItemEmojiReaction implements Serializable {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(senderId, timestamp, emoji, superReactType);
|
return Objects.hash(senderId, timestamp, emoji, superReactType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DirectItemEmojiReaction{" +
|
||||||
|
"senderId=" + senderId +
|
||||||
|
", timestamp=" + timestamp +
|
||||||
|
", emoji='" + emoji + '\'' +
|
||||||
|
", superReactType='" + superReactType + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,4 +51,12 @@ public class DirectItemReactions implements Cloneable, Serializable {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(emojis, likes);
|
return Objects.hash(emojis, likes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DirectItemReactions{" +
|
||||||
|
"emojis=" + emojis +
|
||||||
|
", likes=" + likes +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import java.io.InputStream;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -77,7 +78,12 @@ public final class EmojiParser {
|
|||||||
.addAll(emoji.getVariants())
|
.addAll(emoji.getVariants())
|
||||||
.build()
|
.build()
|
||||||
.stream())
|
.stream())
|
||||||
.collect(Collectors.toMap(Emoji::getUnicode, Function.identity()));
|
.collect(Collectors.toMap(
|
||||||
|
Emoji::getUnicode,
|
||||||
|
Function.identity(),
|
||||||
|
(u, v) -> u,
|
||||||
|
LinkedHashMap::new
|
||||||
|
));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "EmojiParser: ", e);
|
Log.e(TAG, "EmojiParser: ", e);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user