mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 21:28:34 +00:00
Show long-press-magnify in sticker preview screen.
This commit is contained in:
parent
4e7b4da941
commit
277c9e22f1
@ -4,4 +4,5 @@
|
|||||||
android:id="@+id/sticker_install_item_image"
|
android:id="@+id/sticker_install_item_image"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/sticker_preview_sticker_size"
|
android:layout_height="@dimen/sticker_preview_sticker_size"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
android:scaleType="centerInside"/>
|
android:scaleType="centerInside"/>
|
||||||
|
@ -1,14 +1,35 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?sticker_popup_background">
|
android:background="?sticker_popup_background">
|
||||||
|
|
||||||
<ImageView
|
<LinearLayout
|
||||||
android:id="@+id/sticker_popup_image"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="200dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="200dp"
|
android:layout_gravity="center"
|
||||||
android:layout_gravity="center"/>
|
android:orientation="vertical"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
|
android:id="@+id/sticker_popup_emoji"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textSize="22sp"
|
||||||
|
tools:text=":)"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/sticker_popup_image"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
tools:src="@drawable/ic_contact_picture"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
@ -45,8 +45,7 @@ final class StickerKeyboardPageAdapter extends RecyclerView.Adapter<StickerKeybo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull
|
public @NonNull StickerKeyboardPageViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
|
||||||
StickerKeyboardPageViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
|
|
||||||
return new StickerKeyboardPageViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.sticker_keyboard_page_list_item, viewGroup, false));
|
return new StickerKeyboardPageViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.sticker_keyboard_page_list_item, viewGroup, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package org.thoughtcrime.securesms.stickers;
|
package org.thoughtcrime.securesms.stickers;
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModelProviders;
|
import androidx.lifecycle.ViewModelProviders;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -11,9 +10,7 @@ import androidx.annotation.Px;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
@ -21,15 +18,18 @@ import org.thoughtcrime.securesms.R;
|
|||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
|
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.thoughtcrime.securesms.stickers.StickerKeyboardPageAdapter.StickerKeyboardPageViewHolder;
|
import org.thoughtcrime.securesms.stickers.StickerKeyboardPageAdapter.StickerKeyboardPageViewHolder;
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
import org.whispersystems.libsignal.util.Pair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An individual page of stickers in the {@link StickerKeyboardProvider}.
|
* An individual page of stickers in the {@link StickerKeyboardProvider}.
|
||||||
*/
|
*/
|
||||||
public final class StickerKeyboardPageFragment extends Fragment implements StickerKeyboardPageAdapter.EventListener {
|
public final class StickerKeyboardPageFragment extends Fragment implements StickerKeyboardPageAdapter.EventListener,
|
||||||
|
StickerRolloverTouchListener.RolloverStickerRetriever
|
||||||
|
{
|
||||||
|
|
||||||
private static final String TAG = Log.tag(StickerKeyboardPageFragment.class);
|
private static final String TAG = Log.tag(StickerKeyboardPageFragment.class);
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ public final class StickerKeyboardPageFragment extends Fragment implements Stick
|
|||||||
|
|
||||||
private StickerKeyboardPageViewModel viewModel;
|
private StickerKeyboardPageViewModel viewModel;
|
||||||
private EventListener eventListener;
|
private EventListener eventListener;
|
||||||
private ListTouchListener listTouchListener;
|
private StickerRolloverTouchListener listTouchListener;
|
||||||
|
|
||||||
private String packId;
|
private String packId;
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ public final class StickerKeyboardPageFragment extends Fragment implements Stick
|
|||||||
this.list = view.findViewById(R.id.sticker_keyboard_list);
|
this.list = view.findViewById(R.id.sticker_keyboard_list);
|
||||||
this.adapter = new StickerKeyboardPageAdapter(glideRequests, this);
|
this.adapter = new StickerKeyboardPageAdapter(glideRequests, this);
|
||||||
this.layoutManager = new GridLayoutManager(requireContext(), 2);
|
this.layoutManager = new GridLayoutManager(requireContext(), 2);
|
||||||
this.listTouchListener = new ListTouchListener(requireContext(), glideRequests);
|
this.listTouchListener = new StickerRolloverTouchListener(requireContext(), glideRequests, eventListener, this);
|
||||||
this.packId = getArguments().getString(KEY_PACK_ID);
|
this.packId = getArguments().getString(KEY_PACK_ID);
|
||||||
|
|
||||||
list.setLayoutManager(layoutManager);
|
list.setLayoutManager(layoutManager);
|
||||||
@ -101,6 +101,18 @@ public final class StickerKeyboardPageFragment extends Fragment implements Stick
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Pair<Object, String> getStickerDataFromView(@NonNull View view) {
|
||||||
|
if (list != null) {
|
||||||
|
StickerKeyboardPageViewHolder holder = (StickerKeyboardPageViewHolder) list.getChildViewHolder(view);
|
||||||
|
if (holder != null && holder.getCurrentSticker() != null) {
|
||||||
|
return new Pair<>(new DecryptableStreamUriLoader.DecryptableUri(holder.getCurrentSticker().getUri()),
|
||||||
|
holder.getCurrentSticker().getEmoji());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void setEventListener(@NonNull EventListener eventListener) {
|
public void setEventListener(@NonNull EventListener eventListener) {
|
||||||
this.eventListener = eventListener;
|
this.eventListener = eventListener;
|
||||||
}
|
}
|
||||||
@ -146,69 +158,7 @@ public final class StickerKeyboardPageFragment extends Fragment implements Stick
|
|||||||
return (int) ((screenWidth - ((columnCount + 1) * multiplier)) / columnCount);
|
return (int) ((screenWidth - ((columnCount + 1) * multiplier)) / columnCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class ListTouchListener implements RecyclerView.OnItemTouchListener {
|
interface EventListener extends StickerRolloverTouchListener.RolloverEventListener {
|
||||||
|
|
||||||
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 onStickerSelected(@NonNull StickerRecord sticker);
|
||||||
void onStickerPopupStarted();
|
|
||||||
void onStickerPopupEnded();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.thoughtcrime.securesms.stickers;
|
package org.thoughtcrime.securesms.stickers;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.lifecycle.ViewModelProviders;
|
import androidx.lifecycle.ViewModelProviders;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
@ -22,11 +23,13 @@ import org.thoughtcrime.securesms.ApplicationContext;
|
|||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.ShareActivity;
|
import org.thoughtcrime.securesms.ShareActivity;
|
||||||
|
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob;
|
import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
|
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||||
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.thoughtcrime.securesms.stickers.StickerManifest.Sticker;
|
import org.thoughtcrime.securesms.stickers.StickerManifest.Sticker;
|
||||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
@ -40,7 +43,11 @@ import org.whispersystems.libsignal.util.guava.Optional;
|
|||||||
* Shows the contents of a pack and allows the user to install it (if not installed) or remove it
|
* Shows the contents of a pack and allows the user to install it (if not installed) or remove it
|
||||||
* (if installed). This is also the handler for sticker pack deep links.
|
* (if installed). This is also the handler for sticker pack deep links.
|
||||||
*/
|
*/
|
||||||
public final class StickerPackPreviewActivity extends PassphraseRequiredActionBarActivity {
|
public final class StickerPackPreviewActivity extends PassphraseRequiredActionBarActivity
|
||||||
|
implements StickerRolloverTouchListener.RolloverEventListener,
|
||||||
|
StickerRolloverTouchListener.RolloverStickerRetriever,
|
||||||
|
StickerPackPreviewAdapter.EventListener
|
||||||
|
{
|
||||||
|
|
||||||
private static final String TAG = Log.tag(StickerPackPreviewActivity.class);
|
private static final String TAG = Log.tag(StickerPackPreviewActivity.class);
|
||||||
|
|
||||||
@ -57,8 +64,9 @@ public final class StickerPackPreviewActivity extends PassphraseRequiredActionBa
|
|||||||
private View shareButton;
|
private View shareButton;
|
||||||
private View shareButtonImage;
|
private View shareButtonImage;
|
||||||
|
|
||||||
private StickerPackPreviewAdapter adapter;
|
private StickerPackPreviewAdapter adapter;
|
||||||
private GridLayoutManager layoutManager;
|
private GridLayoutManager layoutManager;
|
||||||
|
private StickerRolloverTouchListener touchListener;
|
||||||
|
|
||||||
public static Intent getIntent(@NonNull String packId, @NonNull String packKey) {
|
public static Intent getIntent(@NonNull String packId, @NonNull String packKey) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, StickerUrl.createActionUri(packId, packKey));
|
Intent intent = new Intent(Intent.ACTION_VIEW, StickerUrl.createActionUri(packId, packKey));
|
||||||
@ -105,6 +113,32 @@ public final class StickerPackPreviewActivity extends PassphraseRequiredActionBa
|
|||||||
onScreenWidthChanged(getScreenWidth());
|
onScreenWidthChanged(getScreenWidth());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStickerLongPress(@NonNull View view) {
|
||||||
|
if (touchListener != null) {
|
||||||
|
touchListener.enterHoverMode(stickerList, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStickerPopupStarted() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStickerPopupEnded() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Pair<Object, String> getStickerDataFromView(@NonNull View view) {
|
||||||
|
if (stickerList != null) {
|
||||||
|
StickerPackPreviewAdapter.StickerViewHolder holder = (StickerPackPreviewAdapter.StickerViewHolder) stickerList.getChildViewHolder(view);
|
||||||
|
if (holder != null) {
|
||||||
|
return new Pair<>(holder.getCurrentGlideModel(), holder.getCurrentEmoji());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void initView() {
|
private void initView() {
|
||||||
this.coverImage = findViewById(R.id.sticker_install_cover);
|
this.coverImage = findViewById(R.id.sticker_install_cover);
|
||||||
this.stickerTitle = findViewById(R.id.sticker_install_title);
|
this.stickerTitle = findViewById(R.id.sticker_install_title);
|
||||||
@ -115,11 +149,13 @@ public final class StickerPackPreviewActivity extends PassphraseRequiredActionBa
|
|||||||
this.shareButton = findViewById(R.id.sticker_install_share_button);
|
this.shareButton = findViewById(R.id.sticker_install_share_button);
|
||||||
this.shareButtonImage = findViewById(R.id.sticker_install_share_button_image);
|
this.shareButtonImage = findViewById(R.id.sticker_install_share_button_image);
|
||||||
|
|
||||||
this.adapter = new StickerPackPreviewAdapter(GlideApp.with(this));
|
this.adapter = new StickerPackPreviewAdapter(GlideApp.with(this), this);
|
||||||
this.layoutManager = new GridLayoutManager(this, 2);
|
this.layoutManager = new GridLayoutManager(this, 2);
|
||||||
|
this.touchListener = new StickerRolloverTouchListener(this, GlideApp.with(this), this, this);
|
||||||
onScreenWidthChanged(getScreenWidth());
|
onScreenWidthChanged(getScreenWidth());
|
||||||
|
|
||||||
stickerList.setLayoutManager(layoutManager);
|
stickerList.setLayoutManager(layoutManager);
|
||||||
|
stickerList.addOnItemTouchListener(touchListener);
|
||||||
stickerList.setAdapter(adapter);
|
stickerList.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.stickers;
|
package org.thoughtcrime.securesms.stickers;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -19,10 +20,12 @@ import java.util.List;
|
|||||||
public final class StickerPackPreviewAdapter extends RecyclerView.Adapter<StickerPackPreviewAdapter.StickerViewHolder> {
|
public final class StickerPackPreviewAdapter extends RecyclerView.Adapter<StickerPackPreviewAdapter.StickerViewHolder> {
|
||||||
|
|
||||||
private final GlideRequests glideRequests;
|
private final GlideRequests glideRequests;
|
||||||
|
private final EventListener eventListener;
|
||||||
private final List<StickerManifest.Sticker> list;
|
private final List<StickerManifest.Sticker> list;
|
||||||
|
|
||||||
public StickerPackPreviewAdapter(@NonNull GlideRequests glideRequests) {
|
public StickerPackPreviewAdapter(@NonNull GlideRequests glideRequests, @NonNull EventListener eventListener) {
|
||||||
this.glideRequests = glideRequests;
|
this.glideRequests = glideRequests;
|
||||||
|
this.eventListener = eventListener;
|
||||||
this.list = new ArrayList<>();
|
this.list = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +36,7 @@ public final class StickerPackPreviewAdapter extends RecyclerView.Adapter<Sticke
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull StickerViewHolder stickerViewHolder, int i) {
|
public void onBindViewHolder(@NonNull StickerViewHolder stickerViewHolder, int i) {
|
||||||
stickerViewHolder.bind(glideRequests, list.get(i));
|
stickerViewHolder.bind(glideRequests, list.get(i), eventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -41,6 +44,11 @@ public final class StickerPackPreviewAdapter extends RecyclerView.Adapter<Sticke
|
|||||||
return list.size();
|
return list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewRecycled(@NonNull StickerViewHolder holder) {
|
||||||
|
holder.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
void setStickers(List<StickerManifest.Sticker> stickers) {
|
void setStickers(List<StickerManifest.Sticker> stickers) {
|
||||||
list.clear();
|
list.clear();
|
||||||
list.addAll(stickers);
|
list.addAll(stickers);
|
||||||
@ -51,17 +59,42 @@ public final class StickerPackPreviewAdapter extends RecyclerView.Adapter<Sticke
|
|||||||
|
|
||||||
private final ImageView image;
|
private final ImageView image;
|
||||||
|
|
||||||
|
private Object currentGlideModel;
|
||||||
|
private String currentEmoji;
|
||||||
|
|
||||||
private StickerViewHolder(@NonNull View itemView) {
|
private StickerViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
this.image = itemView.findViewById(R.id.sticker_install_item_image);
|
this.image = itemView.findViewById(R.id.sticker_install_item_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(@NonNull GlideRequests glideRequests, @NonNull StickerManifest.Sticker sticker) {
|
void bind(@NonNull GlideRequests glideRequests, @NonNull StickerManifest.Sticker sticker, @NonNull EventListener eventListener) {
|
||||||
Object model = sticker.getUri().isPresent() ? new DecryptableStreamUriLoader.DecryptableUri(sticker.getUri().get())
|
currentEmoji = sticker.getEmoji();
|
||||||
: new StickerRemoteUri(sticker.getPackId(), sticker.getPackKey(), sticker.getId());
|
currentGlideModel = sticker.getUri().isPresent() ? new DecryptableStreamUriLoader.DecryptableUri(sticker.getUri().get())
|
||||||
glideRequests.load(model)
|
: new StickerRemoteUri(sticker.getPackId(), sticker.getPackKey(), sticker.getId());
|
||||||
|
glideRequests.load(currentGlideModel)
|
||||||
.transition(DrawableTransitionOptions.withCrossFade())
|
.transition(DrawableTransitionOptions.withCrossFade())
|
||||||
.into(image);
|
.into(image);
|
||||||
|
|
||||||
|
image.setOnLongClickListener(v -> {
|
||||||
|
eventListener.onStickerLongPress(v);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void recycle() {
|
||||||
|
image.setOnLongClickListener(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable Object getCurrentGlideModel() {
|
||||||
|
return currentGlideModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable String getCurrentEmoji() {
|
||||||
|
return currentEmoji;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface EventListener {
|
||||||
|
void onStickerLongPress(@NonNull View view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,15 @@ package org.thoughtcrime.securesms.stickers;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.PopupWindow;
|
import android.widget.PopupWindow;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
|
||||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
|
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ final class StickerPreviewPopup extends PopupWindow {
|
|||||||
|
|
||||||
private final GlideRequests glideRequests;
|
private final GlideRequests glideRequests;
|
||||||
private final ImageView image;
|
private final ImageView image;
|
||||||
|
private final TextView emojiText;
|
||||||
|
|
||||||
StickerPreviewPopup(@NonNull Context context, @NonNull GlideRequests glideRequests) {
|
StickerPreviewPopup(@NonNull Context context, @NonNull GlideRequests glideRequests) {
|
||||||
super(LayoutInflater.from(context).inflate(R.layout.sticker_preview_popup, null),
|
super(LayoutInflater.from(context).inflate(R.layout.sticker_preview_popup, null),
|
||||||
@ -27,12 +29,14 @@ final class StickerPreviewPopup extends PopupWindow {
|
|||||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
this.glideRequests = glideRequests;
|
this.glideRequests = glideRequests;
|
||||||
this.image = getContentView().findViewById(R.id.sticker_popup_image);
|
this.image = getContentView().findViewById(R.id.sticker_popup_image);
|
||||||
|
this.emojiText = getContentView().findViewById(R.id.sticker_popup_emoji);
|
||||||
|
|
||||||
setTouchable(false);
|
setTouchable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void presentSticker(@NonNull StickerRecord stickerRecord) {
|
void presentSticker(@NonNull Object stickerGlideModel, @Nullable String emoji) {
|
||||||
glideRequests.load(new DecryptableUri(stickerRecord.getUri()))
|
emojiText.setText(emoji);
|
||||||
|
glideRequests.load(stickerGlideModel)
|
||||||
.into(image);
|
.into(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
package org.thoughtcrime.securesms.stickers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
import org.whispersystems.libsignal.util.Pair;
|
||||||
|
|
||||||
|
public class StickerRolloverTouchListener implements RecyclerView.OnItemTouchListener {
|
||||||
|
private final StickerPreviewPopup popup;
|
||||||
|
private final RolloverEventListener eventListener;
|
||||||
|
private final RolloverStickerRetriever stickerRetriever;
|
||||||
|
|
||||||
|
private boolean hoverMode;
|
||||||
|
|
||||||
|
StickerRolloverTouchListener(@NonNull Context context,
|
||||||
|
@NonNull GlideRequests glideRequests,
|
||||||
|
@NonNull RolloverEventListener eventListener,
|
||||||
|
@NonNull RolloverStickerRetriever stickerRetriever)
|
||||||
|
{
|
||||||
|
this.eventListener = eventListener;
|
||||||
|
this.stickerRetriever = stickerRetriever;
|
||||||
|
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) {
|
||||||
|
Pair<Object, String> stickerData = stickerRetriever.getStickerDataFromView(view);
|
||||||
|
|
||||||
|
if (stickerData != null) {
|
||||||
|
if (!popup.isShowing()) {
|
||||||
|
popup.showAtLocation(recyclerView, Gravity.NO_GRAVITY, 0, 0);
|
||||||
|
eventListener.onStickerPopupStarted();
|
||||||
|
}
|
||||||
|
popup.presentSticker(stickerData.first(), stickerData.second());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface RolloverEventListener {
|
||||||
|
void onStickerPopupStarted();
|
||||||
|
void onStickerPopupEnded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface RolloverStickerRetriever {
|
||||||
|
@Nullable Pair<Object, String> getStickerDataFromView(@NonNull View view);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user