mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
swiftlint
This commit is contained in:
parent
8a41d11ec1
commit
11b95dca4d
11 changed files with 67 additions and 72 deletions
|
|
@ -27,4 +27,4 @@ extension Color {
|
|||
opacity: Double(a) / 255
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ struct UserDefault<T: Decodable> {
|
|||
|
||||
var wrappedValue: T {
|
||||
get {
|
||||
if defaultValue as? any RawRepresentable != nil {
|
||||
if defaultValue is any RawRepresentable {
|
||||
let storedValue = UserDefaults.standard.object(forKey: key.rawValue)
|
||||
|
||||
guard let storedValue,
|
||||
let jsonString = (storedValue as? String != nil) ? "\"\(storedValue)\"" : "\(storedValue)",
|
||||
let jsonString = (storedValue is String) ? "\"\(storedValue)\"" : "\(storedValue)",
|
||||
let data = jsonString.data(using: .utf8),
|
||||
let value = (try? JSONDecoder().decode(T.self, from: data)) else { return defaultValue }
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ struct GeoJSONFeature: Codable {
|
|||
let id: Int?
|
||||
let geometry: GeoJSONGeometry
|
||||
let properties: [String: AnyCodableValue]?
|
||||
|
||||
|
||||
// MARK: - GeoJSON Styling Properties
|
||||
|
||||
|
||||
/// Extract feature name from properties, defaulting to empty string
|
||||
var name: String {
|
||||
// Check for "NAME" first (uppercase), then "name" (lowercase)
|
||||
|
|
@ -30,7 +30,7 @@ struct GeoJSONFeature: Codable {
|
|||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
/// Extract layer metadata from properties
|
||||
var layerId: String? {
|
||||
if case .string(let value) = properties?["layer_id"] {
|
||||
|
|
@ -38,60 +38,60 @@ struct GeoJSONFeature: Codable {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var layerName: String? {
|
||||
if case .string(let value) = properties?["layer_name"] {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var layerDescription: String? {
|
||||
if case .string(let value) = properties?["description"] {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var isVisible: Bool {
|
||||
if case .bool(let value) = properties?["visible"] {
|
||||
return value
|
||||
}
|
||||
return true // Default to visible
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Point/Marker Styling
|
||||
|
||||
|
||||
var markerColor: String? {
|
||||
if case .string(let value) = properties?["marker-color"] {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var markerSize: String? {
|
||||
if case .string(let value) = properties?["marker-size"] {
|
||||
return value
|
||||
}
|
||||
return "medium" // Default size
|
||||
}
|
||||
|
||||
|
||||
var markerSymbol: String? {
|
||||
if case .string(let value) = properties?["marker-symbol"] {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Stroke/Line Styling
|
||||
|
||||
|
||||
var strokeColor: String? {
|
||||
if case .string(let value) = properties?["stroke"] {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var strokeWidth: Double {
|
||||
if case .double(let value) = properties?["stroke-width"] {
|
||||
return value
|
||||
|
|
@ -100,7 +100,7 @@ struct GeoJSONFeature: Codable {
|
|||
}
|
||||
return 1.0 // Default width
|
||||
}
|
||||
|
||||
|
||||
var strokeOpacity: Double {
|
||||
if case .double(let value) = properties?["stroke-opacity"] {
|
||||
return value
|
||||
|
|
@ -109,7 +109,7 @@ struct GeoJSONFeature: Codable {
|
|||
}
|
||||
return 1.0 // Default opacity
|
||||
}
|
||||
|
||||
|
||||
var lineDashArray: [Double]? {
|
||||
if case .array(let values) = properties?["line-dasharray"] {
|
||||
return values.compactMap { value in
|
||||
|
|
@ -122,16 +122,16 @@ struct GeoJSONFeature: Codable {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Fill Styling
|
||||
|
||||
|
||||
var fillColor: String? {
|
||||
if case .string(let value) = properties?["fill"] {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var fillOpacity: Double {
|
||||
if case .double(let value) = properties?["fill-opacity"] {
|
||||
return value
|
||||
|
|
@ -140,14 +140,14 @@ struct GeoJSONFeature: Codable {
|
|||
}
|
||||
return 0.0 // Default to no fill
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Computed Rendering Properties
|
||||
|
||||
|
||||
/// Get effective stroke color (fallback to marker color for points)
|
||||
var effectiveStrokeColor: String {
|
||||
return strokeColor ?? markerColor ?? "#000000"
|
||||
}
|
||||
|
||||
|
||||
/// Get effective fill color (fallback to stroke color if fill opacity > 0)
|
||||
var effectiveFillColor: String {
|
||||
if fillOpacity > 0 {
|
||||
|
|
@ -155,7 +155,7 @@ struct GeoJSONFeature: Codable {
|
|||
}
|
||||
return "#000000"
|
||||
}
|
||||
|
||||
|
||||
/// Convert marker size to point radius
|
||||
var markerRadius: CGFloat {
|
||||
switch markerSize {
|
||||
|
|
@ -174,7 +174,7 @@ struct GeoJSONStyledFeature: Identifiable {
|
|||
let id = UUID()
|
||||
let feature: GeoJSONFeature
|
||||
let overlayId: String
|
||||
|
||||
|
||||
/// Create MKOverlay from this styled feature
|
||||
func createOverlay() -> MKOverlay? {
|
||||
do {
|
||||
|
|
@ -187,14 +187,14 @@ struct GeoJSONStyledFeature: Identifiable {
|
|||
],
|
||||
"properties": feature.properties?.mapValues { $0.toAnyObject() } ?? [:]
|
||||
]
|
||||
|
||||
|
||||
// Creating overlay for geometry
|
||||
|
||||
|
||||
let geojsonData = try JSONSerialization.data(withJSONObject: featureDict)
|
||||
let mkFeatures = try MKGeoJSONDecoder().decode(geojsonData)
|
||||
|
||||
|
||||
// MKGeoJSONDecoder processing
|
||||
|
||||
|
||||
if let mkFeature = mkFeatures.first as? MKGeoJSONFeature {
|
||||
// Processing geometry objects
|
||||
if let geometry = mkFeature.geometry.first as? MKOverlay {
|
||||
|
|
@ -207,7 +207,7 @@ struct GeoJSONStyledFeature: Identifiable {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
/// Get stroke style for this feature
|
||||
var strokeStyle: StrokeStyle {
|
||||
let dashArray = feature.lineDashArray
|
||||
|
|
@ -226,12 +226,12 @@ struct GeoJSONStyledFeature: Identifiable {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Get stroke color with opacity
|
||||
var strokeColor: Color {
|
||||
return Color(hex: feature.effectiveStrokeColor).opacity(feature.strokeOpacity)
|
||||
}
|
||||
|
||||
|
||||
/// Get fill color with opacity
|
||||
var fillColor: Color {
|
||||
return Color(hex: feature.effectiveFillColor).opacity(feature.fillOpacity)
|
||||
|
|
@ -316,26 +316,26 @@ enum AnyCodableValue: Codable {
|
|||
return dict.mapValues { $0.toAnyObject() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Helper to convert Point coordinates to CLLocationCoordinate2D
|
||||
func toCoordinate() -> CLLocationCoordinate2D? {
|
||||
if case .array(let coords) = self,
|
||||
coords.count >= 2 {
|
||||
let lon: Double
|
||||
let lat: Double
|
||||
|
||||
|
||||
switch coords[0] {
|
||||
case .double(let d): lon = d
|
||||
case .int(let i): lon = Double(i)
|
||||
default: return nil
|
||||
}
|
||||
|
||||
|
||||
switch coords[1] {
|
||||
case .double(let d): lat = d
|
||||
case .int(let i): lat = Double(i)
|
||||
default: return nil
|
||||
}
|
||||
|
||||
|
||||
return CLLocationCoordinate2D(latitude: lat, longitude: lon)
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -28,24 +28,24 @@ class GeoJSONOverlayManager {
|
|||
func loadStyledFeaturesForConfigs(_ enabledConfigs: Set<UUID>) -> [GeoJSONStyledFeature] {
|
||||
// Get files that match the enabled configs
|
||||
let enabledFiles = MapDataManager.shared.getUploadedFiles().filter { enabledConfigs.contains($0.id) }
|
||||
|
||||
|
||||
guard !enabledFiles.isEmpty else {
|
||||
return []
|
||||
}
|
||||
|
||||
|
||||
// Load feature collection from enabled files only
|
||||
guard let collection = MapDataManager.shared.loadFeatureCollectionForFiles(enabledFiles) else {
|
||||
return []
|
||||
}
|
||||
|
||||
|
||||
var styledFeatures: [GeoJSONStyledFeature] = []
|
||||
|
||||
|
||||
for feature in collection.features {
|
||||
// Skip invisible features
|
||||
guard feature.isVisible else {
|
||||
continue
|
||||
guard feature.isVisible else {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
let layerId = feature.layerId ?? "default"
|
||||
let styledFeature = GeoJSONStyledFeature(
|
||||
feature: feature,
|
||||
|
|
@ -53,7 +53,7 @@ class GeoJSONOverlayManager {
|
|||
)
|
||||
styledFeatures.append(styledFeature)
|
||||
}
|
||||
|
||||
|
||||
return styledFeatures
|
||||
}
|
||||
|
||||
|
|
@ -62,15 +62,15 @@ class GeoJSONOverlayManager {
|
|||
guard let collection = loadFeatureCollection() else {
|
||||
return []
|
||||
}
|
||||
|
||||
|
||||
var styledFeatures: [GeoJSONStyledFeature] = []
|
||||
|
||||
|
||||
for feature in collection.features {
|
||||
// Skip invisible features
|
||||
guard feature.isVisible else {
|
||||
continue
|
||||
guard feature.isVisible else {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
let layerId = feature.layerId ?? "default"
|
||||
let styledFeature = GeoJSONStyledFeature(
|
||||
feature: feature,
|
||||
|
|
@ -78,16 +78,16 @@ class GeoJSONOverlayManager {
|
|||
)
|
||||
styledFeatures.append(styledFeature)
|
||||
}
|
||||
|
||||
|
||||
return styledFeatures
|
||||
}
|
||||
|
||||
/// Get all features grouped by layer ID
|
||||
func getFeaturesByLayer() -> [String: [GeoJSONFeature]] {
|
||||
guard let collection = loadFeatureCollection() else { return [:] }
|
||||
|
||||
|
||||
var featuresByLayer: [String: [GeoJSONFeature]] = [:]
|
||||
|
||||
|
||||
for feature in collection.features {
|
||||
let layerId = feature.layerId ?? "default"
|
||||
if featuresByLayer[layerId] == nil {
|
||||
|
|
@ -95,7 +95,7 @@ class GeoJSONOverlayManager {
|
|||
}
|
||||
featuresByLayer[layerId]?.append(feature)
|
||||
}
|
||||
|
||||
|
||||
return featuresByLayer
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ class GeoJSONOverlayManager {
|
|||
func hasUserData() -> Bool {
|
||||
return !MapDataManager.shared.getUploadedFiles().isEmpty
|
||||
}
|
||||
|
||||
|
||||
/// Check if there are any active files
|
||||
func hasActiveData() -> Bool {
|
||||
return MapDataManager.shared.getUploadedFiles().contains { $0.isActive }
|
||||
|
|
@ -131,18 +131,18 @@ class GeoJSONOverlayManager {
|
|||
return NSLocalizedString("No Data", comment: "Data source label when no files are available")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - File-based Filtering
|
||||
|
||||
|
||||
/// Get all uploaded files with their active states for UI display
|
||||
func getUploadedFilesWithState() -> [MapDataMetadata] {
|
||||
return MapDataManager.shared.getUploadedFiles()
|
||||
}
|
||||
|
||||
|
||||
/// Toggle the active state of an uploaded file
|
||||
func toggleFileActive(_ fileId: UUID) {
|
||||
MapDataManager.shared.toggleFileActive(fileId)
|
||||
// Clear cache to force reload with new file states
|
||||
clearCache()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,7 +167,6 @@ class MapDataManager: ObservableObject {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
/// Get overlay count from raw GeoJSON data
|
||||
private func getOverlayCount(from data: Data) throws -> Int {
|
||||
// Parse as raw GeoJSON FeatureCollection
|
||||
|
|
@ -305,7 +304,6 @@ class MapDataManager: ObservableObject {
|
|||
throw MapDataError.fileNotFound
|
||||
}
|
||||
|
||||
|
||||
// Check if file exists before trying to delete
|
||||
if !FileManager.default.fileExists(atPath: fileURL.path) {
|
||||
Logger.services.warning("🗑️ MapDataManager: File does not exist at path: \(fileURL.path, privacy: .public)")
|
||||
|
|
@ -351,7 +349,6 @@ class MapDataManager: ObservableObject {
|
|||
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Metadata Persistence
|
||||
|
||||
/// Load metadata from disk
|
||||
|
|
@ -463,4 +460,4 @@ enum MapDataError: Error, LocalizedError {
|
|||
// MARK: - Notification Names
|
||||
extension Foundation.Notification.Name {
|
||||
static let mapDataFileDeleted = Foundation.Notification.Name("mapDataFileDeleted")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1027,7 +1027,7 @@ func textMessageAppPacket(
|
|||
subtitle: "AKA \(newMessage.fromUser?.shortName ?? "?")",
|
||||
content: messageText!,
|
||||
target: "messages",
|
||||
path: "meshtastic:///messages?userNum=\(newMessage.fromUser?.num ?? 0)&messageId=\(newMessage.isEmoji ? newMessage.replyID : newMessage.messageId)",
|
||||
path: "meshtastic:///messages?userNum=\(newMessage.fromUser?.num ?? 0)&messageId=\(newMessage.isEmoji ? newMessage.replyID : newMessage.messageId)",
|
||||
messageId: newMessage.messageId,
|
||||
channel: newMessage.channel,
|
||||
userNum: Int64(packet.from),
|
||||
|
|
|
|||
|
|
@ -248,7 +248,6 @@ struct MeshMapContent: MapContent {
|
|||
// Get all features but filter by enabled configs
|
||||
let allStyledFeatures = GeoJSONOverlayManager.shared.loadStyledFeaturesForConfigs(enabledOverlayConfigs)
|
||||
|
||||
|
||||
return Group {
|
||||
ForEach(0..<allStyledFeatures.count, id: \.self) { index in
|
||||
let styledFeature = allStyledFeatures[index]
|
||||
|
|
|
|||
|
|
@ -153,11 +153,11 @@ struct MapSettingsForm: View {
|
|||
Spacer()
|
||||
}
|
||||
.padding(.leading, 35)
|
||||
|
||||
|
||||
// Individual file toggles
|
||||
ForEach(mapDataManager.getUploadedFiles()) { file in
|
||||
Toggle(isOn: Binding(
|
||||
get: {
|
||||
get: {
|
||||
return enabledOverlayConfigs.contains(file.id)
|
||||
},
|
||||
set: { newValue in
|
||||
|
|
@ -191,7 +191,7 @@ struct MapSettingsForm: View {
|
|||
.tint(.accentColor)
|
||||
.padding(.leading, 35)
|
||||
}
|
||||
|
||||
|
||||
// Manage data link
|
||||
NavigationLink(destination: MapDataFiles()) {
|
||||
HStack {
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ struct MeshMap: View {
|
|||
})
|
||||
.onFirstAppear {
|
||||
UIApplication.shared.isIdleTimerDisabled = true
|
||||
|
||||
|
||||
// Initialize enabled overlay configs with all active files
|
||||
let activeFiles = GeoJSONOverlayManager.shared.getUploadedFilesWithState().filter { $0.isActive }
|
||||
enabledOverlayConfigs = Set(activeFiles.map { $0.id })
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ struct SecurityConfig: View {
|
|||
name: "\(bleManager.connectedPeripheral?.shortName ?? "?")"
|
||||
)
|
||||
})
|
||||
.onChange(of: node) { _, newNode in
|
||||
.onChange(of: node) { _, _ in
|
||||
setSecurityValues()
|
||||
}
|
||||
.onChange(of: isManaged) { _, newIsManaged in
|
||||
|
|
|
|||
|
|
@ -175,7 +175,6 @@ struct MapDataFiles: View {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private func deleteFile(_ file: MapDataMetadata) {
|
||||
Task {
|
||||
do {
|
||||
|
|
@ -252,4 +251,4 @@ struct MapDataFileRow: View {
|
|||
NavigationView {
|
||||
MapDataFiles()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue