Fix crossfade target aspect ratio.
This commit is contained in:
parent
c3e7d6c74c
commit
2d60a88a75
16 changed files with 124 additions and 47 deletions
|
@ -1244,7 +1244,7 @@ public class ConversationParentFragment extends Fragment
|
|||
}
|
||||
|
||||
private void handleStoryRingClick() {
|
||||
startActivity(StoryViewerActivity.createIntent(requireContext(), recipient.getId(), -1L, recipient.get().shouldHideStory(), null, null));
|
||||
startActivity(StoryViewerActivity.createIntent(requireContext(), recipient.getId(), -1L, recipient.get().shouldHideStory(), null, null, null));
|
||||
}
|
||||
|
||||
private void handleConversationSettings() {
|
||||
|
|
|
@ -140,7 +140,7 @@ final class RecipientDialogViewModel extends ViewModel {
|
|||
if (storyViewState.getValue() == null || storyViewState.getValue() == StoryViewState.NONE) {
|
||||
onMessageClicked(activity);
|
||||
} else {
|
||||
activity.startActivity(StoryViewerActivity.createIntent(activity, recipientDialogRepository.getRecipientId(), -1L, recipient.getValue().shouldHideStory(), null, null));
|
||||
activity.startActivity(StoryViewerActivity.createIntent(activity, recipientDialogRepository.getRecipientId(), -1L, recipient.getValue().shouldHideStory(), null, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ final class RecipientDialogViewModel extends ViewModel {
|
|||
if (storyViewState.getValue() == null || storyViewState.getValue() == StoryViewState.NONE) {
|
||||
activity.startActivity(ConversationSettingsActivity.forRecipient(activity, recipientDialogRepository.getRecipientId()));
|
||||
} else {
|
||||
activity.startActivity(StoryViewerActivity.createIntent(activity, recipientDialogRepository.getRecipientId(), -1L, recipient.getValue().shouldHideStory(), null, null));
|
||||
activity.startActivity(StoryViewerActivity.createIntent(activity, recipientDialogRepository.getRecipientId(), -1L, recipient.getValue().shouldHideStory(), null, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package org.thoughtcrime.securesms.stories.landing
|
||||
|
||||
/**
|
||||
* Global Landing page payloads. Currently the only "pulse" we send out
|
||||
* to ViewHolders is RESUMED.
|
||||
*/
|
||||
enum class LandingPayload {
|
||||
/**
|
||||
* Notifies view holders when the fragment is resumed.
|
||||
*/
|
||||
RESUMED
|
||||
}
|
|
@ -33,10 +33,6 @@ object MyStoriesItem {
|
|||
private val badgeView: BadgeImageView = itemView.findViewById(R.id.badge)
|
||||
|
||||
override fun bind(model: Model) {
|
||||
if (payload.contains(LandingPayload.RESUMED)) {
|
||||
return
|
||||
}
|
||||
|
||||
itemView.setOnClickListener { model.onClick() }
|
||||
thumbnail.setOnClickListener { model.onClickThumbnail() }
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
adapter.notifyItemRangeChanged(0, adapter.itemCount, LandingPayload.RESUMED)
|
||||
viewModel.isTransitioningToAnotherScreen = false
|
||||
}
|
||||
|
||||
override fun bindAdapter(adapter: DSLSettingsAdapter) {
|
||||
|
@ -114,7 +114,9 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
.ifNecessary()
|
||||
.withRationaleDialog(getString(R.string.ConversationActivity_to_capture_photos_and_video_allow_signal_access_to_the_camera), R.drawable.ic_camera_24)
|
||||
.withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_needs_the_camera_permission_to_take_photos_or_video))
|
||||
.onAllGranted { startActivity(MediaSelectionActivity.camera(requireContext(), isStory = true)) }
|
||||
.onAllGranted {
|
||||
startActivityIfAble(MediaSelectionActivity.camera(requireContext(), isStory = true))
|
||||
}
|
||||
.onAnyDenied { Toast.makeText(requireContext(), R.string.ConversationActivity_signal_needs_camera_permissions_to_take_photos_or_video, Toast.LENGTH_LONG).show() }
|
||||
.execute()
|
||||
}
|
||||
|
@ -148,7 +150,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
customPref(
|
||||
MyStoriesItem.Model(
|
||||
onClick = {
|
||||
startActivity(Intent(requireContext(), MyStoriesActivity::class.java))
|
||||
startActivityIfAble(Intent(requireContext(), MyStoriesActivity::class.java))
|
||||
},
|
||||
onClickThumbnail = {
|
||||
cameraFab.performClick()
|
||||
|
@ -184,7 +186,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
data = data,
|
||||
onRowClick = { model, preview ->
|
||||
if (model.data.storyRecipient.isMyStory) {
|
||||
startActivity(Intent(requireContext(), MyStoriesActivity::class.java))
|
||||
startActivityIfAble(Intent(requireContext(), MyStoriesActivity::class.java))
|
||||
} else if (model.data.primaryStory.messageRecord.isOutgoing && model.data.primaryStory.messageRecord.isFailed) {
|
||||
if (model.data.primaryStory.messageRecord.isIdentityMismatchFailure) {
|
||||
SafetyNumberChangeDialog.show(requireContext(), childFragmentManager, model.data.primaryStory.messageRecord)
|
||||
|
@ -197,13 +199,14 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(requireActivity(), preview, ViewCompat.getTransitionName(preview) ?: "")
|
||||
|
||||
val record = model.data.primaryStory.messageRecord as MmsMessageRecord
|
||||
val blur = record.slideDeck.thumbnailSlide?.placeholderBlur
|
||||
val (text: StoryTextPostModel?, image: Uri?) = if (record.storyType.isTextStory) {
|
||||
StoryTextPostModel.parseFrom(record) to null
|
||||
} else {
|
||||
null to record.slideDeck.thumbnailSlide?.uri
|
||||
}
|
||||
|
||||
startActivity(StoryViewerActivity.createIntent(requireContext(), model.data.storyRecipient.id, -1L, model.data.isHidden, text, image), options.toBundle())
|
||||
startActivityIfAble(StoryViewerActivity.createIntent(requireContext(), model.data.storyRecipient.id, -1L, model.data.isHidden, text, image, blur), options.toBundle())
|
||||
}
|
||||
},
|
||||
onForwardStory = {
|
||||
|
@ -212,7 +215,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
}
|
||||
},
|
||||
onGoToChat = {
|
||||
startActivity(ConversationIntents.createBuilder(requireContext(), it.data.storyRecipient.id, -1L).build())
|
||||
startActivityIfAble(ConversationIntents.createBuilder(requireContext(), it.data.storyRecipient.id, -1L).build())
|
||||
},
|
||||
onHideStory = {
|
||||
if (!it.data.isHidden) {
|
||||
|
@ -256,7 +259,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return if (item.itemId == R.id.action_settings) {
|
||||
startActivity(StorySettingsActivity.getIntent(requireContext()))
|
||||
startActivityIfAble(StorySettingsActivity.getIntent(requireContext()))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -266,4 +269,13 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
private fun startActivityIfAble(intent: Intent, options: Bundle? = null) {
|
||||
if (viewModel.isTransitioningToAnotherScreen) {
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.isTransitioningToAnotherScreen = true
|
||||
startActivity(intent, options)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ object StoriesLandingItem {
|
|||
presentDateOrStatus(model)
|
||||
setUpClickListeners(model)
|
||||
|
||||
if (payload.contains(STATUS_CHANGE) || payload.contains(LandingPayload.RESUMED)) {
|
||||
if (payload.contains(STATUS_CHANGE)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -223,11 +223,6 @@ object StoriesLandingItem {
|
|||
|
||||
private fun setUpClickListeners(model: Model) {
|
||||
itemView.setOnClickListener {
|
||||
if (!itemView.isClickable) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
itemView.isClickable = false
|
||||
model.onRowClick(model, storyPreview)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ class StoriesLandingViewModel(private val storiesLandingRepository: StoriesLandi
|
|||
private val disposables = CompositeDisposable()
|
||||
|
||||
val state: LiveData<StoriesLandingState> = store.stateLiveData
|
||||
var isTransitioningToAnotherScreen: Boolean = false
|
||||
|
||||
init {
|
||||
disposables += storiesLandingRepository.getStories().subscribe { stories ->
|
||||
|
|
|
@ -93,6 +93,7 @@ class MyStoriesFragment : DSLSettingsFragment(
|
|||
}
|
||||
|
||||
val record = it.distributionStory.messageRecord as MmsMessageRecord
|
||||
val blur = record.slideDeck.thumbnailSlide?.placeholderBlur
|
||||
val (text: StoryTextPostModel?, image: Uri?) = if (record.storyType.isTextStory) {
|
||||
StoryTextPostModel.parseFrom(record) to null
|
||||
} else {
|
||||
|
@ -100,7 +101,7 @@ class MyStoriesFragment : DSLSettingsFragment(
|
|||
}
|
||||
|
||||
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(requireActivity(), preview, ViewCompat.getTransitionName(preview) ?: "")
|
||||
startActivity(StoryViewerActivity.createIntent(requireContext(), recipient.id, conversationMessage.messageRecord.id, recipient.shouldHideStory(), text, image), options.toBundle())
|
||||
startActivity(StoryViewerActivity.createIntent(requireContext(), recipient.id, conversationMessage.messageRecord.id, recipient.shouldHideStory(), text, image, blur), options.toBundle())
|
||||
}
|
||||
},
|
||||
onLongClick = {
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.os.Bundle
|
|||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaController
|
||||
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaControllerOwner
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
|
@ -39,7 +40,8 @@ class StoryViewerActivity : PassphraseRequiredActivity(), VoiceNoteMediaControll
|
|||
intent.getLongExtra(ARG_START_STORY_ID, -1L),
|
||||
intent.getBooleanExtra(ARG_HIDDEN_STORIES, false),
|
||||
intent.getParcelableExtra(ARG_CROSSFADE_TEXT_MODEL),
|
||||
intent.getParcelableExtra(ARG_CROSSFADE_IMAGE_URI)
|
||||
intent.getParcelableExtra(ARG_CROSSFADE_IMAGE_URI),
|
||||
intent.getStringExtra(ARG_CROSSFADE_IMAGE_BLUR)
|
||||
)
|
||||
)
|
||||
.commit()
|
||||
|
@ -58,6 +60,7 @@ class StoryViewerActivity : PassphraseRequiredActivity(), VoiceNoteMediaControll
|
|||
private const val ARG_HIDDEN_STORIES = "hidden_stories"
|
||||
private const val ARG_CROSSFADE_TEXT_MODEL = "crossfade.text.model"
|
||||
private const val ARG_CROSSFADE_IMAGE_URI = "crossfade.image.uri"
|
||||
private const val ARG_CROSSFADE_IMAGE_BLUR = "crossfade.image.blur"
|
||||
|
||||
@JvmStatic
|
||||
fun createIntent(
|
||||
|
@ -66,7 +69,8 @@ class StoryViewerActivity : PassphraseRequiredActivity(), VoiceNoteMediaControll
|
|||
storyId: Long = -1L,
|
||||
onlyIncludeHiddenStories: Boolean = false,
|
||||
storyThumbTextModel: StoryTextPostModel? = null,
|
||||
storyThumbUri: Uri? = null
|
||||
storyThumbUri: Uri? = null,
|
||||
storyThumbBlur: BlurHash? = null
|
||||
): Intent {
|
||||
return Intent(context, StoryViewerActivity::class.java)
|
||||
.putExtra(ARG_START_RECIPIENT_ID, recipientId)
|
||||
|
@ -74,6 +78,7 @@ class StoryViewerActivity : PassphraseRequiredActivity(), VoiceNoteMediaControll
|
|||
.putExtra(ARG_HIDDEN_STORIES, onlyIncludeHiddenStories)
|
||||
.putExtra(ARG_CROSSFADE_TEXT_MODEL, storyThumbTextModel)
|
||||
.putExtra(ARG_CROSSFADE_IMAGE_URI, storyThumbUri)
|
||||
.putExtra(ARG_CROSSFADE_IMAGE_BLUR, storyThumbBlur?.hash)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.fragment.app.viewModels
|
|||
import androidx.lifecycle.LiveDataReactiveStreams
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.stories.StoryTextPostModel
|
||||
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageFragment
|
||||
|
@ -23,7 +24,7 @@ class StoryViewerFragment : Fragment(R.layout.stories_viewer_fragment), StoryVie
|
|||
|
||||
private val viewModel: StoryViewerViewModel by viewModels(
|
||||
factoryProducer = {
|
||||
StoryViewerViewModel.Factory(storyRecipientId, onlyIncludeHiddenStories, storyThumbTextModel, storyThumbUri, StoryViewerRepository())
|
||||
StoryViewerViewModel.Factory(storyRecipientId, onlyIncludeHiddenStories, storyThumbTextModel, storyThumbUri, storuThumbBlur, StoryViewerRepository())
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -42,6 +43,9 @@ class StoryViewerFragment : Fragment(R.layout.stories_viewer_fragment), StoryVie
|
|||
private val storyThumbUri: Uri?
|
||||
get() = requireArguments().getParcelable(ARG_CROSSFADE_IMAGE_URI)
|
||||
|
||||
private val storuThumbBlur: BlurHash?
|
||||
get() = requireArguments().getString(ARG_CROSSFADE_IMAGE_BLUR)?.let { BlurHash.parseOrNull(it) }
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
storyPager = view.findViewById(R.id.story_item_pager)
|
||||
|
||||
|
@ -108,13 +112,15 @@ class StoryViewerFragment : Fragment(R.layout.stories_viewer_fragment), StoryVie
|
|||
private const val ARG_HIDDEN_STORIES = "hidden_stories"
|
||||
private const val ARG_CROSSFADE_TEXT_MODEL = "crossfade.text.model"
|
||||
private const val ARG_CROSSFADE_IMAGE_URI = "crossfade.image.uri"
|
||||
private const val ARG_CROSSFADE_IMAGE_BLUR = "crossfade.image.blur"
|
||||
|
||||
fun create(
|
||||
storyRecipientId: RecipientId,
|
||||
storyId: Long,
|
||||
onlyIncludeHiddenStories: Boolean,
|
||||
storyThumbTextModel: StoryTextPostModel? = null,
|
||||
storyThumbUri: Uri? = null
|
||||
storyThumbUri: Uri? = null,
|
||||
storyThumbBlur: String? = null
|
||||
): Fragment {
|
||||
return StoryViewerFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
|
@ -123,6 +129,7 @@ class StoryViewerFragment : Fragment(R.layout.stories_viewer_fragment), StoryVie
|
|||
putBoolean(ARG_HIDDEN_STORIES, onlyIncludeHiddenStories)
|
||||
putParcelable(ARG_CROSSFADE_TEXT_MODEL, storyThumbTextModel)
|
||||
putParcelable(ARG_CROSSFADE_IMAGE_URI, storyThumbUri)
|
||||
putString(ARG_CROSSFADE_IMAGE_BLUR, storyThumbBlur)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.thoughtcrime.securesms.stories.viewer
|
||||
|
||||
import android.net.Uri
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.stories.StoryTextPostModel
|
||||
|
||||
|
@ -13,7 +14,7 @@ data class StoryViewerState(
|
|||
) {
|
||||
sealed class CrossfadeSource {
|
||||
object None : CrossfadeSource()
|
||||
class ImageUri(val imageUri: Uri) : CrossfadeSource()
|
||||
class ImageUri(val imageUri: Uri, val imageBlur: BlurHash?) : CrossfadeSource()
|
||||
class TextModel(val storyTextPostModel: StoryTextPostModel) : CrossfadeSource()
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.stories.StoryTextPostModel
|
||||
import org.thoughtcrime.securesms.util.rx.RxStore
|
||||
|
@ -18,6 +19,7 @@ class StoryViewerViewModel(
|
|||
private val onlyIncludeHiddenStories: Boolean,
|
||||
storyThumbTextModel: StoryTextPostModel?,
|
||||
storyThumbUri: Uri?,
|
||||
storyThumbBlur: BlurHash?,
|
||||
private val repository: StoryViewerRepository,
|
||||
) : ViewModel() {
|
||||
|
||||
|
@ -25,7 +27,7 @@ class StoryViewerViewModel(
|
|||
StoryViewerState(
|
||||
crossfadeSource = when {
|
||||
storyThumbTextModel != null -> StoryViewerState.CrossfadeSource.TextModel(storyThumbTextModel)
|
||||
storyThumbUri != null -> StoryViewerState.CrossfadeSource.ImageUri(storyThumbUri)
|
||||
storyThumbUri != null -> StoryViewerState.CrossfadeSource.ImageUri(storyThumbUri, storyThumbBlur)
|
||||
else -> StoryViewerState.CrossfadeSource.None
|
||||
}
|
||||
)
|
||||
|
@ -154,10 +156,11 @@ class StoryViewerViewModel(
|
|||
private val onlyIncludeHiddenStories: Boolean,
|
||||
private val storyThumbTextModel: StoryTextPostModel?,
|
||||
private val storyThumbUri: Uri?,
|
||||
private val storyThumbBlur: BlurHash?,
|
||||
private val repository: StoryViewerRepository
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return modelClass.cast(StoryViewerViewModel(startRecipientId, onlyIncludeHiddenStories, storyThumbTextModel, storyThumbUri, repository)) as T
|
||||
return modelClass.cast(StoryViewerViewModel(startRecipientId, onlyIncludeHiddenStories, storyThumbTextModel, storyThumbUri, storyThumbBlur, repository)) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -260,7 +260,7 @@ class StoryViewerPageFragment :
|
|||
viewModel.setIsSelectedPage(true)
|
||||
when (parentState.crossfadeSource) {
|
||||
is StoryViewerState.CrossfadeSource.TextModel -> storyCrossfader.setSourceView(parentState.crossfadeSource.storyTextPostModel)
|
||||
is StoryViewerState.CrossfadeSource.ImageUri -> storyCrossfader.setSourceView(parentState.crossfadeSource.imageUri)
|
||||
is StoryViewerState.CrossfadeSource.ImageUri -> storyCrossfader.setSourceView(parentState.crossfadeSource.imageUri, parentState.crossfadeSource.imageBlur)
|
||||
else -> onReadyToAnimate()
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.bumptech.glide.request.target.Target
|
|||
import org.signal.core.util.DimensionUnit
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.animation.transitions.CrossfaderTransition
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
|
@ -35,10 +36,14 @@ class StoriesSharedElementCrossFaderView @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
private val sourceView: ImageView = findViewById(R.id.source_image)
|
||||
private val sourceBlurView: ImageView = findViewById(R.id.source_image_blur)
|
||||
private val targetView: ImageView = findViewById(R.id.target_image)
|
||||
private val targetBlurView: ImageView = findViewById(R.id.target_image_blur)
|
||||
|
||||
private var isSourceReady: Boolean = false
|
||||
private var isSourceBlurReady: Boolean = false
|
||||
private var isTargetReady: Boolean = false
|
||||
private var isTargetBlurReady: Boolean = false
|
||||
|
||||
private var latestSource: Any? = null
|
||||
private var latestTarget: Any? = null
|
||||
|
@ -64,9 +69,12 @@ class StoriesSharedElementCrossFaderView @JvmOverloads constructor(
|
|||
.dontAnimate()
|
||||
.centerCrop()
|
||||
.into(sourceView)
|
||||
|
||||
GlideApp.with(sourceBlurView).clear(sourceBlurView)
|
||||
isSourceBlurReady = true
|
||||
}
|
||||
|
||||
fun setSourceView(uri: Uri) {
|
||||
fun setSourceView(uri: Uri, blur: BlurHash?) {
|
||||
if (latestSource == uri) {
|
||||
return
|
||||
}
|
||||
|
@ -84,13 +92,31 @@ class StoriesSharedElementCrossFaderView @JvmOverloads constructor(
|
|||
.dontAnimate()
|
||||
.centerCrop()
|
||||
.into(sourceView)
|
||||
|
||||
if (blur == null) {
|
||||
GlideApp.with(sourceBlurView).clear(sourceBlurView)
|
||||
isSourceBlurReady = true
|
||||
} else {
|
||||
GlideApp.with(sourceBlurView)
|
||||
.load(blur)
|
||||
.addListener(
|
||||
OnReadyListener {
|
||||
isSourceBlurReady = true
|
||||
notifyIfReady()
|
||||
}
|
||||
)
|
||||
.dontAnimate()
|
||||
.centerCrop()
|
||||
.into(sourceBlurView)
|
||||
}
|
||||
}
|
||||
|
||||
fun setTargetView(messageRecord: MmsMessageRecord): Boolean {
|
||||
val thumbUri = messageRecord.slideDeck.thumbnailSlide?.uri
|
||||
val thumbBlur: BlurHash? = messageRecord.slideDeck.thumbnailSlide?.placeholderBlur
|
||||
when {
|
||||
messageRecord.storyType.isTextStory -> setTargetView(StoryTextPostModel.parseFrom(messageRecord))
|
||||
thumbUri != null -> setTargetView(thumbUri)
|
||||
thumbUri != null -> setTargetView(thumbUri, thumbBlur)
|
||||
else -> return false
|
||||
}
|
||||
|
||||
|
@ -116,9 +142,12 @@ class StoriesSharedElementCrossFaderView @JvmOverloads constructor(
|
|||
.placeholder(storyTextPostModel.getPlaceholder())
|
||||
.centerCrop()
|
||||
.into(targetView)
|
||||
|
||||
GlideApp.with(sourceBlurView).clear(sourceBlurView)
|
||||
isTargetBlurReady = true
|
||||
}
|
||||
|
||||
private fun setTargetView(uri: Uri) {
|
||||
private fun setTargetView(uri: Uri, blur: BlurHash?) {
|
||||
if (latestTarget == uri) {
|
||||
return
|
||||
}
|
||||
|
@ -134,12 +163,29 @@ class StoriesSharedElementCrossFaderView @JvmOverloads constructor(
|
|||
}
|
||||
)
|
||||
.dontAnimate()
|
||||
.centerCrop()
|
||||
.fitCenter()
|
||||
.into(targetView)
|
||||
|
||||
if (blur == null) {
|
||||
GlideApp.with(targetBlurView).clear(targetBlurView)
|
||||
isTargetBlurReady = true
|
||||
} else {
|
||||
GlideApp.with(targetBlurView)
|
||||
.load(blur)
|
||||
.addListener(
|
||||
OnReadyListener {
|
||||
isTargetBlurReady = true
|
||||
notifyIfReady()
|
||||
}
|
||||
)
|
||||
.dontAnimate()
|
||||
.centerCrop()
|
||||
.into(targetBlurView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyIfReady() {
|
||||
if (isSourceReady && isTargetReady) {
|
||||
if (isSourceReady && isTargetReady && isSourceBlurReady && isTargetBlurReady) {
|
||||
callback?.onReadyToAnimate()
|
||||
}
|
||||
}
|
||||
|
@ -159,11 +205,15 @@ class StoriesSharedElementCrossFaderView @JvmOverloads constructor(
|
|||
override fun onCrossfadeAnimationUpdated(progress: Float, reverse: Boolean) {
|
||||
if (reverse) {
|
||||
sourceView.alpha = progress
|
||||
sourceBlurView.alpha = progress
|
||||
targetView.alpha = 1f - progress
|
||||
targetBlurView.alpha = 1f - progress
|
||||
radius = CORNER_RADIUS_EVALUATOR.evaluate(progress, CORNER_RADIUS_END, CORNER_RADIUS_START)
|
||||
} else {
|
||||
sourceView.alpha = 1f - progress
|
||||
sourceBlurView.alpha = 1f - progress
|
||||
targetView.alpha = progress
|
||||
targetBlurView.alpha = progress
|
||||
radius = CORNER_RADIUS_EVALUATOR.evaluate(progress, CORNER_RADIUS_START, CORNER_RADIUS_END)
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +222,9 @@ class StoriesSharedElementCrossFaderView @JvmOverloads constructor(
|
|||
alpha = 1f
|
||||
|
||||
sourceView.alpha = if (reverse) 0f else 1f
|
||||
sourceBlurView.alpha = if (reverse) 0f else 1f
|
||||
targetView.alpha = if (reverse) 1f else 0f
|
||||
targetBlurView.alpha = if (reverse) 1f else 0f
|
||||
|
||||
radius = if (reverse) CORNER_RADIUS_END else CORNER_RADIUS_START
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
android:focusable="true"
|
||||
android:theme="@style/Widget.Material3.FloatingActionButton.Secondary"
|
||||
android:transitionName="camera_fab"
|
||||
app:elevation="0dp"
|
||||
app:backgroundTint="@color/signal_colorSecondaryContainer"
|
||||
app:elevation="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/ic_camera_outline_24"
|
||||
|
|
|
@ -12,6 +12,15 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/source_image_blur"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintDimensionRatio="48:72"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/source_image"
|
||||
android:layout_width="0dp"
|
||||
|
@ -21,6 +30,13 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/target_image_blur"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:alpha="0"
|
||||
android:importantForAccessibility="no" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/target_image"
|
||||
android:layout_width="match_parent"
|
||||
|
|
Loading…
Add table
Reference in a new issue