Banksia/composeApp/src/commonMain/kotlin/moe/lava/banksia/App.kt

120 lines
4.8 KiB
Kotlin
Raw Normal View History

2025-04-13 00:51:32 +10:00
package moe.lava.banksia
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.add
2025-04-13 01:27:49 +10:00
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.safeContent
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
2025-04-14 13:35:26 +10:00
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SheetValue
import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.material3.rememberStandardBottomSheetState
2025-04-14 13:35:26 +10:00
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
2025-04-14 13:35:26 +10:00
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
2025-04-13 00:51:32 +10:00
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import dev.icerock.moko.geo.compose.BindLocationTrackerEffect
import dev.icerock.moko.geo.compose.LocationTrackerAccuracy
import dev.icerock.moko.geo.compose.rememberLocationTrackerFactory
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
2025-04-14 21:07:05 +10:00
import moe.lava.banksia.api.ptv.PtvService
2025-04-13 01:27:49 +10:00
import moe.lava.banksia.native.maps.Maps
import moe.lava.banksia.native.maps.Point
import moe.lava.banksia.native.maps.getScreenHeight
import moe.lava.banksia.resources.Res
import moe.lava.banksia.resources.my_location_24
2025-04-14 13:35:26 +10:00
import moe.lava.banksia.ui.Searcher
import org.jetbrains.compose.resources.painterResource
2025-04-14 13:35:26 +10:00
import org.jetbrains.compose.ui.tooling.preview.Preview
import kotlin.math.roundToInt
2025-04-13 00:51:32 +10:00
@OptIn(ExperimentalMaterial3Api::class)
2025-04-13 00:51:32 +10:00
@Composable
@Preview
fun App() {
val scaffoldState = rememberBottomSheetScaffoldState(
bottomSheetState = rememberStandardBottomSheetState(
initialValue = SheetValue.PartiallyExpanded,
skipHiddenState = false
)
)
2025-04-14 13:35:26 +10:00
val locationFactory = rememberLocationTrackerFactory(LocationTrackerAccuracy.Best)
val locationTracker = remember { locationFactory.createLocationTracker() }
BindLocationTrackerEffect(locationTracker)
var lastLocation by remember { mutableStateOf(Point(-37.8136, 144.9631)) }
var newCameraPosition by remember { mutableStateOf<Point?>(Point(-37.8136, 144.9631)) }
2025-04-14 13:35:26 +10:00
var searchTextState by remember { mutableStateOf("") }
var searchExpandedState by remember { mutableStateOf(false) }
val sheetState = scaffoldState.bottomSheetState
val extInsets = if (
sheetState.currentValue != SheetValue.Hidden ||
sheetState.targetValue != SheetValue.Hidden
) {
val offset = runCatching { sheetState.requireOffset() }
val scaffoldOffset = offset.getOrDefault(0.0f).roundToInt()
(getScreenHeight() - scaffoldOffset - WindowInsets.safeDrawing.getBottom(LocalDensity.current)).coerceAtLeast(0)
} else 0
var scope = rememberCoroutineScope()
scope.launch {
val flow = locationTracker.getLocationsFlow()
locationTracker.startTracking()
flow.distinctUntilChanged().collect {
lastLocation = Point(it.latitude, it.longitude)
}
}
2025-04-13 00:51:32 +10:00
MaterialTheme {
BottomSheetScaffold(
scaffoldState = scaffoldState,
sheetPeekHeight = 250.dp,
modifier = Modifier.fillMaxSize(),
sheetContent = { Box(modifier = Modifier) },
) {
Maps(
modifier = Modifier.fillMaxSize(),
newCameraPosition = newCameraPosition,
cameraPositionUpdated = { newCameraPosition = null },
extInsets = extInsets,
)
2025-04-14 13:35:26 +10:00
Searcher(
2025-04-14 21:07:05 +10:00
ptvService = PtvService(),
2025-04-14 13:35:26 +10:00
expanded = searchExpandedState,
onExpandedChange = { searchExpandedState = it },
text = searchTextState,
onTextChange = { searchTextState = it },
2025-04-14 21:07:05 +10:00
onRouteChange = {}
2025-04-14 13:35:26 +10:00
)
Box(
Modifier.windowInsetsPadding(WindowInsets.safeContent.add(WindowInsets(bottom = extInsets))),
contentAlignment = Alignment.BottomEnd
) {
FloatingActionButton(
containerColor = MaterialTheme.colorScheme.surfaceContainer,
onClick = {
newCameraPosition = lastLocation
},
) {
Icon(painterResource(Res.drawable.my_location_24), "Move to current location")
}
}
2025-04-13 00:51:32 +10:00
}
}
2025-04-14 21:53:07 +10:00
}