diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index e565394551..71baceb36d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -190,6 +190,7 @@ import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult import org.thoughtcrime.securesms.invites.InviteActions import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.linkpreview.LinkPreview +import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModelV2 import org.thoughtcrime.securesms.longmessage.LongMessageFragment import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory @@ -302,6 +303,12 @@ class ConversationFragment : ) } + private val linkPreviewViewModel: LinkPreviewViewModelV2 by viewModel { + LinkPreviewViewModelV2( + enablePlaceholder = false + ) + } + private val groupCallViewModel: ConversationGroupCallViewModel by viewModels( factoryProducer = { ConversationGroupCallViewModel.Factory(args.threadId, conversationRecipientRepository) @@ -668,6 +675,7 @@ class ConversationFragment : .addTo(disposables) initializeSearch() + initializeLinkPreviews() inputPanel.setListener(InputPanelListener()) } @@ -1031,6 +1039,32 @@ class ConversationFragment : } } + private fun initializeLinkPreviews() { + linkPreviewViewModel.linkPreviewState + .observeOn(AndroidSchedulers.mainThread()) + .subscribeBy { state -> + if (state.isLoading) { + inputPanel.setLinkPreviewLoading() + } else if (state.hasLinks() && !state.linkPreview.isPresent) { + inputPanel.setLinkPreviewNoPreview(state.error) + } else { + inputPanel.setLinkPreview(GlideApp.with(this), state.linkPreview) + } + + updateToggleButtonState() + } + .addTo(disposables) + } + + private fun updateLinkPreviewState() { + if (/* TODO [cfv2] -- viewModel.isPushAvailable && */ !attachmentManager.isAttachmentPresent && context != null) { + linkPreviewViewModel.onEnabled() + linkPreviewViewModel.onTextChanged(composeText.textTrimmed.toString(), composeText.selectionStart, composeText.selectionEnd) + } else { + linkPreviewViewModel.onUserCancel() + } + } + private fun updateToggleButtonState() { val buttonToggle: AnimatingToggle = binding.conversationInputPanel.buttonToggle val quickAttachment: HidingLinearLayout = binding.conversationInputPanel.quickAttachmentToggle @@ -1065,7 +1099,7 @@ class ConversationFragment : buttonToggle.display(sendButton) quickAttachment.hide() - if (!attachmentManager.isAttachmentPresent) { // todo [cfv2] && !linkPreviewViewModel.hasLinkPreviewUi()) { + if (!attachmentManager.isAttachmentPresent && !linkPreviewViewModel.hasLinkPreviewUi) { inlineAttachment.show() } else { inlineAttachment.hide() @@ -1103,7 +1137,8 @@ class ConversationFragment : mentions = emptyList(), bodyRanges = null, messageToEdit = null, - quote = null + quote = null, + linkPreviews = emptyList() ) } @@ -1116,7 +1151,8 @@ class ConversationFragment : scheduledDate: Long = -1, slideDeck: SlideDeck? = if (attachmentManager.isAttachmentPresent) attachmentManager.buildSlideDeck() else null, contacts: List = emptyList(), - clearCompose: Boolean = true + clearCompose: Boolean = true, + linkPreviews: List = linkPreviewViewModel.onSend() ) { val metricId = viewModel.recipientSnapshot?.let { if (it.isGroup == true) SignalLocalMetrics.GroupMessageSend.start() else SignalLocalMetrics.IndividualMessageSend.start() } @@ -1129,7 +1165,8 @@ class ConversationFragment : quote = quote, mentions = mentions, bodyRanges = bodyRanges, - contacts = contacts + contacts = contacts, + linkPreviews = linkPreviews ) disposables += send @@ -1164,7 +1201,7 @@ class ConversationFragment : scrollToPositionDelegate.resetScrollPosition() attachmentManager.cleanup() - // todo [cfv2] updateLinkPreviewState(); + updateLinkPreviewState() draftViewModel.onSendComplete() @@ -2712,7 +2749,7 @@ class ConversationFragment : } override fun onCursorPositionChanged(start: Int, end: Int) { - // todo [cfv2] linkPreviewViewModel.onTextChanged(requireContext(), composeText.getTextTrimmed().toString(), start, end); + linkPreviewViewModel.onTextChanged(composeText.textTrimmed.toString(), start, end) } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { @@ -2809,7 +2846,7 @@ class ConversationFragment : } override fun onLinkPreviewCanceled() { - // TODO [cfv2] Not yet implemented + linkPreviewViewModel.onUserCancel() } override fun onStickerSuggestionSelected(sticker: StickerRecord) { @@ -2845,7 +2882,9 @@ class ConversationFragment : private inner class AttachmentManagerListener : AttachmentManager.AttachmentListener { override fun onAttachmentChanged() { - // TODO [cfv2] implement + // TODO [cfv2] handleSecurityChange(viewModel.getConversationStateSnapshot().getSecurityInfo()); + updateToggleButtonState() + updateLinkPreviewState() } override fun onLocationRemoved() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt index 01a1311bf0..9b8304f408 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt @@ -72,6 +72,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobs.MultiDeviceViewOnceOpenJob import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.linkpreview.LinkPreview import org.thoughtcrime.securesms.messagerequests.MessageRequestState import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.mms.OutgoingMessage @@ -193,7 +194,8 @@ class ConversationRepository( quote: QuoteModel?, mentions: List, bodyRanges: BodyRangeList?, - contacts: List + contacts: List, + linkPreviews: List ): Completable { val sendCompletable = Completable.create { emitter -> if (body.isEmpty() && slideDeck?.containsMediaSlide() != true) { @@ -218,7 +220,8 @@ class ConversationRepository( outgoingQuote = quote, messageToEdit = messageToEdit?.id ?: 0, mentions = mentions, - sharedContacts = contacts + sharedContacts = contacts, + linkPreviews = linkPreviews ) MessageSender.send( diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index ef1079ea34..624f8ac61b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobs.RetrieveProfileJob import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.linkpreview.LinkPreview import org.thoughtcrime.securesms.messagerequests.MessageRequestRepository import org.thoughtcrime.securesms.messagerequests.MessageRequestState import org.thoughtcrime.securesms.mms.GlideRequests @@ -297,7 +298,8 @@ class ConversationViewModel( quote: QuoteModel?, mentions: List, bodyRanges: BodyRangeList?, - contacts: List + contacts: List, + linkPreviews: List ): Completable { return repository.sendMessage( threadId = threadId, @@ -310,7 +312,8 @@ class ConversationViewModel( quote = quote, mentions = mentions, bodyRanges = bodyRanges, - contacts = contacts + contacts = contacts, + linkPreviews = linkPreviews ).observeOn(AndroidSchedulers.mainThread()) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java index 30fdc2c5fd..4f0de26812 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -12,6 +12,7 @@ import androidx.core.util.Consumer; import com.bumptech.glide.load.engine.DiskCacheStrategy; import org.signal.core.util.Hex; +import org.signal.core.util.Result; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.signal.libsignal.protocol.InvalidMessageException; @@ -62,6 +63,8 @@ import java.io.InputStream; import java.util.Optional; import java.util.concurrent.ExecutionException; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.schedulers.Schedulers; import okhttp3.CacheControl; import okhttp3.Call; import okhttp3.OkHttpClient; @@ -86,6 +89,28 @@ public class LinkPreviewRepository { .build(); } + public @NonNull Single> getLinkPreview(@NonNull String url) { + return Single.>create(emitter -> { + RequestController controller = getLinkPreview(ApplicationDependencies.getApplication(), + url, + new Callback() { + @Override + public void onSuccess(@NonNull LinkPreview linkPreview) { + emitter.onSuccess(Result.success(linkPreview)); + } + + @Override + public void onError(@NonNull Error error) { + emitter.onSuccess(Result.failure(error)); + } + }); + + if (controller != null) { + emitter.setCancellable(controller::cancel); + } + }).subscribeOn(Schedulers.io()); + } + @Nullable RequestController getLinkPreview(@NonNull Context context, @NonNull String url, @NonNull Callback callback) diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewState.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewState.java new file mode 100644 index 0000000000..86f7bd0feb --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewState.java @@ -0,0 +1,72 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.linkpreview; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Optional; + +public class LinkPreviewState { + private final String activeUrlForError; + private final boolean isLoading; + private final boolean hasLinks; + private final Optional linkPreview; + private final LinkPreviewRepository.Error error; + + private LinkPreviewState(@Nullable String activeUrlForError, + boolean isLoading, + boolean hasLinks, + Optional linkPreview, + @Nullable LinkPreviewRepository.Error error) + { + this.activeUrlForError = activeUrlForError; + this.isLoading = isLoading; + this.hasLinks = hasLinks; + this.linkPreview = linkPreview; + this.error = error; + } + + public static LinkPreviewState forLoading() { + return new LinkPreviewState(null, true, false, Optional.empty(), null); + } + + public static LinkPreviewState forPreview(@NonNull LinkPreview linkPreview) { + return new LinkPreviewState(null, false, true, Optional.of(linkPreview), null); + } + + public static LinkPreviewState forLinksWithNoPreview(@Nullable String activeUrlForError, @NonNull LinkPreviewRepository.Error error) { + return new LinkPreviewState(activeUrlForError, false, true, Optional.empty(), error); + } + + public static LinkPreviewState forNoLinks() { + return new LinkPreviewState(null, false, false, Optional.empty(), null); + } + + public @Nullable String getActiveUrlForError() { + return activeUrlForError; + } + + public boolean isLoading() { + return isLoading; + } + + public boolean hasLinks() { + return hasLinks; + } + + public Optional getLinkPreview() { + return linkPreview; + } + + public @Nullable LinkPreviewRepository.Error getError() { + return error; + } + + public boolean hasContent() { + return isLoading || hasLinks; + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java index 9b710102c5..4b8d3c84c6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java @@ -255,7 +255,7 @@ public class LinkPreviewViewModel extends ViewModel { } if (enablePlaceholder) { - return state.linkPreview + return state.getLinkPreview() .map(linkPreview -> LinkPreviewState.forLinksWithNoPreview(linkPreview.getUrl(), LinkPreviewRepository.Error.PREVIEW_NOT_AVAILABLE)) .orElse(state); } @@ -263,67 +263,6 @@ public class LinkPreviewViewModel extends ViewModel { return LinkPreviewState.forNoLinks(); } - public static class LinkPreviewState { - private final String activeUrlForError; - private final boolean isLoading; - private final boolean hasLinks; - private final Optional linkPreview; - private final LinkPreviewRepository.Error error; - - private LinkPreviewState(@Nullable String activeUrlForError, - boolean isLoading, - boolean hasLinks, - Optional linkPreview, - @Nullable LinkPreviewRepository.Error error) - { - this.activeUrlForError = activeUrlForError; - this.isLoading = isLoading; - this.hasLinks = hasLinks; - this.linkPreview = linkPreview; - this.error = error; - } - - private static LinkPreviewState forLoading() { - return new LinkPreviewState(null, true, false, Optional.empty(), null); - } - - private static LinkPreviewState forPreview(@NonNull LinkPreview linkPreview) { - return new LinkPreviewState(null, false, true, Optional.of(linkPreview), null); - } - - private static LinkPreviewState forLinksWithNoPreview(@Nullable String activeUrlForError, @NonNull LinkPreviewRepository.Error error) { - return new LinkPreviewState(activeUrlForError, false, true, Optional.empty(), error); - } - - private static LinkPreviewState forNoLinks() { - return new LinkPreviewState(null, false, false, Optional.empty(), null); - } - - public @Nullable String getActiveUrlForError() { - return activeUrlForError; - } - - public boolean isLoading() { - return isLoading; - } - - public boolean hasLinks() { - return hasLinks; - } - - public Optional getLinkPreview() { - return linkPreview; - } - - public @Nullable LinkPreviewRepository.Error getError() { - return error; - } - - boolean hasContent() { - return isLoading || hasLinks; - } - } - public static class Factory extends ViewModelProvider.NewInstanceFactory { private final LinkPreviewRepository repository; diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModelV2.kt b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModelV2.kt new file mode 100644 index 0000000000..13fca726a4 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModelV2.kt @@ -0,0 +1,161 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.linkpreview + +import androidx.lifecycle.ViewModel +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.core.Single +import io.reactivex.rxjava3.disposables.Disposable +import io.reactivex.rxjava3.kotlin.subscribeBy +import org.signal.core.util.Result +import org.signal.core.util.isAbsent +import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.util.Debouncer +import org.thoughtcrime.securesms.util.rx.RxStore +import java.util.Optional + +/** + * Rewrite of [LinkPreviewViewModel] preferring Rx and Kotlin + */ +class LinkPreviewViewModelV2( + private val linkPreviewRepository: LinkPreviewRepository = LinkPreviewRepository(), + private val enablePlaceholder: Boolean +) : ViewModel() { + private var enabled = SignalStore.settings().isLinkPreviewsEnabled + private val linkPreviewStateStore = RxStore(LinkPreviewState.forNoLinks()) + + val linkPreviewState: Flowable = linkPreviewStateStore.stateFlowable + val hasLinkPreview: Boolean = linkPreviewStateStore.state.linkPreview.isPresent + val hasLinkPreviewUi: Boolean = linkPreviewStateStore.state.hasContent() + + private var activeUrl: String? = null + private var activeRequest: Disposable = Disposable.disposed() + private var userCancelled: Boolean = false + private val debouncer: Debouncer = Debouncer(250) + + override fun onCleared() { + activeRequest.dispose() + debouncer.clear() + } + + fun onSend(): List { + val currentState = linkPreviewStateStore.state + + onUserCancel() + + return currentState.linkPreview.map { listOf(it) }.orElse(emptyList()) + } + + fun onTextChanged(text: String, cursorStart: Int, cursorEnd: Int) { + if (!enabled && !enablePlaceholder) { + return + } + + debouncer.publish { + if (text.isEmpty()) { + userCancelled = false + } + + if (userCancelled) { + return@publish + } + + val link: Optional = LinkPreviewUtil.findValidPreviewUrls(text).findFirst() + + activeRequest.dispose() + + if (link.isAbsent() || !isCursorPositionValid(text, link.get(), cursorStart, cursorEnd)) { + activeUrl = null + setLinkPreviewState(LinkPreviewState.forNoLinks()) + return@publish + } + + setLinkPreviewState(LinkPreviewState.forLoading()) + + val activeUrl = link.get().url + this.activeUrl = activeUrl + activeRequest = if (enabled) { + performRequest(activeUrl) + } else { + createPlaceholder(activeUrl) + } + } + } + + fun onEnabled() { + userCancelled = false + enabled = SignalStore.settings().isLinkPreviewsEnabled + } + + fun onUserCancel() { + activeRequest.dispose() + userCancelled = true + activeUrl = null + debouncer.clear() + setLinkPreviewState(LinkPreviewState.forNoLinks()) + } + + private fun isCursorPositionValid(text: String, link: Link, cursorStart: Int, cursorEnd: Int): Boolean { + if (cursorStart != cursorEnd) { + return true + } + + if (text.endsWith(link.url) && cursorStart == link.position + link.url.length) { + return true + } + + return cursorStart < link.position || cursorStart > link.position + link.url.length + } + + private fun createPlaceholder(url: String): Disposable { + return Single.just(url) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeBy { + if (!userCancelled) { + if (activeUrl != null && activeUrl == url) { + setLinkPreviewState(LinkPreviewState.forLinksWithNoPreview(url, LinkPreviewRepository.Error.PREVIEW_NOT_AVAILABLE)) + } else { + setLinkPreviewState(LinkPreviewState.forNoLinks()) + } + } + } + } + + private fun performRequest(url: String): Disposable { + return linkPreviewRepository.getLinkPreview(url) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeBy { result -> + if (!userCancelled) { + val linkPreviewState = when (result) { + is Result.Success -> if (activeUrl == result.success.url) LinkPreviewState.forPreview(result.success) else LinkPreviewState.forNoLinks() + is Result.Failure -> if (activeUrl != null) LinkPreviewState.forLinksWithNoPreview(activeUrl, result.failure) else LinkPreviewState.forNoLinks() + } + + setLinkPreviewState(linkPreviewState) + } + } + } + + private fun setLinkPreviewState(linkPreviewState: LinkPreviewState) { + linkPreviewStateStore.update { cleanseState(linkPreviewState) } + } + + private fun cleanseState(linkPreviewState: LinkPreviewState): LinkPreviewState { + if (enabled) { + return linkPreviewState + } + + if (enablePlaceholder) { + return linkPreviewState + .linkPreview + .map { LinkPreviewState.forLinksWithNoPreview(it.url, LinkPreviewRepository.Error.PREVIEW_NOT_AVAILABLE) } + .orElse(linkPreviewState) + } + + return LinkPreviewState.forNoLinks() + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostCreationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostCreationFragment.kt index 470826f784..fb6486de04 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostCreationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostCreationFragment.kt @@ -21,8 +21,8 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor import org.thoughtcrime.securesms.databinding.StoriesTextPostCreationFragmentBinding import org.thoughtcrime.securesms.linkpreview.LinkPreview import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository +import org.thoughtcrime.securesms.linkpreview.LinkPreviewState import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel -import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState import org.thoughtcrime.securesms.mediasend.CameraDisplay import org.thoughtcrime.securesms.mediasend.v2.HudCommand import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionViewModel diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/StoryLinkPreviewView.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/StoryLinkPreviewView.kt index eaddcd2645..aea93c29eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/StoryLinkPreviewView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/StoryLinkPreviewView.kt @@ -12,8 +12,8 @@ import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.ThumbnailView import org.thoughtcrime.securesms.databinding.StoriesTextPostLinkPreviewBinding import org.thoughtcrime.securesms.linkpreview.LinkPreview +import org.thoughtcrime.securesms.linkpreview.LinkPreviewState import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil -import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel import org.thoughtcrime.securesms.mms.GlideApp import org.thoughtcrime.securesms.mms.ImageSlide import org.thoughtcrime.securesms.mms.Slide @@ -73,7 +73,7 @@ class StoryLinkPreviewView @JvmOverloads constructor( return future ?: SettableFuture(false) } - fun bind(linkPreviewState: LinkPreviewViewModel.LinkPreviewState, hiddenVisibility: Int = View.INVISIBLE, useLargeThumbnail: Boolean) { + fun bind(linkPreviewState: LinkPreviewState, hiddenVisibility: Int = View.INVISIBLE, useLargeThumbnail: Boolean) { val linkPreview: LinkPreview? = linkPreviewState.linkPreview.orElseGet { linkPreviewState.activeUrlForError?.let { LinkPreview(it, LinkPreviewUtil.getTopLevelDomain(it) ?: it, null, -1L, null) diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/StoryTextPostView.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/StoryTextPostView.kt index 5839084a7b..f605e23bea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/StoryTextPostView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/StoryTextPostView.kt @@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost import org.thoughtcrime.securesms.fonts.TextFont import org.thoughtcrime.securesms.linkpreview.LinkPreview -import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel +import org.thoughtcrime.securesms.linkpreview.LinkPreviewState import org.thoughtcrime.securesms.mediasend.v2.text.TextStoryPostCreationState import org.thoughtcrime.securesms.mediasend.v2.text.TextStoryScale import org.thoughtcrime.securesms.mediasend.v2.text.TextStoryTextWatcher @@ -157,7 +157,7 @@ class StoryTextPostView @JvmOverloads constructor( linkPreviewView.setThumbnailDrawable(drawable, useLargeThumbnail) } - fun bindLinkPreviewState(linkPreviewState: LinkPreviewViewModel.LinkPreviewState, hiddenVisibility: Int, useLargeThumbnail: Boolean) { + fun bindLinkPreviewState(linkPreviewState: LinkPreviewState, hiddenVisibility: Int, useLargeThumbnail: Boolean) { linkPreviewView.bind(linkPreviewState, hiddenVisibility, useLargeThumbnail) }