From 2d80511d7d4c1c0a7293d6d1f0bed4aa497b68c9 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 27 Jul 2025 12:24:48 -0700 Subject: [PATCH] Move color extention to the existing file, clean up the connected device widget spacing which seems to be oddly linted --- Meshtastic.xcodeproj/project.pbxproj | 8 ++--- Meshtastic/Extensions/Color+Hex.swift | 30 ---------------- Meshtastic/Extensions/Color.swift | 29 ++++++++++++++- .../Views/Helpers/ConnectedDevice.swift | 35 +++++++++---------- 4 files changed, 47 insertions(+), 55 deletions(-) delete mode 100644 Meshtastic/Extensions/Color+Hex.swift diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index d20cd22e..d41c74af 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -58,7 +58,6 @@ 25F5D5D12C4375DF008036E3 /* RouterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F5D5D02C4375DF008036E3 /* RouterTests.swift */; }; 3D3417B42E2730EC006A988B /* GeoJSONOverlayManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D3417B32E2730EC006A988B /* GeoJSONOverlayManager.swift */; }; 3D3417C82E29D38A006A988B /* GeoJSONOverlayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D3417C72E29D38A006A988B /* GeoJSONOverlayConfig.swift */; }; - 3D3417CB2E29D3B0006A988B /* Color+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D3417C92E29D3B0006A988B /* Color+Hex.swift */; }; 3D3417D22E2DC260006A988B /* MapDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D3417D12E2DC260006A988B /* MapDataManager.swift */; }; 3D3417D42E2DC293006A988B /* MapDataFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D3417D32E2DC293006A988B /* MapDataFiles.swift */; }; 6D825E622C34786C008DBEE4 /* CommonRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D825E612C34786C008DBEE4 /* CommonRegex.swift */; }; @@ -333,7 +332,6 @@ 25F5D5D02C4375DF008036E3 /* RouterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouterTests.swift; sourceTree = ""; }; 3D3417B32E2730EC006A988B /* GeoJSONOverlayManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoJSONOverlayManager.swift; sourceTree = ""; }; 3D3417C72E29D38A006A988B /* GeoJSONOverlayConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoJSONOverlayConfig.swift; sourceTree = ""; }; - 3D3417C92E29D3B0006A988B /* Color+Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Hex.swift"; sourceTree = ""; }; 3D3417D12E2DC260006A988B /* MapDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapDataManager.swift; sourceTree = ""; }; 3D3417D32E2DC293006A988B /* MapDataFiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapDataFiles.swift; sourceTree = ""; }; 6D825E612C34786C008DBEE4 /* CommonRegex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonRegex.swift; sourceTree = ""; }; @@ -798,7 +796,7 @@ DD4A911C2708C57100501B7E /* Settings */ = { isa = PBXGroup; children = ( - 3D3417D32E2DC293006A988B /* MapDataManager.swift */, + 3D3417D32E2DC293006A988B /* MapDataFiles.swift */, DDD5BB0E2C285F92007E03CA /* Logs */, DD93800C2BA74CE3008BEC06 /* Channels */, DD61937A2863876A00E59241 /* Config */, @@ -1181,7 +1179,6 @@ DDDB443E29F79A9400EE2349 /* Extensions */ = { isa = PBXGroup; children = ( - 3D3417C92E29D3B0006A988B /* Color+Hex.swift */, DD007BB12AA59B9A00F5FA12 /* CoreData */, DDFFA7462B3A7F3C004730DB /* Bundle.swift */, DDDB444529F8A96500EE2349 /* Character.swift */, @@ -1454,7 +1451,7 @@ DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */, DDDB444C29F8AAA600EE2349 /* Color.swift in Sources */, DDDFE73F2D0D48FF0044463C /* IgnoreNodeButton.swift in Sources */, - 3D3417D42E2DC293006A988B /* MapDataManager.swift in Sources */, + 3D3417D42E2DC293006A988B /* MapDataFiles.swift in Sources */, DDB8F4122A9EE5DD00230ECE /* UserList.swift in Sources */, DDB75A0F2A05920E006ED576 /* FileManager.swift in Sources */, DD3D17E02C3FB67200561584 /* LocalWeatherConditions.swift in Sources */, @@ -1592,7 +1589,6 @@ DD86D40F2881BE4C00BAEB7A /* CsvDocument.swift in Sources */, DDB75A1E2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift in Sources */, DDA6B2E928419CF2003E8C16 /* MeshPackets.swift in Sources */, - 3D3417CB2E29D3B0006A988B /* Color+Hex.swift in Sources */, DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */, BCB613852C68703800485544 /* NodePositionIntent.swift in Sources */, DDB75A212A12B954006ED576 /* LoRaSignalStrength.swift in Sources */, diff --git a/Meshtastic/Extensions/Color+Hex.swift b/Meshtastic/Extensions/Color+Hex.swift deleted file mode 100644 index c1fe99a7..00000000 --- a/Meshtastic/Extensions/Color+Hex.swift +++ /dev/null @@ -1,30 +0,0 @@ -import SwiftUI - -extension Color { - /// Initialize a Color from a hex string (e.g., "#FF0000" or "FF0000") - init(hex: String) { - let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) - var int: UInt64 = 0 - Scanner(string: hex).scanHexInt64(&int) - - let a, r, g, b: UInt64 - switch hex.count { - case 3: // RGB (12-bit) - (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) - case 6: // RGB (24-bit) - (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) - case 8: // ARGB (32-bit) - (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) - default: - (a, r, g, b) = (255, 0, 0, 0) - } - - self.init( - .sRGB, - red: Double(r) / 255, - green: Double(g) / 255, - blue: Double(b) / 255, - opacity: Double(a) / 255 - ) - } -} diff --git a/Meshtastic/Extensions/Color.swift b/Meshtastic/Extensions/Color.swift index 7b7980f0..aa6d278e 100644 --- a/Meshtastic/Extensions/Color.swift +++ b/Meshtastic/Extensions/Color.swift @@ -2,7 +2,7 @@ // Color.swift // Meshtastic // -// Created by Garth Vander Houwen on 4/25/23. +// Copyright Garth Vander Houwen 4/25/23. // import Foundation @@ -10,6 +10,33 @@ import SwiftUI import UIKit extension Color { + + /// Initialize a Color from a hex string (e.g., "#FF0000" or "FF0000") + init(hex: String) { + let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) + var int: UInt64 = 0 + Scanner(string: hex).scanHexInt64(&int) + + let a, r, g, b: UInt64 + switch hex.count { + case 3: // RGB (12-bit) + (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) + case 6: // RGB (24-bit) + (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) + case 8: // ARGB (32-bit) + (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) + default: + (a, r, g, b) = (255, 0, 0, 0) + } + + self.init( + .sRGB, + red: Double(r) / 255, + green: Double(g) / 255, + blue: Double(b) / 255, + opacity: Double(a) / 255 + ) + } /// Returns a boolean for a SwiftUI Color to determine what color of text to use /// - Returns: true if the color is light func isLight() -> Bool { diff --git a/Meshtastic/Views/Helpers/ConnectedDevice.swift b/Meshtastic/Views/Helpers/ConnectedDevice.swift index 98d2d50e..f0a9fa2a 100644 --- a/Meshtastic/Views/Helpers/ConnectedDevice.swift +++ b/Meshtastic/Views/Helpers/ConnectedDevice.swift @@ -1,7 +1,7 @@ /* -Abstract: -A view draws the indicator used in the upper right corner for views using BLE -*/ + Abstract: + A view that draws the indicator used in the upper right corner for views using BLE + */ import SwiftUI @@ -9,13 +9,12 @@ struct ConnectedDevice: View { var bluetoothOn: Bool var deviceConnected: Bool var name: String - var mqttProxyConnected: Bool = false var mqttUplinkEnabled: Bool = false var mqttDownlinkEnabled: Bool = false - var mqttTopic: String = "" + var mqttTopic: String = "" var phoneOnly: Bool = false - + var body: some View { HStack { if (phoneOnly && UIDevice.current.userInterfaceIdiom == .phone) || !phoneOnly { @@ -69,16 +68,16 @@ struct ConnectedDevice: View { struct ConnectedDevice_Previews: PreviewProvider { static var previews: some View { - VStack(alignment: .trailing) { - ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true) - ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: true, mqttDownlinkEnabled: true) - ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: true, mqttDownlinkEnabled: true, mqttTopic: "msh/US/2/e/#") - ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: true, mqttDownlinkEnabled: false) - ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: true, mqttDownlinkEnabled: false) - ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: false, mqttDownlinkEnabled: true) - ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: false, mqttDownlinkEnabled: true) - ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true) - ConnectedDevice(bluetoothOn: true, deviceConnected: false, name: "MEMO", mqttProxyConnected: false) - }.previewLayout(.fixed(width: 150, height: 275)) - } + VStack(alignment: .trailing) { + ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true) + ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: true, mqttDownlinkEnabled: true) + ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: true, mqttDownlinkEnabled: true, mqttTopic: "msh/US/2/e/#") + ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: true, mqttDownlinkEnabled: false) + ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: true, mqttDownlinkEnabled: false) + ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: false, mqttDownlinkEnabled: true) + ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: false, mqttDownlinkEnabled: true) + ConnectedDevice(bluetoothOn: true, deviceConnected: true, name: "MEMO", mqttProxyConnected: true) + ConnectedDevice(bluetoothOn: true, deviceConnected: false, name: "MEMO", mqttProxyConnected: false) + }.previewLayout(.fixed(width: 150, height: 275)) + } }