diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 76cc973d..9ad98c46 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -2052,7 +2052,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.7.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -2086,7 +2086,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.7.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -2117,7 +2117,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.7.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2149,7 +2149,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.7.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Meshtastic/Helpers/LocationsHandler.swift b/Meshtastic/Helpers/LocationsHandler.swift index 35e16fc6..0946c0cb 100644 --- a/Meshtastic/Helpers/LocationsHandler.swift +++ b/Meshtastic/Helpers/LocationsHandler.swift @@ -262,7 +262,7 @@ import OSLog return CLLocationCoordinate2D(latitude: lat, longitude: lon) } // Fallback 2: Default location if no other location is available. - Logger.services.warning("📍 [App] No Location and no last known location, something is really wrong. Teleporting user to Apple Park") + Logger.services.warning("📍 [App] No Location and no last known location, check your location settings. Falling back to default location.") return DefaultLocation } } diff --git a/Meshtastic/Views/Connect/Connect.swift b/Meshtastic/Views/Connect/Connect.swift index 65880035..cd5f27fd 100644 --- a/Meshtastic/Views/Connect/Connect.swift +++ b/Meshtastic/Views/Connect/Connect.swift @@ -20,6 +20,7 @@ struct Connect: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var accessoryManager: AccessoryManager + @Environment(\.colorScheme) private var colorScheme @State var router: Router @State var node: NodeInfoEntity? @State var isUnsetRegion = false @@ -37,6 +38,8 @@ struct Connect: View { accessoryManager.isConnected || accessoryManager.isConnecting { TipView(ConnectionTip(), arrowEdge: .bottom) .tipViewStyle(PersistentTip()) + .tipBackground(colorScheme == .dark ? Color(.systemBackground) : Color(.secondarySystemBackground)) + .listRowSeparator(.hidden) VStack(alignment: .leading) { HStack { VStack(alignment: .center) { diff --git a/Meshtastic/Views/Helpers/MeshtasticLogo.swift b/Meshtastic/Views/Helpers/MeshtasticLogo.swift index 800793c8..6c717140 100644 --- a/Meshtastic/Views/Helpers/MeshtasticLogo.swift +++ b/Meshtastic/Views/Helpers/MeshtasticLogo.swift @@ -13,33 +13,38 @@ struct MeshtasticLogo: View { var body: some View { #if targetEnvironment(macCatalyst) VStack { - if #available(iOS 26.0, macOS 26.0, *) { - Image(colorScheme == .dark ? "logo-white" : "logo-black") - .resizable() - .foregroundColor(.accentColor) - .scaledToFit() - } else { - Image("logo-white") - .resizable() - .foregroundColor(.accentColor) - .scaledToFit() + Link(destination: URL(string: "meshtastic:///settings/about")!) { + if #available(iOS 26.0, macOS 26.0, *) { + Image(colorScheme == .dark ? "logo-white" : "logo-black") + .resizable() + .foregroundColor(.accentColor) + .scaledToFit() + } else { + Image("logo-white") + .resizable() + .foregroundColor(.accentColor) + .scaledToFit() + } } - } .padding(.bottom, 5) .padding(.top, 5) #else if #available(iOS 26.0, macOS 26.0, *) { VStack { - Image(colorScheme == .dark ? "logo-white" : "logo-black") - .resizable() - .scaledToFit() + Link(destination: URL(string: "meshtastic:///settings/about")!) { + Image(colorScheme == .dark ? "logo-white" : "logo-black") + .resizable() + .scaledToFit() + } } } else { VStack { - Image(colorScheme == .dark ? "logo-white" : "logo-black") - .resizable() - .scaledToFit() + Link(destination: URL(string: "meshtastic:///settings/about")!) { + Image(colorScheme == .dark ? "logo-white" : "logo-black") + .resizable() + .scaledToFit() + } } .padding(.bottom, 5) } diff --git a/Meshtastic/Views/Messages/Messages.swift b/Meshtastic/Views/Messages/Messages.swift index 0fd4e0bf..6f6c5dca 100644 --- a/Meshtastic/Views/Messages/Messages.swift +++ b/Meshtastic/Views/Messages/Messages.swift @@ -13,16 +13,10 @@ import TipKit struct Messages: View { @Environment(\.managedObjectContext) var context - - @ObservedObject - var router: Router - - @Binding - var unreadChannelMessages: Int - - @Binding - var unreadDirectMessages: Int - + @Environment(\.colorScheme) private var colorScheme + @ObservedObject var router: Router + @Binding var unreadChannelMessages: Int + @Binding var unreadDirectMessages: Int @State var node: NodeInfoEntity? @State private var userSelection: UserEntity? // Nothing selected by default. @State private var channelSelection: ChannelEntity? // Nothing selected by default. @@ -63,6 +57,8 @@ struct Messages: View { TipView(MessagesTip(), arrowEdge: .top) .tipViewStyle(PersistentTip()) + .tipBackground(colorScheme == .dark ? Color(.systemBackground) : Color(.secondarySystemBackground)) + .listRowSeparator(.hidden) } .navigationTitle("Messages") .navigationBarTitleDisplayMode(.large) diff --git a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift index 67bd7618..52067991 100644 --- a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift +++ b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift @@ -54,6 +54,7 @@ struct TextMessageField: View { .focused($isFocused) .multilineTextAlignment(.leading) .onSubmit { + #if targetEnvironment(macCatalyst) sendMessage() #endif @@ -69,18 +70,35 @@ struct TextMessageField: View { } .padding(15) if isFocused { - Divider() - HStack { + if #available(iOS 26.0, macOS 26.0, *) { + HStack { + Spacer() + AlertButton { typingMessage += "🔔 Alert Bell Character! \u{7}" } + Spacer() + RequestPositionButton(action: requestPosition) + Spacer() + TextMessageSize(maxbytes: Self.maxbytes, totalBytes: totalBytes) + } + .padding(.vertical, 8) + .padding(.horizontal) + .background(.ultraThinMaterial, in: Capsule()) Spacer() - AlertButton { typingMessage += "🔔 Alert Bell Character! \u{7}" } - Spacer() - RequestPositionButton(action: requestPosition) - Spacer() - TextMessageSize(maxbytes: Self.maxbytes, totalBytes: totalBytes) + .frame(height: 10) + + } else { + Divider() + HStack { + Spacer() + AlertButton { typingMessage += "🔔 Alert Bell Character! \u{7}" } + Spacer() + RequestPositionButton(action: requestPosition) + Spacer() + TextMessageSize(maxbytes: Self.maxbytes, totalBytes: totalBytes) + } + .padding(.horizontal, 15) + .padding(.vertical, 10) + .background(.bar) } - .padding(.horizontal, 15) - .padding(.vertical, 10) - .background(.bar) } } } diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 5d15b4fb..6eff0e17 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -227,7 +227,6 @@ struct NodeList: View { ) .edgesIgnoringSafeArea([.leading, .trailing]) .navigationBarItems( - leading: MeshtasticLogo(), trailing: ZStack { ConnectedDevice( deviceConnected: accessoryManager.isConnected, @@ -236,7 +235,7 @@ struct NodeList: View { ) } // Make sure the ZStack passes through accessibility to the ConnectedDevice component - .accessibilityElement(children: .contain) + .accessibilityElement(children: .contain) ) } } else { diff --git a/Meshtastic/Views/Settings/Channels.swift b/Meshtastic/Views/Settings/Channels.swift index c9a4e705..29f76966 100644 --- a/Meshtastic/Views/Settings/Channels.swift +++ b/Meshtastic/Views/Settings/Channels.swift @@ -26,6 +26,7 @@ struct Channels: View { @EnvironmentObject var accessoryManager: AccessoryManager @Environment(\.dismiss) private var goBack @Environment(\.sizeCategory) var sizeCategory + @Environment(\.colorScheme) private var colorScheme var node: NodeInfoEntity? @@ -62,6 +63,8 @@ struct Channels: View { VStack { List { TipView(CreateChannelsTip(), arrowEdge: .bottom) + .tipBackground(colorScheme == .dark ? Color(.systemBackground) : Color(.secondarySystemBackground)) + .listRowSeparator(.hidden) if node != nil && node?.myInfo != nil { ForEach(node?.myInfo?.channels?.array as? [ChannelEntity] ?? [], id: \.self) { (channel: ChannelEntity) in Button(action: { diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index 9ccfbb9c..3b15fa77 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -157,7 +157,6 @@ struct MQTTConfig: View { .foregroundColor(.gray) } .keyboardType(.asciiCapable) - .scrollDismissesKeyboard(.interactively) .disableAutocorrection(true) .listRowSeparator(.hidden) Text("The root topic to use for MQTT.") @@ -216,7 +215,6 @@ struct MQTTConfig: View { .foregroundColor(.gray) } .keyboardType(.default) - .scrollDismissesKeyboard(.interactively) HStack { Label("Password", systemImage: "wallet.pass") TextField("Password", text: $password) @@ -235,10 +233,9 @@ struct MQTTConfig: View { .foregroundColor(.gray) } .keyboardType(.default) - .scrollDismissesKeyboard(.interactively) .listRowSeparator(/*@START_MENU_TOKEN@*/.visible/*@END_MENU_TOKEN@*/) } - if address != "mqtt.meshtastic.org" && !proxyToClientEnabled { + if !address.contains("mqtt.meshtastic.org") && !proxyToClientEnabled { Toggle(isOn: $tlsEnabled) { Label("TLS Enabled", systemImage: "checkmark.shield.fill") Text("Your MQTT Server must support TLS.") @@ -249,7 +246,7 @@ struct MQTTConfig: View { Text("For all Mqtt functionality other than the map report you must also set uplink and downlink for each channel you want to bridge over Mqtt.") .font(.callout) } - .scrollDismissesKeyboard(.interactively) + .scrollDismissesKeyboard(.immediately) .disabled(!accessoryManager.isConnected || node?.mqttConfig == nil) SaveConfigButton(node: node, hasChanges: $hasChanges) { diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index c8ce9148..2c714b45 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -12,6 +12,7 @@ import MeshtasticProtobufs struct Settings: View { @Environment(\.managedObjectContext) var context + @Environment(\.colorScheme) private var colorScheme @EnvironmentObject var accessoryManager: AccessoryManager @FetchRequest( sortDescriptors: [ @@ -445,6 +446,8 @@ struct Settings: View { } TipView(AdminChannelTip(), arrowEdge: .top) .tipViewStyle(PersistentTip()) + .tipBackground(colorScheme == .dark ? Color(.systemBackground) : Color(.secondarySystemBackground)) + .listRowSeparator(.hidden) } else { if accessoryManager.isConnected { Text("Connected Node \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") diff --git a/Meshtastic/Views/Settings/ShareChannels.swift b/Meshtastic/Views/Settings/ShareChannels.swift index 1d065abc..281a90fd 100644 --- a/Meshtastic/Views/Settings/ShareChannels.swift +++ b/Meshtastic/Views/Settings/ShareChannels.swift @@ -55,7 +55,10 @@ struct ShareChannels: View { VStack { TipView(ShareChannelsTip(), arrowEdge: .bottom) + .tipBackground(Color(.secondarySystemBackground)) + .listRowSeparator(.hidden) } + .padding(.horizontal) GeometryReader { bounds in let smallest = min(bounds.size.width, bounds.size.height) ScrollView {