mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
V 1.25.9 Add Settings and move nav around. Configure project for MacOS TestFlight
This commit is contained in:
parent
c2cb860ab2
commit
49e19a4a76
7 changed files with 125 additions and 31 deletions
|
|
@ -202,6 +202,7 @@
|
|||
DD8EDE9226F97A2B00A5A10B /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
usesTabs = 1;
|
||||
};
|
||||
DDC2E15526CE248E0042C5E4 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
|
|
@ -659,11 +660,11 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.25.7;
|
||||
MARKETING_VERSION = 1.25.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
|
|
@ -686,11 +687,11 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.25.7;
|
||||
MARKETING_VERSION = 1.25.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,6 +29,15 @@ class MeshData: ObservableObject {
|
|||
return
|
||||
}
|
||||
guard let nodeList = try? JSONDecoder().decode([NodeInfoModel].self, from: data) else {
|
||||
do {
|
||||
// If the file is borked delete it so we stop crashing
|
||||
try FileManager.default.removeItem(at: Self.fileURL)
|
||||
}
|
||||
catch {
|
||||
|
||||
fatalError("Can't delete saved node data.")
|
||||
}
|
||||
|
||||
fatalError("Can't decode saved node data.")
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
|
|
|
|||
|
|
@ -21,33 +21,38 @@ struct ContentView: View {
|
|||
Channels()
|
||||
.tabItem {
|
||||
Label("Messages", systemImage: "text.bubble")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.symbolVariant(.none)
|
||||
}
|
||||
.tag(Tab.messages)
|
||||
Connect()
|
||||
.tabItem {
|
||||
Label("Bluetooth", systemImage: "dot.radiowaves.left.and.right")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.symbolVariant(.none)
|
||||
}
|
||||
.tag(Tab.ble)
|
||||
NodeList()
|
||||
.tabItem {
|
||||
Label("Nodes", systemImage: "flipphone")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.symbolVariant(.none)
|
||||
}
|
||||
.tag(Tab.nodes)
|
||||
NodeMap()
|
||||
.tabItem {
|
||||
Label("Mesh Map", systemImage: "map")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.symbolVariant(.none)
|
||||
}
|
||||
.tag(Tab.map)
|
||||
Connect()
|
||||
AppSettings()
|
||||
.tabItem {
|
||||
Label("Bluetooth", systemImage: "dot.radiowaves.left.and.right")
|
||||
.symbolVariant(.none)
|
||||
Label("Settings", systemImage: "gear")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.symbolVariant(.none)
|
||||
}
|
||||
.tag(Tab.ble)
|
||||
//AppSettings()
|
||||
// .tabItem {
|
||||
// Label("Settings", systemImage: "gear")
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// }
|
||||
// .tag(Tab.settings)
|
||||
.tag(Tab.settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import SwiftUI
|
|||
import CoreBluetooth
|
||||
|
||||
struct Channels: View {
|
||||
|
||||
// Message Data and Bluetooth
|
||||
@EnvironmentObject var messageData: MessageData
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
|
@ -33,11 +34,12 @@ struct Channels: View {
|
|||
}
|
||||
.navigationTitle("Channels")
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
.navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||
}
|
||||
}
|
||||
|
||||
struct MessageList_Previews: PreviewProvider {
|
||||
|
||||
static let meshData = MeshData()
|
||||
|
||||
static var previews: some View {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import SwiftUI
|
||||
import MapKit
|
||||
import Foundation
|
||||
import CoreLocation
|
||||
|
||||
struct Messages: View {
|
||||
|
|
@ -8,8 +9,11 @@ struct Messages: View {
|
|||
case messageText
|
||||
}
|
||||
|
||||
@ObservedObject var userSettings = UserSettings()
|
||||
|
||||
|
||||
// Keyboard State
|
||||
@State var typingMessage: String = ""
|
||||
@State var typingMessage: String = ""
|
||||
@State private var totalBytes = 0
|
||||
@State private var lastTypingMessage = ""
|
||||
@FocusState private var focusedField: Field?
|
||||
|
|
@ -43,7 +47,6 @@ struct Messages: View {
|
|||
MessageBubble(contentMessage: message.messagePayload, isCurrentUser: currentUser, time: Int32(message.messageTimestamp), shortName: message.fromUserShortName)
|
||||
}
|
||||
.onAppear(perform: { scrollView.scrollTo(bottomId) } )
|
||||
|
||||
Text("Hidden Bottom Anchor").hidden().frame(height: 0).id(bottomId)
|
||||
}
|
||||
.onReceive(timer) { input in
|
||||
|
|
@ -59,8 +62,9 @@ struct Messages: View {
|
|||
HStack (alignment: .top) {
|
||||
|
||||
ZStack {
|
||||
|
||||
TextEditor(text: $typingMessage)
|
||||
//let kbType = Enum.Parse(typeof(KeyboardType), userSettings.keyboardType, true);
|
||||
let kbType = UIKeyboardType(rawValue: userSettings.keyboardType)
|
||||
TextEditor(text: $typingMessage)
|
||||
.onChange(of: typingMessage, perform: { value in
|
||||
|
||||
let size = value.utf8.count
|
||||
|
|
@ -74,7 +78,7 @@ struct Messages: View {
|
|||
self.typingMessage = lastTypingMessage
|
||||
}
|
||||
})
|
||||
.keyboardType(.default)
|
||||
.keyboardType(kbType!)
|
||||
.toolbar
|
||||
{
|
||||
ToolbarItemGroup(placement: .keyboard) {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ struct NodeList: View {
|
|||
.navigationTitle("All Nodes")
|
||||
}
|
||||
.ignoresSafeArea(.all, edges: [.leading, .trailing])
|
||||
.navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||
.onAppear{
|
||||
meshData.load()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,95 @@
|
|||
import Foundation
|
||||
import Combine
|
||||
import SwiftUI
|
||||
import SwiftProtobuf
|
||||
|
||||
enum KeyboardType: Int, CaseIterable, Identifiable {
|
||||
|
||||
case defaultKeyboard = 0
|
||||
case asciiCapable = 1
|
||||
case twitter = 9
|
||||
case emailAddress = 7
|
||||
case numbersAndPunctuation = 2
|
||||
|
||||
var id: Int { self.rawValue }
|
||||
var description: String {
|
||||
get {
|
||||
switch self {
|
||||
case .defaultKeyboard:
|
||||
return "Default"
|
||||
case .asciiCapable:
|
||||
return "ascii Capable"
|
||||
case .twitter:
|
||||
return "Twitter"
|
||||
case .emailAddress:
|
||||
return "Email Address"
|
||||
case .numbersAndPunctuation:
|
||||
return "Numbers and Punctuation"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UserSettings: ObservableObject {
|
||||
@Published var username: String {
|
||||
didSet {
|
||||
UserDefaults.standard.set(username, forKey: "username")
|
||||
}
|
||||
}
|
||||
@Published var provideLocation: Bool {
|
||||
didSet {
|
||||
UserDefaults.standard.set(provideLocation, forKey: "provideLocation")
|
||||
}
|
||||
}
|
||||
@Published var keyboardType: Int {
|
||||
didSet {
|
||||
UserDefaults.standard.set(keyboardType, forKey: "keyboardType")
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
self.username = UserDefaults.standard.object(forKey: "username") as? String ?? ""
|
||||
self.provideLocation = UserDefaults.standard.object(forKey: "provideLocation") as? Bool ?? false
|
||||
self.keyboardType = UserDefaults.standard.object(forKey: "keyboardType") as? Int ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
struct AppSettings: View {
|
||||
|
||||
|
||||
@ObservedObject var userSettings = UserSettings()
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
|
||||
GeometryReader { bounds in
|
||||
|
||||
NavigationLink(destination: Messages()) {
|
||||
|
||||
List{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Form {
|
||||
Section(header: Text("USER DETAILS")) {
|
||||
HStack{
|
||||
|
||||
Text("User Name")
|
||||
TextField("Username", text: $userSettings.username)
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
Toggle(isOn: $userSettings.provideLocation) {
|
||||
|
||||
Text("Provide location to mesh")
|
||||
}
|
||||
}
|
||||
Section(header: Text("MESSAGING OPTIONS")) {
|
||||
|
||||
Picker("Keyboard Type", selection: $userSettings.keyboardType) {
|
||||
ForEach(KeyboardType.allCases) { kb in
|
||||
Text(kb.description)
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("App Settings")
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle()) }
|
||||
}
|
||||
|
||||
struct AppSettings_Previews: PreviewProvider {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue