Skip to content

Commit 50c9587

Browse files
committed
Merge branch 'feature/mapacalorypoi' into develop
2 parents 5f389dd + 7372261 commit 50c9587

18 files changed

Lines changed: 1236 additions & 160 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ google-services.json
3232

3333
# Android Profiling
3434
*.hprof
35+
36+
.codegraph/

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ dependencies {
9090
implementation(libs.play.services.location)
9191
implementation(libs.accompanist.permissions)
9292
implementation(libs.maps.compose)
93+
implementation(libs.maps.compose.utils)
9394
implementation(libs.play.services.maps)
9495
implementation("androidx.compose.material:material-icons-extended")
9596
implementation("org.osmdroid:osmdroid-android:6.1.16")

app/src/main/java/com/appnotresponding/rumbo/models/placeState.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ package com.appnotresponding.rumbo.models
33
data class PlaceState(
44
val availablePlaces: List<Place> = emptyList(),
55
val itinerary: List<Place> = emptyList(),
6-
val selectedPlace: Place? = null
6+
val selectedPlace: Place? = null,
7+
val previewedPlace: Place? = null,
8+
val searchQuery: String = ""
79
)

app/src/main/java/com/appnotresponding/rumbo/models/review.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.appnotresponding.rumbo.models
22

33
data class Review(
4-
val id: String,
5-
val user: User,
4+
val id: String = "",
5+
val user: User = User(),
66
val authorName: String = user.name,
77
val authorProfilePhotoUrl: String? = user.profilePictureUrl,
8-
val rating: Float,
9-
val text: String,
10-
val time: Long
8+
val rating: Float = 0f,
9+
val text: String = "",
10+
val photoUrl: String? = null,
11+
val time: Long = 0L
1112
)
1213

1314
val sampleReview = Review(

app/src/main/java/com/appnotresponding/rumbo/ui/components/atoms/Rating.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ fun RumboRatingStar(
6565
.size(starSize)
6666
.then(
6767
if (onRatingChanged != null) {
68-
Modifier.clickable { onRatingChanged(i.toFloat()) }
69-
} else Modifier),
68+
Modifier.clickable { onRatingChanged(i.toFloat()) }
69+
} else Modifier),
7070
tint = tint)
7171
}
7272
}

app/src/main/java/com/appnotresponding/rumbo/ui/components/molecules/itinerary/ItineraryItemCard.kt

Lines changed: 151 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,26 @@ import androidx.compose.foundation.layout.Arrangement
66
import androidx.compose.foundation.layout.Box
77
import androidx.compose.foundation.layout.Column
88
import androidx.compose.foundation.layout.Row
9+
import androidx.compose.foundation.layout.Spacer
910
import androidx.compose.foundation.layout.aspectRatio
1011
import androidx.compose.foundation.layout.fillMaxSize
1112
import androidx.compose.foundation.layout.fillMaxWidth
1213
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.layout.width
15+
import androidx.compose.material.icons.Icons
16+
import androidx.compose.material.icons.filled.Delete
17+
import androidx.compose.material3.CardDefaults
18+
import androidx.compose.material3.ElevatedCard
19+
import androidx.compose.material3.Icon
20+
import androidx.compose.material3.IconButton
1321
import androidx.compose.material3.MaterialTheme
1422
import androidx.compose.material3.Text
1523
import androidx.compose.runtime.Composable
24+
import androidx.compose.runtime.collectAsState
25+
import androidx.compose.runtime.getValue
26+
import androidx.compose.runtime.mutableStateOf
27+
import androidx.compose.runtime.remember
28+
import androidx.compose.runtime.setValue
1629
import androidx.compose.ui.Alignment
1730
import androidx.compose.ui.Modifier
1831
import androidx.compose.ui.draw.clip
@@ -42,53 +55,145 @@ import java.util.Locale
4255
*/
4356
@Composable
4457
fun ItineraryItemCard(p: Place, placesViewModel: PlacesViewModel, controller: NavHostController) {
58+
val placesState by placesViewModel.uiState.collectAsState()
59+
val selectedPlace = placesState.selectedPlace
60+
val isActiveRoute = selectedPlace?.id == p.id
4561

46-
Row(modifier = Modifier.fillMaxWidth()) {
47-
Box(
48-
modifier = Modifier
49-
.weight(4f)
50-
.aspectRatio(1f)
51-
.padding(start = 8.dp, end = 8.dp, bottom = 8.dp, top = 2.dp)
52-
.clip(MaterialTheme.shapes.medium)
53-
.background(MaterialTheme.colorScheme.secondaryContainer),
54-
contentAlignment = Alignment.Center
55-
) {
56-
SubcomposeAsyncImage(
57-
model = p.imageUrl,
58-
contentDescription = "Imagen de ${p.name}",
59-
contentScale = ContentScale.Crop,
60-
modifier = Modifier.fillMaxSize(),
61-
error = {
62-
Image(
63-
painter = painterResource(R.drawable.ic_picture),
64-
contentDescription = null,
65-
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSecondaryContainer),
66-
contentScale = ContentScale.Crop
62+
var showReplaceRouteDialog by remember { mutableStateOf(false) }
63+
64+
if (showReplaceRouteDialog) {
65+
androidx.compose.material3.AlertDialog(
66+
onDismissRequest = {
67+
showReplaceRouteDialog = false
68+
},
69+
title = { Text("Ruta activa") },
70+
text = { Text("Tienes una ruta activa en curso. ¿Deseas reemplazarla?") },
71+
confirmButton = {
72+
androidx.compose.material3.TextButton(
73+
onClick = {
74+
showReplaceRouteDialog = false
75+
placesViewModel.selectForNavigation(p)
76+
controller.navigate(AppScreens.Map.name)
77+
}) {
78+
Text("Confirmar")
79+
}
80+
},
81+
dismissButton = {
82+
androidx.compose.material3.TextButton(
83+
onClick = { showReplaceRouteDialog = false }) {
84+
Text("Cancelar")
85+
}
86+
})
87+
}
88+
89+
ElevatedCard(
90+
modifier = Modifier.fillMaxWidth(), colors = CardDefaults.elevatedCardColors(
91+
containerColor = if (isActiveRoute) {
92+
MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.3f)
93+
} else {
94+
MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f)
95+
}
96+
),
97+
98+
elevation = CardDefaults.elevatedCardElevation(
99+
defaultElevation = if (isActiveRoute) 4.dp else 2.dp
100+
), shape = MaterialTheme.shapes.medium
101+
) {
102+
Column {
103+
Row(
104+
modifier = Modifier
105+
.fillMaxWidth()
106+
.padding(12.dp)
107+
) {
108+
Box(
109+
modifier = Modifier
110+
.weight(4f)
111+
.aspectRatio(1f)
112+
.clip(MaterialTheme.shapes.medium)
113+
.background(MaterialTheme.colorScheme.secondaryContainer),
114+
contentAlignment = Alignment.Center
115+
) {
116+
SubcomposeAsyncImage(
117+
model = p.imageUrl,
118+
contentDescription = "Imagen de ${p.name}",
119+
contentScale = ContentScale.Crop,
120+
modifier = Modifier.fillMaxSize(),
121+
error = {
122+
Image(
123+
painter = painterResource(R.drawable.ic_picture),
124+
contentDescription = null,
125+
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSecondaryContainer),
126+
contentScale = ContentScale.Crop
127+
)
128+
})
129+
}
130+
Spacer(modifier = Modifier.width(12.dp))
131+
Column(
132+
modifier = Modifier.weight(6f), verticalArrangement = Arrangement.spacedBy(8.dp)
133+
) {
134+
Row(
135+
verticalAlignment = Alignment.CenterVertically,
136+
horizontalArrangement = Arrangement.spacedBy(8.dp)
137+
) {
138+
Text(
139+
text = p.name,
140+
style = MaterialTheme.typography.titleMedium,
141+
color = MaterialTheme.colorScheme.onBackground,
142+
modifier = Modifier.weight(1f, fill = false)
143+
)
144+
if (isActiveRoute) {
145+
Box(
146+
modifier = Modifier
147+
.background(
148+
color = MaterialTheme.colorScheme.primary,
149+
shape = MaterialTheme.shapes.small
150+
)
151+
.padding(horizontal = 8.dp, vertical = 2.dp)
152+
) {
153+
Text(
154+
text = "Activa",
155+
style = MaterialTheme.typography.labelSmall,
156+
color = MaterialTheme.colorScheme.onPrimary
157+
)
158+
}
159+
}
160+
}
161+
Text(
162+
text = formatOpenHours(p.openHours),
163+
style = MaterialTheme.typography.bodySmall,
164+
color = MaterialTheme.colorScheme.onBackground
67165
)
68-
})
69-
}
70-
Column(
71-
modifier = Modifier
72-
.weight(6f)
73-
.padding(top = 2.dp, end = 8.dp),
74-
verticalArrangement = Arrangement.spacedBy(8.dp)
75-
) {
76-
Text(
77-
text = p.name,
78-
style = MaterialTheme.typography.titleMedium,
79-
color = MaterialTheme.colorScheme.onBackground
80-
)
81-
Text(
82-
text = formatOpenHours(p.openHours),
83-
style = MaterialTheme.typography.bodySmall,
84-
color = MaterialTheme.colorScheme.onBackground
85-
)
166+
Row(
167+
modifier = Modifier.fillMaxWidth(),
168+
horizontalArrangement = Arrangement.spacedBy(8.dp),
169+
verticalAlignment = Alignment.CenterVertically
170+
) {}
171+
}
172+
}
86173
RumboButton(
87-
text = "Iniciar Desplazamiento", onClick = {
88-
placesViewModel.selectForNavigation(p)
89-
controller.navigate(AppScreens.Map.name)
90-
}, style = RumboButtonStyle.Secondary, icon = painterResource(R.drawable.ic_map)
174+
modifier = Modifier.weight(1f).fillMaxWidth()
175+
.padding(horizontal = 12.dp, vertical = 8.dp),
176+
text = if (isActiveRoute) "Ver Ruta Activa" else "Iniciar Desplazamiento",
177+
onClick = {
178+
if (isActiveRoute) {
179+
controller.navigate(AppScreens.Map.name)
180+
} else if (selectedPlace != null) {
181+
showReplaceRouteDialog = true
182+
} else {
183+
placesViewModel.selectForNavigation(p)
184+
controller.navigate(AppScreens.Map.name)
185+
}
186+
},
187+
style = if (isActiveRoute) RumboButtonStyle.Primary else RumboButtonStyle.Secondary,
188+
icon = painterResource(R.drawable.ic_map)
91189
)
190+
IconButton(onClick = { placesViewModel.removeFromItinerary(p) }) {
191+
Icon(
192+
imageVector = Icons.Default.Delete,
193+
contentDescription = "Eliminar del Itinerario",
194+
tint = MaterialTheme.colorScheme.error
195+
)
196+
}
92197
}
93198
}
94199

@@ -103,7 +208,9 @@ fun ItineraryItemCard(p: Place, placesViewModel: PlacesViewModel, controller: Na
103208
* - Si hay un rango mas tarde hoy: "Cerrado ahora. Abre hoy a ...".
104209
* - Si no hay mas rangos hoy: busca el proximo dia con apertura.
105210
*/
106-
fun formatOpenHours(openHours: List<String>?, now: LocalDateTime = LocalDateTime.now()): String {
211+
fun formatOpenHours(
212+
openHours: List<String>?, now: LocalDateTime = LocalDateTime.now()
213+
): String {
107214
if (openHours.isNullOrEmpty()) {
108215
return "No hay información de horario"
109216
}

app/src/main/java/com/appnotresponding/rumbo/ui/components/molecules/map/MapFloatingActions.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,26 @@ fun CancelRoute(onClick: () -> Unit = {}) {
8787
}
8888
}
8989

90+
@Composable
91+
fun ToggleHeatmap(isHeatmapActive: Boolean = false, onClick: () -> Unit = {}) {
92+
val bgColor = if (isHeatmapActive) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.primary
93+
val iconTint = if (isHeatmapActive) MaterialTheme.colorScheme.onTertiary else MaterialTheme.colorScheme.onPrimary
94+
Box(
95+
modifier = Modifier
96+
.aspectRatio(1f)
97+
.clip(CircleShape)
98+
.background(bgColor), contentAlignment = Alignment.Center
99+
) {
100+
IconButton(onClick = onClick) {
101+
Icon(
102+
painter = painterResource(R.drawable.ic_map), // Reusing map icon or any suitable icon
103+
contentDescription = "Toggle Heatmap",
104+
tint = iconTint,
105+
)
106+
}
107+
}
108+
}
109+
90110
@Preview(showBackground = true, name = "MapFloatingActions - Light")
91111
@Composable
92112
private fun MapFloatingActionsLightPreview() {

0 commit comments

Comments
 (0)