Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
ad25342
Bump version
garthvh Oct 18, 2025
69c318a
Message list performance fixes into 2.7.6 (#1475)
garthvh Oct 18, 2025
6705a18
Explicitly set unmessagable, seems unnessary
garthvh Oct 18, 2025
b6b7107
Merge remote-tracking branch 'refs/remotes/origin/2.7.6'
garthvh Oct 18, 2025
9e0a1ff
Add back missing mesh map features
garthvh Oct 20, 2025
16e56e7
Fix: "Retrieving nodes" significantly slower after reconnect extract…
garthvh Oct 20, 2025
4114722
Hide route lines filter from mesh map
garthvh Oct 21, 2025
1d49e02
Merge remote-tracking branch 'refs/remotes/origin/2.7.6'
garthvh Oct 21, 2025
6c3c022
Mesh Map: fuzz imprecise locations so they're distinguishable and cli…
compumike Oct 21, 2025
4aa56b1
Fix bad merge
garthvh Oct 21, 2025
ddb01f5
Update Meshtastic/Extensions/CoreData/UserEntityExtension.swift
garthvh Oct 27, 2025
428b144
Update Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.s…
garthvh Oct 27, 2025
4facf10
Update Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift
garthvh Oct 27, 2025
5ecad21
Update Meshtastic/Extensions/CoreData/MyInfoEntityExtension.swift
garthvh Oct 27, 2025
0c3f1bd
Update Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift
garthvh Oct 27, 2025
3f27e3b
Keep list of previous manual connections (#1484)
jake-b Oct 28, 2025
7668a7a
Show who relayed messages (#1486)
RCGV1 Oct 28, 2025
e7b3583
upsertPositionPacket: don't use future timestamps to set node's lastH…
compumike Oct 28, 2025
92b1646
R1 NEO
garthvh Oct 28, 2025
12a1ca1
Neo
garthvh Oct 28, 2025
ebc84d3
Merge remote-tracking branch 'refs/remotes/origin/2.7.6'
garthvh Oct 28, 2025
58b1204
Update Meshtastic/Views/Settings/AppSettings.swift
garthvh Oct 28, 2025
3b9c0bf
Remove bad if
garthvh Oct 28, 2025
9e8290c
Merge remote-tracking branch 'refs/remotes/origin/2.7.6'
garthvh Oct 28, 2025
247ec49
Git rid of extra environment variable
garthvh Oct 28, 2025
59d106a
Update Meshtastic/Accessory/Transports/TCP/TCPTransport.swift
jake-b Oct 29, 2025
8df7140
MeshMap performance: quick wins (#1490)
compumike Oct 30, 2025
402cb83
NodeMap performance improvements for high # positions history (#1480)
compumike Oct 30, 2025
2ee6cdf
Fix wantRangeTestPackets to correctly follow rangeTestConfig.enabled …
compumike Oct 30, 2025
0fcf4fd
Fix interval drop down formatter
garthvh Oct 31, 2025
b4c749a
Clean up channel qr code functionality.
garthvh Nov 1, 2025
b327f13
perferredPeripheralId fix
jake-b Nov 1, 2025
feb9cf1
Set opt in
garthvh Nov 2, 2025
872c1ef
Retry once 5 second timer. dont throw the error
garthvh Nov 2, 2025
0f90d84
Queue for peripherals
garthvh Nov 6, 2025
ec5dfd5
Fix: hoplimit of dms would always fallback to hops away of the node e…
RCGV1 Nov 6, 2025
b51b5aa
Don't favorite client base
garthvh Nov 18, 2025
6aca186
Update device hardware
garthvh Nov 18, 2025
5762677
Prevent nil environment metrics
garthvh Nov 18, 2025
5707896
Bump datadog sdk
garthvh Nov 24, 2025
a91c62b
fix setting device telemetry enabled (#1515)
RCGV1 Dec 10, 2025
13fd9c3
Don't subscribe to mqtt topic if downlink is not on (#1501)
RCGV1 Dec 10, 2025
b57ba15
Preview enabled in connected devices (#1509)
Vaidios Dec 10, 2025
c19c810
UpdateCoreData.updateAnyPacketFrom: mirror firmware's lastHeard/snr/r…
compumike Dec 10, 2025
865e5e9
`CLIENT_BASE` add-favorite/role-change confirmation dialog (#1493)
compumike Dec 11, 2025
ced43d6
Experimental firmware update features
jake-b Dec 14, 2025
c0d7e4d
Update to Acknowledgements.plist
jake-b Dec 15, 2025
209ce72
Improvements to Nordic DFU views
jake-b Dec 15, 2025
6dd2502
Fix for UIObservationTrackingFeedbackLoopDetected
jake-b Dec 15, 2025
8346fb8
Compass view (#1521)
garthvh Dec 15, 2025
4f37f6a
Fix for supported device batch in NodeInfo
jake-b Dec 15, 2025
fc7d78f
Made JSON structs private: everything CoreData now
jake-b Dec 15, 2025
b4f6498
Improvements to ESP32 firmware screen
jake-b Dec 15, 2025
14efa4c
Remove discovery queue
garthvh Dec 16, 2025
fe1d1d6
revert problematic retry functionalliy
garthvh Dec 16, 2025
ccee0bf
format file
garthvh Dec 16, 2025
fcb20cd
Update & improve zh-Hans translation (#1523)
radiolee Dec 17, 2025
9b6e645
Update protobufs to 2.7.1
thebentern Dec 18, 2025
d6d3a6e
Merge pull request #1525 from meshtastic/protobufs-update-2.7.17
thebentern Dec 18, 2025
34794d8
Add long-turbo preset
thebentern Dec 18, 2025
8e58cd6
Merge pull request #1526 from meshtastic/add-long-turbo
thebentern Dec 18, 2025
ffcbeee
Disable Range Test module when primary channel is public/unsecured (#…
dubsector Dec 18, 2025
2c13159
Merge branch '2.7.6' into firmware-updates
jake-b Dec 18, 2025
0897d96
ESP32 WiFi Flashing
jake-b Dec 18, 2025
811bbdf
Bump Version
garthvh Dec 21, 2025
10ffdf9
Initial unified Meshtastic-OTA updater support
jake-b Dec 22, 2025
5a15051
Changes to OTA Protocol
jake-b Dec 23, 2025
58826f6
Latest OTA protobufs and protocol changes
jake-b Dec 28, 2025
e4a572a
OTA Protocol updates and clean-up
jake-b Dec 28, 2025
38731df
Clean up download and install button files
garthvh Dec 30, 2025
61a9a6c
Smaller firmware download and install buttons so they look decent on …
garthvh Dec 30, 2025
37a37c5
Add back deleted solar node image
garthvh Dec 30, 2025
795c8a8
Use let instead of nil check for connect battery icon
garthvh Dec 30, 2025
66abd09
OTA: file selection on Mac, improved reconnect
jake-b Jan 5, 2026
f44a166
Work in progress
jake-b Jan 5, 2026
cd7e16f
Merge branch 'wip' into firmware-updates
jake-b Jan 5, 2026
fc45e41
Additional OTA robustness improvements
jake-b Jan 6, 2026
c42df05
Indeterminate state inidicator for WiFi OTA erase
jake-b Jan 6, 2026
97d2530
UI improvements
jake-b Jan 6, 2026
c07e078
Update protos
thebentern Jan 15, 2026
c2e8886
Bump version
garthvh Jan 20, 2026
c9c06f1
Minor timing improvement during BLE OTA
jake-b Jan 20, 2026
7b0a5c8
Fix for macCatalyst code trying to build for iOS
jake-b Jan 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
527 changes: 474 additions & 53 deletions Localizable.xcstrings

Large diffs are not rendered by default.

366 changes: 356 additions & 10 deletions Meshtastic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 32 additions & 5 deletions Meshtastic.xcworkspace/xcshareddata/swiftpm/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
99 changes: 99 additions & 0 deletions Meshtastic/API/Helpers/URL+fetch.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// URL+fetch.swift
// Meshtastic
//
// Created by jake on 12/6/25.
//

import Foundation

extension URL {

/// Custom error type for the URL extension
enum TimeoutError: Error, LocalizedError {
case timedOut(TimeInterval)

var errorDescription: String? {
switch self {
case .timedOut(let seconds):
return "The operation timed out after \(seconds) seconds."
}
}
}

/// Fetches data from the URL (local or remote) with a strict timeout.
/// - Parameter timeout: The duration in seconds to wait before throwing an error.
/// - Returns: The `Data` retrieved.
func data(timeout: TimeInterval) async throws -> Data {

return try await withThrowingTaskGroup(of: Data.self) { group in

// Task 1: The Fetch Operation
group.addTask {
if self.isFileURL {
// Handle Local Files
// Note: Data(contentsOf:) is synchronous (blocking).
// Running it inside a Task allows it to be raced, though
// the underlying thread may remain blocked until OS IO completes
// if cancellation occurs.
return try Data(contentsOf: self)
} else {
// Handle Remote Network Requests
let (data, _) = try await URLSession.shared.data(from: self)
return data
}
}

// Task 2: The Timer
group.addTask {
// Convert seconds to nanoseconds
let nanoseconds = UInt64(timeout * 1_000_000_000)
try await Task.sleep(nanoseconds: nanoseconds)

// If we wake up, it means the fetch hasn't finished yet
throw TimeoutError.timedOut(timeout)
}

// Race Handling

// Wait for the first task to finish (either success or error)
guard let result = try await group.next() else {
// Should not be reachable, but required by compiler
throw URLError(.unknown)
}

// If we are here, one task finished successfully.
// Cancel the other task immediately.
group.cancelAll()

return result
}
}

/// Performs a HEAD request to fetch the ETag header for the URL.
/// - Parameter session: The URLSession to use (defaults to .shared).
/// - Returns: The ETag string if found and the request is successful, otherwise nil.
func eTag(using session: URLSession = .shared) async throws -> String? {
var request = URLRequest(url: self)
request.httpMethod = "HEAD"

// Ensure we don't use the local cache so we get the real ETag from the server
request.cachePolicy = .reloadIgnoringLocalCacheData

let (_, response) = try await session.data(for: request)

guard let httpResponse = response as? HTTPURLResponse else {
return nil
}

// Optional: Check for success status codes (200-299)
guard (200...299).contains(httpResponse.statusCode) else {
// You might want to return nil or throw a specific error here
// depending on your requirements (e.g. 404 Not Found)
return nil
}

// Header lookup is case-insensitive
return httpResponse.value(forHTTPHeaderField: "ETag")
}
}
41 changes: 41 additions & 0 deletions Meshtastic/API/Helpers/UTI+UF2.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// UTI+UF2.swift
// Meshtastic
//
// Created by jake on 12/12/25.
//

import UniformTypeIdentifiers
import SwiftUI

extension UTType {
// Define a custom type for your firmware
// Identifier: Use your bundle ID prefix (e.g., com.yourcompany.firmware)
static let UF2Firmware = UTType("com.meshtastic.uf2-firmware")!
static let ZIPFirmware = UTType(importedAs: "com.pkware.zip-firmware")
static let BINFirmware = UTType(importedAs: "com.meshtastic.bin-firmware")
}

struct FirmwareDocument: FileDocument {
// 1. Tell the system this document supports your custom UTType
static var readableContentTypes: [UTType] { [.UF2Firmware] }

var firmwareData: Data

init(data: Data) {
self.firmwareData = data
}

// Initialize from an existing file (Read)
init(configuration: ReadConfiguration) throws {
guard let data = configuration.file.regularFileContents else {
throw CocoaError(.fileReadCorruptFile)
}
self.firmwareData = data
}

// Prepare data for saving (Write)
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
return FileWrapper(regularFileWithContents: firmwareData)
}
}
Loading