Initial commit

This commit is contained in:
2025-06-12 23:20:21 +02:00
parent 1656e706a0
commit 714cdb6795
122 changed files with 3335 additions and 916 deletions

View File

@ -0,0 +1,14 @@
plugins {
alias(libs.plugins.flights.android.library.compose)
alias(libs.plugins.flights.android.library.hilt)
}
android {
namespace = "dev.adriankuta.flights.ui.sharedui"
}
dependencies {
implementation(projects.ui.designsystem)
implementation(libs.timber)
}

View File

@ -0,0 +1,33 @@
# Exceptions for compose. See https://detekt.dev/docs/introduction/compose
naming:
FunctionNaming:
functionPattern: '[a-zA-Z][a-zA-Z0-9]*'
TopLevelPropertyNaming:
constantPattern: '[A-Z][A-Za-z0-9]*'
complexity:
LongParameterList:
ignoreAnnotated: [ 'Composable' ]
TooManyFunctions:
ignoreAnnotatedFunctions: [ 'Preview' ]
style:
MagicNumber:
ignorePropertyDeclaration: true
ignoreCompanionObjectPropertyDeclaration: true
ignoreAnnotated: [ 'Composable' ]
UnusedPrivateMember:
ignoreAnnotated: [ 'Composable' ]
# Deviations from defaults
formatting:
TrailingCommaOnCallSite:
active: true
autoCorrect: true
useTrailingCommaOnCallSite: true
TrailingCommaOnDeclarationSite:
active: true
autoCorrect: true
useTrailingCommaOnDeclarationSite: true

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<issues format="6" by="lint 8.10.1" type="baseline" client="gradle" dependencies="false" name="AGP (8.10.1)" variant="all" version="8.10.1">
<issue
id="Aligned16KB"
message="The native library `arm64-v8a/libmockkjvmtiagent.so` (from `io.mockk:mockk-agent-android:1.14.2`) is not 16 KB aligned">
<location
file="$GRADLE_USER_HOME/caches/8.11.1/transforms/9ee3fe20033b4dd897c7dfcf7c303d16/transformed/mockk-agent-android-1.14.2/jni/arm64-v8a/libmockkjvmtiagent.so"/>
</issue>
<issue
id="Aligned16KB"
message="The native library `arm64-v8a/libmockkjvmtiagent.so` (from `io.mockk:mockk-agent-android:1.14.2`) is not 16 KB aligned">
<location
file="$GRADLE_USER_HOME/caches/8.11.1/transforms/9ee3fe20033b4dd897c7dfcf7c303d16/transformed/mockk-agent-android-1.14.2/jni/arm64-v8a/libmockkjvmtiagent.so"/>
</issue>
</issues>

View File

@ -0,0 +1,127 @@
package dev.adriankuta.flights.ui.sharedui
import android.view.HapticFeedbackConstants
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import dev.adriankuta.flights.ui.designsystem.theme.FlightsTheme
@Suppress("LongMethod")
@Composable
fun Counter(
value: Int,
onCountChange: (diff: Int) -> Unit,
modifier: Modifier = Modifier,
label: String? = null,
) {
val view = LocalView.current
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = modifier.width(IntrinsicSize.Min),
) {
if (label != null) {
Text(
text = label,
style = MaterialTheme.typography.labelLarge,
)
}
AnimatedContent(
modifier = Modifier,
targetState = value,
label = "Questions counter animation",
transitionSpec = {
if (targetState > initialState) {
scaleIn() + slideInHorizontally { it / 2 } togetherWith
scaleOut() + slideOutHorizontally { -it / 2 } using
SizeTransform(clip = false)
} else {
scaleIn() + slideInHorizontally { -it / 2 } togetherWith
scaleOut() + slideOutHorizontally { it / 2 } using
SizeTransform(clip = false)
}
},
) { state ->
Text(
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
text = "$state",
style = MaterialTheme.typography.displayMedium,
)
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Button(
modifier = Modifier.weight(1f),
onClick = {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
onCountChange(-1)
},
shape = MaterialTheme.shapes.medium,
enabled = value > 0,
) {
Text(
text = "-",
style = MaterialTheme.typography.labelLarge,
)
}
Button(
modifier = Modifier.weight(1f),
onClick = {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
onCountChange(1)
},
shape = MaterialTheme.shapes.medium,
enabled = value < 20,
) {
Text(
text = "+",
style = MaterialTheme.typography.labelLarge,
)
}
}
}
}
@Preview(showBackground = true)
@Composable
private fun CounterPreview() {
var tapCounter by remember {
mutableIntStateOf(20)
}
FlightsTheme {
Counter(
value = tapCounter,
label = "Taps",
onCountChange = { tapCounter += it },
)
}
}