kopia lustrzana https://github.com/ryukoposting/Signal-Android
Fix various bugs with KitKat preventing stories from launching.
rodzic
a066271766
commit
e369f56eab
|
@ -3,15 +3,14 @@ package org.thoughtcrime.securesms.animation.transitions
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.transition.Transition
|
|
||||||
import android.transition.TransitionValues
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.transition.Transition
|
||||||
|
import androidx.transition.TransitionValues
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
|
||||||
@RequiresApi(21)
|
class FabElevationFadeTransform(context: Context, attrs: AttributeSet) : Transition(context, attrs) {
|
||||||
class FabElevationFadeTransform(context: Context, attrs: AttributeSet?) : Transition(context, attrs) {
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ELEVATION = "CrossfaderTransition.ELEVATION"
|
private const val ELEVATION = "CrossfaderTransition.ELEVATION"
|
||||||
|
@ -19,23 +18,23 @@ class FabElevationFadeTransform(context: Context, attrs: AttributeSet?) : Transi
|
||||||
|
|
||||||
override fun captureStartValues(transitionValues: TransitionValues) {
|
override fun captureStartValues(transitionValues: TransitionValues) {
|
||||||
if (transitionValues.view is FloatingActionButton) {
|
if (transitionValues.view is FloatingActionButton) {
|
||||||
transitionValues.values[ELEVATION] = transitionValues.view.elevation
|
transitionValues.values[ELEVATION] = ViewCompat.getElevation(transitionValues.view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun captureEndValues(transitionValues: TransitionValues) {
|
override fun captureEndValues(transitionValues: TransitionValues) {
|
||||||
if (transitionValues.view is FloatingActionButton) {
|
if (transitionValues.view is FloatingActionButton) {
|
||||||
transitionValues.values[ELEVATION] = transitionValues.view.elevation
|
transitionValues.values[ELEVATION] = ViewCompat.getElevation(transitionValues.view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createAnimator(sceneRoot: ViewGroup?, startValues: TransitionValues?, endValues: TransitionValues?): Animator? {
|
override fun createAnimator(sceneRoot: ViewGroup, startValues: TransitionValues?, endValues: TransitionValues?): Animator? {
|
||||||
if (startValues?.view !is FloatingActionButton || endValues?.view !is FloatingActionButton) {
|
if (startValues?.view !is FloatingActionButton || endValues?.view !is FloatingActionButton) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val startElevation = startValues.view.elevation
|
val startElevation = ViewCompat.getElevation(startValues.view)
|
||||||
val endElevation = endValues.view.elevation
|
val endElevation = ViewCompat.getElevation(endValues.view)
|
||||||
if (startElevation == endElevation) {
|
if (startElevation == endElevation) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -46,7 +45,7 @@ class FabElevationFadeTransform(context: Context, attrs: AttributeSet?) : Transi
|
||||||
).apply {
|
).apply {
|
||||||
addUpdateListener {
|
addUpdateListener {
|
||||||
val elevation = it.animatedValue as Float
|
val elevation = it.animatedValue as Float
|
||||||
endValues.view.elevation = elevation
|
ViewCompat.setElevation(endValues.view, elevation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.ActionMenuView
|
import androidx.appcompat.widget.ActionMenuView
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
|
@ -108,6 +109,9 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
||||||
val cameraFab = requireView().findViewById<View>(R.id.camera_fab)
|
val cameraFab = requireView().findViewById<View>(R.id.camera_fab)
|
||||||
val newConvoFab = requireView().findViewById<View>(R.id.fab)
|
val newConvoFab = requireView().findViewById<View>(R.id.fab)
|
||||||
|
|
||||||
|
ViewCompat.setTransitionName(cameraFab, "camera_fab")
|
||||||
|
ViewCompat.setTransitionName(newConvoFab, "new_convo_fab")
|
||||||
|
|
||||||
val extras: Navigator.Extras? = if (cameraFab == null || newConvoFab == null) {
|
val extras: Navigator.Extras? = if (cameraFab == null || newConvoFab == null) {
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.transition.TransitionInflater
|
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
@ -16,6 +15,7 @@ import androidx.core.app.SharedElementCallback
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.transition.TransitionInflater
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
|
@ -129,6 +129,10 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
||||||
lifecycleDisposable.bindTo(viewLifecycleOwner)
|
lifecycleDisposable.bindTo(viewLifecycleOwner)
|
||||||
emptyNotice = requireView().findViewById(R.id.empty_notice)
|
emptyNotice = requireView().findViewById(R.id.empty_notice)
|
||||||
cameraFab = requireView().findViewById(R.id.camera_fab)
|
cameraFab = requireView().findViewById(R.id.camera_fab)
|
||||||
|
val sharedElementTarget: View = requireView().findViewById(R.id.camera_fab_shared_element_target)
|
||||||
|
|
||||||
|
ViewCompat.setTransitionName(cameraFab, "new_convo_fab")
|
||||||
|
ViewCompat.setTransitionName(sharedElementTarget, "camera_fab")
|
||||||
|
|
||||||
sharedElementEnterTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.change_transform_fabs)
|
sharedElementEnterTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.change_transform_fabs)
|
||||||
setEnterSharedElementCallback(object : SharedElementCallback() {
|
setEnterSharedElementCallback(object : SharedElementCallback() {
|
||||||
|
@ -139,6 +143,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribeBy {
|
.subscribeBy {
|
||||||
cameraFab.setImageResource(R.drawable.ic_camera_outline_24)
|
cameraFab.setImageResource(R.drawable.ic_camera_outline_24)
|
||||||
|
sharedElementTarget.alpha = 0f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
import com.bumptech.glide.load.DataSource
|
import com.bumptech.glide.load.DataSource
|
||||||
import com.bumptech.glide.load.engine.GlideException
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
import com.bumptech.glide.request.RequestListener
|
import com.bumptech.glide.request.RequestListener
|
||||||
|
@ -116,6 +117,7 @@ object StoriesLandingItem {
|
||||||
private val badgeView: BadgeImageView = itemView.findViewById(R.id.badge)
|
private val badgeView: BadgeImageView = itemView.findViewById(R.id.badge)
|
||||||
private val storyPreview: ImageView = itemView.findViewById<ImageView>(R.id.story).apply {
|
private val storyPreview: ImageView = itemView.findViewById<ImageView>(R.id.story).apply {
|
||||||
isClickable = false
|
isClickable = false
|
||||||
|
ViewCompat.setTransitionName(this, "story")
|
||||||
}
|
}
|
||||||
private val storyBlur: ImageView = itemView.findViewById<ImageView>(R.id.story_blur).apply {
|
private val storyBlur: ImageView = itemView.findViewById<ImageView>(R.id.story_blur).apply {
|
||||||
isClickable = false
|
isClickable = false
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
|
@ -51,6 +52,7 @@ class StoryViewerFragment :
|
||||||
storyCrossfader = view.findViewById(R.id.story_content_crossfader)
|
storyCrossfader = view.findViewById(R.id.story_content_crossfader)
|
||||||
storyPager = view.findViewById(R.id.story_item_pager)
|
storyPager = view.findViewById(R.id.story_item_pager)
|
||||||
|
|
||||||
|
ViewCompat.setTransitionName(storyCrossfader, "story")
|
||||||
storyCrossfader.callback = this
|
storyCrossfader.callback = this
|
||||||
|
|
||||||
val adapter = StoryViewerPagerAdapter(
|
val adapter = StoryViewerPagerAdapter(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.stories.viewer
|
package org.thoughtcrime.securesms.stories.viewer
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
@ -30,7 +31,7 @@ class StoryViewerViewModel(
|
||||||
storyViewerArgs.storyThumbUri != null -> StoryViewerState.CrossfadeSource.ImageUri(storyViewerArgs.storyThumbUri, storyViewerArgs.storyThumbBlur)
|
storyViewerArgs.storyThumbUri != null -> StoryViewerState.CrossfadeSource.ImageUri(storyViewerArgs.storyThumbUri, storyViewerArgs.storyThumbBlur)
|
||||||
else -> StoryViewerState.CrossfadeSource.None
|
else -> StoryViewerState.CrossfadeSource.None
|
||||||
},
|
},
|
||||||
skipCrossfade = storyViewerArgs.isFromNotification || storyViewerArgs.isFromQuote
|
skipCrossfade = storyViewerArgs.isFromNotification || storyViewerArgs.isFromQuote || Build.VERSION.SDK_INT < 21
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import android.view.WindowManager
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.stories.StoryFirstTimeNavigationView
|
import org.thoughtcrime.securesms.stories.StoryFirstTimeNavigationView
|
||||||
|
@ -51,7 +52,7 @@ class StoryFirstTimeNavigationFragment : DialogFragment(R.layout.story_viewer_fi
|
||||||
view.callback = this
|
view.callback = this
|
||||||
viewModel.setIsDisplayingFirstTimeNavigation(true)
|
viewModel.setIsDisplayingFirstTimeNavigation(true)
|
||||||
|
|
||||||
disposables += viewModel.state.subscribe { state ->
|
disposables += viewModel.state.observeOn(AndroidSchedulers.mainThread()).subscribe { state ->
|
||||||
when (state.crossfadeSource) {
|
when (state.crossfadeSource) {
|
||||||
is StoryViewerState.CrossfadeSource.ImageUri -> {
|
is StoryViewerState.CrossfadeSource.ImageUri -> {
|
||||||
view.setBlurHash(state.crossfadeSource.imageBlur)
|
view.setBlurHash(state.crossfadeSource.imageBlur)
|
||||||
|
|
|
@ -7,6 +7,8 @@ import android.view.ViewGroup;
|
||||||
import androidx.annotation.LayoutRes;
|
import androidx.annotation.LayoutRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.signal.core.util.logging.Log;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
android:width="24dp"
|
<shape android:shape="oval" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
android:height="24dp"
|
<solid android:color="@color/signal_colorPrimary" />
|
||||||
android:viewportWidth="24"
|
<stroke android:color="@color/signal_colorOnPrimary" android:width="3dp" />
|
||||||
android:viewportHeight="24">
|
</shape>
|
||||||
<path
|
|
||||||
android:pathData="M12,12m-10.5,0a10.5,10.5 0,1 1,21 0a10.5,10.5 0,1 1,-21 0"
|
|
||||||
android:strokeWidth="3"
|
|
||||||
android:fillColor="@color/signal_colorPrimary"
|
|
||||||
android:strokeColor="@color/signal_colorBackground"/>
|
|
||||||
</vector>
|
|
Ładowanie…
Reference in New Issue