Skip to content

Commit

Permalink
Merge branch 'main' into starfield
Browse files Browse the repository at this point in the history
  • Loading branch information
zsoltk authored Oct 2, 2023
2 parents 7fcbfd8 + c603203 commit 29e2d5b
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.material.icons.filled

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.materialIcon
import androidx.compose.material.icons.materialPath
import androidx.compose.ui.graphics.vector.ImageVector

public val Icons.Filled.Pause: ImageVector
get() {
if (_pause != null) {
return _pause!!
}
_pause = materialIcon(name = "Filled.Pause") {
materialPath {
moveTo(6.0f, 19.0f)
horizontalLineToRelative(4.0f)
lineTo(10.0f, 5.0f)
lineTo(6.0f, 5.0f)
verticalLineToRelative(14.0f)
close()
moveTo(14.0f, 5.0f)
verticalLineToRelative(14.0f)
horizontalLineToRelative(4.0f)
lineTo(18.0f, 5.0f)
horizontalLineToRelative(-4.0f)
close()
}
}
return _pause!!
}

private var _pause: ImageVector? = null
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.material.icons.filled

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.materialIcon
import androidx.compose.material.icons.materialPath
import androidx.compose.ui.graphics.vector.ImageVector

public val Icons.Filled.SkipNext: ImageVector
get() {
if (_skipNext != null) {
return _skipNext!!
}
_skipNext = materialIcon(name = "Filled.SkipNext") {
materialPath {
moveTo(6.0f, 18.0f)
lineToRelative(8.5f, -6.0f)
lineTo(6.0f, 6.0f)
verticalLineToRelative(12.0f)
close()
moveTo(16.0f, 6.0f)
verticalLineToRelative(12.0f)
horizontalLineToRelative(2.0f)
verticalLineTo(6.0f)
horizontalLineToRelative(-2.0f)
close()
}
}
return _skipNext!!
}

private var _skipNext: ImageVector? = null
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.bumble.puzzyx.composable

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import com.bumble.puzzyx.ui.LocalAutoPlayFlow
import kotlinx.coroutines.delay

@Composable
fun AutoPlayScript(
steps: List<Pair<() -> Unit, Long>> = emptyList(),
initialDelayMs: Long = 1,
retryDelayMs: Long = 3000,
repeatSteps: Int = 1,
onFinish: () -> Unit = {}
) {
val autoPlay = LocalAutoPlayFlow.current
LaunchedEffect(Unit) {
delay(initialDelayMs)
for (i in 1..repeatSteps) {
steps.forEach { (action, delayMs) ->
if (autoPlay.value) action()
if (autoPlay.value) delay(delayMs)
while (!autoPlay.value) { delay(retryDelayMs) }
}
}
while (!autoPlay.value) { delay(retryDelayMs) }
onFinish()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,24 @@ package com.bumble.puzzyx.node.app
import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Pause
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.SkipNext
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalDensity
Expand All @@ -29,6 +37,7 @@ import com.bumble.appyx.navigation.node.node
import com.bumble.appyx.utils.multiplatform.Parcelable
import com.bumble.appyx.utils.multiplatform.Parcelize
import com.bumble.puzzyx.appyx.component.backstackclipper.BackStackClipper
import com.bumble.puzzyx.composable.AutoPlayScript
import com.bumble.puzzyx.composable.CallToActionScreen
import com.bumble.puzzyx.composable.MessageBoard
import com.bumble.puzzyx.composable.StarFieldMessageBoard
Expand All @@ -40,6 +49,9 @@ import com.bumble.puzzyx.node.app.PuzzyxAppNode.NavTarget.Puzzle1
import com.bumble.puzzyx.node.app.PuzzyxAppNode.NavTarget.StarFieldMessageBoard
import com.bumble.puzzyx.node.puzzle1.Puzzle1Node
import com.bumble.puzzyx.ui.DottedMeshShape
import com.bumble.puzzyx.ui.LocalAutoPlayFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update

private val screens = listOf(
Puzzle1,
Expand All @@ -61,6 +73,8 @@ class PuzzyxAppNode(
buildContext = buildContext,
appyxComponent = backStack
) {
private var screenIdx = 0

sealed class NavTarget : Parcelable {
@Parcelize
object Puzzle1 : NavTarget()
Expand All @@ -82,18 +96,40 @@ class PuzzyxAppNode(
puzzle = PUZZLE1,
buildContext = buildContext
)
is CallToAction -> node(buildContext) { modifier -> CallToActionScreen(modifier) }
is MessageBoard -> node(buildContext) { modifier -> MessageBoard(modifier) }
is StarFieldMessageBoard -> node(buildContext) { modifier -> StarFieldMessageBoard(modifier) }
is CallToAction -> node(buildContext) { modifier ->
AutoPlayScript(initialDelayMs = 5000) { nextScreen() }
CallToActionScreen(modifier)
}
is MessageBoard -> node(buildContext) { modifier ->
AutoPlayScript(initialDelayMs = 5000) { nextScreen() }
MessageBoard(modifier)
}
is StarFieldMessageBoard -> node(buildContext) { modifier ->
AutoPlayScript(initialDelayMs = 5000) { nextScreen() }
StarFieldMessageBoard(modifier)
}
}

override fun onChildFinished(child: Node) {
nextScreen()
}

@Composable
override fun View(modifier: Modifier) {
Box(
modifier = modifier.fillMaxSize()
) {
CurrentScreen()
NextButton()
var autoPlayFlow = remember { MutableStateFlow(true) }

CompositionLocalProvider(
LocalAutoPlayFlow provides autoPlayFlow
) {
CurrentScreen()
Row {
AutoPlayToggle(autoPlayFlow)
NextButton()
}
}
}
}

Expand All @@ -106,24 +142,47 @@ class PuzzyxAppNode(
}

@Composable
private fun NextButton() {
var screenIdx by remember { mutableStateOf(0) }
private fun AutoPlayToggle(autoPlayFlow: MutableStateFlow<Boolean>) {
val isAutoPlayOn = autoPlayFlow.collectAsState().value

Button(
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
onClick = {
backStack.replace(
target = screens[++screenIdx % screens.size],
animationSpec = tween(
durationMillis = 3000,
easing = FastOutLinearInEasing
)
onClick = { autoPlayFlow.update { !it } },
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent)
) {
Icon(
imageVector = if (isAutoPlayOn) Icons.Filled.Pause else Icons.Filled.PlayArrow,
contentDescription = "Toggle manual controls",
tint = MaterialTheme.colorScheme.onPrimaryContainer,
modifier = Modifier.alpha(if (isAutoPlayOn) 0.035f else 1f),
)
}
}

@Composable
private fun NextButton() {
if (!LocalAutoPlayFlow.current.collectAsState().value) {
Button(
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
onClick = { nextScreen() }
) {
Icon(
imageVector = Icons.Filled.SkipNext,
contentDescription = "Next screen",
tint = MaterialTheme.colorScheme.onPrimaryContainer
)
}
) {
Text("Next")
}
}

private fun nextScreen() {
backStack.replace(
target = screens[++screenIdx % screens.size],
animationSpec = tween(
durationMillis = 3000,
easing = FastOutLinearInEasing
)
)
}
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.BottomCenter
Expand All @@ -35,13 +36,15 @@ import com.bumble.puzzyx.appyx.component.gridpuzzle.operation.assemble
import com.bumble.puzzyx.appyx.component.gridpuzzle.operation.carousel
import com.bumble.puzzyx.appyx.component.gridpuzzle.operation.flip
import com.bumble.puzzyx.appyx.component.gridpuzzle.operation.scatter
import com.bumble.puzzyx.composable.AutoPlayScript
import com.bumble.puzzyx.composable.EntryCardSmall
import com.bumble.puzzyx.composable.FlashCard
import com.bumble.puzzyx.imageloader.ResourceImage
import com.bumble.puzzyx.model.Entry
import com.bumble.puzzyx.model.Puzzle
import com.bumble.puzzyx.model.PuzzlePiece
import com.bumble.puzzyx.model.puzzle1Entries
import com.bumble.puzzyx.ui.LocalAutoPlayFlow
import com.bumble.puzzyx.ui.appyx_dark
import com.bumble.puzzyx.ui.colors
import org.jetbrains.compose.resources.ExperimentalResourceApi
Expand Down Expand Up @@ -112,12 +115,18 @@ class Puzzle1Node(

@Composable
override fun View(modifier: Modifier) {
LaunchedEffect(Unit) {
// We can add the scripted state changes here
// delay(2500)
// gridPuzzle.assemble()
// etc.
}
AutoPlayScript(
steps = listOf(
{ gridPuzzle.assemble() } to 9000,
{ gridPuzzle.flip(KEYFRAME, tween(10000)) } to 8000,
{ gridPuzzle.scatter() } to 500,
),
initialDelayMs = 2000,
onFinish = {
finish()
}
)

Box(
modifier = modifier
.fillMaxSize()
Expand All @@ -140,21 +149,23 @@ class Puzzle1Node(
@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun Controls(modifier: Modifier) {
FlowRow(
modifier = modifier,
horizontalArrangement = Arrangement.Center
) {
Button(onClick = { gridPuzzle.scatter() }) {
Text("Scatter")
}
Button(onClick = { gridPuzzle.assemble() }) {
Text("Assemble")
}
Button(onClick = { gridPuzzle.flip(KEYFRAME, tween(10000)) }) {
Text("Flip")
}
Button(onClick = { gridPuzzle.carousel() }) {
Text("Carousel")
if (!LocalAutoPlayFlow.current.collectAsState().value) {
FlowRow(
modifier = modifier,
horizontalArrangement = Arrangement.Center
) {
Button(onClick = { gridPuzzle.scatter() }) {
Text("Scatter")
}
Button(onClick = { gridPuzzle.assemble() }) {
Text("Assemble")
}
Button(onClick = { gridPuzzle.flip(KEYFRAME, tween(10000)) }) {
Text("Flip")
}
Button(onClick = { gridPuzzle.carousel() }) {
Text("Carousel")
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.bumble.puzzyx.ui

import androidx.compose.runtime.compositionLocalOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

val LocalAutoPlayFlow = compositionLocalOf<StateFlow<Boolean>> { MutableStateFlow(true) }

0 comments on commit 29e2d5b

Please sign in to comment.