mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-08-07 08:39:30 +00:00
Merge branch 'master' of gitlab.futo.org:videostreaming/grayjay
This commit is contained in:
commit
ed29dd8365
9 changed files with 194 additions and 58 deletions
|
@ -67,7 +67,7 @@ class TutorialFragment : MainFragment() {
|
||||||
|
|
||||||
addView(createHeader("Initial setup"))
|
addView(createHeader("Initial setup"))
|
||||||
initialSetupVideos.forEach {
|
initialSetupVideos.forEach {
|
||||||
addView(createTutorialPill(R.drawable.ic_movie, it.name).apply {
|
addView(createTutorialPill(R.drawable.ic_movie, it.name, it.description).apply {
|
||||||
onClick.subscribe {
|
onClick.subscribe {
|
||||||
fragment.navigate<VideoDetailFragment>(it)
|
fragment.navigate<VideoDetailFragment>(it)
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ class TutorialFragment : MainFragment() {
|
||||||
|
|
||||||
addView(createHeader("Features"))
|
addView(createHeader("Features"))
|
||||||
featuresVideos.forEach {
|
featuresVideos.forEach {
|
||||||
addView(createTutorialPill(R.drawable.ic_movie, it.name).apply {
|
addView(createTutorialPill(R.drawable.ic_movie, it.name, it.description).apply {
|
||||||
onClick.subscribe {
|
onClick.subscribe {
|
||||||
fragment.navigate<VideoDetailFragment>(it)
|
fragment.navigate<VideoDetailFragment>(it)
|
||||||
}
|
}
|
||||||
|
@ -95,10 +95,11 @@ class TutorialFragment : MainFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createTutorialPill(iconPrefix: Int, t: String): WidePillButton {
|
private fun createTutorialPill(iconPrefix: Int, t: String, d: String): WidePillButton {
|
||||||
return WidePillButton(context).apply {
|
return WidePillButton(context).apply {
|
||||||
setIconPrefix(iconPrefix)
|
setIconPrefix(iconPrefix)
|
||||||
setText(t)
|
setText(t)
|
||||||
|
setDescription(d)
|
||||||
setIconSuffix(R.drawable.ic_play_notif)
|
setIconSuffix(R.drawable.ic_play_notif)
|
||||||
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT).apply {
|
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT).apply {
|
||||||
setMargins(15.dp(resources), 0, 15.dp(resources), 12.dp(resources))
|
setMargins(15.dp(resources), 0, 15.dp(resources), 12.dp(resources))
|
||||||
|
@ -107,9 +108,9 @@ class TutorialFragment : MainFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TutorialVideoSourceDescriptor(url: String, duration: Long) : VideoUnMuxedSourceDescriptor() {
|
class TutorialVideoSourceDescriptor(url: String, duration: Long, width: Int, height: Int) : VideoUnMuxedSourceDescriptor() {
|
||||||
override val videoSources: Array<IVideoSource> = arrayOf(
|
override val videoSources: Array<IVideoSource> = arrayOf(
|
||||||
VideoUrlSource("1080p", url, 1920, 1080, duration, "video/mp4")
|
VideoUrlSource("Original", url, width, height, duration, "video/mp4")
|
||||||
)
|
)
|
||||||
override val audioSources: Array<IAudioSource> = arrayOf()
|
override val audioSources: Array<IAudioSource> = arrayOf()
|
||||||
}
|
}
|
||||||
|
@ -120,7 +121,9 @@ class TutorialFragment : MainFragment() {
|
||||||
override val description: String,
|
override val description: String,
|
||||||
thumbnailUrl: String,
|
thumbnailUrl: String,
|
||||||
videoUrl: String,
|
videoUrl: String,
|
||||||
override val duration: Long
|
override val duration: Long,
|
||||||
|
width: Int = 1920,
|
||||||
|
height: Int = 1080
|
||||||
) : IPlatformVideoDetails {
|
) : IPlatformVideoDetails {
|
||||||
override val id: PlatformID = PlatformID("tutorial", uuid)
|
override val id: PlatformID = PlatformID("tutorial", uuid)
|
||||||
override val contentType: ContentType = ContentType.MEDIA
|
override val contentType: ContentType = ContentType.MEDIA
|
||||||
|
@ -137,7 +140,7 @@ class TutorialFragment : MainFragment() {
|
||||||
override val isLive: Boolean = false
|
override val isLive: Boolean = false
|
||||||
override val rating: IRating = RatingLikes(-1)
|
override val rating: IRating = RatingLikes(-1)
|
||||||
override val viewCount: Long = -1
|
override val viewCount: Long = -1
|
||||||
override val video: IVideoSourceDescriptor = TutorialVideoSourceDescriptor(videoUrl, duration)
|
override val video: IVideoSourceDescriptor = TutorialVideoSourceDescriptor(videoUrl, duration, width, height)
|
||||||
override fun getComments(client: IPlatformClient): IPager<IPlatformComment> {
|
override fun getComments(client: IPlatformClient): IPager<IPlatformComment> {
|
||||||
return EmptyPager()
|
return EmptyPager()
|
||||||
}
|
}
|
||||||
|
@ -163,7 +166,7 @@ class TutorialFragment : MainFragment() {
|
||||||
TutorialVideo(
|
TutorialVideo(
|
||||||
uuid = "3b99ebfe-2640-4643-bfe0-a0cf04261fc5",
|
uuid = "3b99ebfe-2640-4643-bfe0-a0cf04261fc5",
|
||||||
name = "Getting started",
|
name = "Getting started",
|
||||||
description = "Learn how to get started with Grayjay.",
|
description = "Learn how to get started with Grayjay. How do you install plugins?",
|
||||||
thumbnailUrl = "https://releases.grayjay.app/tutorials/getting-started.jpg",
|
thumbnailUrl = "https://releases.grayjay.app/tutorials/getting-started.jpg",
|
||||||
videoUrl = "https://releases.grayjay.app/tutorials/getting-started.mp4",
|
videoUrl = "https://releases.grayjay.app/tutorials/getting-started.mp4",
|
||||||
duration = 50
|
duration = 50
|
||||||
|
@ -171,7 +174,7 @@ class TutorialFragment : MainFragment() {
|
||||||
TutorialVideo(
|
TutorialVideo(
|
||||||
uuid = "793aa009-516c-4581-b82f-a8efdfef4c27",
|
uuid = "793aa009-516c-4581-b82f-a8efdfef4c27",
|
||||||
name = "Is Grayjay free?",
|
name = "Is Grayjay free?",
|
||||||
description = "Learn how Grayjay is monetized.",
|
description = "Learn how Grayjay is monetized. How do we make money?",
|
||||||
thumbnailUrl = "https://releases.grayjay.app/tutorials/pay.jpg",
|
thumbnailUrl = "https://releases.grayjay.app/tutorials/pay.jpg",
|
||||||
videoUrl = "https://releases.grayjay.app/tutorials/pay.mp4",
|
videoUrl = "https://releases.grayjay.app/tutorials/pay.mp4",
|
||||||
duration = 52
|
duration = 52
|
||||||
|
@ -182,7 +185,7 @@ class TutorialFragment : MainFragment() {
|
||||||
TutorialVideo(
|
TutorialVideo(
|
||||||
uuid = "d2238d88-4252-4a91-a12d-b90c049bb7cf",
|
uuid = "d2238d88-4252-4a91-a12d-b90c049bb7cf",
|
||||||
name = "Searching",
|
name = "Searching",
|
||||||
description = "Learn about searching in Grayjay.",
|
description = "Learn about searching in Grayjay. How can I find channels, videos or playlists?",
|
||||||
thumbnailUrl = "https://releases.grayjay.app/tutorials/search.jpg",
|
thumbnailUrl = "https://releases.grayjay.app/tutorials/search.jpg",
|
||||||
videoUrl = "https://releases.grayjay.app/tutorials/search.mp4",
|
videoUrl = "https://releases.grayjay.app/tutorials/search.mp4",
|
||||||
duration = 39
|
duration = 39
|
||||||
|
@ -198,10 +201,20 @@ class TutorialFragment : MainFragment() {
|
||||||
TutorialVideo(
|
TutorialVideo(
|
||||||
uuid = "94d36959-e3fc-4c24-a988-89147067a179",
|
uuid = "94d36959-e3fc-4c24-a988-89147067a179",
|
||||||
name = "Casting",
|
name = "Casting",
|
||||||
description = "Learn about casting in Grayjay.",
|
description = "Learn about casting in Grayjay. How do I show video on my TV?",
|
||||||
thumbnailUrl = "https://releases.grayjay.app/tutorials/how-to-cast.jpg",
|
thumbnailUrl = "https://releases.grayjay.app/tutorials/how-to-cast.jpg",
|
||||||
videoUrl = "https://releases.grayjay.app/tutorials/how-to-cast.mp4",
|
videoUrl = "https://releases.grayjay.app/tutorials/how-to-cast.mp4",
|
||||||
duration = 79
|
duration = 79
|
||||||
|
),
|
||||||
|
TutorialVideo(
|
||||||
|
uuid = "5128c2e3-852b-4281-869b-efea2ec82a0e",
|
||||||
|
name = "Monetization",
|
||||||
|
description = "How can I monetize as a creator?",
|
||||||
|
thumbnailUrl = "https://releases.grayjay.app/tutorials/monetization.jpg",
|
||||||
|
videoUrl = "https://releases.grayjay.app/tutorials/monetization.mp4",
|
||||||
|
duration = 47,
|
||||||
|
1080,
|
||||||
|
1920
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import android.util.AttributeSet
|
||||||
import android.view.GestureDetector
|
import android.view.GestureDetector
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
|
import android.view.ScaleGestureDetector
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
@ -24,6 +25,7 @@ import com.futo.platformplayer.R
|
||||||
import com.futo.platformplayer.Settings
|
import com.futo.platformplayer.Settings
|
||||||
import com.futo.platformplayer.constructs.Event0
|
import com.futo.platformplayer.constructs.Event0
|
||||||
import com.futo.platformplayer.constructs.Event1
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
import com.futo.platformplayer.constructs.Event2
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.views.others.CircularProgressBar
|
import com.futo.platformplayer.views.others.CircularProgressBar
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
|
@ -74,10 +76,19 @@ class GestureControlView : LinearLayout {
|
||||||
private var _fullScreenFactorUp = 1.0f;
|
private var _fullScreenFactorUp = 1.0f;
|
||||||
private var _fullScreenFactorDown = 1.0f;
|
private var _fullScreenFactorDown = 1.0f;
|
||||||
|
|
||||||
|
private var _scaleGestureDetector: ScaleGestureDetector
|
||||||
|
private var _scaleFactor = 1.0f
|
||||||
|
private var _translationX = 0.0f
|
||||||
|
private var _translationY = 0.0f
|
||||||
|
private val _layoutControlsZoom: FrameLayout
|
||||||
|
private val _textZoom: TextView
|
||||||
|
|
||||||
private val _gestureController: GestureDetectorCompat;
|
private val _gestureController: GestureDetectorCompat;
|
||||||
|
|
||||||
val onSeek = Event1<Long>();
|
val onSeek = Event1<Long>();
|
||||||
val onBrightnessAdjusted = Event1<Float>();
|
val onBrightnessAdjusted = Event1<Float>();
|
||||||
|
val onPan = Event2<Float, Float>();
|
||||||
|
val onZoom = Event1<Float>();
|
||||||
val onSoundAdjusted = Event1<Float>();
|
val onSoundAdjusted = Event1<Float>();
|
||||||
val onToggleFullscreen = Event0();
|
val onToggleFullscreen = Event0();
|
||||||
|
|
||||||
|
@ -95,9 +106,27 @@ class GestureControlView : LinearLayout {
|
||||||
_layoutControlsSound = findViewById(R.id.layout_controls_sound);
|
_layoutControlsSound = findViewById(R.id.layout_controls_sound);
|
||||||
_progressSound = findViewById(R.id.progress_sound);
|
_progressSound = findViewById(R.id.progress_sound);
|
||||||
_layoutControlsBrightness = findViewById(R.id.layout_controls_brightness);
|
_layoutControlsBrightness = findViewById(R.id.layout_controls_brightness);
|
||||||
|
_layoutControlsZoom = findViewById(R.id.layout_controls_zoom)
|
||||||
|
_textZoom = findViewById(R.id.text_zoom)
|
||||||
_progressBrightness = findViewById(R.id.progress_brightness);
|
_progressBrightness = findViewById(R.id.progress_brightness);
|
||||||
_layoutControlsFullscreen = findViewById(R.id.layout_controls_fullscreen);
|
_layoutControlsFullscreen = findViewById(R.id.layout_controls_fullscreen);
|
||||||
|
|
||||||
|
_scaleGestureDetector = ScaleGestureDetector(context, object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||||
|
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||||
|
Logger.i(TAG, "onScale _scaleFactor $_scaleFactor sf " + detector.scaleFactor.toString())
|
||||||
|
_scaleFactor = (_scaleFactor + detector.scaleFactor - 1.0f).coerceAtLeast(1.0f).coerceAtMost(5.0f)
|
||||||
|
onZoom.emit(_scaleFactor)
|
||||||
|
|
||||||
|
_translationX = _translationX.coerceAtLeast(-height / _scaleFactor)
|
||||||
|
_translationY = _translationY.coerceAtLeast(-width / _scaleFactor)
|
||||||
|
onPan.emit(_translationX, _translationY)
|
||||||
|
|
||||||
|
_layoutControlsZoom.visibility = View.VISIBLE
|
||||||
|
_textZoom.text = "${String.format("%.1f", _scaleFactor)}x"
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
_gestureController = GestureDetectorCompat(context, object : GestureDetector.OnGestureListener {
|
_gestureController = GestureDetectorCompat(context, object : GestureDetector.OnGestureListener {
|
||||||
override fun onDown(p0: MotionEvent): Boolean { return false; }
|
override fun onDown(p0: MotionEvent): Boolean { return false; }
|
||||||
override fun onShowPress(p0: MotionEvent) = Unit;
|
override fun onShowPress(p0: MotionEvent) = Unit;
|
||||||
|
@ -107,6 +136,9 @@ class GestureControlView : LinearLayout {
|
||||||
if(p0 == null)
|
if(p0 == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Logger.i(TAG, "p0.pointerCount: " + p0.pointerCount)
|
||||||
|
|
||||||
|
if (p1.pointerCount == 1) {
|
||||||
val minDistance = Math.min(width, height)
|
val minDistance = Math.min(width, height)
|
||||||
if (_isFullScreen && _adjustingBrightness) {
|
if (_isFullScreen && _adjustingBrightness) {
|
||||||
val adjustAmount = (distanceY * 2) / minDistance;
|
val adjustAmount = (distanceY * 2) / minDistance;
|
||||||
|
@ -126,7 +158,7 @@ class GestureControlView : LinearLayout {
|
||||||
val adjustAmount = (-distanceY * 2) / minDistance;
|
val adjustAmount = (-distanceY * 2) / minDistance;
|
||||||
_fullScreenFactorDown = (_fullScreenFactorDown + adjustAmount).coerceAtLeast(0.0f).coerceAtMost(1.0f);
|
_fullScreenFactorDown = (_fullScreenFactorDown + adjustAmount).coerceAtLeast(0.0f).coerceAtMost(1.0f);
|
||||||
_layoutControlsFullscreen.alpha = _fullScreenFactorDown;
|
_layoutControlsFullscreen.alpha = _fullScreenFactorDown;
|
||||||
} else {
|
} else if (p0.pointerCount == 1) {
|
||||||
val rx = (p0.x + p1.x) / (2 * width);
|
val rx = (p0.x + p1.x) / (2 * width);
|
||||||
val ry = (p0.y + p1.y) / (2 * height);
|
val ry = (p0.y + p1.y) / (2 * height);
|
||||||
if (ry > 0.1 && ry < 0.9) {
|
if (ry > 0.1 && ry < 0.9) {
|
||||||
|
@ -143,6 +175,15 @@ class GestureControlView : LinearLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (_isFullScreen) {
|
||||||
|
stopAllGestures()
|
||||||
|
|
||||||
|
_translationX = (_translationX - distanceX).coerceAtLeast(-height / _scaleFactor)
|
||||||
|
_translationY = (_translationY - distanceY).coerceAtLeast(-width / _scaleFactor)
|
||||||
|
|
||||||
|
Logger.i(TAG, "onPan " + _translationX.toString() + ", " + _translationY.toString())
|
||||||
|
onPan.emit(_translationX, _translationY)
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -227,9 +268,14 @@ class GestureControlView : LinearLayout {
|
||||||
stopAdjustingFullscreenDown();
|
stopAdjustingFullscreenDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_layoutControlsZoom.visibility == View.VISIBLE && ev.action == MotionEvent.ACTION_UP) {
|
||||||
|
_layoutControlsZoom.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
startHideJobIfNecessary();
|
startHideJobIfNecessary();
|
||||||
|
|
||||||
_gestureController.onTouchEvent(ev)
|
_gestureController.onTouchEvent(ev)
|
||||||
|
_scaleGestureDetector.onTouchEvent(ev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,6 +608,12 @@ class GestureControlView : LinearLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setFullscreen(isFullScreen: Boolean) {
|
fun setFullscreen(isFullScreen: Boolean) {
|
||||||
|
_scaleFactor = 1.0f
|
||||||
|
onZoom.emit(_scaleFactor)
|
||||||
|
_translationX = 0f
|
||||||
|
_translationY = 0f
|
||||||
|
onPan.emit(_translationX, _translationY)
|
||||||
|
|
||||||
if (isFullScreen) {
|
if (isFullScreen) {
|
||||||
val c = context
|
val c = context
|
||||||
if (c is Activity && Settings.instance.gestureControls.useSystemBrightness) {
|
if (c is Activity && Settings.instance.gestureControls.useSystemBrightness) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ class WidePillButton : LinearLayout {
|
||||||
private val _iconPrefix: ImageView
|
private val _iconPrefix: ImageView
|
||||||
private val _iconSuffix: ImageView
|
private val _iconSuffix: ImageView
|
||||||
private val _text: TextView
|
private val _text: TextView
|
||||||
|
private val _textDescription: TextView
|
||||||
val onClick = Event0()
|
val onClick = Event0()
|
||||||
|
|
||||||
constructor(context: Context, attrs: AttributeSet? = null) : super(context, attrs) {
|
constructor(context: Context, attrs: AttributeSet? = null) : super(context, attrs) {
|
||||||
|
@ -21,11 +22,13 @@ class WidePillButton : LinearLayout {
|
||||||
_iconPrefix = findViewById(R.id.image_prefix)
|
_iconPrefix = findViewById(R.id.image_prefix)
|
||||||
_iconSuffix = findViewById(R.id.image_suffix)
|
_iconSuffix = findViewById(R.id.image_suffix)
|
||||||
_text = findViewById(R.id.text)
|
_text = findViewById(R.id.text)
|
||||||
|
_textDescription = findViewById(R.id.text_description)
|
||||||
|
|
||||||
val attrArr = context.obtainStyledAttributes(attrs, R.styleable.WidePillButton, 0, 0)
|
val attrArr = context.obtainStyledAttributes(attrs, R.styleable.WidePillButton, 0, 0)
|
||||||
setIconPrefix(attrArr.getResourceId(R.styleable.WidePillButton_widePillIconPrefix, -1))
|
setIconPrefix(attrArr.getResourceId(R.styleable.WidePillButton_widePillIconPrefix, -1))
|
||||||
setIconSuffix(attrArr.getResourceId(R.styleable.WidePillButton_widePillIconSuffix, -1))
|
setIconSuffix(attrArr.getResourceId(R.styleable.WidePillButton_widePillIconSuffix, -1))
|
||||||
setText(attrArr.getText(R.styleable.PillButton_pillText) ?: "")
|
setText(attrArr.getText(R.styleable.WidePillButton_widePillText) ?: "")
|
||||||
|
setDescription(attrArr.getText(R.styleable.WidePillButton_widePillDescription))
|
||||||
attrArr.recycle()
|
attrArr.recycle()
|
||||||
|
|
||||||
findViewById<LinearLayout>(R.id.root).setOnClickListener {
|
findViewById<LinearLayout>(R.id.root).setOnClickListener {
|
||||||
|
@ -54,4 +57,13 @@ class WidePillButton : LinearLayout {
|
||||||
fun setText(t: CharSequence) {
|
fun setText(t: CharSequence) {
|
||||||
_text.text = t
|
_text.text = t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setDescription(t: CharSequence?) {
|
||||||
|
if (!t.isNullOrEmpty()) {
|
||||||
|
_textDescription.visibility = View.VISIBLE
|
||||||
|
_textDescription.text = t
|
||||||
|
} else {
|
||||||
|
_textDescription.visibility= View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -263,6 +263,14 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
gestureControl.onPan.subscribe { x, y ->
|
||||||
|
_videoView.translationX = x
|
||||||
|
_videoView.translationY = y
|
||||||
|
}
|
||||||
|
gestureControl.onZoom.subscribe {
|
||||||
|
_videoView.scaleX = it
|
||||||
|
_videoView.scaleY = it
|
||||||
|
}
|
||||||
|
|
||||||
if(!isInEditMode) {
|
if(!isInEditMode) {
|
||||||
_videoView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM;
|
_videoView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM;
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#2A2A2A" />
|
||||||
|
<corners android:radius="25dp" />
|
||||||
|
<size android:height="20dp" />
|
||||||
|
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
|
||||||
|
</shape>
|
|
@ -152,4 +152,29 @@
|
||||||
android:textSize="16dp"/>
|
android:textSize="16dp"/>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/layout_controls_zoom"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:background="@drawable/background_gesture_controls"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_zoom"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
tools:text="@string/zoom"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16dp"/>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -3,7 +3,7 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="50dp"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="6dp"
|
android:paddingTop="6dp"
|
||||||
android:paddingBottom="7dp"
|
android:paddingBottom="7dp"
|
||||||
android:paddingStart="7dp"
|
android:paddingStart="7dp"
|
||||||
|
@ -21,19 +21,36 @@
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
app:srcCompat="@drawable/ic_thumb_up" />
|
app:srcCompat="@drawable/ic_thumb_up" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:fontFamily="@font/inter_light"
|
android:fontFamily="@font/inter_light"
|
||||||
tools:text="500K" />
|
tools:text="500K" />
|
||||||
|
|
||||||
<Space android:layout_height="match_parent"
|
<TextView
|
||||||
android:layout_width="0dp"
|
android:id="@+id/text_description"
|
||||||
android:layout_weight="1" />
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#848484"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:fontFamily="@font/inter_light"
|
||||||
|
tools:text="500K" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image_suffix"
|
android:id="@+id/image_suffix"
|
||||||
|
|
|
@ -739,6 +739,7 @@
|
||||||
<string name="do_you_want_to_see_the_tutorials_you_can_find_them_at_any_time_through_the_more_button">Do you want to see the tutorials? You can find them at any time through the more button.</string>
|
<string name="do_you_want_to_see_the_tutorials_you_can_find_them_at_any_time_through_the_more_button">Do you want to see the tutorials? You can find them at any time through the more button.</string>
|
||||||
<string name="add_creator">Add Creators</string>
|
<string name="add_creator">Add Creators</string>
|
||||||
<string name="select">Select</string>
|
<string name="select">Select</string>
|
||||||
|
<string name="zoom">Zoom</string>
|
||||||
<string-array name="home_screen_array">
|
<string-array name="home_screen_array">
|
||||||
<item>Recommendations</item>
|
<item>Recommendations</item>
|
||||||
<item>Subscriptions</item>
|
<item>Subscriptions</item>
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
<resources>
|
<resources>
|
||||||
<declare-styleable name="WidePillButton">
|
<declare-styleable name="WidePillButton">
|
||||||
<attr name="widePillIconPrefix" format="reference" />
|
<attr name="widePillIconPrefix" format="reference" />
|
||||||
<attr name="widePilllText" format="string" />
|
<attr name="widePillText" format="string" />
|
||||||
|
<attr name="widePillDescription" format="string" />
|
||||||
<attr name="widePillIconSuffix" format="reference" />
|
<attr name="widePillIconSuffix" format="reference" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
</resources>
|
</resources>
|
Loading…
Add table
Add a link
Reference in a new issue