diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1ef53468..5ccdf0d6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -216,8 +216,8 @@ dependencies { implementation("com.google.code.gson:gson:2.10.1") // Signal Protocol - implementation("org.signal:libsignal-client:0.64.1") - implementation("org.signal:libsignal-android:0.64.1") + implementation("org.signal:libsignal-client:0.65.0") + implementation("org.signal:libsignal-android:0.65.0") implementation(project(":data")) } diff --git a/app/src/main/java/com/canopas/yourspace/ui/flow/journey/components/JourneyMap.kt b/app/src/main/java/com/canopas/yourspace/ui/flow/journey/components/JourneyMap.kt index 3d119d1e..ec7a724b 100644 --- a/app/src/main/java/com/canopas/yourspace/ui/flow/journey/components/JourneyMap.kt +++ b/app/src/main/java/com/canopas/yourspace/ui/flow/journey/components/JourneyMap.kt @@ -91,13 +91,18 @@ fun JourneyMap( val boundsBuilder = LatLngBounds.builder() .apply { include(fromLatLang) - include(toLatLang) + if (location?.to_latitude != null && location.to_longitude != null) { + include(toLatLang) + } routePoints.forEach { latLng -> this.include(latLng) } }.build() val update = CameraUpdateFactory.newLatLngBounds(boundsBuilder, 50) cameraPositionState.move(update) + if (location?.to_latitude == null && location?.to_longitude == null) { + cameraPositionState.move(CameraUpdateFactory.newLatLngZoom(fromLatLang, 18f)) + } } catch (e: Exception) { e.printStackTrace() } @@ -135,8 +140,9 @@ fun JourneyMap( ) { location?.let { LocationMarker(fromLatLang, anchor, fromMarkerContent) - - LocationMarker(toLatLang, anchor, toMarkerContent) + if (location.to_latitude != null && location.to_longitude != null) { + LocationMarker(toLatLang, anchor, toMarkerContent) + } Polyline( points = if (shouldAnimate) animatedPoints else routePoints, diff --git a/app/src/main/java/com/canopas/yourspace/ui/flow/journey/components/LocationHistory.kt b/app/src/main/java/com/canopas/yourspace/ui/flow/journey/components/LocationHistory.kt index cc9e15ee..d937e620 100644 --- a/app/src/main/java/com/canopas/yourspace/ui/flow/journey/components/LocationHistory.kt +++ b/app/src/main/java/com/canopas/yourspace/ui/flow/journey/components/LocationHistory.kt @@ -5,6 +5,7 @@ import android.location.Address import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -72,7 +73,7 @@ fun LocationHistoryItem( selectedMapStyle: String ) { if (location.isSteady()) { - SteadyLocationItem(location, isFirstItem, isLastItem, journeyList) { + SteadyLocationItem(location, isFirstItem, isLastItem, journeyList, showJourneyDetails) { addPlaceTap(location.from_latitude, location.from_longitude) } } else { @@ -155,6 +156,7 @@ fun SteadyLocationItem( isFirstItem: Boolean, isLastItem: Boolean, journeyList: List, + onTap: () -> Unit, addPlace: () -> Unit ) { val context = LocalContext.current @@ -209,6 +211,7 @@ fun SteadyLocationItem( Column( modifier = Modifier + .clickable { onTap() } .padding(start = 16.dp) .weight(1f) ) { diff --git a/app/src/main/java/com/canopas/yourspace/ui/flow/journey/detail/UserJourneyDetailScreen.kt b/app/src/main/java/com/canopas/yourspace/ui/flow/journey/detail/UserJourneyDetailScreen.kt index d0ec3a82..83d5c102 100644 --- a/app/src/main/java/com/canopas/yourspace/ui/flow/journey/detail/UserJourneyDetailScreen.kt +++ b/app/src/main/java/com/canopas/yourspace/ui/flow/journey/detail/UserJourneyDetailScreen.kt @@ -8,12 +8,14 @@ import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack @@ -38,6 +40,8 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.canopas.yourspace.R @@ -139,43 +143,84 @@ private fun JourneyInfo(journey: LocationJourney) { val distance = getDistanceString(journey.route_distance ?: 0.0) val duration = getRouteDurationString(journey.route_duration ?: 0) - Text( - text = "$distance - $duration", - color = AppTheme.colorScheme.textPrimary, - style = AppTheme.appTypography.header2, - modifier = Modifier - .padding(top = 8.dp, bottom = 24.dp) - .padding(horizontal = 16.dp) - ) + if (toAddress != null) { + Text( + text = "$distance - $duration", + color = AppTheme.colorScheme.textPrimary, + style = AppTheme.appTypography.header2, + modifier = Modifier + .padding(top = 8.dp, bottom = 24.dp) + .padding(horizontal = 16.dp) + ) - Row( - verticalAlignment = Alignment.Top, - modifier = Modifier - .height(90.dp) - ) { - DottedTimeline(isSteadyLocation = false, isLastItem = false, isJourneyDetail = true) - Column( + Row( + verticalAlignment = Alignment.Top, modifier = Modifier - .padding(start = 16.dp) - .weight(1f) + .height(90.dp) ) { - PlaceInfo(fromAddressStr, getFormattedLocationTime(journey.created_at!!)) + DottedTimeline(isSteadyLocation = false, isLastItem = false, isJourneyDetail = true) + Column( + modifier = Modifier + .padding(start = 16.dp) + .weight(1f) + ) { + PlaceInfo(fromAddressStr, getFormattedLocationTime(journey.created_at)) + } } - } - Row( - verticalAlignment = Alignment.Top, - modifier = Modifier - .height(90.dp) - ) { - DottedTimeline(isSteadyLocation = true, isLastItem = true, isJourneyDetail = true) - Column( + Row( + verticalAlignment = Alignment.Top, modifier = Modifier - .padding(start = 16.dp) - .weight(1f) + .height(90.dp) ) { - journey.updated_at?.let { getFormattedLocationTime(it) } - ?.let { PlaceInfo(toAddressStr, it) } + DottedTimeline(isSteadyLocation = true, isLastItem = true, isJourneyDetail = true) + Column( + modifier = Modifier + .padding(start = 16.dp) + .weight(1f) + ) { + PlaceInfo(toAddressStr, getFormattedLocationTime(journey.updated_at)) + } + } + } else { + Row( + verticalAlignment = Alignment.Top, + modifier = Modifier + .wrapContentHeight() + .padding(4.dp) + ) { + Icon( + painter = painterResource(R.drawable.ic_journey_destination), + contentDescription = "", + tint = AppTheme.colorScheme.primary, + modifier = Modifier + .padding(start = 8.dp) + .background(AppTheme.colorScheme.secondaryInverseVariant, CircleShape) + .size(30.dp) + .padding(4.dp) + ) + Column( + modifier = Modifier + .padding(start = 16.dp) + .weight(1f) + ) { + Text( + text = fromAddressStr, + style = AppTheme.appTypography.body2.copy( + color = AppTheme.colorScheme.textPrimary, + fontWeight = FontWeight.Medium + ), + overflow = TextOverflow.Ellipsis, + modifier = Modifier.padding(end = 16.dp) + ) + + Spacer(modifier = Modifier.size(8.dp)) + + Text( + text = getFormattedLocationTime(journey.created_at), + style = AppTheme.appTypography.caption.copy(color = AppTheme.colorScheme.textDisabled) + ) + } } } } diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 523a621c..f8701047 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -46,17 +46,17 @@ android { dependencies { - implementation("androidx.core:core-ktx:1.13.1") + implementation("androidx.core:core-ktx:1.15.0") implementation("androidx.appcompat:appcompat:1.7.0") implementation("com.google.android.material:material:1.12.0") implementation("androidx.hilt:hilt-common:1.2.0") - implementation("androidx.work:work-runtime:2.9.1") + implementation("androidx.work:work-runtime:2.10.0") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.2.1") androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") // Hilt - val hilt = "2.50" + val hilt = "2.51.1" implementation("com.google.dagger:hilt-android:$hilt") ksp("com.google.dagger:hilt-compiler:$hilt") @@ -64,9 +64,9 @@ dependencies { implementation("androidx.datastore:datastore-preferences:1.1.1") // Firebase - implementation(platform("com.google.firebase:firebase-bom:33.4.0")) + implementation(platform("com.google.firebase:firebase-bom:33.7.0")) implementation("com.google.firebase:firebase-auth") - implementation("com.google.android.gms:play-services-auth:21.2.0") + implementation("com.google.android.gms:play-services-auth:21.3.0") implementation("com.google.firebase:firebase-firestore") implementation("com.google.firebase:firebase-storage") implementation("com.google.firebase:firebase-functions") @@ -90,7 +90,7 @@ dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") // Place - implementation("com.google.android.libraries.places:places:4.0.0") + implementation("com.google.android.libraries.places:places:4.1.0") // Signal Protocol implementation("org.signal:libsignal-client:0.65.0") diff --git a/data/src/main/java/com/canopas/yourspace/data/service/user/ApiUserService.kt b/data/src/main/java/com/canopas/yourspace/data/service/user/ApiUserService.kt index 3af443e8..4c35127a 100644 --- a/data/src/main/java/com/canopas/yourspace/data/service/user/ApiUserService.kt +++ b/data/src/main/java/com/canopas/yourspace/data/service/user/ApiUserService.kt @@ -49,7 +49,8 @@ class ApiUserService @Inject constructor( suspend fun getUser(userId: String): ApiUser? { return try { - val user = userRef.document(userId).get().await().toObject(ApiUser::class.java) + val user = userRef.document(userId.takeIf { it.isNotBlank() } ?: "null").get().await() + .toObject(ApiUser::class.java) when { user == null -> null currentUser == null || user.id != currentUser.id -> user