mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 08:47:46 +00:00
215 lines
7.6 KiB
Java
215 lines
7.6 KiB
Java
|
package org.thoughtcrime.securesms.stickers;
|
||
|
|
||
|
import android.arch.lifecycle.ViewModelProviders;
|
||
|
import android.content.Context;
|
||
|
import android.content.res.Configuration;
|
||
|
import android.graphics.Point;
|
||
|
import android.os.Bundle;
|
||
|
import android.support.annotation.NonNull;
|
||
|
import android.support.annotation.Nullable;
|
||
|
import android.support.annotation.Px;
|
||
|
import android.support.v4.app.Fragment;
|
||
|
import android.support.v7.widget.GridLayoutManager;
|
||
|
import android.support.v7.widget.RecyclerView;
|
||
|
import android.view.Gravity;
|
||
|
import android.view.LayoutInflater;
|
||
|
import android.view.MotionEvent;
|
||
|
import android.view.View;
|
||
|
import android.view.ViewGroup;
|
||
|
|
||
|
import org.thoughtcrime.securesms.R;
|
||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||
|
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||
|
import org.thoughtcrime.securesms.logging.Log;
|
||
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
||
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||
|
import org.thoughtcrime.securesms.stickers.StickerKeyboardPageAdapter.StickerKeyboardPageViewHolder;
|
||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||
|
|
||
|
/**
|
||
|
* An individual page of stickers in the {@link StickerKeyboardProvider}.
|
||
|
*/
|
||
|
public final class StickerKeyboardPageFragment extends Fragment implements StickerKeyboardPageAdapter.EventListener {
|
||
|
|
||
|
private static final String TAG = Log.tag(StickerKeyboardPageFragment.class);
|
||
|
|
||
|
private static final String KEY_PACK_ID = "pack_id";
|
||
|
|
||
|
public static final String RECENT_PACK_ID = StickerKeyboardPageViewModel.RECENT_PACK_ID;
|
||
|
|
||
|
private RecyclerView list;
|
||
|
private StickerKeyboardPageAdapter adapter;
|
||
|
private GridLayoutManager layoutManager;
|
||
|
|
||
|
private StickerKeyboardPageViewModel viewModel;
|
||
|
private EventListener eventListener;
|
||
|
private ListTouchListener listTouchListener;
|
||
|
|
||
|
private String packId;
|
||
|
|
||
|
public static StickerKeyboardPageFragment newInstance(@NonNull String packId) {
|
||
|
Bundle args = new Bundle();
|
||
|
args.putString(KEY_PACK_ID, packId);
|
||
|
|
||
|
StickerKeyboardPageFragment fragment = new StickerKeyboardPageFragment();
|
||
|
fragment.setArguments(args);
|
||
|
fragment.packId = packId;
|
||
|
|
||
|
return fragment;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||
|
return inflater.inflate(R.layout.sticker_keyboard_page, container, false);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||
|
GlideRequests glideRequests = GlideApp.with(this);
|
||
|
|
||
|
this.list = view.findViewById(R.id.sticker_keyboard_list);
|
||
|
this.adapter = new StickerKeyboardPageAdapter(glideRequests, this);
|
||
|
this.layoutManager = new GridLayoutManager(requireContext(), 2);
|
||
|
this.listTouchListener = new ListTouchListener(requireContext(), glideRequests);
|
||
|
this.packId = getArguments().getString(KEY_PACK_ID);
|
||
|
|
||
|
list.setLayoutManager(layoutManager);
|
||
|
list.setAdapter(adapter);
|
||
|
list.addOnItemTouchListener(listTouchListener);
|
||
|
|
||
|
initViewModel(packId);
|
||
|
onScreenWidthChanged(getScreenWidth());
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onConfigurationChanged(Configuration newConfig) {
|
||
|
super.onConfigurationChanged(newConfig);
|
||
|
onScreenWidthChanged(getScreenWidth());
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onStickerClicked(@NonNull StickerRecord sticker) {
|
||
|
if (eventListener != null) {
|
||
|
eventListener.onStickerSelected(sticker);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onStickerLongClicked(@NonNull View targetView) {
|
||
|
if (listTouchListener != null) {
|
||
|
listTouchListener.enterHoverMode(list, targetView);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void setEventListener(@NonNull EventListener eventListener) {
|
||
|
this.eventListener = eventListener;
|
||
|
}
|
||
|
|
||
|
public @NonNull String getPackId() {
|
||
|
return packId;
|
||
|
}
|
||
|
|
||
|
private void initViewModel(@NonNull String packId) {
|
||
|
StickerKeyboardRepository repository = new StickerKeyboardRepository(DatabaseFactory.getStickerDatabase(requireContext()));
|
||
|
viewModel = ViewModelProviders.of(this, new StickerKeyboardPageViewModel.Factory(requireActivity().getApplication(), repository)).get(StickerKeyboardPageViewModel.class);
|
||
|
|
||
|
viewModel.getStickers(packId).observe(getViewLifecycleOwner(), stickerRecords -> {
|
||
|
if (stickerRecords == null) return;
|
||
|
|
||
|
adapter.setStickers(stickerRecords, calculateStickerSize(getScreenWidth()));
|
||
|
});
|
||
|
}
|
||
|
|
||
|
private void onScreenWidthChanged(@Px int newWidth) {
|
||
|
if (layoutManager != null) {
|
||
|
layoutManager.setSpanCount(calculateColumnCount(newWidth));
|
||
|
adapter.setStickerSize(calculateStickerSize(newWidth));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private int getScreenWidth() {
|
||
|
Point size = new Point();
|
||
|
requireActivity().getWindowManager().getDefaultDisplay().getSize(size);
|
||
|
return size.x;
|
||
|
}
|
||
|
|
||
|
private int calculateColumnCount(@Px int screenWidth) {
|
||
|
float modifier = getResources().getDimensionPixelOffset(R.dimen.sticker_page_item_padding);
|
||
|
float divisor = getResources().getDimensionPixelOffset(R.dimen.sticker_page_item_divisor);
|
||
|
return (int) ((screenWidth - modifier) / divisor);
|
||
|
}
|
||
|
|
||
|
private int calculateStickerSize(@Px int screenWidth) {
|
||
|
float multiplier = getResources().getDimensionPixelOffset(R.dimen.sticker_page_item_multiplier);
|
||
|
int columnCount = calculateColumnCount(screenWidth);
|
||
|
|
||
|
return (int) ((screenWidth - ((columnCount + 1) * multiplier)) / columnCount);
|
||
|
}
|
||
|
|
||
|
private final class ListTouchListener implements RecyclerView.OnItemTouchListener {
|
||
|
|
||
|
private final StickerPreviewPopup popup;
|
||
|
|
||
|
private boolean hoverMode;
|
||
|
|
||
|
ListTouchListener(@NonNull Context context, @NonNull GlideRequests glideRequests) {
|
||
|
this.popup = new StickerPreviewPopup(context, glideRequests);
|
||
|
popup.setAnimationStyle(R.style.StickerPopupAnimation);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean onInterceptTouchEvent(@NonNull RecyclerView recyclerView, @NonNull MotionEvent motionEvent) {
|
||
|
return hoverMode;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onTouchEvent(@NonNull RecyclerView recyclerView, @NonNull MotionEvent motionEvent) {
|
||
|
switch (motionEvent.getAction()) {
|
||
|
case MotionEvent.ACTION_UP:
|
||
|
case MotionEvent.ACTION_CANCEL:
|
||
|
hoverMode = false;
|
||
|
popup.dismiss();
|
||
|
eventListener.onStickerPopupEnded();
|
||
|
break;
|
||
|
default:
|
||
|
for (int i = 0, len = recyclerView.getChildCount(); i < len; i++) {
|
||
|
View child = recyclerView.getChildAt(i);
|
||
|
|
||
|
if (ViewUtil.isPointInsideView(recyclerView, motionEvent.getRawX(), motionEvent.getRawY()) &&
|
||
|
ViewUtil.isPointInsideView(child, motionEvent.getRawX(), motionEvent.getRawY()))
|
||
|
{
|
||
|
showStickerForView(recyclerView, child);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onRequestDisallowInterceptTouchEvent(boolean b) {
|
||
|
}
|
||
|
|
||
|
void enterHoverMode(@NonNull RecyclerView recyclerView, View targetView) {
|
||
|
this.hoverMode = true;
|
||
|
showStickerForView(recyclerView, targetView);
|
||
|
}
|
||
|
|
||
|
private void showStickerForView(@NonNull RecyclerView recyclerView, @NonNull View view) {
|
||
|
StickerKeyboardPageViewHolder holder = (StickerKeyboardPageViewHolder) recyclerView.getChildViewHolder(view);
|
||
|
|
||
|
if (holder != null && holder.getCurrentSticker() != null) {
|
||
|
if (!popup.isShowing()) {
|
||
|
popup.showAtLocation(recyclerView, Gravity.NO_GRAVITY, 0, 0);
|
||
|
eventListener.onStickerPopupStarted();
|
||
|
}
|
||
|
popup.presentSticker(holder.getCurrentSticker());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
interface EventListener {
|
||
|
void onStickerSelected(@NonNull StickerRecord sticker);
|
||
|
void onStickerPopupStarted();
|
||
|
void onStickerPopupEnded();
|
||
|
}
|
||
|
}
|