Created
June 17, 2022 11:30
-
-
Save GibsonRuitiari/0c25bbf2d781d2e34f98a9b712df1ddb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.gibsonruitiari.eatoutui | |
import android.os.Bundle | |
import androidx.activity.ComponentActivity | |
import androidx.activity.compose.setContent | |
import androidx.compose.animation.core.Animatable | |
import androidx.compose.animation.core.tween | |
import androidx.compose.foundation.layout.* | |
import androidx.compose.material.MaterialTheme | |
import androidx.compose.material.Surface | |
import androidx.compose.material.Text | |
import androidx.compose.runtime.* | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.graphics.graphicsLayer | |
import androidx.compose.ui.unit.dp | |
import androidx.compose.ui.unit.sp | |
import androidx.core.view.WindowCompat | |
import com.gibsonruitiari.eatoutui.ui.theme.EatOutUiTheme | |
import com.google.accompanist.systemuicontroller.rememberSystemUiController | |
import kotlinx.coroutines.* | |
import kotlinx.coroutines.flow.MutableStateFlow | |
import java.util.* | |
import kotlin.concurrent.schedule | |
import kotlin.random.Random | |
class MainActivity : ComponentActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
// turns of decor fitting system windows | |
WindowCompat.setDecorFitsSystemWindows(window, false) | |
super.onCreate(savedInstanceState) | |
setContent { | |
val systemUiController = rememberSystemUiController() | |
val useDarkIcons = MaterialTheme.colors.isLight | |
SideEffect { | |
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = useDarkIcons) | |
} | |
EatOutUiTheme { | |
Surface( | |
modifier = Modifier.fillMaxSize(), | |
color = MaterialTheme.colors.background | |
) { | |
MainScreenHeaderComponent() | |
} | |
} | |
} | |
} | |
enum class Face(val angle:Float){ | |
Front(0f){ | |
override val next: Face | |
get() = Back | |
}, | |
Back(180f){ | |
override val next: Face | |
get() = Front | |
}; | |
abstract val next:Face | |
} | |
enum class RotationAxis{AxisX, AxisY} | |
@Composable | |
private fun MainScreenHeaderComponent() { | |
BoxWithConstraints(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { | |
var face by remember { mutableStateOf(Face.Front) } | |
val angle_ = remember { Animatable(0f) } | |
val scope = rememberCoroutineScope() | |
val firstPair = Container("Steak".toCharArray(), "Indian".toCharArray()) | |
val secondPair = Container("Ethiopian".toCharArray(), "Barbeque".toCharArray()) | |
val fourthPair = Container("African".toCharArray(), "Italian".toCharArray()) | |
val fifthPair = Container("Eritrean".toCharArray(), "Lebanese".toCharArray()) | |
val sixthPair = Container("Spanish".toCharArray(), "Mexican".toCharArray()) | |
var front by remember { | |
mutableStateOf(firstPair.front) | |
} | |
var back by remember { | |
mutableStateOf(firstPair.back) | |
} | |
val seventhPair = Container("Mediterranean".toCharArray(), "Italian".toCharArray()) | |
val list = listOf(firstPair,secondPair,fourthPair,sixthPair, fifthPair, seventhPair) | |
var isTransitioned by remember { | |
mutableStateOf(false) | |
} | |
LaunchedEffect(key1 = Unit) { | |
scope.timer { | |
face = face.next | |
angle_.animateTo(face.angle, tween(2500)) | |
if (!isTransitioned){ | |
val randomIndex= list.random() | |
front=randomIndex.front | |
back= randomIndex.back | |
delay(3000) | |
isTransitioned=false | |
}else { | |
isTransitioned=true | |
} | |
} | |
} | |
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier | |
.wrapContentSize() | |
.padding(10.dp)) { | |
Container(front,back).iterator().forEach { | |
val axis = if (it.first.code%2==0) RotationAxis.AxisY else RotationAxis.AxisX | |
FlipComposable(angle = angle_.value, front =it.first.toString(), back =it.second.toString(), axis = axis) | |
} | |
} | |
} | |
} | |
fun Container.iterator(): Iterator<Pair<Char, Char>> { | |
val (leading,other) = if(front.size>back.size) front to back else back to front | |
val pair=leading.zip(other).toMutableList() + leading.drop(other.size).map { it to ' ' } | |
return pair.iterator() | |
} | |
data class Container(val front: CharArray,val back: CharArray) { | |
override fun equals(other: Any?): Boolean { | |
if (this === other) return true | |
if (javaClass != other?.javaClass) return false | |
other as Container | |
if (!front.contentEquals(other.front)) return false | |
if (!back.contentEquals(other.back)) return false | |
return true | |
} | |
override fun hashCode(): Int { | |
var result = front.contentHashCode() | |
result = 31 * result + back.contentHashCode() | |
return result | |
} | |
} | |
@Composable | |
private fun FlipComposable(axis:RotationAxis=RotationAxis.AxisY,angle: Float,front: String,back: String){ | |
Row( | |
verticalAlignment = Alignment.CenterVertically, | |
modifier = Modifier | |
.wrapContentSize() | |
.graphicsLayer { | |
if (axis == RotationAxis.AxisX) rotationX = angle | |
else rotationY = angle | |
cameraDistance = 12 * density | |
}) { | |
if (angle <= 90) { | |
Text(text = front, fontSize = 24.sp, modifier = Modifier.wrapContentSize()) | |
} else{ | |
Text(text =back, fontSize = 24.sp, modifier = Modifier | |
.graphicsLayer { | |
if (axis == RotationAxis.AxisX) rotationX = 180f | |
else rotationY = 180f | |
} | |
.wrapContentSize()) | |
} | |
} | |
} | |
private fun CoroutineScope.timer(delay:Long=500,action:suspend ()->Unit):Job=launch { | |
// if the job is not active anymore i.e has completed/cancelled due to cancellation of scope associated with this job | |
// the while loop will be broken automatically | |
while (isActive){ | |
try { | |
action() | |
delay(delay) | |
}catch (ex:Exception){ | |
println("error $ex") | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment