237 lines
9.2 KiB
Kotlin
237 lines
9.2 KiB
Kotlin
package com.aiosman.riderpro
|
|
|
|
import android.content.pm.PackageManager
|
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
|
import androidx.activity.result.contract.ActivityResultContracts
|
|
import androidx.compose.foundation.Image
|
|
import androidx.compose.foundation.background
|
|
import androidx.compose.foundation.clickable
|
|
import androidx.compose.foundation.layout.Box
|
|
import androidx.compose.foundation.layout.Row
|
|
import androidx.compose.foundation.layout.Spacer
|
|
import androidx.compose.foundation.layout.WindowInsets
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
import androidx.compose.foundation.layout.navigationBars
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.foundation.layout.size
|
|
import androidx.compose.foundation.layout.width
|
|
import androidx.compose.foundation.shape.CircleShape
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
import androidx.compose.foundation.text.BasicTextField
|
|
import androidx.compose.material3.Button
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.runtime.setValue
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.draw.clip
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.graphics.ColorFilter
|
|
import androidx.compose.ui.platform.LocalContext
|
|
import androidx.compose.ui.platform.LocalDensity
|
|
import androidx.compose.ui.res.painterResource
|
|
import androidx.compose.ui.text.TextStyle
|
|
import androidx.compose.ui.text.font.FontWeight
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.unit.sp
|
|
import androidx.core.content.ContextCompat
|
|
import com.google.android.gms.location.FusedLocationProviderClient
|
|
import com.google.android.gms.location.LocationServices
|
|
import com.google.android.gms.maps.model.CameraPosition
|
|
import com.google.android.gms.maps.model.LatLng
|
|
import com.google.maps.android.compose.GoogleMap
|
|
import com.google.maps.android.compose.MapProperties
|
|
import com.google.maps.android.compose.MapUiSettings
|
|
import com.google.maps.android.compose.MarkerComposable
|
|
import com.google.maps.android.compose.MarkerState
|
|
import com.google.maps.android.compose.rememberCameraPositionState
|
|
|
|
@Composable
|
|
fun StreetPage() {
|
|
val navController = LocalNavController.current
|
|
val context = LocalContext.current
|
|
val fusedLocationClient: FusedLocationProviderClient =
|
|
LocationServices.getFusedLocationProviderClient(context)
|
|
var currentLocation by remember { mutableStateOf<LatLng?>(null) }
|
|
val navigationBarHeight = with(LocalDensity.current) {
|
|
WindowInsets.navigationBars.getBottom(this).toDp()
|
|
}
|
|
val cameraPositionState = rememberCameraPositionState {
|
|
position = CameraPosition.fromLatLngZoom(currentLocation ?: LatLng(0.0, 0.0), 10f)
|
|
}
|
|
var hasLocationPermission by remember { mutableStateOf(false) }
|
|
var searchText by remember { mutableStateOf("") }
|
|
val permissionLauncher = rememberLauncherForActivityResult(
|
|
contract = ActivityResultContracts.RequestPermission(),
|
|
onResult = { isGranted ->
|
|
hasLocationPermission = isGranted
|
|
if (isGranted) {
|
|
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
|
|
if (location != null) {
|
|
currentLocation = LatLng(location.latitude, location.longitude)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
LaunchedEffect(Unit) {
|
|
when (PackageManager.PERMISSION_GRANTED) {
|
|
ContextCompat.checkSelfPermission(
|
|
context,
|
|
android.Manifest.permission.ACCESS_FINE_LOCATION
|
|
) -> {
|
|
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
|
|
if (location != null) {
|
|
currentLocation = LatLng(location.latitude, location.longitude)
|
|
}
|
|
}
|
|
hasLocationPermission = true
|
|
}
|
|
|
|
else -> {
|
|
permissionLauncher.launch(android.Manifest.permission.ACCESS_FINE_LOCATION)
|
|
}
|
|
}
|
|
}
|
|
LaunchedEffect(currentLocation) {
|
|
cameraPositionState.position =
|
|
CameraPosition.fromLatLngZoom(currentLocation ?: LatLng(0.0, 0.0), 10f)
|
|
}
|
|
Box(
|
|
modifier = Modifier.fillMaxSize().padding(bottom = 56.dp + navigationBarHeight)
|
|
) {
|
|
GoogleMap(
|
|
modifier = Modifier.fillMaxSize(),
|
|
cameraPositionState = cameraPositionState,
|
|
properties = MapProperties(
|
|
isMyLocationEnabled = hasLocationPermission,
|
|
),
|
|
uiSettings = MapUiSettings(
|
|
compassEnabled = true,
|
|
myLocationButtonEnabled = false,
|
|
zoomControlsEnabled = false
|
|
)
|
|
) {
|
|
|
|
countries.forEach { position ->
|
|
MarkerComposable(
|
|
state = MarkerState(position = LatLng(position.lat, position.lng)),
|
|
onClick = { it ->
|
|
navController.navigate("LocationDetail")
|
|
true
|
|
}
|
|
) {
|
|
Image(
|
|
painter = painterResource(id = R.drawable.rider_pro_map_mark),
|
|
contentDescription = "",
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
Image(
|
|
painter = painterResource(id = R.drawable.rider_pro_my_location),
|
|
contentDescription = "",
|
|
modifier = Modifier
|
|
.align(Alignment.BottomStart)
|
|
.padding(start = 16.dp, bottom = 16.dp + navigationBarHeight) .clickable {
|
|
currentLocation?.let {
|
|
cameraPositionState.position = CameraPosition.fromLatLngZoom(it, cameraPositionState.position.zoom)
|
|
}
|
|
}
|
|
)
|
|
Box(
|
|
modifier = Modifier
|
|
.align(Alignment.BottomEnd)
|
|
.padding(end = 16.dp, bottom = 16.dp + navigationBarHeight)
|
|
) {
|
|
Box(
|
|
modifier = Modifier
|
|
.size(48.dp)
|
|
.clip(CircleShape)
|
|
.background(color = Color(0xffda3832))
|
|
|
|
) {
|
|
Image(
|
|
painter = painterResource(id = R.drawable.rider_pro_new_post_add_pic),
|
|
contentDescription = "",
|
|
modifier = Modifier
|
|
.align(Alignment.Center).size(36.dp),
|
|
colorFilter = ColorFilter.tint(Color.White)
|
|
|
|
)
|
|
}
|
|
}
|
|
|
|
Box(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.align(Alignment.TopCenter)
|
|
.padding(top = 64.dp, start = 16.dp,end=16.dp)
|
|
) {
|
|
Box(
|
|
modifier = Modifier.background(Color.White).padding(16.dp),
|
|
) {
|
|
Box(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.clip(RoundedCornerShape(16.dp))
|
|
.background(Color(0xfff7f7f7))
|
|
.padding(vertical = 8.dp, horizontal = 16.dp)
|
|
) {
|
|
Row(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
verticalAlignment = Alignment.CenterVertically
|
|
) {
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.rider_pro_search_location),
|
|
contentDescription = "",
|
|
tint = Color(0xffc6c6c6),
|
|
modifier = Modifier.size(24.dp)
|
|
)
|
|
Spacer(modifier = Modifier.width(8.dp))
|
|
Box(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
) {
|
|
if (searchText.isEmpty()){
|
|
Text(
|
|
text = "Please enter a search location",
|
|
color = Color(0xffc6c6c6),
|
|
fontSize = 16.sp,
|
|
modifier = Modifier.padding(start = 8.dp)
|
|
)
|
|
}
|
|
|
|
BasicTextField(
|
|
value = searchText,
|
|
onValueChange = {
|
|
searchText = it
|
|
},
|
|
modifier = Modifier
|
|
.fillMaxWidth(),
|
|
textStyle = TextStyle(
|
|
fontSize = 16.sp,
|
|
fontWeight = FontWeight.Normal
|
|
)
|
|
)
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} |