Added Minimal View.

Tap the eye icon to toggle Minimal view.
This commit is contained in:
justin authored and GitHub committed 2025-05-05 17:44:04 -07:00
1 parent ad9fc7c03c
commit 2aad798a56
1 file changed
+60 -22
+60 -22
View File
@@ -9,27 +9,41 @@ import SwiftUI
import CoreLocation import CoreLocation
struct ContentView: View { struct ContentView: View {
// Location manager to track speed and position
@StateObject private var locationManager = LocationManager() @StateObject private var locationManager = LocationManager()
// Unit toggle (true = MPH, false = KPH)
@State private var isMPH = true @State private var isMPH = true
// For tracking total trip distance
@State private var previousLocation: CLLocation? @State private var previousLocation: CLLocation?
@State private var tripDistanceMeters: Double = 0.0 @State private var tripDistanceMeters: Double = 0.0
@State private var isDarkMode = true // 🌗 Track current theme
// Dark mode toggle
@State private var isDarkMode = true
// Controls whether only speed is shown (minimal view)
@State private var isMinimalView = false
// Computed speed based on selected unit
var currentSpeed: Int { var currentSpeed: Int {
let multiplier = isMPH ? 1.0 : 1.60934 let multiplier = isMPH ? 1.0 : 1.60934
return Int(Double(locationManager.speed) * multiplier) return Int(Double(locationManager.speed) * multiplier)
} }
// Label for speed unit
var unitLabel: String { var unitLabel: String {
isMPH ? "mph" : "kph" isMPH ? "mph" : "kph"
} }
// Distance label (formatted with appropriate unit)
var distanceLabel: String { var distanceLabel: String {
let distance = isMPH ? tripDistanceMeters * 0.000621371 : tripDistanceMeters / 1000 let distance = isMPH ? tripDistanceMeters * 0.000621371 : tripDistanceMeters / 1000
let roundedDistance = Int(distance.rounded()) let roundedDistance = Int(distance.rounded())
return "\(roundedDistance) \(isMPH ? "miles" : "km")" return "\(roundedDistance) \(isMPH ? "miles" : "km")"
} }
// Color indicating GPS accuracy
var accuracyColor: Color { var accuracyColor: Color {
switch locationManager.accuracy { switch locationManager.accuracy {
case ..<10: case ..<10:
@@ -41,6 +55,7 @@ struct ContentView: View {
} }
} }
// Text and background colors based on theme
var foregroundColor: Color { var foregroundColor: Color {
isDarkMode ? .white : .black isDarkMode ? .white : .black
} }
@@ -55,11 +70,14 @@ struct ContentView: View {
var body: some View { var body: some View {
ZStack { ZStack {
// Full-screen background color
backgroundColor.ignoresSafeArea() backgroundColor.ignoresSafeArea()
// Main vertical layout
VStack(spacing: 30) { VStack(spacing: 30) {
Spacer() Spacer()
// Speed display with unit
HStack(alignment: .bottom, spacing: 4) { HStack(alignment: .bottom, spacing: 4) {
Text("\(currentSpeed)") Text("\(currentSpeed)")
.font(.system(size: 140, weight: .bold, design: .rounded)) .font(.system(size: 140, weight: .bold, design: .rounded))
@@ -69,39 +87,58 @@ struct ContentView: View {
.font(.title2) .font(.title2)
.foregroundColor(secondaryTextColor) .foregroundColor(secondaryTextColor)
.onTapGesture { .onTapGesture {
isMPH.toggle() isMPH.toggle() // Toggle between mph and kph
} }
} }
Text("Trip: \(distanceLabel)") // Show trip info and controls only if not in minimal view
.font(.title2) if !isMinimalView {
.foregroundColor(secondaryTextColor) // Trip distance
Text("Trip: \(distanceLabel)")
.font(.title2)
.foregroundColor(secondaryTextColor)
Text(String(format: "GPS Accuracy: ±%.0f meters", locationManager.accuracy)) // GPS accuracy
.font(.headline) Text(String(format: "GPS Accuracy: ±%.0f meters", locationManager.accuracy))
.foregroundColor(accuracyColor)
Button(action: {
tripDistanceMeters = 0
previousLocation = nil
}) {
Text("Reset Trip")
.font(.headline) .font(.headline)
.padding(.horizontal, 20) .foregroundColor(accuracyColor)
.padding(.vertical, 10)
.background(secondaryTextColor) // Reset trip button
.foregroundColor(backgroundColor) Button(action: {
.cornerRadius(12) tripDistanceMeters = 0
previousLocation = nil
}) {
Text("Reset Trip")
.font(.headline)
.padding(.horizontal, 20)
.padding(.vertical, 10)
.background(secondaryTextColor)
.foregroundColor(backgroundColor)
.cornerRadius(12)
}
} }
Spacer() Spacer()
} }
.padding() .padding()
// Overlay controls (bottom corners)
VStack { VStack {
Spacer() Spacer()
HStack { HStack {
// 👁 Eye icon to toggle minimal view (bottom-left)
Button(action: {
isMinimalView.toggle()
}) {
Image(systemName: isMinimalView ? "eye.slash.fill" : "eye.fill")
.font(.title2)
.foregroundColor(foregroundColor)
.padding()
}
Spacer() Spacer()
// ⚙️ Gear icon to open app settings (bottom-right)
Button(action: { Button(action: {
if let url = URL(string: UIApplication.openSettingsURLString) { if let url = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(url) UIApplication.shared.open(url)
@@ -112,15 +149,15 @@ struct ContentView: View {
.foregroundColor(foregroundColor) .foregroundColor(foregroundColor)
.padding() .padding()
} }
.padding(.bottom, 10)
} }
.padding(.trailing) .padding([.leading, .trailing, .bottom], 10)
} }
} }
.onTapGesture { .onTapGesture {
isDarkMode.toggle() // Toggle between black/white background isDarkMode.toggle() // Toggle between light and dark mode
} }
.alert(isPresented: $locationManager.showAlert) { .alert(isPresented: $locationManager.showAlert) {
// Show alert if location services are unavailable
Alert( Alert(
title: Text("Location Services"), title: Text("Location Services"),
message: Text(locationManager.alertMessage), message: Text(locationManager.alertMessage),
@@ -131,6 +168,7 @@ struct ContentView: View {
} }
) )
} }
// Track location updates and calculate distance
.onReceive(locationManager.$location) { location in .onReceive(locationManager.$location) { location in
if let newLocation = location { if let newLocation = location {
if let oldLocation = previousLocation { if let oldLocation = previousLocation {