mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Add SaveChannelLinkData so MessageText and MeshtasticApp can use .sheet(item: ...) and avoid infinite loop hang due to Binding rebuild
This commit is contained in:
parent
28f6332277
commit
9982f24a51
3 changed files with 39 additions and 53 deletions
|
|
@ -19,10 +19,8 @@ struct MeshtasticAppleApp: App {
|
|||
private let persistenceController: PersistenceController
|
||||
private let accessoryManager: AccessoryManager
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
@State var saveChannels = false
|
||||
@State var saveChannelLink: SaveChannelLinkData?
|
||||
@State var incomingUrl: URL?
|
||||
@State var channelSettings: String?
|
||||
@State var addChannels = false
|
||||
|
||||
init() {
|
||||
|
||||
|
|
@ -36,7 +34,7 @@ struct MeshtasticAppleApp: App {
|
|||
let appID = "79fe92a9-74c9-4c8f-ba63-6308384ecfa9"
|
||||
let clientToken = "pub4427bea20dbdb08a6af68034de22cd3b"
|
||||
var environment = "AppStore"
|
||||
|
||||
|
||||
#if DEBUG
|
||||
environment = "Local"
|
||||
#else
|
||||
|
|
@ -44,7 +42,8 @@ struct MeshtasticAppleApp: App {
|
|||
environment = "TestFlight"
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if false
|
||||
Datadog.initialize(
|
||||
with: Datadog.Configuration(
|
||||
clientToken: clientToken,
|
||||
|
|
@ -81,6 +80,7 @@ struct MeshtasticAppleApp: App {
|
|||
)
|
||||
)
|
||||
}
|
||||
#endif
|
||||
accessoryManager = AccessoryManager.shared
|
||||
accessoryManager.appState = appState
|
||||
|
||||
|
|
@ -110,20 +110,11 @@ struct MeshtasticAppleApp: App {
|
|||
appState: appState,
|
||||
router: appState.router
|
||||
)
|
||||
.sheet(isPresented: Binding(
|
||||
get: {
|
||||
saveChannels && !(channelSettings == nil)
|
||||
},
|
||||
set: { newValue in
|
||||
saveChannels = newValue
|
||||
if !newValue {
|
||||
channelSettings = nil
|
||||
}
|
||||
}
|
||||
)) {
|
||||
.sheet(item: $saveChannelLink
|
||||
) { link in
|
||||
SaveChannelQRCode(
|
||||
channelSetLink: channelSettings ?? "Empty Channel URL",
|
||||
addChannels: addChannels,
|
||||
channelSetLink: link.data,
|
||||
addChannels: link.add,
|
||||
accessoryManager: accessoryManager )
|
||||
.presentationDetents([.large])
|
||||
.presentationDragIndicator(.visible)
|
||||
|
|
@ -131,54 +122,54 @@ struct MeshtasticAppleApp: App {
|
|||
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
|
||||
Logger.mesh.debug("URL received \(userActivity, privacy: .public)")
|
||||
self.incomingUrl = userActivity.webpageURL
|
||||
self.saveChannels = false
|
||||
self.saveChannelLink = nil
|
||||
var addChannels = false
|
||||
if self.incomingUrl?.absoluteString.lowercased().contains("meshtastic.org/v/#") == true {
|
||||
ContactURLHandler.handleContactUrl(url: self.incomingUrl!, accessoryManager: accessoryManager)
|
||||
} else if self.incomingUrl?.absoluteString.lowercased().contains("meshtastic.org/e/") == true {
|
||||
if let components = self.incomingUrl?.absoluteString.components(separatedBy: "#") {
|
||||
self.addChannels = Bool(self.incomingUrl?["add"] ?? "false") ?? false
|
||||
addChannels = Bool(self.incomingUrl?["add"] ?? "false") ?? false
|
||||
if (self.incomingUrl?.absoluteString.lowercased().contains("?")) != nil {
|
||||
guard let cs = components.last!.components(separatedBy: "?").first else {
|
||||
return
|
||||
}
|
||||
self.channelSettings = cs
|
||||
self.saveChannelLink = SaveChannelLinkData(data: cs, add: addChannels)
|
||||
} else {
|
||||
guard let cs = components.first else {
|
||||
return
|
||||
}
|
||||
self.channelSettings = cs
|
||||
self.saveChannelLink = SaveChannelLinkData(data: cs, add: addChannels)
|
||||
}
|
||||
Logger.services.debug("Add Channel \(self.addChannels, privacy: .public)")
|
||||
Logger.services.debug("Add Channel \(addChannels, privacy: .public)")
|
||||
}
|
||||
self.saveChannels = true
|
||||
Logger.mesh.debug("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link")")
|
||||
}
|
||||
if self.saveChannels {
|
||||
if self.saveChannelLink != nil {
|
||||
Logger.mesh.debug("User wants to open Channel Settings URL: \(String(describing: self.incomingUrl!.relativeString), privacy: .public)")
|
||||
}
|
||||
}
|
||||
.onOpenURL(perform: { (url) in
|
||||
Logger.mesh.debug("Some sort of URL was received \(url, privacy: .public)")
|
||||
self.incomingUrl = url
|
||||
var addChannels = false
|
||||
if url.absoluteString.lowercased().contains("meshtastic.org/v/#") {
|
||||
ContactURLHandler.handleContactUrl(url: url, accessoryManager: accessoryManager)
|
||||
} else if url.absoluteString.lowercased().contains("meshtastic.org/e/") {
|
||||
if let components = self.incomingUrl?.absoluteString.components(separatedBy: "#") {
|
||||
self.addChannels = Bool(self.incomingUrl?["add"] ?? "false") ?? false
|
||||
addChannels = Bool(self.incomingUrl?["add"] ?? "false") ?? false
|
||||
if self.incomingUrl?.absoluteString.lowercased().contains("?") != nil {
|
||||
guard let cs = components.last!.components(separatedBy: "?").first else {
|
||||
return
|
||||
}
|
||||
self.channelSettings = cs
|
||||
self.saveChannelLink = SaveChannelLinkData(data: cs, add: addChannels)
|
||||
} else {
|
||||
guard let cs = components.first else {
|
||||
return
|
||||
}
|
||||
self.channelSettings = cs
|
||||
self.saveChannelLink = SaveChannelLinkData(data: cs, add: addChannels)
|
||||
}
|
||||
Logger.services.debug("Add Channel \(self.addChannels, privacy: .public)")
|
||||
Logger.services.debug("Add Channel \(addChannels, privacy: .public)")
|
||||
}
|
||||
self.saveChannels = true
|
||||
Logger.mesh.debug("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link", privacy: .public)")
|
||||
} else if url.absoluteString.lowercased().contains("meshtastic:///") {
|
||||
appState.router.route(url: url)
|
||||
|
|
@ -221,7 +212,7 @@ struct MeshtasticAppleApp: App {
|
|||
.environment(\.managedObjectContext, persistenceController.container.viewContext)
|
||||
.environmentObject(appState)
|
||||
.environmentObject(accessoryManager)
|
||||
.environmentObject(appState.router)
|
||||
.environmentObject(appState.router)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ struct MessageText: View {
|
|||
let isCurrentUser: Bool
|
||||
let onReply: () -> Void
|
||||
// State for handling channel URL sheet
|
||||
@State private var saveChannels = false
|
||||
@State private var channelSettings: String?
|
||||
@State private var addChannels = false
|
||||
@State private var saveChannelLink: SaveChannelLinkData?
|
||||
@State private var isShowingDeleteConfirmation = false
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -97,7 +95,8 @@ struct MessageText: View {
|
|||
)
|
||||
}
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
channelSettings = nil
|
||||
saveChannelLink = nil
|
||||
var addChannels = false
|
||||
if url.absoluteString.lowercased().contains("meshtastic.org/v/#") {
|
||||
// Handle contact URL
|
||||
ContactURLHandler.handleContactUrl(url: url, accessoryManager: AccessoryManager.shared)
|
||||
|
|
@ -109,35 +108,25 @@ struct MessageText: View {
|
|||
Logger.services.error("No valid components found in channel URL: \(url.absoluteString, privacy: .public)")
|
||||
return .discarded
|
||||
}
|
||||
self.addChannels = Bool(url.query?.contains("add=true") ?? false)
|
||||
addChannels = Bool(url.query?.contains("add=true") ?? false)
|
||||
guard let lastComponent = components.last else {
|
||||
Logger.services.error("Channel URL missing fragment component: \(url.absoluteString, privacy: .public)")
|
||||
self.channelSettings = nil
|
||||
self.saveChannelLink = nil
|
||||
return .discarded
|
||||
}
|
||||
self.channelSettings = lastComponent.components(separatedBy: "?").first ?? ""
|
||||
Logger.services.debug("Add Channel: \(self.addChannels, privacy: .public)")
|
||||
self.saveChannels = true
|
||||
let cs = lastComponent.components(separatedBy: "?").first ?? ""
|
||||
self.saveChannelLink = SaveChannelLinkData(data: cs, add: addChannels)
|
||||
Logger.services.debug("Add Channel: \(addChannels, privacy: .public)")
|
||||
Logger.mesh.debug("Opening Channel Settings URL: \(url.absoluteString, privacy: .public)")
|
||||
return .handled // Prevent default browser opening
|
||||
}
|
||||
return .systemAction // Open other URLs in browser
|
||||
})
|
||||
// Display sheet for channel settings
|
||||
.sheet(isPresented: Binding(
|
||||
get: {
|
||||
saveChannels && !(channelSettings == nil)
|
||||
},
|
||||
set: { newValue in
|
||||
saveChannels = newValue
|
||||
if !newValue {
|
||||
channelSettings = nil
|
||||
}
|
||||
}
|
||||
)) {
|
||||
.sheet(item: $saveChannelLink) { link in
|
||||
SaveChannelQRCode(
|
||||
channelSetLink: channelSettings ?? "Empty Channel URL",
|
||||
addChannels: addChannels,
|
||||
channelSetLink: link.data,
|
||||
addChannels: link.add,
|
||||
accessoryManager: accessoryManager
|
||||
)
|
||||
.presentationDetents([.large])
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ import CoreData
|
|||
import OSLog
|
||||
import MeshtasticProtobufs
|
||||
|
||||
struct SaveChannelLinkData: Identifiable {
|
||||
let id = UUID()
|
||||
let data: String
|
||||
let add: Bool
|
||||
}
|
||||
|
||||
struct SaveChannelQRCode: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.managedObjectContext) var context
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue