diff --git a/Meshtastic/Helpers/Extensions.swift b/Meshtastic/Helpers/Extensions.swift index 8f6abe9e..1640950f 100644 --- a/Meshtastic/Helpers/Extensions.swift +++ b/Meshtastic/Helpers/Extensions.swift @@ -57,6 +57,24 @@ extension String { return data } + func base64urlToBase64() -> String { + var base64 = self + .replacingOccurrences(of: "-", with: "+") + .replacingOccurrences(of: "_", with: "/") + if base64.count % 4 != 0 { + base64.append(String(repeating: "=", count: 4 - base64.count % 4)) + } + return base64 + } + + func base64ToBase64url() -> String { + let base64url = self + .replacingOccurrences(of: "+", with: "-") + .replacingOccurrences(of: "/", with: "_") + .replacingOccurrences(of: "=", with: "") + return base64url + } + func image(fontSize:CGFloat = 40, bgColor:UIColor = UIColor.clear, imageSize:CGSize? = nil) -> UIImage? { let font = UIFont.systemFont(ofSize: fontSize) diff --git a/Meshtastic/Views/Settings/SaveChannelQRCode.swift b/Meshtastic/Views/Settings/SaveChannelQRCode.swift index b9f1020d..5ff03068 100644 --- a/Meshtastic/Views/Settings/SaveChannelQRCode.swift +++ b/Meshtastic/Views/Settings/SaveChannelQRCode.swift @@ -37,10 +37,7 @@ struct SaveChannelQRCode: View { } .onChange(of: channelHash) { newSettings in - var decodedString = newSettings - if !decodedString.hasSuffix("==") { - decodedString = decodedString + "==" - } + var decodedString = newSettings.base64urlToBase64() if let decodedData = Data(base64Encoded: decodedString) { decodedString = String(data: decodedData, encoding: .utf8)! diff --git a/Meshtastic/Views/Settings/ShareChannels.swift b/Meshtastic/Views/Settings/ShareChannels.swift index 48000f25..6d93b643 100644 --- a/Meshtastic/Views/Settings/ShareChannels.swift +++ b/Meshtastic/Views/Settings/ShareChannels.swift @@ -97,50 +97,50 @@ struct ShareChannels: View { .toggleStyle(.switch) .labelsHidden() .disabled(channel.role == 1) - Text((channel.name!.isEmpty ? "Primary" : channel.name) ?? "Primary") + Text((channel.name!.isEmpty ? "primary" : channel.name) ?? "primary") } else if channel.index == 1 { Toggle("Channel 1 Included", isOn: $includeChannel1) .toggleStyle(.switch) .labelsHidden() .disabled(channel.role == 0) - Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") + Text((channel.name!.isEmpty ? "channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") } else if channel.index == 2 { Toggle("Channel 2 Included", isOn: $includeChannel2) .toggleStyle(.switch) .labelsHidden() .disabled(channel.role == 0) - Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") + Text((channel.name!.isEmpty ? "channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") } else if channel.index == 3 { Toggle("Channel 3 Included", isOn: $includeChannel3) .toggleStyle(.switch) .labelsHidden() .disabled(channel.role == 0) - Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") + Text((channel.name!.isEmpty ? "channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") } else if channel.index == 4 { Toggle("Channel 4 Included", isOn: $includeChannel4) .toggleStyle(.switch) .labelsHidden() .disabled(channel.role == 0) - Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") + Text((channel.name!.isEmpty ? "channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") } else if channel.index == 5 { Toggle("Channel 5 Included", isOn: $includeChannel5) .toggleStyle(.switch) .labelsHidden() .disabled(channel.role == 0) - Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") + Text((channel.name!.isEmpty ? "channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") } else if channel.index == 6 { Toggle("Channel 6 Included", isOn: $includeChannel6) .toggleStyle(.switch) .labelsHidden() .disabled(channel.role == 0) - Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") + Text((channel.name!.isEmpty ? "channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") } else if channel.index == 7 { Toggle("Channel 7 Included", isOn: $includeChannel7) .toggleStyle(.switch) .labelsHidden() .disabled(channel.role == 0) - Text((channel.name!.isEmpty ? "Admin" : channel.name) ?? "Admin") + Text((channel.name!.isEmpty ? "channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)") } if channel.role > 0 { Image(systemName: "lock.fill") @@ -206,7 +206,7 @@ struct ShareChannels: View { .font(.callout) .padding([.leading,.trailing,.bottom]) Text("Admin Channel").font(.title2) - Text("The last channel is the Admin channel and can be used to remotely administer nodes on your mesh, text messages can not be sent over the admin channel.") + Text("A channel with the name 'admin' is the Admin channel and can be used to remotely administer nodes on your mesh, text messages can not be sent over the admin channel.") .font(.callout) .padding([.leading,.trailing,.bottom]) Text("Private Channels").font(.title2) @@ -301,6 +301,6 @@ struct ShareChannels: View { } let settingsString = try! channelSet.serializedData().base64EncodedString() - channelsUrl = ("https://www.meshtastic.org/e/#" + settingsString.dropLast(2)) + channelsUrl = ("https://www.meshtastic.org/e/#" + settingsString.base64ToBase64url()) } }