Add media keyboard support in CFv2.
This commit is contained in:
parent
b042945fef
commit
65255121de
8 changed files with 171 additions and 21 deletions
|
@ -34,10 +34,13 @@ class InputAwareConstraintLayout @JvmOverloads constructor(
|
|||
hideInput(resetKeyboardGuideline = false)
|
||||
}
|
||||
|
||||
fun toggleInput(fragmentCreator: FragmentCreator, imeTarget: EditText, toggled: (Boolean) -> Unit = { }) {
|
||||
fun toggleInput(fragmentCreator: FragmentCreator, imeTarget: EditText, showSoftKeyOnHide: Boolean = false) {
|
||||
if (fragmentCreator.id == inputId) {
|
||||
hideInput(resetKeyboardGuideline = true)
|
||||
toggled(false)
|
||||
if (showSoftKeyOnHide) {
|
||||
showSoftkey(imeTarget)
|
||||
} else {
|
||||
hideInput(resetKeyboardGuideline = true)
|
||||
}
|
||||
} else {
|
||||
hideInput(resetKeyboardGuideline = false)
|
||||
showInput(fragmentCreator, imeTarget)
|
||||
|
@ -55,6 +58,7 @@ class InputAwareConstraintLayout @JvmOverloads constructor(
|
|||
fragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.input_container, input!!)
|
||||
.runOnCommit { (input as? InputFragment)?.show() }
|
||||
.commit()
|
||||
|
||||
overrideKeyboardGuidelineWithPreviousHeight()
|
||||
|
@ -66,6 +70,7 @@ class InputAwareConstraintLayout @JvmOverloads constructor(
|
|||
private fun hideInput(resetKeyboardGuideline: Boolean) {
|
||||
val inputHidden = input != null
|
||||
input?.let {
|
||||
(input as? InputFragment)?.hide()
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
.remove(it)
|
||||
|
@ -94,4 +99,9 @@ class InputAwareConstraintLayout @JvmOverloads constructor(
|
|||
fun onInputShown()
|
||||
fun onInputHidden()
|
||||
}
|
||||
|
||||
interface InputFragment {
|
||||
fun show()
|
||||
fun hide()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,6 @@ public class MediaKeyboard extends FrameLayout implements InputView {
|
|||
if (!isInitialised) initView();
|
||||
|
||||
setVisibility(VISIBLE);
|
||||
if (keyboardListener != null) keyboardListener.onShown();
|
||||
keyboardPagerFragment.show();
|
||||
}
|
||||
|
||||
|
@ -113,7 +112,6 @@ public class MediaKeyboard extends FrameLayout implements InputView {
|
|||
public void hide(boolean immediate) {
|
||||
setVisibility(GONE);
|
||||
onCloseEmojiSearchInternal(false);
|
||||
if (keyboardListener != null) keyboardListener.onHidden();
|
||||
Log.i(TAG, "hide()");
|
||||
keyboardPagerFragment.hide();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.contactshare.Contact
|
|||
import org.thoughtcrime.securesms.contactshare.ContactShareEditActivity
|
||||
import org.thoughtcrime.securesms.conversation.MessageSendType
|
||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||
import org.thoughtcrime.securesms.giph.ui.GiphyActivity
|
||||
import org.thoughtcrime.securesms.mediasend.Media
|
||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivityResult
|
||||
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity
|
||||
|
@ -32,6 +33,7 @@ class ConversationActivityResultContracts(fragment: Fragment, private val callba
|
|||
|
||||
private val contactShareLauncher = fragment.registerForActivityResult(ContactShareEditor) { contacts -> callbacks.onSendContacts(contacts) }
|
||||
private val mediaSelectionLauncher = fragment.registerForActivityResult(MediaSelection) { result -> callbacks.onMediaSend(result) }
|
||||
private val gifSearchLauncher = fragment.registerForActivityResult(GifSearch) { result -> callbacks.onMediaSend(result) }
|
||||
|
||||
fun launchContactShareEditor(uri: Uri, chatColors: ChatColors) {
|
||||
contactShareLauncher.launch(uri to chatColors)
|
||||
|
@ -41,14 +43,18 @@ class ConversationActivityResultContracts(fragment: Fragment, private val callba
|
|||
mediaSelectionLauncher.launch(MediaSelectionInput(mediaList, recipientId, text))
|
||||
}
|
||||
|
||||
private object MediaSelection : ActivityResultContract<MediaSelectionInput, MediaSendActivityResult>() {
|
||||
fun launchGifSearch(recipientId: RecipientId, text: CharSequence?) {
|
||||
gifSearchLauncher.launch(GifSearchInput(recipientId, text))
|
||||
}
|
||||
|
||||
private object MediaSelection : ActivityResultContract<MediaSelectionInput, MediaSendActivityResult?>() {
|
||||
override fun createIntent(context: Context, input: MediaSelectionInput): Intent {
|
||||
val (media, recipientId, text) = input
|
||||
return MediaSelectionActivity.editor(context, MessageSendType.SignalMessageSendType, media, recipientId, text)
|
||||
}
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): MediaSendActivityResult {
|
||||
return MediaSendActivityResult.fromData(intent!!)
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): MediaSendActivityResult? {
|
||||
return intent?.let { MediaSendActivityResult.fromData(intent) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,10 +69,27 @@ class ConversationActivityResultContracts(fragment: Fragment, private val callba
|
|||
}
|
||||
}
|
||||
|
||||
private object GifSearch : ActivityResultContract<GifSearchInput, MediaSendActivityResult?>() {
|
||||
override fun createIntent(context: Context, input: GifSearchInput): Intent {
|
||||
return Intent(context, GiphyActivity::class.java).apply {
|
||||
putExtra(GiphyActivity.EXTRA_IS_MMS, false)
|
||||
putExtra(GiphyActivity.EXTRA_RECIPIENT_ID, input.recipientId)
|
||||
putExtra(GiphyActivity.EXTRA_TRANSPORT, MessageSendType.SignalMessageSendType)
|
||||
putExtra(GiphyActivity.EXTRA_TEXT, input.text)
|
||||
}
|
||||
}
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): MediaSendActivityResult? {
|
||||
return intent?.let { MediaSendActivityResult.fromData(intent) }
|
||||
}
|
||||
}
|
||||
|
||||
private data class MediaSelectionInput(val media: List<Media>, val recipientId: RecipientId, val text: CharSequence?)
|
||||
|
||||
private data class GifSearchInput(val recipientId: RecipientId, val text: CharSequence?)
|
||||
|
||||
interface Callbacks {
|
||||
fun onSendContacts(contacts: List<Contact>)
|
||||
fun onMediaSend(result: MediaSendActivityResult)
|
||||
fun onMediaSend(result: MediaSendActivityResult?)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import androidx.core.view.doOnPreDraw
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentResultListener
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
|
@ -106,6 +107,9 @@ import org.thoughtcrime.securesms.components.ProgressCardDialogFragmentArgs
|
|||
import org.thoughtcrime.securesms.components.ScrollToPositionDelegate
|
||||
import org.thoughtcrime.securesms.components.SendButton
|
||||
import org.thoughtcrime.securesms.components.ViewBinderDelegate
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiEventListener
|
||||
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard
|
||||
import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel
|
||||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation
|
||||
import org.thoughtcrime.securesms.components.menu.ActionItem
|
||||
import org.thoughtcrime.securesms.components.menu.SignalBottomActionBar
|
||||
|
@ -190,6 +194,12 @@ import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationSuggestio
|
|||
import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult
|
||||
import org.thoughtcrime.securesms.invites.InviteActions
|
||||
import org.thoughtcrime.securesms.keyboard.KeyboardPage
|
||||
import org.thoughtcrime.securesms.keyboard.KeyboardPagerFragment
|
||||
import org.thoughtcrime.securesms.keyboard.KeyboardPagerViewModel
|
||||
import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardPageFragment
|
||||
import org.thoughtcrime.securesms.keyboard.gif.GifKeyboardPageFragment
|
||||
import org.thoughtcrime.securesms.keyboard.sticker.StickerKeyboardPageFragment
|
||||
import org.thoughtcrime.securesms.keyboard.sticker.StickerSearchDialogFragment
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModelV2
|
||||
|
@ -219,6 +229,7 @@ import org.thoughtcrime.securesms.notifications.v2.ConversationId
|
|||
import org.thoughtcrime.securesms.payments.preferences.PaymentsActivity
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.profiles.spoofing.ReviewCardDialogFragment
|
||||
import org.thoughtcrime.securesms.providers.BlobProvider
|
||||
import org.thoughtcrime.securesms.ratelimit.RecaptchaProofBottomSheetFragment
|
||||
import org.thoughtcrime.securesms.reactions.ReactionsBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiBottomSheetDialogFragment
|
||||
|
@ -233,7 +244,9 @@ import org.thoughtcrime.securesms.revealable.ViewOnceMessageActivity
|
|||
import org.thoughtcrime.securesms.revealable.ViewOnceUtil
|
||||
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
||||
import org.thoughtcrime.securesms.sms.MessageSender
|
||||
import org.thoughtcrime.securesms.stickers.StickerEventListener
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.thoughtcrime.securesms.stickers.StickerManagementActivity
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
|
||||
import org.thoughtcrime.securesms.stories.StoryViewerArgs
|
||||
|
@ -271,6 +284,7 @@ import org.thoughtcrime.securesms.wallpaper.ChatWallpaperDimLevelUtil
|
|||
import java.util.Locale
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.ExecutionException
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
/**
|
||||
* A single unified fragment for Conversations.
|
||||
|
@ -278,7 +292,13 @@ import java.util.concurrent.ExecutionException
|
|||
class ConversationFragment :
|
||||
LoggingFragment(R.layout.v2_conversation_fragment),
|
||||
ReactWithAnyEmojiBottomSheetDialogFragment.Callback,
|
||||
ReactionsBottomSheetDialogFragment.Callback {
|
||||
ReactionsBottomSheetDialogFragment.Callback,
|
||||
EmojiKeyboardPageFragment.Callback,
|
||||
EmojiEventListener,
|
||||
GifKeyboardPageFragment.Host,
|
||||
StickerEventListener,
|
||||
StickerKeyboardPageFragment.Callback,
|
||||
MediaKeyboard.MediaKeyboardListener {
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(ConversationFragment::class.java)
|
||||
|
@ -340,6 +360,8 @@ class ConversationFragment :
|
|||
ConversationSearchViewModel(getString(R.string.note_to_self))
|
||||
}
|
||||
|
||||
private val keyboardPagerViewModel: KeyboardPagerViewModel by activityViewModels()
|
||||
|
||||
private val stickerViewModel: StickerSuggestionsViewModel by viewModel {
|
||||
StickerSuggestionsViewModel()
|
||||
}
|
||||
|
@ -347,6 +369,7 @@ class ConversationFragment :
|
|||
private val conversationTooltips = ConversationTooltips(this)
|
||||
private val colorizer = Colorizer()
|
||||
private val textDraftSaveDebouncer = Debouncer(500)
|
||||
private val recentEmojis: RecentEmojiPageModel by lazy { RecentEmojiPageModel(ApplicationDependencies.getApplication(), TextSecurePreferences.RECENT_STORAGE_KEY) }
|
||||
|
||||
private lateinit var layoutManager: LinearLayoutManager
|
||||
private lateinit var markReadHelper: MarkReadHelper
|
||||
|
@ -441,7 +464,7 @@ class ConversationFragment :
|
|||
container.fragmentManager = childFragmentManager
|
||||
|
||||
ToolbarDependentMarginListener(binding.toolbar)
|
||||
initializeMediaKeyboardToggle()
|
||||
initializeMediaKeyboard()
|
||||
}
|
||||
|
||||
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
||||
|
@ -506,6 +529,70 @@ class ConversationFragment :
|
|||
clearFocusedItem()
|
||||
}
|
||||
|
||||
override fun openEmojiSearch() {
|
||||
// TODO [cfv2] emoji search
|
||||
}
|
||||
|
||||
override fun onEmojiSelected(emoji: String?) {
|
||||
if (emoji != null) {
|
||||
inputPanel.onEmojiSelected(emoji)
|
||||
recentEmojis.onCodePointSelected(emoji)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onKeyEvent(keyEvent: KeyEvent?) {
|
||||
if (keyEvent != null) {
|
||||
inputPanel.onKeyEvent(keyEvent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun openStickerSearch() {
|
||||
StickerSearchDialogFragment.show(childFragmentManager)
|
||||
}
|
||||
|
||||
override fun onStickerSelected(sticker: StickerRecord) {
|
||||
sendSticker(
|
||||
stickerRecord = sticker,
|
||||
clearCompose = false
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStickerManagementClicked() {
|
||||
startActivity(StickerManagementActivity.getIntent(requireContext()))
|
||||
container.hideInput()
|
||||
}
|
||||
|
||||
override fun isMms(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun openGifSearch() {
|
||||
val recipientId = viewModel.recipientSnapshot?.id ?: return
|
||||
conversationActivityResultContracts.launchGifSearch(recipientId, composeText.textTrimmed)
|
||||
}
|
||||
|
||||
override fun onGifSelectSuccess(blobUri: Uri, width: Int, height: Int) {
|
||||
setMedia(
|
||||
uri = blobUri,
|
||||
mediaType = SlideFactory.MediaType.from(BlobProvider.getMimeType(blobUri))!!,
|
||||
width = width,
|
||||
height = height,
|
||||
videoGif = true
|
||||
)
|
||||
}
|
||||
|
||||
override fun onShown() {
|
||||
inputPanel.mediaKeyboardListener.onShown()
|
||||
}
|
||||
|
||||
override fun onHidden() {
|
||||
inputPanel.mediaKeyboardListener.onHidden()
|
||||
}
|
||||
|
||||
override fun onKeyboardChanged(page: KeyboardPage) {
|
||||
inputPanel.mediaKeyboardListener.onKeyboardChanged(page)
|
||||
}
|
||||
|
||||
private fun observeConversationThread() {
|
||||
var firstRender = true
|
||||
disposables += viewModel
|
||||
|
@ -1069,20 +1156,21 @@ class ConversationFragment :
|
|||
.addTo(disposables)
|
||||
}
|
||||
|
||||
private fun initializeMediaKeyboardToggle() {
|
||||
private fun initializeMediaKeyboard() {
|
||||
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) {
|
||||
val keyboardPage = 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)
|
||||
inputPanel.setMediaKeyboardToggleMode(keyboardPage)
|
||||
keyboardPagerViewModel.switchToPage(keyboardPage)
|
||||
|
||||
if (stickerIntro) {
|
||||
TextSecurePreferences.setMediaKeyboardMode(requireContext(), TextSecurePreferences.MediaKeyboardMode.STICKER)
|
||||
|
@ -1165,6 +1253,8 @@ class ConversationFragment :
|
|||
)
|
||||
|
||||
sendMessageWithoutComposeInput(slide, clearCompose = clearCompose)
|
||||
|
||||
viewModel.updateStickerLastUsedTime(stickerRecord, System.currentTimeMillis().milliseconds)
|
||||
}
|
||||
|
||||
private fun sendMessageWithoutComposeInput(
|
||||
|
@ -1199,7 +1289,7 @@ class ConversationFragment :
|
|||
preUploadResults: List<MessageSender.PreUploadResult> = emptyList(),
|
||||
afterSendComplete: () -> Unit = {}
|
||||
) {
|
||||
val metricId = viewModel.recipientSnapshot?.let { if (it.isGroup == true) SignalLocalMetrics.GroupMessageSend.start() else SignalLocalMetrics.IndividualMessageSend.start() }
|
||||
val metricId = viewModel.recipientSnapshot?.let { if (it.isGroup) SignalLocalMetrics.GroupMessageSend.start() else SignalLocalMetrics.IndividualMessageSend.start() }
|
||||
|
||||
val send: Completable = viewModel.sendMessage(
|
||||
metricId = metricId,
|
||||
|
@ -2511,7 +2601,11 @@ class ConversationFragment :
|
|||
)
|
||||
}
|
||||
|
||||
override fun onMediaSend(result: MediaSendActivityResult) {
|
||||
override fun onMediaSend(result: MediaSendActivityResult?) {
|
||||
if (result == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val recipientSnapshot = viewModel.recipientSnapshot
|
||||
if (result.recipientId != recipientSnapshot?.id) {
|
||||
Log.w(TAG, "Result's recipientId did not match ours! Result: " + result.recipientId + ", Ours: " + recipientSnapshot?.id)
|
||||
|
@ -2955,7 +3049,7 @@ class ConversationFragment :
|
|||
}
|
||||
|
||||
override fun onEmojiToggle() {
|
||||
// TODO [cfv2] Not yet implemented
|
||||
container.toggleInput(MediaKeyboardFragmentCreator, composeText, showSoftKeyOnHide = true)
|
||||
}
|
||||
|
||||
override fun onLinkPreviewCanceled() {
|
||||
|
@ -3032,6 +3126,11 @@ class ConversationFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private object MediaKeyboardFragmentCreator : InputAwareConstraintLayout.FragmentCreator {
|
||||
override val id: Int = 2
|
||||
override fun create(): Fragment = KeyboardPagerFragment()
|
||||
}
|
||||
|
||||
private inner class KeyboardEvents : OnBackPressedCallback(false), InputAwareConstraintLayout.Listener {
|
||||
override fun handleOnBackPressed() {
|
||||
container.hideInput()
|
||||
|
|
|
@ -68,6 +68,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord
|
|||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.Quote
|
||||
import org.thoughtcrime.securesms.database.model.ReactionRecord
|
||||
import org.thoughtcrime.securesms.database.model.StickerRecord
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceViewOnceOpenJob
|
||||
|
@ -102,6 +103,7 @@ import org.thoughtcrime.securesms.util.requireTextSlide
|
|||
import java.io.IOException
|
||||
import java.util.Optional
|
||||
import kotlin.math.max
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
class ConversationRepository(
|
||||
|
@ -225,7 +227,8 @@ class ConversationRepository(
|
|||
messageToEdit = messageToEdit?.id ?: 0,
|
||||
mentions = mentions,
|
||||
sharedContacts = contacts,
|
||||
linkPreviews = linkPreviews
|
||||
linkPreviews = linkPreviews,
|
||||
attachments = slideDeck?.asAttachments() ?: emptyList()
|
||||
)
|
||||
|
||||
if (preUploadResults.isEmpty()) {
|
||||
|
@ -551,6 +554,12 @@ class ConversationRepository(
|
|||
}
|
||||
}
|
||||
|
||||
fun updateStickerLastUsedTime(stickerRecord: StickerRecord, timestamp: Duration) {
|
||||
SignalExecutors.BOUNDED_IO.execute {
|
||||
SignalDatabase.stickers.updateStickerLastUsedTime(stickerRecord.rowId, timestamp.inWholeMilliseconds)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Glide target for a contact photo which expects an error drawable, and publishes
|
||||
* the result to the given emitter.
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord
|
|||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.Quote
|
||||
import org.thoughtcrime.securesms.database.model.ReactionRecord
|
||||
import org.thoughtcrime.securesms.database.model.StickerRecord
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.jobs.RetrieveProfileJob
|
||||
|
@ -62,6 +63,7 @@ import org.thoughtcrime.securesms.util.hasGiftBadge
|
|||
import org.thoughtcrime.securesms.util.rx.RxStore
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||
import java.util.Optional
|
||||
import kotlin.time.Duration
|
||||
|
||||
/**
|
||||
* ConversationViewModel, which operates solely off of a thread id that never changes.
|
||||
|
@ -362,4 +364,8 @@ class ConversationViewModel(
|
|||
fun deleteSlideData(slides: List<Slide>) {
|
||||
repository.deleteSlideData(slides)
|
||||
}
|
||||
|
||||
fun updateStickerLastUsedTime(stickerRecord: StickerRecord, timestamp: Duration) {
|
||||
repository.updateStickerLastUsedTime(stickerRecord, timestamp)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import androidx.core.os.bundleOf
|
|||
import androidx.fragment.app.setFragmentResult
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.signal.core.util.concurrent.LifecycleDisposable
|
||||
import org.signal.core.util.concurrent.addTo
|
||||
|
@ -62,6 +63,7 @@ class AttachmentKeyboardFragment : LoggingFragment(R.layout.attachment_keyboard_
|
|||
conversationViewModel = ViewModelProvider(requireParentFragment()).get(ConversationViewModel::class.java)
|
||||
conversationViewModel
|
||||
.recipient
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy {
|
||||
attachmentKeyboardView.setWallpaperEnabled(it.hasWallpaper())
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.view.ViewGroup
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.InputAwareConstraintLayout
|
||||
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard
|
||||
import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardPageFragment
|
||||
import org.thoughtcrime.securesms.keyboard.gif.GifKeyboardPageFragment
|
||||
|
@ -20,7 +21,7 @@ import org.thoughtcrime.securesms.util.fragments.findListener
|
|||
import org.thoughtcrime.securesms.util.visible
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class KeyboardPagerFragment : Fragment() {
|
||||
class KeyboardPagerFragment : Fragment(), InputAwareConstraintLayout.InputFragment {
|
||||
|
||||
private lateinit var emojiButton: View
|
||||
private lateinit var stickerButton: View
|
||||
|
@ -113,7 +114,8 @@ class KeyboardPagerFragment : Fragment() {
|
|||
transaction.commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
fun show() {
|
||||
override fun show() {
|
||||
findListener<MediaKeyboard.MediaKeyboardListener>()?.onShown()
|
||||
if (isAdded && view != null) {
|
||||
onHiddenChanged(false)
|
||||
|
||||
|
@ -121,7 +123,8 @@ class KeyboardPagerFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
fun hide() {
|
||||
override fun hide() {
|
||||
findListener<MediaKeyboard.MediaKeyboardListener>()?.onHidden()
|
||||
if (isAdded && view != null) {
|
||||
onHiddenChanged(true)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue