From c388bf9b409e13153f2a8ec245de5d6ea2130b63 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 18:02:32 -0700 Subject: [PATCH] Add missing SwiftUI #Preview blocks across 65 views (#1649) * Add SwiftUI previews for simple helper views Agent-Logs-Url: https://github.com/meshtastic/Meshtastic-Apple/sessions/a2a43e8c-24fd-443a-8a98-13b678770edd Co-authored-by: garthvh <1795163+garthvh@users.noreply.github.com> * Add previews for action buttons, ChannelForm, MetricsColumnDetail, and DeviceOnboarding Agent-Logs-Url: https://github.com/meshtastic/Meshtastic-Apple/sessions/a2a43e8c-24fd-443a-8a98-13b678770edd Co-authored-by: garthvh <1795163+garthvh@users.noreply.github.com> * Add previews for config views, log views, AppLog, Firmware, AppData, and UserConfig Agent-Logs-Url: https://github.com/meshtastic/Meshtastic-Apple/sessions/a2a43e8c-24fd-443a-8a98-13b678770edd Co-authored-by: garthvh <1795163+garthvh@users.noreply.github.com> * Add preview for PositionConfig Agent-Logs-Url: https://github.com/meshtastic/Meshtastic-Apple/sessions/a2a43e8c-24fd-443a-8a98-13b678770edd Co-authored-by: garthvh <1795163+garthvh@users.noreply.github.com> * Fix formatting bugs in #Preview blocks: restore missing .environmentObject/.environment modifiers and add proper tab indentation Agent-Logs-Url: https://github.com/meshtastic/Meshtastic-Apple/sessions/7eeb7a54-7928-466f-8e39-b00d0012a09d Co-authored-by: garthvh <1795163+garthvh@users.noreply.github.com> * Linting fixes --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: garthvh <1795163+garthvh@users.noreply.github.com> Co-authored-by: Garth Vander Houwen --- .../CoreData/MessageEntityExtension.swift | 3 +-- Meshtastic/Helpers/MeshPackets.swift | 1 - .../Helpers/Mqtt/MqttClientProxyManager.swift | 1 - Meshtastic/Helpers/TAK/CoTXMLParser.swift | 8 ++------ Meshtastic/Helpers/TAK/TAKConnection.swift | 1 - Meshtastic/Views/Connect/Connect.swift | 9 ++++----- Meshtastic/Views/Connect/InvalidVersion.swift | 4 ++++ .../Helpers/BLESignalStrengthIndicator.swift | 8 ++++++++ Meshtastic/Views/Helpers/BatteryCompact.swift | 12 +++++++++++ Meshtastic/Views/Helpers/ChannelLock.swift | 12 +++++++++++ Meshtastic/Views/Helpers/CompassView.swift | 20 ++++--------------- Meshtastic/Views/Helpers/DateTimeText.swift | 8 ++++++++ Meshtastic/Views/Helpers/MeshtasticLogo.swift | 5 +++++ .../Helpers/Messages/MessageTemplate.swift | 12 +++++++++++ Meshtastic/Views/Helpers/PowerMetrics.swift | 12 +++++++++++ .../Views/Helpers/RXTXIndicatorView.swift | 9 +++++++++ .../Views/Helpers/RateLimitedButton.swift | 10 ++++++++++ Meshtastic/Views/Helpers/SecureInput.swift | 8 ++++++++ .../Weather/LocalWeatherConditions.swift | 4 ++++ Meshtastic/Views/Layouts/TraceRoute.swift | 7 +++++++ .../Messages/MessageContextMenuItems.swift | 2 -- .../Views/Messages/TapbackInputView.swift | 7 ++++++- .../Views/Nodes/DetectionSensorLog.swift | 13 ++++++++++++ Meshtastic/Views/Nodes/DeviceMetricsLog.swift | 13 ++++++++++++ .../Views/Nodes/EnvironmentMetricsLog.swift | 13 ++++++++++++ .../Helpers/Actions/ClientHistoryButton.swift | 10 ++++++++++ .../Helpers/Actions/DeleteNodeButton.swift | 11 ++++++++++ .../Actions/ExchangePositionsButton.swift | 10 ++++++++++ .../Actions/ExchangeUserInfoButton.swift | 10 ++++++++++ .../Helpers/Actions/FavoriteNodeButton.swift | 13 ++++++++++++ .../Helpers/Actions/IgnoreNodeButton.swift | 9 +++++++++ .../Helpers/Actions/NavigateToButton.swift | 12 +++++++++++ .../Helpers/Actions/NodeAlertsButton.swift | 11 ++++++++++ .../Helpers/Actions/TraceRouteButton.swift | 12 +++++++++++ .../Map/MapContent/AnimatedNodePin.swift | 8 ++++++++ .../Nodes/Helpers/Map/MapSettingsForm.swift | 10 ++++++++++ .../Metrics Columns/MetricsColumnDetail.swift | 7 +++++++ .../Views/Nodes/Helpers/NodeListFilter.swift | 4 ++++ Meshtastic/Views/Nodes/PaxCounterLog.swift | 13 ++++++++++++ Meshtastic/Views/Nodes/PositionLog.swift | 13 ++++++++++++ Meshtastic/Views/Nodes/PowerMetricsLog.swift | 13 ++++++++++++ Meshtastic/Views/Nodes/TraceRouteLog.swift | 13 ++++++++++++ .../Views/Onboarding/DeviceOnboarding.swift | 5 +++++ Meshtastic/Views/Settings/About.swift | 6 ++++++ Meshtastic/Views/Settings/AppData.swift | 7 +++++++ Meshtastic/Views/Settings/AppLog.swift | 4 ++++ .../Views/Settings/Channels/ChannelForm.swift | 18 +++++++++++++++++ .../Settings/Config/BluetoothConfig.swift | 7 +++++++ .../Views/Settings/Config/ConfigHeader.swift | 10 ++++++++++ .../Views/Settings/Config/DeviceConfig.swift | 7 +++++++ .../Views/Settings/Config/DisplayConfig.swift | 7 +++++++ .../Views/Settings/Config/LoRaConfig.swift | 7 +++++++ .../Config/Module/AmbientLightingConfig.swift | 7 +++++++ .../Config/Module/CannedMessagesConfig.swift | 7 +++++++ .../Config/Module/DetectionSensorConfig.swift | 7 +++++++ .../Module/ExternalNotificationConfig.swift | 6 ++++++ .../Settings/Config/Module/MQTTConfig.swift | 7 +++++++ .../Config/Module/PaxCounterConfig.swift | 7 +++++++ .../Config/Module/RangeTestConfig.swift | 7 +++++++ .../Settings/Config/Module/RtttlConfig.swift | 7 +++++++ .../Settings/Config/Module/SerialConfig.swift | 7 +++++++ .../Config/Module/StoreForwardConfig.swift | 7 +++++++ .../Config/Module/TelemetryConfig.swift | 7 +++++++ .../Views/Settings/Config/NetworkConfig.swift | 7 +++++++ .../Settings/Config/PositionConfig.swift | 7 +++++++ .../Views/Settings/Config/PowerConfig.swift | 7 +++++++ .../Settings/Config/SaveConfigButton.swift | 5 +++++ .../Settings/Config/SecurityConfig.swift | 7 +++++++ Meshtastic/Views/Settings/Firmware.swift | 7 +++++++ Meshtastic/Views/Settings/GPSStatus.swift | 4 ++++ .../Views/Settings/Logs/AppLogFilter.swift | 4 ++++ .../Views/Settings/TAKServerConfig.swift | 2 -- .../Views/Settings/UpdateIntervalPicker.swift | 8 ++++++++ Meshtastic/Views/Settings/UserConfig.swift | 7 +++++++ MeshtasticTests/ConnectViewTests.swift | 6 +++--- MeshtasticTests/RouterTests.swift | 2 +- 76 files changed, 567 insertions(+), 41 deletions(-) diff --git a/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift b/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift index d6d2c997..c9fab38a 100644 --- a/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift @@ -59,8 +59,7 @@ extension MessageEntity { let users = try context.fetch(request) // If exactly one match is found, return its name - if users.count == 1, let name = users.first?.longName, !name.isEmpty - { + if users.count == 1, let name = users.first?.longName, !name.isEmpty { return "\(name)" } diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 54e1661f..f6b8c485 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -1278,4 +1278,3 @@ actor MeshPackets { } } } - diff --git a/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift b/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift index 936f23ad..e0cd2473 100644 --- a/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift +++ b/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift @@ -184,4 +184,3 @@ extension MqttClientProxyManager: CocoaMQTTDelegate { Logger.mqtt.debug("📲 [MQTT Client Proxy] pong") } } - diff --git a/Meshtastic/Helpers/TAK/CoTXMLParser.swift b/Meshtastic/Helpers/TAK/CoTXMLParser.swift index 7f9325e2..eada8793 100644 --- a/Meshtastic/Helpers/TAK/CoTXMLParser.swift +++ b/Meshtastic/Helpers/TAK/CoTXMLParser.swift @@ -71,10 +71,7 @@ final class CoTXMLParser: NSObject, XMLParserDelegate { } // MARK: - XMLParserDelegate - - func parser(_ parser: XMLParser, didStartElement elementName: String, - namespaceURI: String?, qualifiedName qName: String?, - attributes attributeDict: [String: String] = [:]) { + func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) { elementStack.append(elementName) currentElement = elementName currentText = "" @@ -138,8 +135,7 @@ final class CoTXMLParser: NSObject, XMLParserDelegate { } } - func parser(_ parser: XMLParser, didEndElement elementName: String, - namespaceURI: String?, qualifiedName qName: String?) { + func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { if elementName == "remarks" { remarksText = currentText.trimmingCharacters(in: .whitespacesAndNewlines) } diff --git a/Meshtastic/Helpers/TAK/TAKConnection.swift b/Meshtastic/Helpers/TAK/TAKConnection.swift index b4678f06..57340154 100644 --- a/Meshtastic/Helpers/TAK/TAKConnection.swift +++ b/Meshtastic/Helpers/TAK/TAKConnection.swift @@ -494,4 +494,3 @@ enum TAKConnectionError: LocalizedError { } } } - diff --git a/Meshtastic/Views/Connect/Connect.swift b/Meshtastic/Views/Connect/Connect.swift index b66b1b59..84e90c6e 100644 --- a/Meshtastic/Views/Connect/Connect.swift +++ b/Meshtastic/Views/Connect/Connect.swift @@ -565,18 +565,18 @@ struct DeviceConnectRow: View { } // Show transport type #if !targetEnvironment(macCatalyst) - HStack(alignment: .center){ + HStack(alignment: .center) { TransportIcon(transportType: device.transportType) if device.isManualConnection && (device.longName != nil || device.shortName != nil) { - VStack (alignment: .leading) { + VStack(alignment: .leading) { Text("Last seen device:") Text("\(String(describing: device))") } } }.padding(.top, 3.0) #else - //Different alignment for Mac - HStack(alignment: .firstTextBaseline){ + // Different alignment for Mac + HStack(alignment: .firstTextBaseline) { TransportIcon(transportType: device.transportType) if device.isManualConnection && (device.longName != nil || device.shortName != nil) { Text("Last seen device: \(String(describing: device))") @@ -609,4 +609,3 @@ struct DeviceConnectRow: View { } } } - diff --git a/Meshtastic/Views/Connect/InvalidVersion.swift b/Meshtastic/Views/Connect/InvalidVersion.swift index 5d475756..d6030139 100644 --- a/Meshtastic/Views/Connect/InvalidVersion.swift +++ b/Meshtastic/Views/Connect/InvalidVersion.swift @@ -62,3 +62,7 @@ struct InvalidVersion: View { } } } + +#Preview { + InvalidVersion(minimumVersion: "2.5.4", version: "2.3.0") +} diff --git a/Meshtastic/Views/Helpers/BLESignalStrengthIndicator.swift b/Meshtastic/Views/Helpers/BLESignalStrengthIndicator.swift index a68b3597..7e83940f 100644 --- a/Meshtastic/Views/Helpers/BLESignalStrengthIndicator.swift +++ b/Meshtastic/Views/Helpers/BLESignalStrengthIndicator.swift @@ -94,3 +94,11 @@ enum BLESignalStrength: Int { case normal = 1 case strong = 2 } + +#Preview { + HStack(spacing: 16) { + SignalStrengthIndicator(signalStrength: .weak) + SignalStrengthIndicator(signalStrength: .normal) + SignalStrengthIndicator(signalStrength: .strong) + } +} diff --git a/Meshtastic/Views/Helpers/BatteryCompact.swift b/Meshtastic/Views/Helpers/BatteryCompact.swift index 60c1307a..aed8472b 100644 --- a/Meshtastic/Views/Helpers/BatteryCompact.swift +++ b/Meshtastic/Views/Helpers/BatteryCompact.swift @@ -111,3 +111,15 @@ struct BatteryCompact: View { } ?? "Unknown") } } + +#Preview { + VStack(spacing: 12) { + BatteryCompact(batteryLevel: 75, font: .caption, iconFont: .caption, color: .gray) + BatteryCompact(batteryLevel: 50, font: .caption, iconFont: .caption, color: .gray) + BatteryCompact(batteryLevel: 25, font: .caption, iconFont: .caption, color: .gray) + BatteryCompact(batteryLevel: 10, font: .caption, iconFont: .caption, color: .gray) + BatteryCompact(batteryLevel: 100, font: .caption, iconFont: .caption, color: .gray) + BatteryCompact(batteryLevel: 101, font: .caption, iconFont: .caption, color: .gray) + BatteryCompact(batteryLevel: nil, font: .caption, iconFont: .caption, color: .gray) + } +} diff --git a/Meshtastic/Views/Helpers/ChannelLock.swift b/Meshtastic/Views/Helpers/ChannelLock.swift index 2621311a..facc07cb 100644 --- a/Meshtastic/Views/Helpers/ChannelLock.swift +++ b/Meshtastic/Views/Helpers/ChannelLock.swift @@ -32,3 +32,15 @@ struct ChannelLock: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let encryptedChannel = ChannelEntity(context: context) + encryptedChannel.psk = Data([0x01, 0x02, 0x03, 0x04]) + let unencryptedChannel = ChannelEntity(context: context) + unencryptedChannel.psk = Data() + return HStack(spacing: 16) { + ChannelLock(channel: encryptedChannel) + ChannelLock(channel: unencryptedChannel) + } +} diff --git a/Meshtastic/Views/Helpers/CompassView.swift b/Meshtastic/Views/Helpers/CompassView.swift index 1e58b224..c7185acf 100644 --- a/Meshtastic/Views/Helpers/CompassView.swift +++ b/Meshtastic/Views/Helpers/CompassView.swift @@ -38,7 +38,7 @@ struct CompassView: View { } // Trigger a vibration if aligned with waypoint - private func checkAlignment(bearing: Double,heading: Double) { + private func checkAlignment(bearing: Double, heading: Double) { // Compute minimal angular difference between heading and bearing in [0, 180] let rawDiff = abs(heading - bearing).truncatingRemainder(dividingBy: 360) let diff = min(rawDiff, 360 - rawDiff) @@ -53,7 +53,6 @@ struct CompassView: View { inAlignment = false } } - private func distanceToWaypoint() -> CLLocationDistance? { guard @@ -76,7 +75,6 @@ struct CompassView: View { return formatter.string(from: measurement) } - var body: some View { NavigationStack { VStack(spacing: 15) { @@ -88,14 +86,14 @@ struct CompassView: View { .foregroundColor(color) if let wp = waypointLocation { - HStack{ + HStack { Image(systemName: "mappin.and.ellipse") Text("\(String(format: "%.4f", wp.latitude)), \(String(format: "%.4f", wp.longitude))") .font(.subheadline) } if let distance = distanceToWaypoint() { - HStack{ + HStack { Image(systemName: "lines.measurement.horizontal") Text("Distance: \(formatDistance(distance))") .font(.subheadline) @@ -137,7 +135,7 @@ struct CompassView: View { ) // Move waypoint marker outside compass .onChange(of: locationsHandler.heading) { _, _ in - checkAlignment(bearing: bearing,heading:locationsHandler.heading) + checkAlignment(bearing: bearing, heading:locationsHandler.heading) } } @@ -159,9 +157,7 @@ struct CompassView: View { } } - // MARK: - Waypoint Marker View - struct WaypointMarkerView: View { let bearing: Double let compassDegrees: Double @@ -177,9 +173,7 @@ struct WaypointMarkerView: View { } - // MARK: - Bearing Calculator - struct BearingCalculator { static func bearingBetween( @@ -205,9 +199,7 @@ struct BearingCalculator { } } - // MARK: - Marker Model - struct Marker: Hashable { let degrees: Double let label: String @@ -239,9 +231,7 @@ struct Marker: Hashable { } } - // MARK: - Compass Marker View - struct CompassMarkerView: View { let marker: Marker let compassDegrees: Double @@ -281,9 +271,7 @@ struct CompassMarkerView: View { } } - // MARK: - Preview - struct CompassView_Previews: PreviewProvider { static var previews: some View { CompassView( diff --git a/Meshtastic/Views/Helpers/DateTimeText.swift b/Meshtastic/Views/Helpers/DateTimeText.swift index 38e386f3..34ffcdcf 100644 --- a/Meshtastic/Views/Helpers/DateTimeText.swift +++ b/Meshtastic/Views/Helpers/DateTimeText.swift @@ -28,3 +28,11 @@ struct DateTimeText: View { } } } + +#Preview { + VStack { + DateTimeText(dateTime: Date()) + DateTimeText(dateTime: Calendar.current.date(byAdding: .day, value: -1, to: Date())) + DateTimeText(dateTime: nil) + } +} diff --git a/Meshtastic/Views/Helpers/MeshtasticLogo.swift b/Meshtastic/Views/Helpers/MeshtasticLogo.swift index 6c717140..099728c9 100644 --- a/Meshtastic/Views/Helpers/MeshtasticLogo.swift +++ b/Meshtastic/Views/Helpers/MeshtasticLogo.swift @@ -51,3 +51,8 @@ struct MeshtasticLogo: View { #endif } } + +#Preview { + MeshtasticLogo() + .frame(width: 200, height: 44) +} diff --git a/Meshtastic/Views/Helpers/Messages/MessageTemplate.swift b/Meshtastic/Views/Helpers/Messages/MessageTemplate.swift index e604b564..2173c5c5 100644 --- a/Meshtastic/Views/Helpers/Messages/MessageTemplate.swift +++ b/Meshtastic/Views/Helpers/Messages/MessageTemplate.swift @@ -36,3 +36,15 @@ struct MessageTemplate: View { } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let user = UserEntity(context: context) + user.longName = "Test User" + user.shortName = "TU" + let message = MessageEntity(context: context) + message.messagePayload = "Hello, World!" + message.messageTimestamp = Int32(Date().timeIntervalSince1970) + message.replyID = 0 + return MessageTemplate(user: user, message: message) +} diff --git a/Meshtastic/Views/Helpers/PowerMetrics.swift b/Meshtastic/Views/Helpers/PowerMetrics.swift index e85c0f6a..6009e5a6 100644 --- a/Meshtastic/Views/Helpers/PowerMetrics.swift +++ b/Meshtastic/Views/Helpers/PowerMetrics.swift @@ -94,3 +94,15 @@ struct PowerMetricCompactWidget: View { .background(.tertiary, in: RoundedRectangle(cornerRadius: 20, style: .continuous)) } } + +#Preview { + let gridItemLayout = Array(repeating: GridItem(.flexible(), spacing: 10), count: 2) + Form { + LazyVGrid(columns: gridItemLayout) { + PowerMetricCompactWidget(type: .voltage, value: 3.72, title: "Channel 1 Voltage") + PowerMetricCompactWidget(type: .current, value: 125.3, title: "Channel 1 Current") + PowerMetricCompactWidget(type: .voltage, value: 5.01, title: "Channel 2 Voltage") + PowerMetricCompactWidget(type: .current, value: 42.7, title: "Channel 2 Current") + } + } +} diff --git a/Meshtastic/Views/Helpers/RXTXIndicatorView.swift b/Meshtastic/Views/Helpers/RXTXIndicatorView.swift index 860b3734..f31ae179 100644 --- a/Meshtastic/Views/Helpers/RXTXIndicatorView.swift +++ b/Meshtastic/Views/Helpers/RXTXIndicatorView.swift @@ -119,3 +119,12 @@ struct LEDIndicator: View { } } } + +#Preview { + HStack(spacing: 12) { + LEDIndicator(flash: .constant(1), color: .green) + .frame(width: 10, height: 10) + LEDIndicator(flash: .constant(0), color: .red) + .frame(width: 10, height: 10) + } +} diff --git a/Meshtastic/Views/Helpers/RateLimitedButton.swift b/Meshtastic/Views/Helpers/RateLimitedButton.swift index 30c5d667..894bd526 100644 --- a/Meshtastic/Views/Helpers/RateLimitedButton.swift +++ b/Meshtastic/Views/Helpers/RateLimitedButton.swift @@ -45,6 +45,16 @@ public struct RateLimitedButton: View { } } +#Preview { + RateLimitedButton(key: "preview", rateLimit: 30, action: { }) { rateLimitInfo in + if let info = rateLimitInfo { + Label("\(Int(info.secondsRemaining))s", systemImage: "clock") + } else { + Label("Send", systemImage: "paperplane") + } + } +} + // To store the time an action occured (name by a key) and the time limit // Does not persist across app launches class RateLimitStorage: ObservableObject { diff --git a/Meshtastic/Views/Helpers/SecureInput.swift b/Meshtastic/Views/Helpers/SecureInput.swift index 687cc6fe..bbffe662 100644 --- a/Meshtastic/Views/Helpers/SecureInput.swift +++ b/Meshtastic/Views/Helpers/SecureInput.swift @@ -69,3 +69,11 @@ struct SecureInput: View { } } } + +#Preview { + List { + SecureInput("Password", text: .constant("s3cretP@ss"), isValid: .constant(true)) + SecureInput("Invalid Key", text: .constant("short"), isValid: .constant(false)) + SecureInput("Empty", text: .constant(""), isValid: .constant(true)) + } +} diff --git a/Meshtastic/Views/Helpers/Weather/LocalWeatherConditions.swift b/Meshtastic/Views/Helpers/Weather/LocalWeatherConditions.swift index def3ae6c..967c2c2b 100644 --- a/Meshtastic/Views/Helpers/Weather/LocalWeatherConditions.swift +++ b/Meshtastic/Views/Helpers/Weather/LocalWeatherConditions.swift @@ -118,3 +118,7 @@ func calculateDewPoint(temp: Float, relativeHumidity: Float, convertToLocale: Bo } return dewPointUnit.converted(to: format).value } + +#Preview { + LocalWeatherConditions(location: CLLocation(latitude: 47.6062, longitude: -122.3321)) +} diff --git a/Meshtastic/Views/Layouts/TraceRoute.swift b/Meshtastic/Views/Layouts/TraceRoute.swift index fd4d7d92..f8f8e8d0 100644 --- a/Meshtastic/Views/Layouts/TraceRoute.swift +++ b/Meshtastic/Views/Layouts/TraceRoute.swift @@ -22,6 +22,13 @@ struct TraceRouteComponent: View { } } +#Preview { + TraceRouteComponent { + Image(systemName: "antenna.radiowaves.left.and.right") + .font(.title) + } +} + struct TraceRoute: Layout { var animatableData: AnimatablePair { get { diff --git a/Meshtastic/Views/Messages/MessageContextMenuItems.swift b/Meshtastic/Views/Messages/MessageContextMenuItems.swift index 0d8843ef..8c5a301b 100644 --- a/Meshtastic/Views/Messages/MessageContextMenuItems.swift +++ b/Meshtastic/Views/Messages/MessageContextMenuItems.swift @@ -56,8 +56,6 @@ struct MessageContextMenuItems: View { let sixMonthsAgo = Calendar.current.date(byAdding: .month, value: -6, to: Date()) // Compute a relay display string if relayNode is present - - VStack { Text("\(messageDate.formattedDate(format: MessageText.dateFormatString))") .foregroundColor(.gray) diff --git a/Meshtastic/Views/Messages/TapbackInputView.swift b/Meshtastic/Views/Messages/TapbackInputView.swift index 36a1e9b0..03c6597c 100644 --- a/Meshtastic/Views/Messages/TapbackInputView.swift +++ b/Meshtastic/Views/Messages/TapbackInputView.swift @@ -79,6 +79,12 @@ struct TapbackInputView: View { } } +#Preview { + TapbackInputView(text: .constant(""), isPresented: .constant(true)) { emoji in + print("Selected: \(emoji)") + } +} + extension UIView { var firstResponder: UIView? { guard !isFirstResponder else { return self } @@ -90,4 +96,3 @@ extension UIView { return nil } } - diff --git a/Meshtastic/Views/Nodes/DetectionSensorLog.swift b/Meshtastic/Views/Nodes/DetectionSensorLog.swift index f86b9acb..ae57cab0 100644 --- a/Meshtastic/Views/Nodes/DetectionSensorLog.swift +++ b/Meshtastic/Views/Nodes/DetectionSensorLog.swift @@ -141,3 +141,16 @@ struct DetectionSensorLog: View { ) } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return DetectionSensorLog(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/DeviceMetricsLog.swift b/Meshtastic/Views/Nodes/DeviceMetricsLog.swift index 90e8d119..09bca3e7 100644 --- a/Meshtastic/Views/Nodes/DeviceMetricsLog.swift +++ b/Meshtastic/Views/Nodes/DeviceMetricsLog.swift @@ -254,3 +254,16 @@ struct DeviceMetricsLog: View { ) } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return DeviceMetricsLog(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/EnvironmentMetricsLog.swift b/Meshtastic/Views/Nodes/EnvironmentMetricsLog.swift index 84148d2e..ca19ebee 100644 --- a/Meshtastic/Views/Nodes/EnvironmentMetricsLog.swift +++ b/Meshtastic/Views/Nodes/EnvironmentMetricsLog.swift @@ -186,3 +186,16 @@ struct EnvironmentMetricsLog: View { return lower...upper } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return EnvironmentMetricsLog(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/ClientHistoryButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/ClientHistoryButton.swift index 624ca183..020855e7 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/ClientHistoryButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/ClientHistoryButton.swift @@ -40,3 +40,13 @@ struct ClientHistoryButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let connectedNode = NodeInfoEntity(context: context) + connectedNode.num = 987654321 + return ClientHistoryButton(connectedNode: connectedNode, node: node) + .environmentObject(AccessoryManager.shared) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift index 70ffc217..a7b096b3 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift @@ -64,3 +64,14 @@ struct DeleteNodeButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let connectedNode = NodeInfoEntity(context: context) + connectedNode.num = 987654321 + let node = NodeInfoEntity(context: context) + node.num = 123456789 + return DeleteNodeButton(connectedNode: connectedNode, node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/ExchangePositionsButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/ExchangePositionsButton.swift index f303f21e..c71e6b87 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/ExchangePositionsButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/ExchangePositionsButton.swift @@ -61,3 +61,13 @@ struct ExchangePositionsButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let connectedNode = NodeInfoEntity(context: context) + connectedNode.num = 987654321 + return ExchangePositionsButton(node: node, connectedNode: connectedNode) + .environmentObject(AccessoryManager.shared) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/ExchangeUserInfoButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/ExchangeUserInfoButton.swift index 321b1532..595eec4f 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/ExchangeUserInfoButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/ExchangeUserInfoButton.swift @@ -59,3 +59,13 @@ struct ExchangeUserInfoButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let connectedNode = NodeInfoEntity(context: context) + connectedNode.num = 987654321 + return ExchangeUserInfoButton(node: node, connectedNode: connectedNode) + .environmentObject(AccessoryManager.shared) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/FavoriteNodeButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/FavoriteNodeButton.swift index 83bac1d3..d3a54864 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/FavoriteNodeButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/FavoriteNodeButton.swift @@ -79,3 +79,16 @@ struct FavoriteNodeButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return FavoriteNodeButton(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift index c15c69d1..51a8801b 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift @@ -51,3 +51,12 @@ struct IgnoreNodeButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + return IgnoreNodeButton(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift index 403d1b98..ec130098 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift @@ -54,3 +54,15 @@ struct NavigateToButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + user.num = 123456789 + node.user = user + return NavigateToButton(node: node) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/NodeAlertsButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/NodeAlertsButton.swift index 663d2900..179fb1af 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/NodeAlertsButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/NodeAlertsButton.swift @@ -31,3 +31,14 @@ struct NodeAlertsButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return NodeAlertsButton(context: context, node: node, user: user) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/TraceRouteButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/TraceRouteButton.swift index 11a14460..62e696d4 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/TraceRouteButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/TraceRouteButton.swift @@ -43,3 +43,15 @@ struct TraceRouteButton: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return TraceRouteButton(node: node) + .environmentObject(AccessoryManager.shared) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/AnimatedNodePin.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/AnimatedNodePin.swift index 6868f499..245142c9 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/AnimatedNodePin.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/AnimatedNodePin.swift @@ -51,6 +51,14 @@ struct AnimatedNodePin: View, Equatable { } } +#Preview { + VStack(spacing: 20) { + AnimatedNodePin(nodeColor: .systemBlue, shortName: "TN", hasDetectionSensorMetrics: false, isOnline: true, calculatedDelay: 0.0) + AnimatedNodePin(nodeColor: .systemGreen, shortName: "AB", hasDetectionSensorMetrics: true, isOnline: true, calculatedDelay: 0.2) + AnimatedNodePin(nodeColor: .systemRed, shortName: "XY", hasDetectionSensorMetrics: false, isOnline: false, calculatedDelay: 0.0) + } +} + struct PulsingCircle: View { let nodeColor: UIColor let calculatedDelay: Double diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift index ca17c6fa..b284d49b 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift @@ -228,3 +228,13 @@ struct MapSettingsForm: View { } } + +#Preview { + MapSettingsForm( + traffic: .constant(false), + pointsOfInterest: .constant(true), + mapLayer: .constant(.standard), + meshMap: .constant(true), + enabledOverlayConfigs: .constant(Set()) + ) +} diff --git a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift index e456ce31..e2061044 100644 --- a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift @@ -99,3 +99,10 @@ struct MetricsColumnDetail: View { .interactiveDismissDisabled(false) } } + +#Preview { + MetricsColumnDetail( + columnList: MetricsColumnList(columns: []), + seriesList: MetricsSeriesList() + ) +} diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index 3236f0d3..9f1c03c1 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -208,3 +208,7 @@ struct NodeListFilter: View { .presentationBackgroundInteraction(.enabled(upThrough: .large)) } } + +#Preview { + NodeListFilter(filters: NodeFilterParameters()) +} diff --git a/Meshtastic/Views/Nodes/PaxCounterLog.swift b/Meshtastic/Views/Nodes/PaxCounterLog.swift index 482e0d69..c4a93e59 100644 --- a/Meshtastic/Views/Nodes/PaxCounterLog.swift +++ b/Meshtastic/Views/Nodes/PaxCounterLog.swift @@ -224,3 +224,16 @@ struct PaxCounterLog: View { ) } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return PaxCounterLog(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/PositionLog.swift b/Meshtastic/Views/Nodes/PositionLog.swift index af307f20..f667f5ee 100644 --- a/Meshtastic/Views/Nodes/PositionLog.swift +++ b/Meshtastic/Views/Nodes/PositionLog.swift @@ -181,3 +181,16 @@ struct PositionLog: View { }) } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return PositionLog(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/PowerMetricsLog.swift b/Meshtastic/Views/Nodes/PowerMetricsLog.swift index b4578a59..b43b1c47 100644 --- a/Meshtastic/Views/Nodes/PowerMetricsLog.swift +++ b/Meshtastic/Views/Nodes/PowerMetricsLog.swift @@ -297,3 +297,16 @@ struct PowerMetricsLog: View { ) } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return PowerMetricsLog(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Nodes/TraceRouteLog.swift b/Meshtastic/Views/Nodes/TraceRouteLog.swift index 3b84aec3..a4c4c91e 100644 --- a/Meshtastic/Views/Nodes/TraceRouteLog.swift +++ b/Meshtastic/Views/Nodes/TraceRouteLog.swift @@ -287,3 +287,16 @@ func getTraceRouteHops(context: NSManagedObjectContext) -> [TraceRouteHopEntity] array.append(trh8) return array } + +#Preview { + let context = PersistenceController.preview.container.viewContext + let node = NodeInfoEntity(context: context) + node.num = 123456789 + let user = UserEntity(context: context) + user.longName = "Test Node" + user.shortName = "TN" + node.user = user + return TraceRouteLog(node: node) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Onboarding/DeviceOnboarding.swift b/Meshtastic/Views/Onboarding/DeviceOnboarding.swift index d95d6977..f0c9f1f1 100644 --- a/Meshtastic/Views/Onboarding/DeviceOnboarding.swift +++ b/Meshtastic/Views/Onboarding/DeviceOnboarding.swift @@ -454,3 +454,8 @@ struct DeviceOnboarding: View { } } + +#Preview { + DeviceOnboarding() + .environmentObject(AccessoryManager.shared) +} diff --git a/Meshtastic/Views/Settings/About.swift b/Meshtastic/Views/Settings/About.swift index 98355864..9d95c472 100644 --- a/Meshtastic/Views/Settings/About.swift +++ b/Meshtastic/Views/Settings/About.swift @@ -67,3 +67,9 @@ struct AboutMeshtastic: View { .navigationBarTitleDisplayMode(.inline) } } + +#Preview { + NavigationView { + AboutMeshtastic() + } +} diff --git a/Meshtastic/Views/Settings/AppData.swift b/Meshtastic/Views/Settings/AppData.swift index aa7ac625..16034020 100644 --- a/Meshtastic/Views/Settings/AppData.swift +++ b/Meshtastic/Views/Settings/AppData.swift @@ -143,3 +143,10 @@ struct AppData: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return AppData() + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/AppLog.swift b/Meshtastic/Views/Settings/AppLog.swift index 08c09664..77f90440 100644 --- a/Meshtastic/Views/Settings/AppLog.swift +++ b/Meshtastic/Views/Settings/AppLog.swift @@ -271,3 +271,7 @@ extension AppLog { } extension OSLogEntry: @retroactive Identifiable { } + +#Preview { + AppLog() +} diff --git a/Meshtastic/Views/Settings/Channels/ChannelForm.swift b/Meshtastic/Views/Settings/Channels/ChannelForm.swift index 3579b938..78f85344 100644 --- a/Meshtastic/Views/Settings/Channels/ChannelForm.swift +++ b/Meshtastic/Views/Settings/Channels/ChannelForm.swift @@ -250,3 +250,21 @@ struct ChannelForm: View { } } } + +#Preview { + ChannelForm( + channelIndex: .constant(0), + channelName: .constant("LongFast"), + channelKeySize: .constant(32), + channelKey: .constant("AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE="), + channelRole: .constant(1), + uplink: .constant(false), + downlink: .constant(false), + positionPrecision: .constant(14), + preciseLocation: .constant(false), + positionsEnabled: .constant(true), + hasChanges: .constant(false), + hasValidKey: .constant(true), + supportedVersion: .constant(true) + ) +} diff --git a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift index a5955caa..b1934df3 100644 --- a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift +++ b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift @@ -147,3 +147,10 @@ struct BluetoothConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return BluetoothConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/ConfigHeader.swift b/Meshtastic/Views/Settings/Config/ConfigHeader.swift index 1331235d..c8ed4f91 100644 --- a/Meshtastic/Views/Settings/Config/ConfigHeader.swift +++ b/Meshtastic/Views/Settings/Config/ConfigHeader.swift @@ -37,3 +37,13 @@ struct ConfigHeader: View { } } } + +#Preview { + ConfigHeader( + title: "Bluetooth Configuration", + config: \NodeInfoEntity.bluetoothConfig, + node: nil, + onAppear: { } + ) + .environmentObject(AccessoryManager.shared) +} diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index 6bfd711b..7d0814dc 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -345,3 +345,10 @@ struct DeviceConfig: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return DeviceConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/DisplayConfig.swift b/Meshtastic/Views/Settings/Config/DisplayConfig.swift index ddc67d0f..a9240da0 100644 --- a/Meshtastic/Views/Settings/Config/DisplayConfig.swift +++ b/Meshtastic/Views/Settings/Config/DisplayConfig.swift @@ -235,3 +235,10 @@ struct DisplayConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return DisplayConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/LoRaConfig.swift b/Meshtastic/Views/Settings/Config/LoRaConfig.swift index 17e18dc7..4129e133 100644 --- a/Meshtastic/Views/Settings/Config/LoRaConfig.swift +++ b/Meshtastic/Views/Settings/Config/LoRaConfig.swift @@ -321,3 +321,10 @@ struct LoRaConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return LoRaConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift index 515ca933..db2c98c2 100644 --- a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift @@ -134,3 +134,10 @@ struct AmbientLightingConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return AmbientLightingConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index cc0a87eb..54a9a6bd 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -355,3 +355,10 @@ struct CannedMessagesConfig: View { self.hasMessagesChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return CannedMessagesConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift index 02afcc3a..a56d42b1 100644 --- a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift @@ -261,3 +261,10 @@ struct DetectionSensorConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return DetectionSensorConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift index 23f4ef40..b3694ee3 100644 --- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift @@ -283,3 +283,9 @@ struct ExternalNotificationConfig: View { } } +#Preview { + let context = PersistenceController.preview.container.viewContext + return ExternalNotificationConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index 5336c5ef..a3417650 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -464,3 +464,10 @@ struct MQTTConfig: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return MQTTConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift index edc46ed0..90b83f73 100644 --- a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift @@ -123,3 +123,10 @@ struct PaxCounterConfig: View { paxcounterUpdateInterval = UpdateInterval(from: Int(node?.paxCounterConfig?.updateInterval ?? 1800)) } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return PaxCounterConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift index ed65ce4e..74386285 100644 --- a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift @@ -143,3 +143,10 @@ struct RangeTestConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return RangeTestConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift index d052bf7e..6f45103a 100644 --- a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift @@ -114,3 +114,10 @@ struct RtttlConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return RtttlConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift index a773190d..ff070c09 100644 --- a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift @@ -205,3 +205,10 @@ struct SerialConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return SerialConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift index bc35258d..577ef4b5 100644 --- a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift @@ -197,3 +197,10 @@ struct StoreForwardConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return StoreForwardConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift index 44a38cbd..caae19c3 100644 --- a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift @@ -241,3 +241,10 @@ struct TelemetryConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return TelemetryConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/NetworkConfig.swift b/Meshtastic/Views/Settings/Config/NetworkConfig.swift index 92c5cc5e..044e2a2f 100644 --- a/Meshtastic/Views/Settings/Config/NetworkConfig.swift +++ b/Meshtastic/Views/Settings/Config/NetworkConfig.swift @@ -209,3 +209,10 @@ struct NetworkConfig: View { self.hasChanges = false } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return NetworkConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/PositionConfig.swift b/Meshtastic/Views/Settings/Config/PositionConfig.swift index 3b7f65ec..68c8e9bd 100644 --- a/Meshtastic/Views/Settings/Config/PositionConfig.swift +++ b/Meshtastic/Views/Settings/Config/PositionConfig.swift @@ -562,3 +562,10 @@ struct PositionConfig: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return PositionConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/PowerConfig.swift b/Meshtastic/Views/Settings/Config/PowerConfig.swift index 2ad978b5..737bd7f7 100644 --- a/Meshtastic/Views/Settings/Config/PowerConfig.swift +++ b/Meshtastic/Views/Settings/Config/PowerConfig.swift @@ -226,3 +226,10 @@ private struct FloatField: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return PowerConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Config/SaveConfigButton.swift b/Meshtastic/Views/Settings/Config/SaveConfigButton.swift index 43fcb66a..e21f6a1b 100644 --- a/Meshtastic/Views/Settings/Config/SaveConfigButton.swift +++ b/Meshtastic/Views/Settings/Config/SaveConfigButton.swift @@ -58,3 +58,8 @@ struct SaveConfigButton: View { } } } + +#Preview { + SaveConfigButton(node: nil, hasChanges: .constant(true), onConfirmation: { }) + .environmentObject(AccessoryManager.shared) +} diff --git a/Meshtastic/Views/Settings/Config/SecurityConfig.swift b/Meshtastic/Views/Settings/Config/SecurityConfig.swift index c6a6a6d3..d8c2a969 100644 --- a/Meshtastic/Views/Settings/Config/SecurityConfig.swift +++ b/Meshtastic/Views/Settings/Config/SecurityConfig.swift @@ -428,3 +428,10 @@ struct SecurityConfig: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return SecurityConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/Firmware.swift b/Meshtastic/Views/Settings/Firmware.swift index 490f7e01..3869d145 100644 --- a/Meshtastic/Views/Settings/Firmware.swift +++ b/Meshtastic/Views/Settings/Firmware.swift @@ -206,3 +206,10 @@ struct Firmware: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return Firmware(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/Meshtastic/Views/Settings/GPSStatus.swift b/Meshtastic/Views/Settings/GPSStatus.swift index c92a647c..f138f980 100644 --- a/Meshtastic/Views/Settings/GPSStatus.swift +++ b/Meshtastic/Views/Settings/GPSStatus.swift @@ -65,3 +65,7 @@ struct GPSStatus: View { } } } + +#Preview { + GPSStatus() +} diff --git a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift index 52927149..8b0bfbb3 100644 --- a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift +++ b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift @@ -169,3 +169,7 @@ struct AppLogFilter: View { .presentationBackgroundInteraction(.enabled(upThrough: .medium)) } } + +#Preview { + AppLogFilter(categories: .constant(Set()), levels: .constant(Set())) +} diff --git a/Meshtastic/Views/Settings/TAKServerConfig.swift b/Meshtastic/Views/Settings/TAKServerConfig.swift index cb8e3666..7e8b6502 100644 --- a/Meshtastic/Views/Settings/TAKServerConfig.swift +++ b/Meshtastic/Views/Settings/TAKServerConfig.swift @@ -424,9 +424,7 @@ struct TAKServerConfig: View { } } - // MARK: - Channel Label - @ViewBuilder private func channelLabel(_ channel: ChannelEntity) -> some View { if channel.name?.isEmpty ?? false { diff --git a/Meshtastic/Views/Settings/UpdateIntervalPicker.swift b/Meshtastic/Views/Settings/UpdateIntervalPicker.swift index c8601624..46e59088 100644 --- a/Meshtastic/Views/Settings/UpdateIntervalPicker.swift +++ b/Meshtastic/Views/Settings/UpdateIntervalPicker.swift @@ -55,3 +55,11 @@ struct UpdateIntervalPicker: View { } } } + +#Preview { + UpdateIntervalPicker( + config: .broadcastShort, + pickerLabel: "Update Interval", + selectedInterval: .constant(UpdateInterval(from: 30)) + ) +} diff --git a/Meshtastic/Views/Settings/UserConfig.swift b/Meshtastic/Views/Settings/UserConfig.swift index ef0c1ffb..aab5a127 100644 --- a/Meshtastic/Views/Settings/UserConfig.swift +++ b/Meshtastic/Views/Settings/UserConfig.swift @@ -253,3 +253,10 @@ struct UserConfig: View { } } } + +#Preview { + let context = PersistenceController.preview.container.viewContext + return UserConfig(node: nil) + .environmentObject(AccessoryManager.shared) + .environment(\.managedObjectContext, context) +} diff --git a/MeshtasticTests/ConnectViewTests.swift b/MeshtasticTests/ConnectViewTests.swift index cbbcd331..450591ad 100644 --- a/MeshtasticTests/ConnectViewTests.swift +++ b/MeshtasticTests/ConnectViewTests.swift @@ -55,7 +55,7 @@ struct DeviceTests { (-80, BLESignalStrength.normal), (-84, BLESignalStrength.normal), (-85, BLESignalStrength.weak), - (-100, BLESignalStrength.weak), + (-100, BLESignalStrength.weak) ]) func signalStrength(rssi: Int, expected: BLESignalStrength) { let device = Device( @@ -209,7 +209,7 @@ struct TransportTypeTests { @Test(arguments: [ (TransportType.ble, "BLE"), (TransportType.tcp, "TCP"), - (TransportType.serial, "Serial"), + (TransportType.serial, "Serial") ]) func rawValues(type: TransportType, expected: String) { #expect(type.rawValue == expected) @@ -307,7 +307,7 @@ struct NavigationStateTests { NavigationState.Tab.connect, NavigationState.Tab.nodes, NavigationState.Tab.map, - NavigationState.Tab.settings, + NavigationState.Tab.settings ]) func tabRawValues(tab: NavigationState.Tab) { #expect(NavigationState.Tab(rawValue: tab.rawValue) == tab) diff --git a/MeshtasticTests/RouterTests.swift b/MeshtasticTests/RouterTests.swift index 1175dc59..11af217c 100644 --- a/MeshtasticTests/RouterTests.swift +++ b/MeshtasticTests/RouterTests.swift @@ -214,7 +214,7 @@ struct RouterTests { ("debugLogs", SettingsNavigationState.debugLogs), ("appFiles", SettingsNavigationState.appFiles), ("firmwareUpdates", SettingsNavigationState.firmwareUpdates), - ("tak", SettingsNavigationState.tak), + ("tak", SettingsNavigationState.tak) ]) func routeSettingsPage(path: String, expected: SettingsNavigationState) async throws { try await assertRoute(