mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-24 02:39:55 +01:00
Add CFV2 Sticker Suggestions.
This commit is contained in:
committed by
Nicholas Tinsley
parent
2fbcc23451
commit
4ce05a064c
@@ -2175,7 +2175,7 @@ public class ConversationParentFragment extends Fragment
|
||||
}
|
||||
|
||||
private void initializeStickerObserver() {
|
||||
StickerSearchRepository repository = new StickerSearchRepository(requireContext());
|
||||
StickerSearchRepository repository = new StickerSearchRepository();
|
||||
|
||||
stickerViewModel = new ViewModelProvider(this, (ViewModelProvider.Factory) new ConversationStickerViewModel.Factory(requireActivity().getApplication(), repository))
|
||||
.get(ConversationStickerViewModel.class);
|
||||
|
||||
@@ -188,6 +188,7 @@ import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationInitiatio
|
||||
import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationSuggestionsDialog
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult
|
||||
import org.thoughtcrime.securesms.invites.InviteActions
|
||||
import org.thoughtcrime.securesms.keyboard.KeyboardPage
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModelV2
|
||||
@@ -229,6 +230,7 @@ import org.thoughtcrime.securesms.revealable.ViewOnceMessageActivity
|
||||
import org.thoughtcrime.securesms.revealable.ViewOnceUtil
|
||||
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
|
||||
import org.thoughtcrime.securesms.stories.StoryViewerArgs
|
||||
import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity
|
||||
@@ -333,6 +335,10 @@ class ConversationFragment :
|
||||
ConversationSearchViewModel(getString(R.string.note_to_self))
|
||||
}
|
||||
|
||||
private val stickerViewModel: StickerSuggestionsViewModel by viewModel {
|
||||
StickerSuggestionsViewModel()
|
||||
}
|
||||
|
||||
private val conversationTooltips = ConversationTooltips(this)
|
||||
private val colorizer = Colorizer()
|
||||
private val textDraftSaveDebouncer = Debouncer(500)
|
||||
@@ -430,6 +436,7 @@ class ConversationFragment :
|
||||
container.fragmentManager = childFragmentManager
|
||||
|
||||
ToolbarDependentMarginListener(binding.toolbar)
|
||||
initializeMediaKeyboardToggle()
|
||||
}
|
||||
|
||||
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
||||
@@ -676,6 +683,7 @@ class ConversationFragment :
|
||||
|
||||
initializeSearch()
|
||||
initializeLinkPreviews()
|
||||
initializeStickerSuggestions()
|
||||
|
||||
inputPanel.setListener(InputPanelListener())
|
||||
}
|
||||
@@ -1056,6 +1064,36 @@ class ConversationFragment :
|
||||
.addTo(disposables)
|
||||
}
|
||||
|
||||
private fun initializeMediaKeyboardToggle() {
|
||||
val isSystemEmojiPreferred = SignalStore.settings().isPreferSystemEmoji
|
||||
val keyboardMode: TextSecurePreferences.MediaKeyboardMode = TextSecurePreferences.getMediaKeyboardMode(requireContext())
|
||||
val stickerIntro: Boolean = !TextSecurePreferences.hasSeenStickerIntroTooltip(requireContext())
|
||||
|
||||
inputPanel.showMediaKeyboardToggle(true)
|
||||
|
||||
val toggleMode = when (keyboardMode) {
|
||||
TextSecurePreferences.MediaKeyboardMode.EMOJI -> if (isSystemEmojiPreferred) KeyboardPage.STICKER else KeyboardPage.EMOJI
|
||||
TextSecurePreferences.MediaKeyboardMode.STICKER -> KeyboardPage.STICKER
|
||||
TextSecurePreferences.MediaKeyboardMode.GIF -> KeyboardPage.GIF
|
||||
}
|
||||
|
||||
inputPanel.setMediaKeyboardToggleMode(toggleMode)
|
||||
|
||||
if (stickerIntro) {
|
||||
TextSecurePreferences.setMediaKeyboardMode(requireContext(), TextSecurePreferences.MediaKeyboardMode.STICKER)
|
||||
inputPanel.setMediaKeyboardToggleMode(KeyboardPage.STICKER)
|
||||
conversationTooltips.displayStickerIntroductionTooltip(inputPanel.mediaKeyboardToggleAnchorView) {
|
||||
EventBus.getDefault().removeStickyEvent(StickerPackInstallEvent::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeStickerSuggestions() {
|
||||
stickerViewModel.stickers
|
||||
.subscribeBy(onNext = inputPanel::setStickerSuggestions)
|
||||
.addTo(disposables)
|
||||
}
|
||||
|
||||
private fun updateLinkPreviewState() {
|
||||
if (/* TODO [cfv2] -- viewModel.isPushAvailable && */ !attachmentManager.isAttachmentPresent && context != null) {
|
||||
linkPreviewViewModel.onEnabled()
|
||||
@@ -2739,7 +2777,8 @@ class ConversationFragment :
|
||||
if (composeText.textTrimmed.isEmpty() || beforeLength == 0) {
|
||||
composeText.postDelayed({ updateToggleButtonState() }, 50)
|
||||
}
|
||||
// todo [cfv2] stickerViewModel.onInputTextUpdated(s.toString())
|
||||
|
||||
stickerViewModel.onInputTextUpdated(s.toString())
|
||||
}
|
||||
|
||||
override fun onFocusChange(v: View, hasFocus: Boolean) {
|
||||
@@ -2942,6 +2981,23 @@ class ConversationFragment :
|
||||
viewModel.updateIdentityRecords()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||
fun onStickerPackInstalled(event: StickerPackInstallEvent?) {
|
||||
if (event == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!TextSecurePreferences.hasSeenStickerIntroTooltip(requireContext())) {
|
||||
return
|
||||
}
|
||||
|
||||
EventBus.getDefault().removeStickyEvent(event)
|
||||
|
||||
if (!inputPanel.isStickerMode) {
|
||||
conversationTooltips.displayStickerPackInstalledTooltip(inputPanel.mediaKeyboardToggleAnchorView, event)
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
private inner class SearchEventListener : ConversationSearchBottomBar.EventListener {
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.TooltipPopup
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
|
||||
/**
|
||||
* Any and all tooltips that the conversation can display, and a light amount of related presentation logic.
|
||||
@@ -51,6 +53,31 @@ class ConversationTooltips(fragment: Fragment) {
|
||||
.show(TooltipPopup.POSITION_BELOW)
|
||||
}
|
||||
|
||||
/**
|
||||
* Displayed to teach the user about sticker packs
|
||||
*/
|
||||
fun displayStickerIntroductionTooltip(anchor: View, onDismiss: () -> Unit) {
|
||||
TooltipPopup.forTarget(anchor)
|
||||
.setBackgroundTint(ContextCompat.getColor(anchor.context, R.color.core_ultramarine))
|
||||
.setTextColor(ContextCompat.getColor(anchor.context, R.color.core_white))
|
||||
.setText(R.string.ConversationActivity_new_say_it_with_stickers)
|
||||
.setOnDismissListener {
|
||||
TextSecurePreferences.setHasSeenStickerIntroTooltip(anchor.context, true)
|
||||
onDismiss()
|
||||
}
|
||||
.show(TooltipPopup.POSITION_ABOVE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Displayed after a sticker pack is installed
|
||||
*/
|
||||
fun displayStickerPackInstalledTooltip(anchor: View, event: StickerPackInstallEvent) {
|
||||
TooltipPopup.forTarget(anchor)
|
||||
.setText(R.string.ConversationActivity_sticker_pack_installed)
|
||||
.setIconGlideModel(event.iconGlideModel)
|
||||
.show(TooltipPopup.POSITION_ABOVE)
|
||||
}
|
||||
|
||||
/**
|
||||
* ViewModel which holds different bits of session-local persistent state for different tooltips.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.conversation.v2
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.processors.BehaviorProcessor
|
||||
import org.thoughtcrime.securesms.database.model.StickerRecord
|
||||
import org.thoughtcrime.securesms.stickers.StickerSearchRepository
|
||||
|
||||
class StickerSuggestionsViewModel(
|
||||
private val stickerSearchRepository: StickerSearchRepository = StickerSearchRepository()
|
||||
) : ViewModel() {
|
||||
|
||||
private val stickerSearchProcessor = BehaviorProcessor.createDefault("")
|
||||
|
||||
val stickers: Flowable<List<StickerRecord>> = stickerSearchProcessor
|
||||
.switchMapSingle { stickerSearchRepository.searchByEmoji(it) }
|
||||
|
||||
fun onInputTextUpdated(text: String) {
|
||||
stickerSearchProcessor.onNext(text)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user