diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java b/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java index 7dff8c17fe..90ac88f27a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java @@ -31,11 +31,10 @@ import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.animation.AnimationCompleteListener; -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider; +import org.thoughtcrime.securesms.components.emoji.EmojiEventListener; import org.thoughtcrime.securesms.components.emoji.EmojiToggle; import org.thoughtcrime.securesms.components.emoji.MediaKeyboard; import org.thoughtcrime.securesms.conversation.ConversationStickerSuggestionAdapter; -import org.thoughtcrime.securesms.conversation.colors.Colorizer; import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.keyboard.KeyboardPage; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -59,7 +58,7 @@ import java.util.concurrent.TimeUnit; public class InputPanel extends LinearLayout implements MicrophoneRecorderView.Listener, KeyboardAwareLinearLayout.OnKeyboardShownListener, - EmojiKeyboardProvider.EmojiEventListener, + EmojiEventListener, ConversationStickerSuggestionAdapter.EventListener { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEventListener.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEventListener.java new file mode 100644 index 0000000000..e17ef37734 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEventListener.java @@ -0,0 +1,9 @@ +package org.thoughtcrime.securesms.components.emoji; + +import android.view.KeyEvent; + +public interface EmojiEventListener { + void onEmojiSelected(String emoji); + + void onKeyEvent(KeyEvent keyEvent); +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiKeyboardProvider.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiKeyboardProvider.java deleted file mode 100644 index 93cf7109a8..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiKeyboardProvider.java +++ /dev/null @@ -1,180 +0,0 @@ -package org.thoughtcrime.securesms.components.emoji; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.viewpager.widget.PagerAdapter; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.VariationSelectorListener; -import org.thoughtcrime.securesms.emoji.EmojiSource; -import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.mms.GlideRequests; -import org.thoughtcrime.securesms.util.ResUtil; - -import java.util.LinkedList; -import java.util.List; - -/** - * A provider to select emoji in the {@link org.thoughtcrime.securesms.components.emoji.MediaKeyboard}. - * - * TODO [alex] -- Are we still using any of this? - */ -public class EmojiKeyboardProvider implements MediaKeyboardProvider, - MediaKeyboardProvider.TabIconProvider, - MediaKeyboardProvider.BackspaceObserver, - VariationSelectorListener -{ - private static final KeyEvent DELETE_KEY_EVENT = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL); - - // TODO [alex] -- We are using this. - public static final String RECENT_STORAGE_KEY = "pref_recent_emoji2"; - - private final Context context; - private final List models; - private final RecentEmojiPageModel recentModel; - private final EmojiPagerAdapter emojiPagerAdapter; - private final EmojiEventListener emojiEventListener; - - private Controller controller; - private int currentPosition; - - public EmojiKeyboardProvider(@NonNull Context context, @Nullable EmojiEventListener emojiEventListener) { - this.context = context; - this.emojiEventListener = emojiEventListener; - this.models = new LinkedList<>(); - this.recentModel = new RecentEmojiPageModel(context, RECENT_STORAGE_KEY); - this.emojiPagerAdapter = new EmojiPagerAdapter(context, models, new EmojiEventListener() { - @Override - public void onEmojiSelected(String emoji) { - recentModel.onCodePointSelected(emoji); - SignalStore.emojiValues().setPreferredVariation(emoji); - - if (emojiEventListener != null) { - emojiEventListener.onEmojiSelected(emoji); - } - } - - @Override - public void onKeyEvent(KeyEvent keyEvent) { - if (emojiEventListener != null) { - emojiEventListener.onKeyEvent(keyEvent); - } - } - }, this); - - models.add(recentModel); - models.addAll(EmojiSource.getLatest().getDisplayPages()); - - currentPosition = recentModel.getEmoji().size() > 0 ? 0 : 1; - } - - @Override - public void requestPresentation(@NonNull Presenter presenter, boolean isSoloProvider) { - presenter.present(this, emojiPagerAdapter, this, this, null, null, currentPosition); - } - - @Override - public void setCurrentPosition(int currentPosition) { - this.currentPosition = currentPosition; - } - - @Override - public void setController(@Nullable Controller controller) { - this.controller = controller; - } - - @Override - public int getProviderIconView(boolean selected) { - if (selected) { - return R.layout.emoji_keyboard_icon_selected; - } else { - return R.layout.emoji_keyboard_icon; - } - } - - @Override - public void loadCategoryTabIcon(@NonNull GlideRequests glideRequests, @NonNull ImageView imageView, int index) { - Drawable drawable = ResUtil.getDrawable(context, models.get(index).getIconAttr()); - imageView.setImageDrawable(drawable); - } - - @Override - public void onBackspaceClicked() { - if (emojiEventListener != null) { - emojiEventListener.onKeyEvent(DELETE_KEY_EVENT); - } - } - - @Override - public void onVariationSelectorStateChanged(boolean open) { - if (controller != null) { - controller.setViewPagerEnabled(!open); - } - } - - @Override - public boolean equals(@Nullable Object obj) { - return obj instanceof EmojiKeyboardProvider; - } - - private static class EmojiPagerAdapter extends PagerAdapter { - private Context context; - private List pages; - private EmojiEventListener emojiSelectionListener; - private VariationSelectorListener variationSelectorListener; - - public EmojiPagerAdapter(@NonNull Context context, - @NonNull List pages, - @NonNull EmojiEventListener emojiSelectionListener, - @NonNull VariationSelectorListener variationSelectorListener) - { - super(); - this.context = context; - this.pages = pages; - this.emojiSelectionListener = emojiSelectionListener; - this.variationSelectorListener = variationSelectorListener; - } - - @Override - public int getCount() { - return pages.size(); - } - - @Override - public @NonNull Object instantiateItem(@NonNull ViewGroup container, int position) { - EmojiPageView page = new EmojiPageView(context, emojiSelectionListener, variationSelectorListener, true); - page.setModel(pages.get(position)); - container.addView(page); - return page; - } - - @Override - public void destroyItem(ViewGroup container, int position, Object object) { - container.removeView((View)object); - } - - @Override - public void setPrimaryItem(ViewGroup container, int position, Object object) { - EmojiPageView current = (EmojiPageView) object; - current.onSelected(); - super.setPrimaryItem(container, position, object); - } - - @Override - public boolean isViewFromObject(View view, Object object) { - return view == object; - } - } - - public interface EmojiEventListener { - void onEmojiSelected(String emoji); - void onKeyEvent(KeyEvent keyEvent); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java index 93d692f9a1..4a216c9e7c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java @@ -16,7 +16,6 @@ import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.RecyclerView; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider.EmojiEventListener; import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.EmojiHeader; import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.EmojiNoResultsModel; import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.VariationSelectorListener; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageViewGridAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageViewGridAdapter.java index f622d4c21b..8b5ef44ad8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageViewGridAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageViewGridAdapter.java @@ -10,7 +10,6 @@ import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider.EmojiEventListener; import org.thoughtcrime.securesms.util.MappingAdapter; import org.thoughtcrime.securesms.util.MappingModel; import org.thoughtcrime.securesms.util.MappingViewHolder; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiToggle.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiToggle.java index 4e041cfd91..77bccd899b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiToggle.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiToggle.java @@ -6,11 +6,9 @@ import android.util.AttributeSet; import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageButton; -import androidx.core.content.ContextCompat; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.keyboard.KeyboardPage; -import org.thoughtcrime.securesms.stickers.StickerKeyboardProvider; import org.thoughtcrime.securesms.util.ContextUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiVariationSelectorPopup.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiVariationSelectorPopup.java index 56e4befe4c..c4527ae94a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiVariationSelectorPopup.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiVariationSelectorPopup.java @@ -11,7 +11,6 @@ import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider.EmojiEventListener; import java.util.List; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboard.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboard.java index c7827f3c84..fab9bdbd6e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboard.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboard.java @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.components.emoji; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -13,7 +12,6 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; -import androidx.viewpager.widget.PagerAdapter; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; @@ -22,13 +20,7 @@ import org.thoughtcrime.securesms.keyboard.KeyboardPage; import org.thoughtcrime.securesms.keyboard.KeyboardPagerFragment; import org.thoughtcrime.securesms.keyboard.emoji.search.EmojiSearchFragment; -import java.security.Key; - -public class MediaKeyboard extends FrameLayout implements InputView, - MediaKeyboardProvider.Presenter, - MediaKeyboardProvider.Controller, - MediaKeyboardBottomTabAdapter.EventListener -{ +public class MediaKeyboard extends FrameLayout implements InputView { private static final String TAG = Log.tag(MediaKeyboard.class); private static final String EMOJI_SEARCH = "emoji_search_fragment"; @@ -88,60 +80,6 @@ public class MediaKeyboard extends FrameLayout implements InputView, keyboardPagerFragment.hide(); } - @Override - public void present(@NonNull MediaKeyboardProvider provider, - @NonNull PagerAdapter pagerAdapter, - @NonNull MediaKeyboardProvider.TabIconProvider tabIconProvider, - @Nullable MediaKeyboardProvider.BackspaceObserver backspaceObserver, - @Nullable MediaKeyboardProvider.AddObserver addObserver, - @Nullable MediaKeyboardProvider.SearchObserver searchObserver, - int startingIndex) - { -// if (categoryPager == null) return; -// if (!provider.equals(providers[providerIndex])) return; -// if (keyboardListener != null) keyboardListener.onKeyboardChanged(provider); -// -// boolean isSolo = providers.length == 1; -// -// presentProviderStrip(isSolo); -// presentCategoryPager(pagerAdapter, tabIconProvider, startingIndex); -// presentProviderTabs(providers, providerIndex); -// presentSearchButton(searchObserver); -// presentBackspaceButton(backspaceObserver, isSolo); -// presentAddButton(addObserver); - } - - @Override - public int getCurrentPosition() { -// return categoryPager != null ? categoryPager.getCurrentItem() : 0; - return 0; - } - - @Override - public void requestDismissal() { - hide(true); - } - - @Override - public boolean isVisible() { - return getVisibility() == View.VISIBLE; - } - - @Override - public void onTabSelected(int index) { -// if (categoryPager != null) { -// categoryPager.setCurrentItem(index); -// categoryTabs.smoothScrollToPosition(index); -// } - } - - @Override - public void setViewPagerEnabled(boolean enabled) { -// if (categoryPager != null) { -// categoryPager.setEnabled(enabled); -// } - } - public void onCloseEmojiSearch() { onCloseEmojiSearchInternal(true); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboardBottomTabAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboardBottomTabAdapter.java deleted file mode 100644 index b2f5f962b4..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboardBottomTabAdapter.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.thoughtcrime.securesms.components.emoji; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.MediaKeyboardProvider.TabIconProvider; -import org.thoughtcrime.securesms.mms.GlideRequests; - -public class MediaKeyboardBottomTabAdapter extends RecyclerView.Adapter { - - private final GlideRequests glideRequests; - private final EventListener eventListener; - - private TabIconProvider tabIconProvider; - private int activePosition; - private int count; - - public MediaKeyboardBottomTabAdapter(@NonNull GlideRequests glideRequests, @NonNull EventListener eventListener) { - this.glideRequests = glideRequests; - this.eventListener = eventListener; - } - - @Override - public @NonNull MediaKeyboardBottomTabViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { - return new MediaKeyboardBottomTabViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.media_keyboard_bottom_tab_item, viewGroup, false)); - } - - @Override - public void onBindViewHolder(@NonNull MediaKeyboardBottomTabViewHolder viewHolder, int i) { - viewHolder.bind(glideRequests, eventListener, tabIconProvider, i, i == activePosition); - } - - @Override - public void onViewRecycled(@NonNull MediaKeyboardBottomTabViewHolder holder) { - holder.recycle(); - } - - @Override - public int getItemCount() { - return count; - } - - public void setTabIconProvider(@NonNull TabIconProvider iconProvider, int count) { - this.tabIconProvider = iconProvider; - this.count = count; - - notifyDataSetChanged(); - } - - public void setActivePosition(int position) { - this.activePosition = position; - notifyDataSetChanged(); - } - - static class MediaKeyboardBottomTabViewHolder extends RecyclerView.ViewHolder { - - private final ImageView image; - private final View imageSelected; - - public MediaKeyboardBottomTabViewHolder(@NonNull View itemView) { - super(itemView); - this.image = itemView.findViewById(R.id.category_icon); - this.imageSelected = itemView.findViewById(R.id.category_icon_selected); - } - - void bind(@NonNull GlideRequests glideRequests, - @NonNull EventListener eventListener, - @NonNull TabIconProvider tabIconProvider, - int index, - boolean selected) - { - tabIconProvider.loadCategoryTabIcon(glideRequests, image, index); - image.setAlpha(selected ? 1 : 0.5f); - imageSelected.setSelected(selected); - - itemView.setOnClickListener(v -> eventListener.onTabSelected(index)); - } - - void recycle() { - itemView.setOnClickListener(null); - } - } - - public interface EventListener { - void onTabSelected(int index); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboardProvider.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboardProvider.java deleted file mode 100644 index 4488463508..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/MediaKeyboardProvider.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.thoughtcrime.securesms.components.emoji; - -import android.widget.ImageView; - -import androidx.annotation.LayoutRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.viewpager.widget.PagerAdapter; - -import org.thoughtcrime.securesms.mms.GlideRequests; - -public interface MediaKeyboardProvider { - @LayoutRes int getProviderIconView(boolean selected); - /** @return True if the click was handled with provider-specific logic, otherwise false */ - void requestPresentation(@NonNull Presenter presenter, boolean isSoloProvider); - void setController(@Nullable Controller controller); - void setCurrentPosition(int currentPosition); - - interface BackspaceObserver { - void onBackspaceClicked(); - } - - interface AddObserver { - void onAddClicked(); - } - - interface SearchObserver { - void onSearchOpened(); - void onSearchClosed(); - void onSearchChanged(@NonNull String query); - } - - interface Controller { - void setViewPagerEnabled(boolean enabled); - } - - interface Presenter { - void present(@NonNull MediaKeyboardProvider provider, - @NonNull PagerAdapter pagerAdapter, - @NonNull TabIconProvider iconProvider, - @Nullable BackspaceObserver backspaceObserver, - @Nullable AddObserver addObserver, - @Nullable SearchObserver searchObserver, - int startingIndex); - int getCurrentPosition(); - void requestDismissal(); - boolean isVisible(); - } - - interface TabIconProvider { - void loadCategoryTabIcon(@NonNull GlideRequests glideRequests, @NonNull ImageView imageView, int index); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 839f8c768e..aaf2b4073b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -116,7 +116,7 @@ import org.thoughtcrime.securesms.components.MaskView; import org.thoughtcrime.securesms.components.SendButton; import org.thoughtcrime.securesms.components.TooltipPopup; import org.thoughtcrime.securesms.components.TypingStatusSender; -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider; +import org.thoughtcrime.securesms.components.emoji.EmojiEventListener; import org.thoughtcrime.securesms.components.emoji.EmojiStrings; import org.thoughtcrime.securesms.components.emoji.MediaKeyboard; import org.thoughtcrime.securesms.components.identity.UnverifiedBannerView; @@ -244,7 +244,7 @@ import org.thoughtcrime.securesms.sms.MessageSender; import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage; import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; -import org.thoughtcrime.securesms.stickers.StickerKeyboardProvider; +import org.thoughtcrime.securesms.stickers.StickerEventListener; import org.thoughtcrime.securesms.stickers.StickerLocator; import org.thoughtcrime.securesms.stickers.StickerManagementActivity; import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent; @@ -318,14 +318,14 @@ public class ConversationActivity extends PassphraseRequiredActivity InputPanel.MediaListener, ComposeText.CursorPositionChangedListener, ConversationSearchBottomBar.EventListener, - StickerKeyboardProvider.StickerEventListener, + StickerEventListener, AttachmentKeyboard.Callback, ConversationReactionOverlay.OnReactionSelectedListener, ReactWithAnyEmojiBottomSheetDialogFragment.Callback, SafetyNumberChangeDialog.Callback, ReactionsBottomSheetDialogFragment.Callback, MediaKeyboard.MediaKeyboardListener, - EmojiKeyboardProvider.EmojiEventListener, + EmojiEventListener, GifKeyboardPageFragment.Host, EmojiKeyboardPageFragment.Callback, EmojiSearchFragment.Callback diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4MediaKeyboardProvider.java b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4MediaKeyboardProvider.java deleted file mode 100644 index 8eba32737c..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4MediaKeyboardProvider.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.thoughtcrime.securesms.giph.mp4; - -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.MediaKeyboardProvider; -import org.thoughtcrime.securesms.mms.GlideRequests; - -/** - * MediaKeyboardProvider for MP4 Gifs - */ -@SuppressWarnings("unused") -public final class GiphyMp4MediaKeyboardProvider implements MediaKeyboardProvider { - - private final GiphyMp4MediaKeyboardPagerAdapter pagerAdapter; - - private Controller controller; - - public GiphyMp4MediaKeyboardProvider(@NonNull FragmentActivity fragmentActivity, boolean isForMms) { - pagerAdapter = new GiphyMp4MediaKeyboardPagerAdapter(fragmentActivity.getSupportFragmentManager(), isForMms); - } - - @Override - public int getProviderIconView(boolean selected) { - if (selected) { - return R.layout.giphy_mp4_keyboard_icon_selected; - } else { - return R.layout.giphy_mp4_keyboard_icon; - } - } - - @Override - public void requestPresentation(@NonNull Presenter presenter, boolean isSoloProvider) { - presenter.present(this, pagerAdapter, new GiphyMp4MediaKeyboardTabIconProvider(), null, null, null, 0); - } - - @Override - public void setController(@Nullable Controller controller) { - this.controller = controller; - } - - @Override - public void setCurrentPosition(int currentPosition) { - // ignored. - } - - private static final class GiphyMp4MediaKeyboardPagerAdapter extends FragmentStatePagerAdapter { - - private final boolean isForMms; - - public GiphyMp4MediaKeyboardPagerAdapter(@NonNull FragmentManager fm, boolean isForMms) { - super(fm, FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - this.isForMms = isForMms; - } - - @Override - public @NonNull Fragment getItem(int position) { - return GiphyMp4Fragment.create(isForMms); - } - - @Override public int getCount() { - return 1; - } - } - - private static final class GiphyMp4MediaKeyboardTabIconProvider implements TabIconProvider { - @Override public void loadCategoryTabIcon(@NonNull GlideRequests glideRequests, @NonNull ImageView imageView, int index) { } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageFragment.kt index dc1b1378df..cec0782e79 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageFragment.kt @@ -11,7 +11,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE import com.google.android.material.appbar.AppBarLayout import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider +import org.thoughtcrime.securesms.components.emoji.EmojiEventListener import org.thoughtcrime.securesms.components.emoji.EmojiPageView import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.EmojiHeader @@ -22,14 +22,14 @@ import java.util.Optional private val DELETE_KEY_EVENT: KeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL) -class EmojiKeyboardPageFragment : Fragment(R.layout.keyboard_pager_emoji_page_fragment), EmojiKeyboardProvider.EmojiEventListener, EmojiPageViewGridAdapter.VariationSelectorListener { +class EmojiKeyboardPageFragment : Fragment(R.layout.keyboard_pager_emoji_page_fragment), EmojiEventListener, EmojiPageViewGridAdapter.VariationSelectorListener { private lateinit var viewModel: EmojiKeyboardPageViewModel private lateinit var emojiPageView: EmojiPageView private lateinit var searchView: View private lateinit var emojiCategoriesRecycler: RecyclerView private lateinit var backspaceView: View - private lateinit var eventListener: EmojiKeyboardProvider.EmojiEventListener + private lateinit var eventListener: EmojiEventListener private lateinit var callback: Callback private lateinit var categoriesAdapter: EmojiKeyboardPageCategoriesAdapter private lateinit var searchBar: KeyboardPageSearchView diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageRepository.kt index d403ec4230..150cd96105 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageRepository.kt @@ -2,15 +2,15 @@ package org.thoughtcrime.securesms.keyboard.emoji import android.content.Context import org.signal.core.util.concurrent.SignalExecutors -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider import org.thoughtcrime.securesms.components.emoji.EmojiPageModel import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel import org.thoughtcrime.securesms.emoji.EmojiSource.Companion.latest +import org.thoughtcrime.securesms.util.TextSecurePreferences import java.util.function.Consumer class EmojiKeyboardPageRepository(context: Context) { - private val recentEmojiPageModel: RecentEmojiPageModel = RecentEmojiPageModel(context, EmojiKeyboardProvider.RECENT_STORAGE_KEY) + private val recentEmojiPageModel: RecentEmojiPageModel = RecentEmojiPageModel(context, TextSecurePreferences.RECENT_STORAGE_KEY) fun getEmoji(consumer: Consumer>) { SignalExecutors.BOUNDED.execute { diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageViewModel.kt index a97e8541b4..6cee1e039e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageViewModel.kt @@ -6,7 +6,6 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider import org.thoughtcrime.securesms.components.emoji.EmojiPageModel import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.EmojiHeader @@ -19,6 +18,7 @@ import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardPageCategoryMappin 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 class EmojiKeyboardPageViewModel(repository: EmojiKeyboardPageRepository) : ViewModel() { @@ -70,12 +70,12 @@ class EmojiKeyboardPageViewModel(repository: EmojiKeyboardPageRepository) : View } fun addToRecents(emoji: String) { - RecentEmojiPageModel(ApplicationDependencies.getApplication(), EmojiKeyboardProvider.RECENT_STORAGE_KEY).onCodePointSelected(emoji) + RecentEmojiPageModel(ApplicationDependencies.getApplication(), TextSecurePreferences.RECENT_STORAGE_KEY).onCodePointSelected(emoji) } companion object { fun getStartingTab(): String { - return if (RecentEmojiPageModel.hasRecents(ApplicationDependencies.getApplication(), EmojiKeyboardProvider.RECENT_STORAGE_KEY)) { + return if (RecentEmojiPageModel.hasRecents(ApplicationDependencies.getApplication(), TextSecurePreferences.RECENT_STORAGE_KEY)) { RecentEmojiPageModel.KEY } else { EmojiCategory.PEOPLE.key diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchFragment.kt index dedc0f091f..a9cb27d39a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchFragment.kt @@ -11,7 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider +import org.thoughtcrime.securesms.components.emoji.EmojiEventListener import org.thoughtcrime.securesms.components.emoji.EmojiPageView import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView @@ -36,7 +36,7 @@ class EmojiSearchFragment : Fragment(R.layout.emoji_search_fragment), EmojiPageV viewModel = ViewModelProviders.of(this, factory)[EmojiSearchViewModel::class.java] val keyboardAwareLinearLayout: KeyboardAwareLinearLayout = view.findViewById(R.id.kb_aware_layout) - val eventListener: EmojiKeyboardProvider.EmojiEventListener = requireNotNull(findListener()) + val eventListener: EmojiEventListener = requireNotNull(findListener()) 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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchRepository.kt index 79c06e3967..5b9982b21a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchRepository.kt @@ -4,12 +4,12 @@ import android.content.Context import android.net.Uri import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.components.emoji.Emoji -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider import org.thoughtcrime.securesms.components.emoji.EmojiPageModel import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.EmojiSearchDatabase import org.thoughtcrime.securesms.emoji.EmojiSource +import org.thoughtcrime.securesms.util.TextSecurePreferences import java.util.function.Consumer private const val MINIMUM_QUERY_THRESHOLD = 1 @@ -21,7 +21,7 @@ class EmojiSearchRepository(private val context: Context) { fun submitQuery(query: String, includeRecents: Boolean, limit: Int = EMOJI_SEARCH_LIMIT, consumer: Consumer) { if (query.length < MINIMUM_QUERY_THRESHOLD && includeRecents) { - consumer.accept(RecentEmojiPageModel(context, EmojiKeyboardProvider.RECENT_STORAGE_KEY)) + consumer.accept(RecentEmojiPageModel(context, TextSecurePreferences.RECENT_STORAGE_KEY)) } else { SignalExecutors.SERIAL.execute { val emoji: List = emojiSearchDatabase.query(query, limit) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerPackListAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/KeyboardStickerPackListAdapter.kt similarity index 92% rename from app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerPackListAdapter.kt rename to app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/KeyboardStickerPackListAdapter.kt index 9e6e121757..6571b96d62 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerPackListAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/KeyboardStickerPackListAdapter.kt @@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.util.MappingAdapter import org.thoughtcrime.securesms.util.MappingModel import org.thoughtcrime.securesms.util.MappingViewHolder -class StickerPackListAdapter(private val glideRequests: GlideRequests, private val allowApngAnimation: Boolean, private val onTabSelected: (StickerPack) -> Unit) : MappingAdapter() { +class KeyboardStickerPackListAdapter(private val glideRequests: GlideRequests, private val allowApngAnimation: Boolean, private val onTabSelected: (StickerPack) -> Unit) : MappingAdapter() { init { registerFactory(StickerPack::class.java, LayoutFactory(::StickerPackViewHolder, R.layout.keyboard_pager_category_icon)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageFragment.kt index e8c2d326a9..1230da2a53 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageFragment.kt @@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView import org.thoughtcrime.securesms.keyboard.findListener import org.thoughtcrime.securesms.mms.GlideApp -import org.thoughtcrime.securesms.stickers.StickerKeyboardProvider.StickerEventListener +import org.thoughtcrime.securesms.stickers.StickerEventListener import org.thoughtcrime.securesms.stickers.StickerRolloverTouchListener import org.thoughtcrime.securesms.stickers.StickerRolloverTouchListener.RolloverStickerRetriever import org.thoughtcrime.securesms.util.DeviceProperties @@ -36,12 +36,12 @@ class StickerKeyboardPageFragment : View.OnLayoutChangeListener { private lateinit var stickerList: RecyclerView - private lateinit var keyboardStickerListAdapter: KeyboardStickerListAdapter + private lateinit var stickerListAdapter: KeyboardStickerListAdapter private lateinit var layoutManager: GridLayoutManager private lateinit var listTouchListener: StickerRolloverTouchListener private lateinit var stickerPacksRecycler: RecyclerView private lateinit var appBarLayout: AppBarLayout - private lateinit var stickerPacksAdapter: StickerPackListAdapter + private lateinit var stickerPacksAdapter: KeyboardStickerPackListAdapter private lateinit var viewModel: StickerKeyboardPageViewModel @@ -53,11 +53,11 @@ class StickerKeyboardPageFragment : super.onViewCreated(view, savedInstanceState) val glideRequests = GlideApp.with(this) - keyboardStickerListAdapter = KeyboardStickerListAdapter(glideRequests, this, DeviceProperties.shouldAllowApngStickerAnimation(requireContext())) + stickerListAdapter = KeyboardStickerListAdapter(glideRequests, this, DeviceProperties.shouldAllowApngStickerAnimation(requireContext())) layoutManager = GridLayoutManager(requireContext(), 2).apply { spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { - val model: Optional> = keyboardStickerListAdapter.getModel(position) + val model: Optional> = stickerListAdapter.getModel(position) if (model.isPresent && model.get() is KeyboardStickerListAdapter.StickerHeader) { return spanCount } @@ -69,13 +69,13 @@ class StickerKeyboardPageFragment : stickerList = view.findViewById(R.id.sticker_keyboard_list) stickerList.layoutManager = layoutManager - stickerList.adapter = keyboardStickerListAdapter + stickerList.adapter = stickerListAdapter stickerList.addOnItemTouchListener(listTouchListener) stickerList.addOnScrollListener(packIdSelectionOnScroll) stickerPacksRecycler = view.findViewById(R.id.sticker_packs_recycler) - stickerPacksAdapter = StickerPackListAdapter(glideRequests, DeviceProperties.shouldAllowApngStickerAnimation(requireContext()), this::onTabSelected) + stickerPacksAdapter = KeyboardStickerPackListAdapter(glideRequests, DeviceProperties.shouldAllowApngStickerAnimation(requireContext()), this::onTabSelected) stickerPacksRecycler.adapter = stickerPacksAdapter appBarLayout = view.findViewById(R.id.sticker_keyboard_search_appbar) @@ -106,21 +106,21 @@ class StickerKeyboardPageFragment : viewModel = ViewModelProviders.of(requireActivity(), StickerKeyboardPageViewModel.Factory(requireContext())) .get(StickerKeyboardPageViewModel::class.java) - viewModel.stickers.observe(viewLifecycleOwner, keyboardStickerListAdapter::submitList) + viewModel.stickers.observe(viewLifecycleOwner, stickerListAdapter::submitList) viewModel.packs.observe(viewLifecycleOwner, stickerPacksAdapter::submitList) viewModel.getSelectedPack().observe(viewLifecycleOwner, this::updateCategoryTab) viewModel.refreshStickers() } - private fun onTabSelected(stickerPack: StickerPackListAdapter.StickerPack) { + private fun onTabSelected(stickerPack: KeyboardStickerPackListAdapter.StickerPack) { scrollTo(stickerPack.packRecord.packId) viewModel.selectPack(stickerPack.packRecord.packId) } private fun updateCategoryTab(packId: String) { stickerPacksRecycler.post { - val index: Int = stickerPacksAdapter.indexOfFirst(StickerPackListAdapter.StickerPack::class.java) { it.packRecord.packId == packId } + val index: Int = stickerPacksAdapter.indexOfFirst(KeyboardStickerPackListAdapter.StickerPack::class.java) { it.packRecord.packId == packId } if (index != -1) { stickerPacksRecycler.smoothScrollToPosition(index) @@ -129,7 +129,7 @@ class StickerKeyboardPageFragment : } private fun scrollTo(packId: String) { - val index = keyboardStickerListAdapter.indexOfFirst(KeyboardStickerListAdapter.StickerHeader::class.java) { it.packId == packId } + val index = stickerListAdapter.indexOfFirst(KeyboardStickerListAdapter.StickerHeader::class.java) { it.packId == packId } if (index != -1) { appBarLayout.setExpanded(false, true) packIdSelectionOnScroll.startAutoScrolling() @@ -163,7 +163,7 @@ class StickerKeyboardPageFragment : override fun getStickerDataFromView(view: View): Pair? { val position: Int = stickerList.getChildAdapterPosition(view) - val model: Optional> = keyboardStickerListAdapter.getModel(position) + val model: Optional> = stickerListAdapter.getModel(position) if (model.isPresent && model.get() is KeyboardStickerListAdapter.Sticker) { val sticker = model.get() as KeyboardStickerListAdapter.Sticker return Pair(sticker.uri, sticker.stickerRecord.emoji) @@ -216,7 +216,7 @@ class StickerKeyboardPageFragment : val layoutManager = recyclerView.layoutManager as LinearLayoutManager val index = layoutManager.findFirstCompletelyVisibleItemPosition() - val item: Optional> = keyboardStickerListAdapter.getModel(index) + val item: Optional> = stickerListAdapter.getModel(index) if (item.isPresent && item.get() is KeyboardStickerListAdapter.HasPackId) { viewModel.selectPack((item.get() as KeyboardStickerListAdapter.HasPackId).packId) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageViewModel.kt index 2f30576271..9345a0fa30 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageViewModel.kt @@ -6,7 +6,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.keyboard.sticker.StickerPackListAdapter.StickerPack +import org.thoughtcrime.securesms.keyboard.sticker.KeyboardStickerPackListAdapter.StickerPack import org.thoughtcrime.securesms.util.MappingModelList import org.thoughtcrime.securesms.util.livedata.LiveDataUtil diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchDialogFragment.kt index 10a01dc66e..b8d33d5980 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchDialogFragment.kt @@ -1,7 +1,5 @@ package org.thoughtcrime.securesms.keyboard.sticker -import android.content.res.Configuration -import android.graphics.Point import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -13,25 +11,23 @@ import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.database.model.StickerRecord import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView import org.thoughtcrime.securesms.keyboard.findListener import org.thoughtcrime.securesms.mms.GlideApp -import org.thoughtcrime.securesms.stickers.StickerKeyboardPageAdapter -import org.thoughtcrime.securesms.stickers.StickerKeyboardProvider +import org.thoughtcrime.securesms.stickers.StickerEventListener import org.thoughtcrime.securesms.util.DeviceProperties import org.thoughtcrime.securesms.util.ViewUtil /** * Search dialog for finding stickers. */ -class StickerSearchDialogFragment : DialogFragment(), StickerKeyboardPageAdapter.EventListener { +class StickerSearchDialogFragment : DialogFragment(), KeyboardStickerListAdapter.EventListener, View.OnLayoutChangeListener { private lateinit var search: KeyboardPageSearchView private lateinit var list: RecyclerView private lateinit var noResults: View - private lateinit var adapter: StickerKeyboardPageAdapter + private lateinit var adapter: KeyboardStickerListAdapter private lateinit var layoutManager: GridLayoutManager override fun onCreate(savedInstanceState: Bundle?) { @@ -49,19 +45,17 @@ class StickerSearchDialogFragment : DialogFragment(), StickerKeyboardPageAdapter list = view.findViewById(R.id.sticker_search_list) noResults = view.findViewById(R.id.sticker_search_no_results) - adapter = StickerKeyboardPageAdapter(GlideApp.with(this), this, DeviceProperties.shouldAllowApngStickerAnimation(requireContext())) + adapter = KeyboardStickerListAdapter(GlideApp.with(this), this, DeviceProperties.shouldAllowApngStickerAnimation(requireContext())) layoutManager = GridLayoutManager(requireContext(), 2) list.layoutManager = layoutManager list.adapter = adapter - onScreenWidthChanged(getScreenWidth()) - val viewModel: StickerSearchViewModel = ViewModelProviders.of(this, StickerSearchViewModel.Factory(requireContext())).get(StickerSearchViewModel::class.java) - viewModel.searchResults.observe(viewLifecycleOwner) { stickerRecords -> - adapter.setStickers(stickerRecords, calculateStickerSize(getScreenWidth())) - noResults.visibility = if (stickerRecords.isEmpty()) View.VISIBLE else View.GONE + viewModel.searchResults.observe(viewLifecycleOwner) { stickers -> + adapter.submitList(stickers) + noResults.visibility = if (stickers.isEmpty()) View.VISIBLE else View.GONE } search.enableBackNavigation() @@ -77,22 +71,12 @@ class StickerSearchDialogFragment : DialogFragment(), StickerKeyboardPageAdapter } search.requestFocus() + + view.addOnLayoutChangeListener(this) } - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - onScreenWidthChanged(getScreenWidth()) - } - - private fun onScreenWidthChanged(@Px newWidth: Int) { - layoutManager.spanCount = calculateColumnCount(newWidth) - adapter.setStickerSize(calculateStickerSize(newWidth)) - } - - private fun getScreenWidth(): Int { - val size = Point() - requireActivity().windowManager.defaultDisplay.getSize(size) - return size.x + override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) { + layoutManager.spanCount = calculateColumnCount(view?.width ?: 0) } private fun calculateColumnCount(@Px screenWidth: Int): Int { @@ -101,23 +85,17 @@ class StickerSearchDialogFragment : DialogFragment(), StickerKeyboardPageAdapter return ((screenWidth - modifier) / divisor).toInt() } - private fun calculateStickerSize(@Px screenWidth: Int): Int { - val multiplier = resources.getDimensionPixelOffset(R.dimen.sticker_page_item_multiplier).toFloat() - val columnCount = calculateColumnCount(screenWidth) - return ((screenWidth - (columnCount + 1) * multiplier) / columnCount).toInt() + override fun onStickerClicked(sticker: KeyboardStickerListAdapter.Sticker) { + ViewUtil.hideKeyboard(requireContext(), requireView()) + findListener()?.onStickerSelected(sticker.stickerRecord) + dismissAllowingStateLoss() } + override fun onStickerLongClicked(sticker: KeyboardStickerListAdapter.Sticker) = Unit + companion object { fun show(fragmentManager: FragmentManager) { StickerSearchDialogFragment().show(fragmentManager, "TAG") } } - - override fun onStickerClicked(sticker: StickerRecord) { - ViewUtil.hideKeyboard(requireContext(), requireView()) - findListener()?.onStickerSelected(sticker) - dismissAllowingStateLoss() - } - - override fun onStickerLongClicked(targetView: View) = Unit } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchViewModel.kt index 29e4661d88..d660f11ed7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchViewModel.kt @@ -5,14 +5,16 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import org.thoughtcrime.securesms.database.model.StickerRecord import org.thoughtcrime.securesms.util.livedata.LiveDataUtil class StickerSearchViewModel(private val searchRepository: StickerSearchRepository) : ViewModel() { private val searchQuery: MutableLiveData = MutableLiveData("") - val searchResults: LiveData> = LiveDataUtil.mapAsync(searchQuery) { q -> searchRepository.search(q) } + val searchResults: LiveData> = LiveDataUtil.mapAsync(searchQuery) { q -> + searchRepository.search(q) + .map { KeyboardStickerListAdapter.Sticker(it.packId, it) } + } fun query(query: String) { searchQuery.postValue(query) diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendActivity.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendActivity.java index 3198ce10a7..e4a9c8e581 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendActivity.java @@ -46,7 +46,7 @@ import org.thoughtcrime.securesms.components.InputAwareLayout; import org.thoughtcrime.securesms.components.SendButton; import org.thoughtcrime.securesms.components.TooltipPopup; import org.thoughtcrime.securesms.components.emoji.EmojiEditText; -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider; +import org.thoughtcrime.securesms.components.emoji.EmojiEventListener; import org.thoughtcrime.securesms.components.emoji.EmojiToggle; import org.thoughtcrime.securesms.components.emoji.MediaKeyboard; import org.thoughtcrime.securesms.components.mention.MentionAnnotation; @@ -104,18 +104,18 @@ import java.util.Set; * It will return the {@link Media} that the user decided to send. */ public class MediaSendActivity extends PassphraseRequiredActivity implements MediaPickerFolderFragment.Controller, - MediaPickerItemFragment.Controller, - ImageEditorFragment.Controller, - MediaSendVideoFragment.Controller, - CameraFragment.Controller, - CameraContactSelectionFragment.Controller, - ViewTreeObserver.OnGlobalLayoutListener, - MediaRailAdapter.RailItemListener, - InputAwareLayout.OnKeyboardShownListener, - InputAwareLayout.OnKeyboardHiddenListener, - EmojiKeyboardProvider.EmojiEventListener, - EmojiKeyboardPageFragment.Callback, - EmojiSearchFragment.Callback + MediaPickerItemFragment.Controller, + ImageEditorFragment.Controller, + MediaSendVideoFragment.Controller, + CameraFragment.Controller, + CameraContactSelectionFragment.Controller, + ViewTreeObserver.OnGlobalLayoutListener, + MediaRailAdapter.RailItemListener, + InputAwareLayout.OnKeyboardShownListener, + InputAwareLayout.OnKeyboardHiddenListener, + EmojiEventListener, + EmojiKeyboardPageFragment.Callback, + EmojiSearchFragment.Callback { private static final String TAG = Log.tag(MediaSendActivity.class); diff --git a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiBottomSheetDialogFragment.java index ebee706b90..ccc7f3fc9f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiBottomSheetDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiBottomSheetDialogFragment.java @@ -32,7 +32,7 @@ import com.google.android.material.shape.MaterialShapeDrawable; import com.google.android.material.shape.ShapeAppearanceModel; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider; +import org.thoughtcrime.securesms.components.emoji.EmojiEventListener; import org.thoughtcrime.securesms.components.emoji.EmojiPageView; import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter; import org.thoughtcrime.securesms.database.model.MessageRecord; @@ -42,18 +42,19 @@ import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView; import org.thoughtcrime.securesms.reactions.ReactionsLoader; import org.thoughtcrime.securesms.reactions.edit.EditReactionsActivity; import org.thoughtcrime.securesms.util.MappingModel; +import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ViewUtil; import java.util.Optional; import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE; -public final class ReactWithAnyEmojiBottomSheetDialogFragment extends BottomSheetDialogFragment implements EmojiKeyboardProvider.EmojiEventListener, +public final class ReactWithAnyEmojiBottomSheetDialogFragment extends BottomSheetDialogFragment implements EmojiEventListener, EmojiPageViewGridAdapter.VariationSelectorListener { private static final String REACTION_STORAGE_KEY = "reactions_recent_emoji"; - private static final String ABOUT_STORAGE_KEY = EmojiKeyboardProvider.RECENT_STORAGE_KEY; + private static final String ABOUT_STORAGE_KEY = TextSecurePreferences.RECENT_STORAGE_KEY; private static final String ARG_MESSAGE_ID = "arg_message_id"; private static final String ARG_IS_MMS = "arg_is_mms"; diff --git a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiViewModel.java index c43f09e0a0..78fc9b2707 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiViewModel.java @@ -10,7 +10,6 @@ import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; -import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider; import org.thoughtcrime.securesms.components.emoji.EmojiPageModel; import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter; import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel; @@ -21,6 +20,7 @@ import org.thoughtcrime.securesms.keyboard.emoji.search.EmojiSearchRepository; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.reactions.ReactionsLoader; import org.thoughtcrime.securesms.util.MappingModelList; +import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import java.util.List; @@ -133,7 +133,7 @@ public final class ReactWithAnyEmojiViewModel extends ViewModel { } private static @NonNull String getStartingKey() { - if (RecentEmojiPageModel.hasRecents(ApplicationDependencies.getApplication(), EmojiKeyboardProvider.RECENT_STORAGE_KEY)) { + if (RecentEmojiPageModel.hasRecents(ApplicationDependencies.getApplication(), TextSecurePreferences.RECENT_STORAGE_KEY)) { return RecentEmojiPageModel.KEY; } else { return EmojiCategory.PEOPLE.getKey(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java index 446ce9831d..f407b786a5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java @@ -18,11 +18,11 @@ import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.keyboard.KeyboardPage; import org.thoughtcrime.securesms.keyboard.KeyboardPagerViewModel; -import org.thoughtcrime.securesms.stickers.StickerKeyboardProvider; +import org.thoughtcrime.securesms.stickers.StickerEventListener; import org.thoughtcrime.securesms.stickers.StickerManagementActivity; import org.thoughtcrime.securesms.util.ViewUtil; -public final class ImageEditorStickerSelectActivity extends AppCompatActivity implements StickerKeyboardProvider.StickerEventListener, MediaKeyboard.MediaKeyboardListener { +public final class ImageEditorStickerSelectActivity extends AppCompatActivity implements StickerEventListener, MediaKeyboard.MediaKeyboardListener { @Override protected void attachBaseContext(@NonNull Context newBase) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerEventListener.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerEventListener.java new file mode 100644 index 0000000000..9761bdb12f --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerEventListener.java @@ -0,0 +1,11 @@ +package org.thoughtcrime.securesms.stickers; + +import androidx.annotation.NonNull; + +import org.thoughtcrime.securesms.database.model.StickerRecord; + +public interface StickerEventListener { + void onStickerSelected(@NonNull StickerRecord sticker); + + void onStickerManagementClicked(); +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageAdapter.java deleted file mode 100644 index b14fa7b93a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageAdapter.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.thoughtcrime.securesms.stickers; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.Px; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.model.StickerRecord; -import org.thoughtcrime.securesms.glide.cache.ApngOptions; -import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri; -import org.thoughtcrime.securesms.mms.GlideRequests; - -import java.util.ArrayList; -import java.util.List; - -/** - * Adapter for a specific page in the sticker keyboard. Shows the stickers in a grid. - * @see StickerKeyboardPageFragment - */ -public final class StickerKeyboardPageAdapter extends RecyclerView.Adapter { - - private final GlideRequests glideRequests; - private final EventListener eventListener; - private final List stickers; - private final boolean allowApngAnimation; - - private int stickerSize; - - public StickerKeyboardPageAdapter(@NonNull GlideRequests glideRequests, @NonNull EventListener eventListener, boolean allowApngAnimation) { - this.glideRequests = glideRequests; - this.eventListener = eventListener; - this.allowApngAnimation = allowApngAnimation; - this.stickers = new ArrayList<>(); - - setHasStableIds(true); - } - - @Override - public long getItemId(int position) { - return stickers.get(position).getRowId(); - } - - @Override - public @NonNull StickerKeyboardPageViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { - return new StickerKeyboardPageViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.sticker_keyboard_page_list_item, viewGroup, false)); - } - - @Override - public void onBindViewHolder(@NonNull StickerKeyboardPageViewHolder viewHolder, int i) { - viewHolder.bind(glideRequests, eventListener, stickers.get(i), stickerSize, allowApngAnimation); - } - - @Override - public void onViewRecycled(@NonNull StickerKeyboardPageViewHolder holder) { - holder.recycle(); - } - - @Override - public int getItemCount() { - return stickers.size(); - } - - public void setStickers(@NonNull List stickers, @Px int stickerSize) { - this.stickers.clear(); - this.stickers.addAll(stickers); - - this.stickerSize = stickerSize; - - notifyDataSetChanged(); - } - - public void setStickerSize(@Px int stickerSize) { - this.stickerSize = stickerSize; - notifyDataSetChanged(); - } - - static class StickerKeyboardPageViewHolder extends RecyclerView.ViewHolder { - - private final ImageView image; - - private StickerRecord currentSticker; - - public StickerKeyboardPageViewHolder(@NonNull View itemView) { - super(itemView); - image = itemView.findViewById(R.id.sticker_keyboard_page_image); - } - - public void bind(@NonNull GlideRequests glideRequests, - @Nullable EventListener eventListener, - @NonNull StickerRecord sticker, - @Px int size, - boolean allowApngAnimation) - { - currentSticker = sticker; - - itemView.getLayoutParams().height = size; - itemView.getLayoutParams().width = size; - itemView.requestLayout(); - - glideRequests.load(new DecryptableUri(sticker.getUri())) - .set(ApngOptions.ANIMATE, allowApngAnimation) - .transition(DrawableTransitionOptions.withCrossFade()) - .into(image); - - if (eventListener != null) { - image.setOnClickListener(v -> eventListener.onStickerClicked(sticker)); - image.setOnLongClickListener(v -> { - eventListener.onStickerLongClicked(v); - return true; - }); - } else { - image.setOnClickListener(null); - image.setOnLongClickListener(null); - } - } - - void recycle() { - image.setOnClickListener(null); - } - - @Nullable StickerRecord getCurrentSticker() { - return currentSticker; - } - } - - public interface EventListener { - void onStickerClicked(@NonNull StickerRecord sticker); - void onStickerLongClicked(@NonNull View targetView); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageFragment.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageFragment.java deleted file mode 100644 index a615a01ff5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageFragment.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.thoughtcrime.securesms.stickers; - -import android.content.res.Configuration; -import android.graphics.Point; -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.annotation.Px; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProviders; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.model.StickerRecord; -import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader; -import org.thoughtcrime.securesms.mms.GlideApp; -import org.thoughtcrime.securesms.mms.GlideRequests; -import org.thoughtcrime.securesms.stickers.StickerKeyboardPageAdapter.StickerKeyboardPageViewHolder; -import org.thoughtcrime.securesms.util.DeviceProperties; -import org.whispersystems.libsignal.util.Pair; - -/** - * An individual page of stickers in the {@link StickerKeyboardProvider}. - */ -public final class StickerKeyboardPageFragment extends Fragment implements StickerKeyboardPageAdapter.EventListener, - StickerRolloverTouchListener.RolloverStickerRetriever -{ - - 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 StickerRolloverTouchListener 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, DeviceProperties.shouldAllowApngStickerAnimation(requireContext())); - this.layoutManager = new GridLayoutManager(requireContext(), 2); - this.listTouchListener = new StickerRolloverTouchListener(requireContext(), glideRequests, eventListener, this); - 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); - } - } - - @Override - public @Nullable Pair 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) { - 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); - } - - interface EventListener extends StickerRolloverTouchListener.RolloverEventListener { - void onStickerSelected(@NonNull StickerRecord sticker); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageViewModel.java deleted file mode 100644 index 4c664c5953..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardPageViewModel.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.thoughtcrime.securesms.stickers; - -import android.app.Application; -import android.database.ContentObserver; -import android.os.Handler; -import android.os.Looper; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import org.thoughtcrime.securesms.database.DatabaseContentProviders; -import org.thoughtcrime.securesms.database.model.StickerRecord; -import org.thoughtcrime.securesms.util.Throttler; - -import java.util.List; - -final class StickerKeyboardPageViewModel extends ViewModel { - - static final String RECENT_PACK_ID = "RECENT"; - - private final Application application; - private final StickerKeyboardRepository repository; - private final MutableLiveData> stickers; - private final Throttler observerThrottler; - private final ContentObserver observer; - - private String packId; - - private StickerKeyboardPageViewModel(@NonNull Application application, @NonNull StickerKeyboardRepository repository) { - this.application = application; - this.repository = repository; - this.stickers = new MutableLiveData<>(); - this.observerThrottler = new Throttler(500); - this.observer = new ContentObserver(new Handler(Looper.getMainLooper())) { - @Override - public void onChange(boolean selfChange) { - observerThrottler.publish(() -> getStickers(packId)); - } - }; - - application.getContentResolver().registerContentObserver(DatabaseContentProviders.Sticker.CONTENT_URI, true, observer); - } - - LiveData> getStickers(@NonNull String packId) { - this.packId = packId; - - if (RECENT_PACK_ID.equals(packId)) { - repository.getRecentStickers(stickers::postValue); - } else { - repository.getStickersForPack(packId, stickers::postValue); - } - - return stickers; - } - - @Override - protected void onCleared() { - application.getContentResolver().unregisterContentObserver(observer); - } - - static class Factory extends ViewModelProvider.NewInstanceFactory { - private final Application application; - private final StickerKeyboardRepository repository; - - Factory(@NonNull Application application, @NonNull StickerKeyboardRepository repository) { - this.application = application; - this.repository = repository; - } - - @Override - public @NonNull T create(@NonNull Class modelClass) { - //noinspection ConstantConditions - return modelClass.cast(new StickerKeyboardPageViewModel(application, repository)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardProvider.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardProvider.java deleted file mode 100644 index f595ef9852..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardProvider.java +++ /dev/null @@ -1,270 +0,0 @@ -package org.thoughtcrime.securesms.stickers; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; -import androidx.lifecycle.ViewModelProviders; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.MediaKeyboardProvider; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.model.StickerPackRecord; -import org.thoughtcrime.securesms.database.model.StickerRecord; -import org.thoughtcrime.securesms.glide.cache.ApngOptions; -import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader; -import org.thoughtcrime.securesms.mms.GlideRequests; -import org.thoughtcrime.securesms.stickers.StickerKeyboardPageFragment.EventListener; -import org.thoughtcrime.securesms.stickers.StickerKeyboardRepository.PackListResult; -import org.thoughtcrime.securesms.util.DeviceProperties; -import org.thoughtcrime.securesms.util.Throttler; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * A provider to select stickers in the {@link org.thoughtcrime.securesms.components.emoji.MediaKeyboard}. - */ -public final class StickerKeyboardProvider implements MediaKeyboardProvider, - MediaKeyboardProvider.AddObserver, - StickerKeyboardPageFragment.EventListener -{ - private static final int UNSET = -1; - - private final Context context; - private final StickerEventListener eventListener; - private final StickerPagerAdapter pagerAdapter; - private final Throttler stickerThrottler; - - private Controller controller; - private Presenter presenter; - private boolean isSoloProvider; - private StickerKeyboardViewModel viewModel; - private int currentPosition; - - public StickerKeyboardProvider(@NonNull FragmentActivity activity, - @NonNull StickerEventListener eventListener) - { - this.context = activity; - this.eventListener = eventListener; - this.pagerAdapter = new StickerPagerAdapter(activity.getSupportFragmentManager(), this); - this.stickerThrottler = new Throttler(100); - this.currentPosition = UNSET; - - initViewModel(activity); - } - - @Override - public int getProviderIconView(boolean selected) { - if (selected) { - return R.layout.sticker_keyboard_icon_selected; - } else { - return R.layout.sticker_keyboard_icon; - } - } - - @Override - public void requestPresentation(@NonNull Presenter presenter, boolean isSoloProvider) { - this.presenter = presenter; - this.isSoloProvider = isSoloProvider; - - PackListResult result = viewModel.getPacks().getValue(); - - if (result != null) { - present(presenter, result, false); - } - } - - @Override - public void setController(@Nullable Controller controller) { - this.controller = controller; - } - - @Override - public void onAddClicked() { - eventListener.onStickerManagementClicked(); - } - - @Override - public void onStickerSelected(@NonNull StickerRecord sticker) { - stickerThrottler.publish(() -> eventListener.onStickerSelected(sticker)); - } - - @Override - public void onStickerPopupStarted() { - if (controller != null) { - controller.setViewPagerEnabled(false); - } - } - - @Override - public void onStickerPopupEnded() { - if (controller != null) { - controller.setViewPagerEnabled(true); - } - } - - @Override - public void setCurrentPosition(int currentPosition) { - this.currentPosition = currentPosition; - } - - private void initViewModel(@NonNull FragmentActivity activity) { - StickerKeyboardRepository repository = new StickerKeyboardRepository(DatabaseFactory.getStickerDatabase(activity)); - viewModel = ViewModelProviders.of(activity, new StickerKeyboardViewModel.Factory(activity.getApplication(), repository)).get(StickerKeyboardViewModel.class); - - viewModel.getPacks().observe(activity, result -> { - if (result == null) return; - - int previousCount = pagerAdapter.getCount(); - - pagerAdapter.setPacks(result.getPacks()); - - if (presenter != null) { - present(presenter, result, previousCount != pagerAdapter.getCount()); - } - }); - } - - private void present(@NonNull Presenter presenter, @NonNull PackListResult result, boolean calculateStartingIndex) { - if (result.getPacks().isEmpty() && presenter.isVisible()) { - context.startActivity(StickerManagementActivity.getIntent(context)); - presenter.requestDismissal(); - return; - } - - int startingIndex = currentPosition; - - if (calculateStartingIndex || startingIndex == UNSET) { - startingIndex = !result.hasRecents() && result.getPacks().size() > 0 ? 1 : 0; - } - - presenter.present(this, pagerAdapter, new IconProvider(context, result.getPacks(), DeviceProperties.shouldAllowApngStickerAnimation(context)), null, this, null, startingIndex); - - if (isSoloProvider && result.getPacks().isEmpty()) { - context.startActivity(StickerManagementActivity.getIntent(context)); - } - } - - @Override - public boolean equals(@Nullable Object obj) { - return obj instanceof StickerKeyboardProvider; - } - - private static class StickerPagerAdapter extends FragmentStatePagerAdapter { - - private final List packs; - private final Map itemPositions; - private final EventListener eventListener; - - public StickerPagerAdapter(@NonNull FragmentManager fm, @NonNull EventListener eventListener) { - super(fm); - this.eventListener = eventListener; - this.packs = new ArrayList<>(); - this.itemPositions = new HashMap<>(); - } - - @Override - public int getItemPosition(@NonNull Object object) { - String packId = ((StickerKeyboardPageFragment) object).getPackId(); - - if (itemPositions.containsKey(packId)) { - //noinspection ConstantConditions - return itemPositions.get(packId); - } - - return POSITION_NONE; - } - - @Override - public Fragment getItem(int i) { - StickerKeyboardPageFragment fragment; - - if (i == 0) { - fragment = StickerKeyboardPageFragment.newInstance(StickerKeyboardPageFragment.RECENT_PACK_ID); - } else { - StickerPackRecord pack = packs.get(i - 1); - fragment = StickerKeyboardPageFragment.newInstance(pack.getPackId()); - } - - fragment.setEventListener(eventListener); - - return fragment; - } - - @Override - public int getCount() { - return packs.isEmpty() ? 0 : packs.size() + 1; - } - - void setPacks(@NonNull List packs) { - itemPositions.clear(); - - if (areListsEqual(this.packs, packs)) { - itemPositions.put(StickerKeyboardPageFragment.RECENT_PACK_ID, 0); - for (int i = 0; i < packs.size(); i++) { - itemPositions.put(packs.get(i).getPackId(), i + 1); - } - } - - this.packs.clear(); - this.packs.addAll(packs); - - notifyDataSetChanged(); - } - - boolean areListsEqual(@NonNull List a, @NonNull List b) { - if (a.size() != b.size()) return false; - - for (int i = 0; i < a.size(); i++) { - if (!a.get(i).equals(b.get(i))) { - return false; - } - } - - return true; - } - } - - private static class IconProvider implements TabIconProvider { - - private final Context context; - private final List packs; - private final boolean allowApngAnimation; - - private IconProvider(@NonNull Context context, List packs, boolean allowApngAnimation) { - this.context = context; - this.packs = packs; - this.allowApngAnimation = allowApngAnimation; - } - - @Override - public void loadCategoryTabIcon(@NonNull GlideRequests glideRequests, @NonNull ImageView imageView, int index) { - if (index == 0) { - Drawable icon = ContextCompat.getDrawable(context, R.drawable.ic_recent_20); - imageView.setImageDrawable(icon); - } else { - Uri uri = packs.get(index - 1).getCover().getUri(); - - glideRequests.load(new DecryptableStreamUriLoader.DecryptableUri(uri)) - .set(ApngOptions.ANIMATE, allowApngAnimation) - .into(imageView); - } - } - } - - public interface StickerEventListener { - void onStickerSelected(@NonNull StickerRecord sticker); - void onStickerManagementClicked(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardRepository.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardRepository.java deleted file mode 100644 index bad0d2e8ba..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardRepository.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.thoughtcrime.securesms.stickers; - -import android.database.Cursor; - -import androidx.annotation.NonNull; - -import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.StickerDatabase; -import org.thoughtcrime.securesms.database.StickerDatabase.StickerPackRecordReader; -import org.thoughtcrime.securesms.database.StickerDatabase.StickerRecordReader; -import org.thoughtcrime.securesms.database.model.StickerPackRecord; -import org.thoughtcrime.securesms.database.model.StickerRecord; - -import java.util.ArrayList; -import java.util.List; - -final class StickerKeyboardRepository { - - private static final int RECENT_LIMIT = 24; - - private final StickerDatabase stickerDatabase; - - StickerKeyboardRepository(@NonNull StickerDatabase stickerDatabase) { - this.stickerDatabase = stickerDatabase; - } - - void getPackList(@NonNull Callback callback) { - SignalExecutors.BOUNDED.execute(() -> { - List packs = new ArrayList<>(); - - try (StickerPackRecordReader reader = new StickerPackRecordReader(stickerDatabase.getInstalledStickerPacks())) { - StickerPackRecord pack; - while ((pack = reader.getNext()) != null) { - packs.add(pack); - } - } - - boolean hasRecents; - - try (Cursor recentsCursor = stickerDatabase.getRecentlyUsedStickers(1)) { - hasRecents = recentsCursor != null && recentsCursor.moveToFirst(); - } - - callback.onComplete(new PackListResult(packs, hasRecents)); - }); - } - - void getStickersForPack(@NonNull String packId, @NonNull Callback> callback) { - SignalExecutors.BOUNDED.execute(() -> { - List stickers = new ArrayList<>(); - - try (StickerRecordReader reader = new StickerRecordReader(stickerDatabase.getStickersForPack(packId))) { - StickerRecord sticker; - while ((sticker = reader.getNext()) != null) { - stickers.add(sticker); - } - } - - callback.onComplete(stickers); - }); - } - - void getRecentStickers(@NonNull Callback> callback) { - SignalExecutors.BOUNDED.execute(() -> { - List stickers = new ArrayList<>(); - - try (StickerRecordReader reader = new StickerRecordReader(stickerDatabase.getRecentlyUsedStickers(RECENT_LIMIT))) { - StickerRecord sticker; - while ((sticker = reader.getNext()) != null) { - stickers.add(sticker); - } - } - - callback.onComplete(stickers); - }); - } - - static class PackListResult { - - private final List packs; - private final boolean hasRecents; - - PackListResult(List packs, boolean hasRecents) { - this.packs = packs; - this.hasRecents = hasRecents; - } - - List getPacks() { - return packs; - } - - boolean hasRecents() { - return hasRecents; - } - } - - interface Callback { - void onComplete(T result); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardViewModel.java deleted file mode 100644 index febcfb5bd3..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerKeyboardViewModel.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.thoughtcrime.securesms.stickers; - -import android.app.Application; -import android.database.ContentObserver; -import android.os.Handler; -import android.os.Looper; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import org.thoughtcrime.securesms.database.DatabaseContentProviders; -import org.thoughtcrime.securesms.stickers.StickerKeyboardRepository.PackListResult; -import org.thoughtcrime.securesms.util.Throttler; - -final class StickerKeyboardViewModel extends ViewModel { - - private final Application application; - private final MutableLiveData packs; - private final Throttler observerThrottler; - private final ContentObserver observer; - - private StickerKeyboardViewModel(@NonNull Application application, @NonNull StickerKeyboardRepository repository) { - this.application = application; - this.packs = new MutableLiveData<>(); - this.observerThrottler = new Throttler(500); - this.observer = new ContentObserver(new Handler(Looper.getMainLooper())) { - @Override - public void onChange(boolean selfChange) { - observerThrottler.publish(() -> repository.getPackList(packs::postValue)); - } - }; - - repository.getPackList(packs::postValue); - application.getContentResolver().registerContentObserver(DatabaseContentProviders.StickerPack.CONTENT_URI, true, observer); - } - - @NonNull LiveData getPacks() { - return packs; - } - - @Override - protected void onCleared() { - application.getContentResolver().unregisterContentObserver(observer); - } - - public static final class Factory extends ViewModelProvider.NewInstanceFactory { - private final Application application; - private final StickerKeyboardRepository repository; - - public Factory(@NonNull Application application, @NonNull StickerKeyboardRepository repository) { - this.application = application; - this.repository = repository; - } - - @Override - public @NonNull T create(@NonNull Class modelClass) { - //noinspection ConstantConditions - return modelClass.cast(new StickerKeyboardViewModel(application, repository)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java index e24d33349e..95a1ad33be 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -197,6 +197,7 @@ public class TextSecurePreferences { private static final String SEEN_STICKER_INTRO_TOOLTIP = "pref_seen_sticker_intro_tooltip"; private static final String MEDIA_KEYBOARD_MODE = "pref_media_keyboard_mode"; + public static final String RECENT_STORAGE_KEY = "pref_recent_emoji2"; private static final String VIEW_ONCE_TOOLTIP_SEEN = "pref_revealable_message_tooltip_seen"; diff --git a/app/src/main/res/drawable-night/media_keyboard_selected_background.xml b/app/src/main/res/drawable-night/media_keyboard_selected_background.xml deleted file mode 100644 index b41f2cf6d8..0000000000 --- a/app/src/main/res/drawable-night/media_keyboard_selected_background.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/media_keyboard_selected_background.xml b/app/src/main/res/drawable/media_keyboard_selected_background.xml deleted file mode 100644 index e0afb0fc4a..0000000000 --- a/app/src/main/res/drawable/media_keyboard_selected_background.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/emoji_keyboard_icon.xml b/app/src/main/res/layout/emoji_keyboard_icon.xml deleted file mode 100644 index 83432e0892..0000000000 --- a/app/src/main/res/layout/emoji_keyboard_icon.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/emoji_keyboard_icon_selected.xml b/app/src/main/res/layout/emoji_keyboard_icon_selected.xml deleted file mode 100644 index 75700d4f00..0000000000 --- a/app/src/main/res/layout/emoji_keyboard_icon_selected.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/giphy_mp4_keyboard_icon.xml b/app/src/main/res/layout/giphy_mp4_keyboard_icon.xml deleted file mode 100644 index 608266246a..0000000000 --- a/app/src/main/res/layout/giphy_mp4_keyboard_icon.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/giphy_mp4_keyboard_icon_selected.xml b/app/src/main/res/layout/giphy_mp4_keyboard_icon_selected.xml deleted file mode 100644 index b468e5524e..0000000000 --- a/app/src/main/res/layout/giphy_mp4_keyboard_icon_selected.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/media_keyboard_bottom_tab_item.xml b/app/src/main/res/layout/media_keyboard_bottom_tab_item.xml deleted file mode 100644 index 7baaf1c73e..0000000000 --- a/app/src/main/res/layout/media_keyboard_bottom_tab_item.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/layout/react_with_any_emoji_tab.xml b/app/src/main/res/layout/react_with_any_emoji_tab.xml deleted file mode 100644 index d4e9fcaacb..0000000000 --- a/app/src/main/res/layout/react_with_any_emoji_tab.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/sticker_keyboard_icon.xml b/app/src/main/res/layout/sticker_keyboard_icon.xml deleted file mode 100644 index 9713bd10ad..0000000000 --- a/app/src/main/res/layout/sticker_keyboard_icon.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/sticker_keyboard_icon_selected.xml b/app/src/main/res/layout/sticker_keyboard_icon_selected.xml deleted file mode 100644 index bfb311f081..0000000000 --- a/app/src/main/res/layout/sticker_keyboard_icon_selected.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/sticker_keyboard_page.xml b/app/src/main/res/layout/sticker_keyboard_page.xml deleted file mode 100644 index e9fbd96a20..0000000000 --- a/app/src/main/res/layout/sticker_keyboard_page.xml +++ /dev/null @@ -1,12 +0,0 @@ - -