Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions design/api/current.api
Original file line number Diff line number Diff line change
Expand Up @@ -428,11 +428,36 @@ package com.urlaunched.android.design.ui.scrollbar.controller {
package com.urlaunched.android.design.ui.shadow {

public final class ShadowKt {
method public static androidx.compose.ui.Modifier shadow(androidx.compose.ui.Modifier, com.urlaunched.android.design.ui.shadow.models.ShadowStyle style);
method public static androidx.compose.ui.Modifier shadow(androidx.compose.ui.Modifier, optional long color, optional float alpha, optional float cornersRadius, optional float shadowBlurRadius, optional long offset);
}

}

package com.urlaunched.android.design.ui.shadow.models {

public final class ShadowStyle {
ctor public ShadowStyle(optional long color, optional float alpha, optional float cornersRadius, optional float blurRadius, optional long offset);
method public long component1-0d7_KjU();
method public float component2();
method public float component3-D9Ej5fM();
method public float component4-D9Ej5fM();
method public long component5-RKDOV3M();
method public com.urlaunched.android.design.ui.shadow.models.ShadowStyle copy-w1ByDHw(long color, float alpha, float cornersRadius, float blurRadius, long offset);
method public float getAlpha();
method public float getBlurRadius();
method public long getColor();
method public float getCornersRadius();
method public long getOffset();
property public final float alpha;
property public final float blurRadius;
property public final long color;
property public final float cornersRadius;
property public final long offset;
}

}

package com.urlaunched.android.design.ui.shimmer {

public final class ShimmerKt {
Expand Down Expand Up @@ -730,3 +755,38 @@ package com.urlaunched.android.design.ui.tutorial.utils {

}

package com.urlaunched.android.design.ui.videotutorial.model {

public final class VideoProgressColors {
ctor public VideoProgressColors(optional long trackColor, optional long progressColor);
method public long component1-0d7_KjU();
method public long component2-0d7_KjU();
method public com.urlaunched.android.design.ui.videotutorial.model.VideoProgressColors copy--OWjLjI(long trackColor, long progressColor);
method public long getProgressColor();
method public long getTrackColor();
property public final long progressColor;
property public final long trackColor;
}

public final class VideoProgressStyle {
ctor public VideoProgressStyle(optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, optional float gapSize);
method public com.urlaunched.android.design.ui.shadow.models.ShadowStyle? component1();
method public float component2-D9Ej5fM();
method public com.urlaunched.android.design.ui.videotutorial.model.VideoProgressStyle copy-3ABfNKs(com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, float gapSize);
method public float getGapSize();
method public com.urlaunched.android.design.ui.shadow.models.ShadowStyle? getShadow();
property public final float gapSize;
property public final com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow;
}

}

package com.urlaunched.android.design.ui.videotutorial.ui {

public final class VideoTutorialContainerKt {
method @androidx.compose.runtime.Composable public static void VideoTutorialContainer(optional androidx.compose.ui.Modifier modifier, androidx.media3.common.Player? player, int mediaCount, int currentMediaIndex, @FloatRange(from=0.0, to=1.0) float currentMediaProgress, kotlin.jvm.functions.Function0<kotlin.Unit> onPreviousVideo, kotlin.jvm.functions.Function0<kotlin.Unit> onNextVideo, optional int videoResizeMode, optional androidx.compose.foundation.layout.PaddingValues progressBarPadding, optional com.urlaunched.android.design.ui.videotutorial.model.VideoProgressColors videoProgressColors, optional com.urlaunched.android.design.ui.videotutorial.model.VideoProgressStyle videoProgressStyle, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> closeButton);
method @androidx.compose.runtime.Composable public static void VideoTutorialContainer(optional androidx.compose.ui.Modifier modifier, java.util.List<java.lang.String> videoUrls, kotlin.jvm.functions.Function0<kotlin.Unit> onTutorialFinish, optional int videoResizeMode, optional androidx.compose.foundation.layout.PaddingValues progressBarPadding, optional com.urlaunched.android.design.ui.videotutorial.model.VideoProgressColors videoProgressColors, optional com.urlaunched.android.design.ui.videotutorial.model.VideoProgressStyle videoProgressStyle, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> closeButton);
}

}

6 changes: 6 additions & 0 deletions design/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ dependencies {
debugImplementation libs.composeDependencies.composeUiTooling
debugImplementation libs.composeDependencies.composeUiTestManifest

// Media3
implementation libs.media3Dependencies.core
implementation libs.media3Dependencies.ui

// Paging
implementation libs.pagingDependencies.core
implementation libs.pagingDependencies.compose
Expand All @@ -91,6 +95,8 @@ dependencies {

// Local modules
implementation project(":cdn:models:presentation")
implementation project(":player")
implementation project(":common")

// Bottom sheet
implementation libs.bottomSheet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import com.urlaunched.android.design.ui.shadow.models.ShadowStyle

fun Modifier.shadow(style: ShadowStyle) = this.shadow(
color = style.color,
alpha = style.alpha,
cornersRadius = style.cornersRadius,
shadowBlurRadius = style.blurRadius,
offset = style.offset
)

fun Modifier.shadow(
color: Color = Color.Black,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.urlaunched.android.design.ui.shadow.models

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp

data class ShadowStyle(
val color: Color = Color.Black,
val alpha: Float = 1f,
val cornersRadius: Dp = 0.dp,
val blurRadius: Dp = 0.dp,
val offset: DpOffset = DpOffset.Zero
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.urlaunched.android.design.ui.videotutorial.constants

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import com.urlaunched.android.design.resources.dimens.Dimens
import com.urlaunched.android.design.ui.shadow.models.ShadowStyle

internal object VideoProgressDefaults {

private const val SHADOW_ALPHA = 0.15f

private val shadowBlurRadius = 4.dp
private val shadowOffset = DpOffset(0.dp, 2.dp)

val DefaultProgressShadow = ShadowStyle(
color = Color.Black,
alpha = SHADOW_ALPHA,
cornersRadius = Dimens.cornerRadiusLarge,
blurRadius = shadowBlurRadius,
offset = shadowOffset
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.urlaunched.android.design.ui.videotutorial.model

import androidx.compose.ui.graphics.Color

data class VideoProgressColors(
val trackColor: Color = Color.LightGray,
val progressColor: Color = Color.White
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.urlaunched.android.design.ui.videotutorial.model

import androidx.compose.ui.unit.Dp
import com.urlaunched.android.design.resources.dimens.Dimens
import com.urlaunched.android.design.ui.shadow.models.ShadowStyle
import com.urlaunched.android.design.ui.videotutorial.constants.VideoProgressDefaults

data class VideoProgressStyle(
val shadow: ShadowStyle? = VideoProgressDefaults.DefaultProgressShadow,
val gapSize: Dp = Dimens.spacingTiny
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.urlaunched.android.design.ui.videotutorial.ui

import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.annotation.OptIn
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView

@OptIn(UnstableApi::class)
@Composable
internal fun VideoPlayer(videoPlayer: Player?, videoResizeMode: Int = AspectRatioFrameLayout.RESIZE_MODE_ZOOM) {
if (LocalInspectionMode.current) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFF4CAF50))
)
} else {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
PlayerView(context).apply {
player = videoPlayer
useController = false
resizeMode = videoResizeMode

layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
}
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.urlaunched.android.design.ui.videotutorial.ui

import androidx.annotation.FloatRange
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import com.urlaunched.android.design.resources.dimens.Dimens
import com.urlaunched.android.design.ui.modifiers.ifNotNull
import com.urlaunched.android.design.ui.shadow.models.ShadowStyle
import com.urlaunched.android.design.ui.shadow.shadow
import com.urlaunched.android.design.ui.videotutorial.constants.VideoProgressDefaults

@Composable
internal fun VideoProgress(
modifier: Modifier = Modifier,
mediaCount: Int,
currentMediaIndex: Int,
@FloatRange(0.0, 1.0)
currentMediaProgress: Float,
trackColor: Color = Color.LightGray,
progressColor: Color = Color.White,
shadow: ShadowStyle? = VideoProgressDefaults.DefaultProgressShadow,
gapSize: Dp = Dimens.spacingTiny,
closeButton: @Composable RowScope.() -> Unit = {}
) {
Row(
modifier = modifier.statusBarsPadding(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(gapSize)
) {
repeat(mediaCount) { index ->
LinearProgressIndicator(
modifier = Modifier
.ifNotNull(shadow) { Modifier.shadow(it) }
.weight(1f),
strokeCap = StrokeCap.Round,
trackColor = trackColor,
color = progressColor,
gapSize = Dimens.zeroDp,
drawStopIndicator = {
// Do nothing
},
progress = {
when {
currentMediaIndex > index -> 1f
currentMediaIndex == index -> currentMediaProgress
else -> 0f
}
}
)
}

closeButton()
}
}

@Preview
@Composable
private fun VideoProgressPreview() {
VideoProgress(
modifier = Modifier
.fillMaxWidth()
.padding(Dimens.spacingNormal),
progressColor = Color.Red,
mediaCount = 5,
currentMediaIndex = 3,
currentMediaProgress = 0.5f
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.urlaunched.android.design.ui.videotutorial.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
internal fun VideoTapNavigator(modifier: Modifier = Modifier, onPreviousVideo: () -> Unit, onNextVideo: () -> Unit) {
Row(modifier = modifier) {
Box(
modifier = Modifier
.fillMaxHeight()
.weight(1f)
.clickable(
interactionSource = null,
indication = null,
onClick = onPreviousVideo
)
)

Box(
modifier = Modifier
.fillMaxHeight()
.weight(1f)
.clickable(
interactionSource = null,
indication = null,
onClick = onNextVideo
)
)
}
}
Loading