Add favourite price-drop Check now action
This commit is contained in:
+19
@@ -106,6 +106,19 @@ Status: TODO / IN PROGRESS / DONE / BLOCKED.
|
|||||||
scene (CPListTemplate) for navigation deep-links.
|
scene (CPListTemplate) for navigation deep-links.
|
||||||
- [ ] **Alert region tuning** — make alert trigger radius + dedup window
|
- [ ] **Alert region tuning** — make alert trigger radius + dedup window
|
||||||
user-configurable (currently fixed 300 m trigger / 1 per station per hour).
|
user-configurable (currently fixed 300 m trigger / 1 per station per hour).
|
||||||
|
- [ ] **Price-drop alerts: threshold control + Check now** — keep the current
|
||||||
|
cache-first / 12 h refresh policy, but add a per-alert sensitivity control
|
||||||
|
for favourite price-drop alerts instead of a fetch-frequency slider. Scope:
|
||||||
|
`Minimum change` picker (e.g. 0.5p / 1.0p / 2.0p), plus a `Check now`
|
||||||
|
action in the Alerts tab that forces a fetch and immediately re-evaluates the
|
||||||
|
cheapest-favourite alert. Copy should set expectation honestly: standard
|
||||||
|
mode checks when FuelBoard refreshes prices (up to twice daily).
|
||||||
|
- [ ] **Price-drop alerts: optional frequent-check mode** — if the app ever
|
||||||
|
relaxes the current "twice daily max" data policy, expose this as a clearly
|
||||||
|
separate mode rather than a freeform frequency slider. Example framing:
|
||||||
|
`Standard` (current behaviour) vs `Frequent` (best-effort extra checks),
|
||||||
|
with conservative caps (e.g. every 4–6 h, not hourly) and copy that does not
|
||||||
|
promise exact timing under iOS background scheduling.
|
||||||
- [ ] **Pull-to-refresh spinner state** — surface refresh in-flight state
|
- [ ] **Pull-to-refresh spinner state** — surface refresh in-flight state
|
||||||
(currently `refreshable` fires but no visible progress in the row list).
|
(currently `refreshable` fires but no visible progress in the row list).
|
||||||
- [x] **Offline first-run** — bundled REAL 8,022-station dump (`FuelBoardDump`,
|
- [x] **Offline first-run** — bundled REAL 8,022-station dump (`FuelBoardDump`,
|
||||||
@@ -135,6 +148,12 @@ Status: TODO / IN PROGRESS / DONE / BLOCKED.
|
|||||||
trend, after the Trends UI lands (one-kind rule preserved).
|
trend, after the Trends UI lands (one-kind rule preserved).
|
||||||
- [ ] **Price alerts for a specific station** — notify when a starred station's
|
- [ ] **Price alerts for a specific station** — notify when a starred station's
|
||||||
price drops below a user threshold.
|
price drops below a user threshold.
|
||||||
|
- [ ] **Price-drop alerts: mode = Cheapest favourite / All favourites** — keep
|
||||||
|
`Cheapest favourite` as the default low-noise mode, but explore an optional
|
||||||
|
`All favourites` mode for one fuel. Guardrails if built: threshold required,
|
||||||
|
per-station dedupe based on last-alerted price (not just time), and combine
|
||||||
|
multiple drops from one refresh into a single summary notification rather
|
||||||
|
than one alert per station.
|
||||||
- [ ] **Share sheet** — share "Cheapest Unleaded near me" as text/image card.
|
- [ ] **Share sheet** — share "Cheapest Unleaded near me" as text/image card.
|
||||||
- [ ] **Watch app** — glanceable cheapest-price complication (WatchKit + shared
|
- [ ] **Watch app** — glanceable cheapest-price complication (WatchKit + shared
|
||||||
app-group store; watch target would need to be added to the project).
|
app-group store; watch target would need to be added to the project).
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ struct AlertsView: View {
|
|||||||
let distanceUnit: DistanceUnit
|
let distanceUnit: DistanceUnit
|
||||||
let monitoredCount: Int
|
let monitoredCount: Int
|
||||||
let lastAlert: String?
|
let lastAlert: String?
|
||||||
|
let onCheckFavouriteDropNow: () -> Void
|
||||||
|
|
||||||
/// The Stations-tab search distance shown in the user's unit, e.g.
|
/// The Stations-tab search distance shown in the user's unit, e.g.
|
||||||
/// "5 miles" or "8 km" — for the "Follow search" rows.
|
/// "5 miles" or "8 km" — for the "Follow search" rows.
|
||||||
@@ -139,6 +140,8 @@ struct AlertsView: View {
|
|||||||
Text(fuel.displayName).tag(fuel)
|
Text(fuel.displayName).tag(fuel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Button("Check now", action: onCheckFavouriteDropNow)
|
||||||
|
.disabled(!favouriteDropEnabled)
|
||||||
} header: {
|
} header: {
|
||||||
Text("Price-drop alerts")
|
Text("Price-drop alerts")
|
||||||
} footer: {
|
} footer: {
|
||||||
|
|||||||
@@ -623,7 +623,10 @@ struct ContentView: View {
|
|||||||
stationLimit: stationLimit,
|
stationLimit: stationLimit,
|
||||||
distanceUnit: distanceUnit,
|
distanceUnit: distanceUnit,
|
||||||
monitoredCount: monitor.monitoredStationIDs.count,
|
monitoredCount: monitor.monitoredStationIDs.count,
|
||||||
lastAlert: monitor.lastAlert
|
lastAlert: monitor.lastAlert,
|
||||||
|
onCheckFavouriteDropNow: {
|
||||||
|
Task { await refresh(force: true) }
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user