Browse Source
Allow reacting direct item with any emoji. Fixes austinhuang0131/barinsta#1137
renovate/org.robolectric-robolectric-4.x
Allow reacting direct item with any emoji. Fixes austinhuang0131/barinsta#1137
renovate/org.robolectric-robolectric-4.x
Ammar Githam
4 years ago
11 changed files with 172 additions and 204 deletions
-
2app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java
-
4app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java
-
100app/src/main/java/awais/instagrabber/customviews/emoji/EmojiBottomSheetDialog.java
-
13app/src/main/java/awais/instagrabber/customviews/emoji/EmojiGridAdapter.java
-
163app/src/main/java/awais/instagrabber/customviews/emoji/EmojiPopupWindow.java
-
1app/src/main/java/awais/instagrabber/customviews/emoji/GoogleCompatEmojiDrawable.java
-
45app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
-
4app/src/main/java/awais/instagrabber/managers/ThreadManager.java
-
10app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemEmojiReaction.java
-
8app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemReactions.java
-
8app/src/main/java/awais/instagrabber/utils/emoji/EmojiParser.java
@ -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); |
|||
} |
|||
} |
@ -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(); |
|||
} |
|||
} |
|||
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue