Capture location at every step, not just step 1
- Show the location button on all three steps - Send lat/lon to the server for every photo upload - Clear gpsCoords after each upload so each step gets a fresh capture - Store location_1 (step 1) and location_2 (step 2) in the session - Ride 1 LogEntry uses location_1; Ride 2 LogEntry uses location_2 https://claude.ai/code/session_015myTTMs6yDsAGarATe5ePZ
This commit is contained in:
parent
8c5450348a
commit
1faaf4f65b
2 changed files with 28 additions and 13 deletions
32
src/main.rs
32
src/main.rs
|
|
@ -22,7 +22,8 @@ struct Session {
|
||||||
date: Option<String>,
|
date: Option<String>,
|
||||||
time_1: Option<String>, // start of ride 1
|
time_1: Option<String>, // start of ride 1
|
||||||
time_2: Option<String>, // end of ride 1 / start of ride 2
|
time_2: Option<String>, // end of ride 1 / start of ride 2
|
||||||
location: Option<String>,
|
location_1: Option<String>, // location at step 1 (start of ride 1)
|
||||||
|
location_2: Option<String>, // location at step 2 (start of ride 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppState = Arc<Mutex<Session>>;
|
type AppState = Arc<Mutex<Session>>;
|
||||||
|
|
@ -144,7 +145,7 @@ async fn upload(
|
||||||
s.reading_1 = Some(reading);
|
s.reading_1 = Some(reading);
|
||||||
s.date = Some(date_str);
|
s.date = Some(date_str);
|
||||||
s.time_1 = Some(time_str);
|
s.time_1 = Some(time_str);
|
||||||
s.location = Some(location.clone());
|
s.location_1 = Some(location.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Json(UploadResponse {
|
Ok(Json(UploadResponse {
|
||||||
|
|
@ -158,11 +159,21 @@ async fn upload(
|
||||||
}
|
}
|
||||||
|
|
||||||
2 => {
|
2 => {
|
||||||
let (reading_1, location) = {
|
// Reverse-geocode before acquiring the lock (async operation)
|
||||||
|
let location = if let (Some(la), Some(lo)) = (lat, lon) {
|
||||||
|
geocode::reverse_geocode(la, lo)
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|_| format!("{:.5}, {:.5}", la, lo))
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
let reading_1 = {
|
||||||
let mut s = state.lock().unwrap();
|
let mut s = state.lock().unwrap();
|
||||||
s.reading_2 = Some(reading);
|
s.reading_2 = Some(reading);
|
||||||
s.time_2 = Some(time_str);
|
s.time_2 = Some(time_str);
|
||||||
(s.reading_1, s.location.clone())
|
s.location_2 = Some(location.clone());
|
||||||
|
s.reading_1
|
||||||
};
|
};
|
||||||
|
|
||||||
let ride1_km = reading_1.map(|r1| reading.saturating_sub(r1));
|
let ride1_km = reading_1.map(|r1| reading.saturating_sub(r1));
|
||||||
|
|
@ -170,7 +181,7 @@ async fn upload(
|
||||||
Ok(Json(UploadResponse {
|
Ok(Json(UploadResponse {
|
||||||
step: 2,
|
step: 2,
|
||||||
reading,
|
reading,
|
||||||
location,
|
location: Some(location),
|
||||||
ride1_km,
|
ride1_km,
|
||||||
ride2_km: None,
|
ride2_km: None,
|
||||||
done: false,
|
done: false,
|
||||||
|
|
@ -179,7 +190,7 @@ async fn upload(
|
||||||
|
|
||||||
3 => {
|
3 => {
|
||||||
// Read everything we need from the session and release the lock
|
// Read everything we need from the session and release the lock
|
||||||
let (r1, r2, date, time_1, time_2, location) = {
|
let (r1, r2, date, time_1, time_2, location_1, location_2) = {
|
||||||
let s = state.lock().unwrap();
|
let s = state.lock().unwrap();
|
||||||
(
|
(
|
||||||
s.reading_1,
|
s.reading_1,
|
||||||
|
|
@ -187,7 +198,8 @@ async fn upload(
|
||||||
s.date.clone(),
|
s.date.clone(),
|
||||||
s.time_1.clone(),
|
s.time_1.clone(),
|
||||||
s.time_2.clone(),
|
s.time_2.clone(),
|
||||||
s.location.clone().unwrap_or_default(),
|
s.location_1.clone().unwrap_or_default(),
|
||||||
|
s.location_2.clone().unwrap_or_default(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -209,7 +221,7 @@ async fn upload(
|
||||||
odometer_start: r1,
|
odometer_start: r1,
|
||||||
odometer_end: r2,
|
odometer_end: r2,
|
||||||
trip_km: r2.saturating_sub(r1),
|
trip_km: r2.saturating_sub(r1),
|
||||||
location: location.clone(),
|
location: location_1,
|
||||||
notes: "Ride 1".into(),
|
notes: "Ride 1".into(),
|
||||||
},
|
},
|
||||||
LogEntry {
|
LogEntry {
|
||||||
|
|
@ -218,7 +230,7 @@ async fn upload(
|
||||||
odometer_start: r2,
|
odometer_start: r2,
|
||||||
odometer_end: r3,
|
odometer_end: r3,
|
||||||
trip_km: r3.saturating_sub(r2),
|
trip_km: r3.saturating_sub(r2),
|
||||||
location: location.clone(),
|
location: location_2.clone(),
|
||||||
notes: "Ride 2".into(),
|
notes: "Ride 2".into(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -232,7 +244,7 @@ async fn upload(
|
||||||
Ok(Json(UploadResponse {
|
Ok(Json(UploadResponse {
|
||||||
step: 3,
|
step: 3,
|
||||||
reading: r3,
|
reading: r3,
|
||||||
location: Some(location),
|
location: Some(location_2),
|
||||||
ride1_km: Some(r2.saturating_sub(r1)),
|
ride1_km: Some(r2.saturating_sub(r1)),
|
||||||
ride2_km: Some(r3.saturating_sub(r2)),
|
ride2_km: Some(r3.saturating_sub(r2)),
|
||||||
done: true,
|
done: true,
|
||||||
|
|
|
||||||
|
|
@ -203,9 +203,9 @@
|
||||||
3: 'End of ride 2',
|
3: 'End of ride 2',
|
||||||
};
|
};
|
||||||
dots(n, n - 1);
|
dots(n, n - 1);
|
||||||
const locBlock = n === 1 ? `
|
const locBlock = `
|
||||||
<button class="btn btn-gray" style="margin-bottom:10px" onclick="getLocation()">📍 Share location (optional)</button>
|
<button class="btn btn-gray" style="margin-bottom:10px" onclick="getLocation()">📍 Share location (optional)</button>
|
||||||
<div id="loc-status" style="font-size:0.85rem;text-align:center;min-height:1.2em;margin-bottom:6px"></div>` : '';
|
<div id="loc-status" style="font-size:0.85rem;text-align:center;min-height:1.2em;margin-bottom:6px"></div>`;
|
||||||
render(`
|
render(`
|
||||||
<div class="step-label">Step ${n} of 3</div>
|
<div class="step-label">Step ${n} of 3</div>
|
||||||
<div class="step-title">${labels[n]}</div>
|
<div class="step-title">${labels[n]}</div>
|
||||||
|
|
@ -230,10 +230,13 @@
|
||||||
|
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append('image', file);
|
form.append('image', file);
|
||||||
if (step === 1 && gpsCoords) {
|
if (gpsCoords) {
|
||||||
form.append('lat', gpsCoords.lat);
|
form.append('lat', gpsCoords.lat);
|
||||||
form.append('lon', gpsCoords.lon);
|
form.append('lon', gpsCoords.lon);
|
||||||
}
|
}
|
||||||
|
// Clear so next step starts fresh
|
||||||
|
gpsCoords = null;
|
||||||
|
sessionStorage.removeItem('gpsCoords');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/upload?step=' + step, { method: 'POST', body: form });
|
const resp = await fetch('/upload?step=' + step, { method: 'POST', body: form });
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue