diff --git a/Localizable.xcstrings b/Localizable.xcstrings index e93f67a7..e585534f 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -752,7 +752,6 @@ "shouldTranslate" : false }, "%@ %@" : { - "extractionState" : "stale", "localizations" : { "da" : { "stringUnit" : { diff --git a/Meshtastic/Views/Helpers/CompassView.swift b/Meshtastic/Views/Helpers/CompassView.swift index c6844fc3..d0e63939 100644 --- a/Meshtastic/Views/Helpers/CompassView.swift +++ b/Meshtastic/Views/Helpers/CompassView.swift @@ -13,9 +13,8 @@ struct CompassView: View { /// Single waypoint parameter let waypointLocation: CLLocationCoordinate2D? - - let waypointName: String? - + let waypointLongName: String? + let waypointShortName: String? let color: Color @ObservedObject private var locationsHandler = LocationsHandler.shared @@ -79,6 +78,27 @@ struct CompassView: View { NavigationStack { ZStack { VStack(spacing: 0) { + + if waypointLongName != nil || waypointLocation != nil { + Spacer() + VStack(spacing: 4) { + Text(waypointLongName ?? "Waypoint") + .font(.largeTitle) + + if let bearing = bearingToWaypoint() { + HStack(spacing: 4) { + Image(systemName: "location.north.fill") + .font(.title2) + .rotationEffect(.degrees(bearing)) + Text("\(String(format: "%.0f°", bearing))") + .font(.title2) + } + .foregroundColor(.secondary) + } + } + .padding(.bottom, 8) + } + Spacer() // Top fixed heading indicator triangle Image(systemName: "triangle.fill") .font(.system(size: 14, weight: .bold)) @@ -86,6 +106,7 @@ struct CompassView: View { .rotationEffect(.degrees(180)) .padding(.bottom, 4) + // Rotating compass dial ZStack { // Outer bezel ring @@ -107,22 +128,35 @@ struct CompassView: View { CompassNorthIndicator(radius: dialRadius + 2) // Degree readout at center (counter-rotate to stay fixed) - VStack(spacing: 4) { - Text(headingText()) - .font(.system(size: 42, weight: .light, design: .rounded)) - .foregroundColor(.primary) - .monospacedDigit() + ZStack { + let textColor = color.isLight() ? Color.black : Color.white - if let distance = distanceToWaypoint() { - Text(formatDistance(distance)) - .font(.system(size: 18, weight: .semibold, design: .rounded)) - .foregroundColor(color) - } + Circle() + .fill(color) + .overlay( + Circle().stroke(textColor.opacity(0.75), lineWidth: 4) + ) + .frame(width: 172, height: 172) + + VStack(spacing: 4) { + Text(headingText()) + .font(.system(size: 42, weight: .light, design: .rounded)) + .foregroundColor(textColor) + .monospacedDigit() + + if let distance = distanceToWaypoint() { + Text(formatDistance(distance)) + .font(.system(size: 18, weight: .semibold, design: .rounded)) + .foregroundColor(textColor.opacity(0.9)) + + } + + if waypointShortName != nil || waypointLocation != nil { + Text(waypointShortName ?? "WP") + .font(.title3) + .foregroundColor(textColor.opacity(0.75)) + } - if waypointName != nil || waypointLocation != nil { - Text(waypointName ?? "Waypoint") - .font(.system(size: 13, weight: .medium)) - .foregroundColor(color.opacity(0.8)) } } .rotationEffect(Angle(degrees: locationsHandler.heading)) @@ -141,30 +175,20 @@ struct CompassView: View { } .frame(width: dialRadius * 2 + 40, height: dialRadius * 2 + 40) .rotationEffect(Angle(degrees: -locationsHandler.heading)) - + Spacer() // Bottom info if let wp = waypointLocation { VStack(spacing: 6) { HStack(spacing: 4) { Image(systemName: "mappin") - .font(.system(size: 11)) - Text("\(String(format: "%.4f", wp.latitude)), \(String(format: "%.4f", wp.longitude))") - .font(.system(size: 12, design: .monospaced)) + .font(.title2) + Text("\(String(format: "%.4f", wp.latitude)) \(String(format: "%.4f", wp.longitude))") + .font(.title3) } .foregroundColor(.secondary) - if let bearing = bearingToWaypoint() { - HStack(spacing: 4) { - Image(systemName: "location.north.fill") - .font(.system(size: 11)) - .rotationEffect(.degrees(bearing)) - Text("\(String(format: "%.0f°", bearing))") - .font(.system(size: 12, weight: .medium, design: .monospaced)) - } - .foregroundColor(color.opacity(0.7)) - } } - .padding(.top, 20) + Spacer() } } } @@ -325,7 +349,8 @@ struct CompassView_Previews: PreviewProvider { static var previews: some View { CompassView( waypointLocation: CLLocationCoordinate2D(latitude: 37.3346, longitude: -122.0090), - waypointName: "Apple Park", + waypointLongName: "Apple Park", + waypointShortName: "", color: Color.orange ) } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift index 9ad7a2a2..bc40ddf3 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift @@ -264,7 +264,8 @@ struct PositionPopover: View { .navigationDestination(isPresented: $navigateToCompass) { CompassView( waypointLocation: position.coordinate, - waypointName: position.nodePosition?.user?.longName ?? "Unknown node", + waypointLongName: position.nodePosition?.user?.longName ?? "Unknown node", + waypointShortName: position.nodePosition?.user?.shortName ?? "???", color: (position.nodePosition?.user?.num != nil && position.nodePosition?.user?.num != 0) ? Color(UIColor(hex: UInt32(position.nodePosition!.user!.num))) : .orange ) } diff --git a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift index f4f4a929..fcfad87d 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift @@ -578,7 +578,7 @@ struct NodeDetail: View { } } .sheet(isPresented: $showingCompassSheet) { - CompassView(waypointLocation: node.latestPosition?.nodeCoordinate ?? nil, waypointName: node.user?.longName ?? nil, color: Color(UIColor(hex: UInt32(node.num)))) + CompassView(waypointLocation: node.latestPosition?.nodeCoordinate ?? nil, waypointLongName: node.user?.longName ?? nil, waypointShortName: node.user?.shortName ?? nil, color: Color(UIColor(hex: UInt32(node.num)))) } .onAppear { scrollView.scrollTo("topOfList", anchor: .top)