Design and animation updates for Media Preview.

main
Nicholas 2022-10-27 10:54:14 -04:00 zatwierdzone przez GitHub
rodzic 8e1ec5ab5b
commit d003dc435a
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
13 zmienionych plików z 169 dodań i 44 usunięć

Wyświetl plik

@ -1,13 +1,24 @@
package org.thoughtcrime.securesms.mediapreview
import android.animation.Animator
import android.animation.Animator.AnimatorListener
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieProperty
import com.airbnb.lottie.model.KeyPath
import com.google.android.exoplayer2.ui.PlayerControlView
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.util.MediaUtil
import kotlin.time.DurationUnit
import kotlin.time.toDuration
/**
* The bottom bar for the media preview. This includes the standard seek bar as well as playback controls,
@ -23,6 +34,7 @@ class MediaPreviewPlayerControlView @JvmOverloads constructor(
val recyclerView: RecyclerView = findViewById(R.id.media_preview_album_rail)
private val durationBar: LinearLayout = findViewById(R.id.exo_duration_viewgroup)
private val videoControls: LinearLayout = findViewById(R.id.exo_button_viewgroup)
private val durationLabel: TextView = findViewById(R.id.exo_duration)
private val shareButton: ImageButton = findViewById(R.id.exo_share)
private val forwardButton: ImageButton = findViewById(R.id.exo_forward)
@ -47,12 +59,65 @@ class MediaPreviewPlayerControlView @JvmOverloads constructor(
showTimeoutMs = -1
}
fun setVisibility(mediaMode: MediaMode) {
@SuppressLint("SetTextI18n")
fun setMediaMode(mediaMode: MediaMode) {
durationBar.visibility = if (mediaMode == MediaMode.VIDEO) VISIBLE else GONE
videoControls.visibility = if (mediaMode == MediaMode.VIDEO) VISIBLE else INVISIBLE
if (mediaMode == MediaMode.VIDEO) {
setProgressUpdateListener { position, _ ->
val finalPlayer = player ?: return@setProgressUpdateListener
val remainingDuration = (finalPlayer.duration - position).toDuration(DurationUnit.MILLISECONDS)
val minutes: Long = remainingDuration.inWholeMinutes
val seconds: Long = remainingDuration.inWholeSeconds % 60
durationLabel.text = "${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}"
}
} else {
setProgressUpdateListener(null)
}
}
fun setShareButtonListener(listener: OnClickListener?) = shareButton.setOnClickListener(listener)
fun setForwardButtonListener(listener: OnClickListener?) = forwardButton.setOnClickListener(listener)
}
class LottieAnimatedButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : LottieAnimationView(context, attrs) {
init {
addValueCallback(KeyPath("**"), LottieProperty.COLOR) { ContextCompat.getColor(context, R.color.signal_colorOnSurface) }
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
speed = 1f
playAnimation()
}
MotionEvent.ACTION_UP -> {
if (isAnimating) {
addAnimatorListener(object : AnimatorListener {
override fun onAnimationEnd(animation: Animator?) {
removeAllAnimatorListeners()
playAnimationReverse()
}
override fun onAnimationStart(animation: Animator?) {}
override fun onAnimationCancel(animation: Animator?) {}
override fun onAnimationRepeat(animation: Animator?) {}
})
} else {
playAnimationReverse()
}
}
}
return super.onTouchEvent(event)
}
private fun playAnimationReverse() {
speed = -1f
playAnimation()
}
}

Wyświetl plik

@ -190,7 +190,7 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
} else {
MediaPreviewPlayerControlView.MediaMode.fromString(currentItem.contentType)
}
binding.mediaPreviewPlaybackControls.setVisibility(mediaType)
binding.mediaPreviewPlaybackControls.setMediaMode(mediaType)
binding.toolbar.title = getTitleText(currentItem, currentState.showThread)
binding.toolbar.subtitle = getSubTitleText(currentItem)

Wyświetl plik

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/touch_highlight_material3">
<item android:id="@android:id/mask">
<shape android:shape="oval">
<solid android:color="@color/black" />
</shape>
</item>
</ripple>

Wyświetl plik

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="oval">
<solid android:color="@color/touch_highlight_material3" />
</shape>
</item>
</selector>

Wyświetl plik

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners android:radius="5dp" />
<corners android:radius="8dp" />
<stroke
android:width="3dp"

Wyświetl plik

@ -14,9 +14,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/media_preview_video_timestamp_inset"
android:layout_marginTop="@dimen/media_preview_bottom_bar_vertical_margin"
android:layout_marginTop="@dimen/media_preview_bottom_bar_vertical_outer_margin"
android:layout_marginEnd="@dimen/media_preview_video_timestamp_inset"
android:layout_marginBottom="@dimen/media_preview_bottom_bar_vertical_margin"
android:layout_marginBottom="@dimen/media_preview_bottom_bar_vertical_inner_margin"
android:gravity="center_vertical"
android:orientation="horizontal">
@ -28,13 +28,12 @@
android:includeFontPadding="false"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:textColor="#FFBEBEBE"
android:textSize="14sp" />
android:textColor="@color/signal_colorOnSurface" />
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="0dp"
android:layout_height="26dp"
android:layout_height="24dp"
android:layout_weight="1" />
<TextView
@ -45,8 +44,7 @@
android:includeFontPadding="false"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:textColor="#FFBEBEBE"
android:textSize="14sp" />
android:textColor="@color/signal_colorOnSurface" />
</LinearLayout>
@ -56,26 +54,28 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="12dp"
android:orientation="horizontal"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:layout_height="64dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/media_preview_bottom_bar_vertical_margin"
android:layout_marginBottom="@dimen/media_preview_bottom_bar_vertical_margin"
android:layout_marginTop="@dimen/media_preview_bottom_bar_vertical_outer_margin"
android:layout_marginBottom="@dimen/media_preview_bottom_bar_vertical_outer_margin"
android:gravity="center"
android:orientation="horizontal"
android:paddingTop="4dp">
<ImageButton
android:id="@+id/exo_share"
android:layout_width="@dimen/exo_media_button_width"
android:layout_height="@dimen/exo_media_button_height"
android:background="?selectableItemBackground"
android:layout_width="@dimen/exo_media_preview_button_width"
android:layout_height="@dimen/exo_media_preview_button_height"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:background="@drawable/circle_touch_highlight_background_material3"
app:srcCompat="@drawable/ic_share_24_outline" />
<Space
@ -87,48 +87,74 @@
android:id="@+id/exo_button_viewgroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="invisible"
android:gravity="center"
android:orientation="horizontal">
<ImageButton
android:id="@id/exo_prev"
style="@style/ExoMediaButton.Previous" />
style="@style/ExoMediaButton.Previous"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" />
<ImageButton
<org.thoughtcrime.securesms.mediapreview.LottieAnimatedButton
android:id="@id/exo_rew"
style="@style/ExoMediaButton"
style="@style/MediaPreviewButton"
android:layout_width="32dp"
android:layout_height="32dp"
android:contentDescription="@string/exo_controls_rewind_description"
app:srcCompat="@drawable/ic_media_skipback_outline_24" />
android:layout_gravity="center_vertical"
android:background="@drawable/circle_touch_highlight_background_material3"
app:lottie_rawRes="@raw/lottie_15s_skip_back"
app:tint="@color/signal_colorOnSurface"
tools:visibility="visible" />
<ImageButton
android:id="@id/exo_shuffle"
style="@style/ExoMediaButton" />
style="@style/ExoMediaButton"
android:layout_marginStart="@dimen/media_preview_button_horizontal_margin"
android:layout_marginEnd="@dimen/media_preview_button_horizontal_margin" />
<ImageButton
android:id="@id/exo_repeat_toggle"
style="@style/ExoMediaButton" />
style="@style/ExoMediaButton"
android:layout_marginStart="@dimen/media_preview_button_horizontal_margin"
android:layout_marginEnd="@dimen/media_preview_button_horizontal_margin" />
<ImageButton
android:id="@id/exo_play"
style="@style/ExoMediaButton.Play" />
style="@style/MediaPreviewButton"
android:src="@drawable/exo_controls_play" />
<ImageButton
android:id="@id/exo_pause"
style="@style/ExoMediaButton.Pause" />
style="@style/MediaPreviewButton"
android:src="@drawable/exo_controls_pause" />
<ImageButton
<org.thoughtcrime.securesms.mediapreview.LottieAnimatedButton
android:id="@id/exo_ffwd"
style="@style/ExoMediaButton"
style="@style/MediaPreviewButton"
android:layout_width="32dp"
android:layout_height="32dp"
android:contentDescription="@string/exo_controls_fastforward_description"
app:srcCompat="@drawable/ic_media_skipforward_outline_24" />
android:layout_gravity="center_vertical"
android:background="@drawable/circle_touch_highlight_background_material3"
android:backgroundTint="@color/signal_colorOnSurface"
app:lottie_rawRes="@raw/lottie_15s_skip_forward"
app:tint="@color/signal_colorOnSurface"
tools:visibility="visible" />
<ImageButton
android:id="@id/exo_next"
style="@style/ExoMediaButton.Next" />
style="@style/ExoMediaButton.Next"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" />
<ImageButton
android:id="@id/exo_vr"
style="@style/ExoMediaButton.VR" />
style="@style/ExoMediaButton.VR"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" />
</LinearLayout>
<Space
@ -138,9 +164,11 @@
<ImageButton
android:id="@+id/exo_forward"
android:layout_width="@dimen/exo_media_button_width"
android:layout_height="@dimen/exo_media_button_height"
android:background="?selectableItemBackground"
android:layout_width="@dimen/exo_media_preview_button_width"
android:layout_height="@dimen/exo_media_preview_button_height"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:background="@drawable/circle_touch_highlight_background_material3"
app:srcCompat="@drawable/ic_forward_outline_24" />
</LinearLayout>

Wyświetl plik

@ -4,31 +4,31 @@
tools:viewBindingIgnore="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="57dp"
android:layout_height="57dp"
android:layout_margin="2dp"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_margin="4dp"
android:animateLayoutChanges="true">
<org.thoughtcrime.securesms.components.ThumbnailView
android:id="@+id/rail_item_image"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_gravity="center"
android:background="@drawable/mediarail_media_outline"
app:thumbnail_radius="5dp"/>
app:thumbnail_radius="8dp"/>
<ImageView
android:id="@+id/rail_item_outline"
android:layout_width="57dp"
android:layout_height="57dp"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_gravity="center"
android:src="@drawable/mediarail_media_outline"
android:visibility="gone"
tools:visibility="visible"/>
<ImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_gravity="center"
android:src="@drawable/mediapicker_item_border_dark"/>

Wyświetl plik

@ -0,0 +1 @@
{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.0.2","a":"","k":"","d":"","tc":""},"fr":60,"ip":0,"op":50,"w":704,"h":704,"nm":"Pause","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Play","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[100]},{"t":10,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":10,"s":[90]}],"ix":10},"p":{"a":0,"k":[352,352,0],"ix":2},"a":{"a":0,"k":[264,264,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"t":10,"s":[50,50,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.051,-2.95],[0,-3.593],[2.051,-2.95],[3.368,-1.25],[0,0],[0,18.15],[0,0],[-15.752,-9.108]],"o":[[3.368,1.25],[2.051,2.95],[0,3.593],[-2.051,2.95],[0,0],[-15.708,9.108],[0,0],[0,-18.15],[0,0]],"v":[[188.962,-16.544],[197.287,-10.093],[200.438,-0.044],[197.287,10.005],[188.962,16.456],[-171.838,225.456],[-200.438,209],[-200.438,-209],[-171.838,-225.456]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[288.438,263.999],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1800,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Pause","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":10,"s":[100]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[-90]},{"t":10,"s":[0]}],"ix":10},"p":{"a":0,"k":[352,352,0],"ix":2},"a":{"a":0,"k":[264,264,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[50,50,100]},{"t":10,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.075,0],[0,0],[0,-6.075],[0,0],[6.075,0],[0,0],[0,6.075],[0,0]],"o":[[0,0],[6.075,0],[0,0],[0,6.075],[0,0],[-6.075,0],[0,0],[0,-6.075]],"v":[[-55,-220],[55,-220],[66,-209],[66,209],[55,220],[-55,220],[-66,209],[-66,-209]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[374,264],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.075,0],[0,0],[0,-6.075],[0,0],[6.075,0],[0,0],[0,6.075],[0,0]],"o":[[0,0],[6.075,0],[0,0],[0,6.075],[0,0],[-6.075,0],[0,0],[0,-6.075]],"v":[[-55,-220],[55,-220],[66,-209],[66,209],[55,220],[-55,220],[-66,209],[-66,-209]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[154,264],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1800,"st":0,"bm":0}],"markers":[]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -41,6 +41,7 @@
<color name="conversation_item_selected_system_ui">#4d4d4d</color>
<color name="touch_highlight">#400099cc</color>
<color name="touch_highlight_material3">#14E2E1E5</color>
<color name="device_link_item_background_light">#ffffffff</color>
<color name="device_link_item_background_dark">#ff333333</color>

Wyświetl plik

@ -236,5 +236,9 @@
<dimen name="stories_landing_item_thumb_outline_height">76dp</dimen>
<dimen name="stories_landing_item_text_horizontal_margin">20dp</dimen>
<dimen name="media_preview_video_timestamp_inset">24dp</dimen>
<dimen name="media_preview_bottom_bar_vertical_margin">20dp</dimen>
<dimen name="media_preview_bottom_bar_vertical_inner_margin">24dp</dimen>
<dimen name="media_preview_bottom_bar_vertical_outer_margin">16dp</dimen>
<dimen name="exo_media_preview_button_width">48dp</dimen>
<dimen name="exo_media_preview_button_height">48dp</dimen>
<dimen name="media_preview_button_horizontal_margin">8dp</dimen>
</resources>

Wyświetl plik

@ -520,4 +520,11 @@
<item name="android:textSize">24sp</item>
<item name="android:gravity">center</item>
</style>
<style name="MediaPreviewButton">
<item name="android:layout_marginEnd">@dimen/media_preview_button_horizontal_margin</item>
<item name="android:layout_marginStart">@dimen/media_preview_button_horizontal_margin</item>
<item name="android:background">@drawable/circle_touch_highlight_background</item>
<item name="android:layout_width">@dimen/exo_media_preview_button_width</item>
<item name="android:layout_height">@dimen/exo_media_preview_button_width</item>
</style>
</resources>