mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Messages bug fix
This commit is contained in:
parent
4022c99874
commit
bed7c5ce5c
9 changed files with 429 additions and 409 deletions
|
|
@ -719,7 +719,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.37;
|
||||
MARKETING_VERSION = 1.38;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -746,7 +746,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.37;
|
||||
MARKETING_VERSION = 1.38;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
var timeoutTimerCount = 0
|
||||
|
||||
let broadcastNodeNum: UInt32 = 4294967295
|
||||
var nextSentMessageId: Int64 = 1
|
||||
|
||||
/* Meshtastic Service Details */
|
||||
var TORADIO_characteristic: CBCharacteristic!
|
||||
|
|
@ -632,7 +631,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
// Save the broadcast user if it does not exist
|
||||
let bcu: UserEntity = UserEntity(context: context!)
|
||||
bcu.shortName = "ALL"
|
||||
bcu.longName = "ALL - Broadcast"
|
||||
bcu.longName = "All - Broadcast"
|
||||
bcu.hwModel = "UNSET"
|
||||
bcu.num = Int64(broadcastNodeNum)
|
||||
bcu.userId = "BROADCASTNODE"
|
||||
|
|
@ -862,7 +861,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
} else if fetchedUsers.count >= 1 {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64.random(in: Int64.min..<Int64.max)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32.min..<UInt32.max))
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "IN"
|
||||
|
|
@ -871,7 +870,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
let bcu: UserEntity = UserEntity(context: context!)
|
||||
bcu.shortName = "ALL"
|
||||
bcu.longName = "ALL - Broadcast"
|
||||
bcu.longName = "All - Broadcast"
|
||||
bcu.hwModel = "UNSET"
|
||||
bcu.num = Int64(broadcastNodeNum)
|
||||
bcu.userId = "BROADCASTNODE"
|
||||
|
|
@ -910,7 +909,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
print("💾 Saved a new sent message to \(toUserNum)")
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new sent message from \(connectedPeripheral.num) to \(toUserNum)") }
|
||||
success = true
|
||||
nextSentMessageId+=1
|
||||
|
||||
} catch {
|
||||
|
||||
|
|
@ -929,7 +927,3 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
return success
|
||||
}
|
||||
}
|
||||
|
||||
func bytes2String(_ array: [UInt8]) -> String {
|
||||
return String(data: Data(bytes: array, count: array.count), encoding: .utf8) ?? ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ extension Data {
|
|||
var hexDescription: String {
|
||||
return reduce("") {$0 + String(format: "%02x", $1)}
|
||||
}
|
||||
var macAddressString: String {
|
||||
let mac: String = reduce("") {$0 + String(format: "%02x:", $1)}
|
||||
return String(mac.dropLast())
|
||||
}
|
||||
}
|
||||
|
||||
extension Date {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ class PersistenceController {
|
|||
container.loadPersistentStores(completionHandler: { (_, error) in
|
||||
// Merge policy that favors in memory data over data in the db
|
||||
self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
|
||||
|
||||
|
||||
|
||||
if let error = error as NSError? {
|
||||
// Replace this implementation with code to handle the error appropriately.
|
||||
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||||
|
|
@ -52,7 +53,20 @@ class PersistenceController {
|
|||
* The store could not be migrated to the current model version.
|
||||
Check the error message to determine what the actual problem was.
|
||||
*/
|
||||
fatalError("Unresolved error \(error), \(error.userInfo)")
|
||||
|
||||
let firstStoreURL = self.container.persistentStoreCoordinator.persistentStores.first?.url
|
||||
|
||||
do {
|
||||
|
||||
try self.container.persistentStoreCoordinator.destroyPersistentStore(at: firstStoreURL!, type: .sqlite, options: nil)
|
||||
|
||||
print("💥 Something went terribly wrong, CoreData database truncated. All app data is lost.")
|
||||
|
||||
} catch {
|
||||
print("💣 Failed to destroy broken CoreData database, delete the app.")
|
||||
}
|
||||
|
||||
print("💣💥 Unresolved error \(error), \(error.userInfo)")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,21 +19,21 @@ struct ContentView: View {
|
|||
var body: some View {
|
||||
|
||||
TabView(selection: $selection) {
|
||||
Contacts()
|
||||
.tabItem {
|
||||
Label("Messages", systemImage: "text.bubble")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.symbolVariant(.none)
|
||||
|
||||
}
|
||||
.tag(Tab.contacts)
|
||||
// Channels()
|
||||
// .tabItem {
|
||||
// Label("Messages", systemImage: "text.bubble")
|
||||
// Contacts()
|
||||
// .tabItem {
|
||||
// Label("Messages", systemImage: "text.bubble")
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// .symbolVariant(.none)
|
||||
// }
|
||||
// .tag(Tab.messages)
|
||||
// .symbolVariant(.none)
|
||||
//
|
||||
// }
|
||||
// .tag(Tab.contacts)
|
||||
Channels()
|
||||
.tabItem {
|
||||
Label("Messages", systemImage: "text.bubble")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.symbolVariant(.none)
|
||||
}
|
||||
.tag(Tab.messages)
|
||||
Connect()
|
||||
.tabItem {
|
||||
Label("Bluetooth", systemImage: "dot.radiowaves.left.and.right")
|
||||
|
|
|
|||
|
|
@ -1,44 +1,44 @@
|
|||
//import Foundation
|
||||
//import SwiftUI
|
||||
//import CoreBluetooth
|
||||
//
|
||||
//struct Channels: View {
|
||||
//
|
||||
// @State private var isShowingDetailView = true
|
||||
//
|
||||
// var body: some View {
|
||||
//
|
||||
// NavigationView {
|
||||
//
|
||||
// NavigationLink(destination: Messages(), isActive: $isShowingDetailView) {
|
||||
//
|
||||
// List {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// Image(systemName: "dial.max.fill")
|
||||
// .font(.system(size: 62))
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// .padding(.trailing)
|
||||
// .foregroundColor(.accentColor)
|
||||
//
|
||||
// Text("Primary")
|
||||
// .font(.largeTitle)
|
||||
//
|
||||
// }.padding()
|
||||
// }
|
||||
// }
|
||||
// .navigationTitle("Channels")
|
||||
// }
|
||||
// .navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//struct MessageList_Previews: PreviewProvider {
|
||||
//
|
||||
// static var previews: some View {
|
||||
// Group {
|
||||
// Channels()
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import CoreBluetooth
|
||||
|
||||
struct Channels: View {
|
||||
|
||||
@State private var isShowingDetailView = true
|
||||
|
||||
var body: some View {
|
||||
|
||||
NavigationView {
|
||||
|
||||
NavigationLink(destination: Messages(), isActive: $isShowingDetailView) {
|
||||
|
||||
List {
|
||||
|
||||
HStack {
|
||||
|
||||
Image(systemName: "dial.max.fill")
|
||||
.font(.system(size: 62))
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.padding(.trailing)
|
||||
.foregroundColor(.accentColor)
|
||||
|
||||
Text("All - Broadcast")
|
||||
.font(.largeTitle)
|
||||
|
||||
}.padding()
|
||||
}
|
||||
}
|
||||
.navigationTitle("Contacts")
|
||||
}
|
||||
.navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||
}
|
||||
}
|
||||
|
||||
struct MessageList_Previews: PreviewProvider {
|
||||
|
||||
static var previews: some View {
|
||||
Group {
|
||||
Channels()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,141 +1,141 @@
|
|||
////
|
||||
//// Contacts.swift
|
||||
//// MeshtasticClient
|
||||
////
|
||||
//// Created by Garth Vander Houwen on 12/21/21.
|
||||
////
|
||||
//
|
||||
// Contacts.swift
|
||||
// MeshtasticClient
|
||||
//import SwiftUI
|
||||
//
|
||||
// Created by Garth Vander Houwen on 12/21/21.
|
||||
//struct Contacts: View {
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct Contacts: View {
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
||||
@FetchRequest(
|
||||
sortDescriptors: [NSSortDescriptor(key: "longName", ascending: true)],
|
||||
animation: .default)
|
||||
|
||||
private var users: FetchedResults<UserEntity>
|
||||
|
||||
var body: some View {
|
||||
|
||||
NavigationView {
|
||||
|
||||
List(users) { (user: UserEntity) in
|
||||
|
||||
if user.receivedMessages?.count ?? 0 > 0 {
|
||||
|
||||
let currentUserNum = self.bleManager.connectedPeripheral != nil ? self.bleManager.connectedPeripheral.num : 0
|
||||
|
||||
let mostRecentBC = user.receivedMessages?.array.last as! MessageEntity
|
||||
|
||||
let mostRecentDM = user.receivedMessages?.array.last(where: {($0 as! MessageEntity).toUser!.num == currentUserNum }) as? MessageEntity
|
||||
|
||||
let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64(mostRecentDM?.messageTimestamp ?? mostRecentBC.messageTimestamp)))
|
||||
let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0
|
||||
let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0
|
||||
|
||||
if user.num != currentUserNum && (user.num == bleManager.broadcastNodeNum || mostRecentDM != nil) { //}|| user.num == mostRecent.toUser!.num {
|
||||
|
||||
NavigationLink(destination: UserMessageList(user: user)) {
|
||||
|
||||
HStack {
|
||||
|
||||
VStack {
|
||||
|
||||
CircleText(text: user.shortName ?? "???", color: Color.blue)
|
||||
}
|
||||
.padding([.leading, .trailing])
|
||||
|
||||
VStack {
|
||||
|
||||
HStack {
|
||||
|
||||
VStack {
|
||||
|
||||
Text(user.longName ?? "Unknown").font(.headline).fixedSize()
|
||||
}
|
||||
|
||||
VStack {
|
||||
|
||||
if lastMessageDay == currentDay {
|
||||
|
||||
Text(lastMessageTime, style: .time )
|
||||
.font(.caption)
|
||||
.foregroundColor(.gray)
|
||||
|
||||
} else if lastMessageDay == (currentDay - 1) {
|
||||
|
||||
Text("Yesterday")
|
||||
.font(.callout)
|
||||
.foregroundColor(.gray)
|
||||
|
||||
} else if lastMessageDay < (currentDay - 1) && lastMessageDay > (currentDay - 5) {
|
||||
|
||||
Text(lastMessageTime, style: .date)
|
||||
|
||||
} else {
|
||||
|
||||
Text(lastMessageTime, style: .date)
|
||||
}
|
||||
}.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
}
|
||||
.listRowSeparator(.hidden).frame(height: 5)
|
||||
|
||||
HStack(alignment: .top) {
|
||||
Text(mostRecentDM != nil ? mostRecentDM?.messagePayload as! String : (mostRecentBC.messagePayload ?? "Unknown" as! String))
|
||||
.frame(height: 60)
|
||||
.truncationMode(.tail)
|
||||
.foregroundColor(Color.gray)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
}.padding(.top, 15)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if self.bleManager.connectedPeripheral == nil || ((self.bleManager.connectedPeripheral != nil ? self.bleManager.connectedPeripheral.num : 0) != user.num) {
|
||||
|
||||
NavigationLink(destination: UserMessageList(user: user)) {
|
||||
|
||||
HStack {
|
||||
|
||||
VStack {
|
||||
|
||||
CircleText(text: user.shortName ?? "???", color: Color.blue)
|
||||
}
|
||||
.padding(.trailing)
|
||||
|
||||
VStack {
|
||||
|
||||
HStack {
|
||||
|
||||
VStack {
|
||||
|
||||
Text(user.longName ?? "Unknown").font(.headline).fixedSize()
|
||||
}
|
||||
|
||||
VStack {
|
||||
Text(" ")
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
}
|
||||
.listRowSeparator(.hidden).frame(height: 5)
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("Contacts")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
}
|
||||
}
|
||||
|
||||
struct Contacts_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Contacts()
|
||||
}
|
||||
}
|
||||
// @Environment(\.managedObjectContext) var context
|
||||
// @EnvironmentObject var bleManager: BLEManager
|
||||
//
|
||||
// @FetchRequest(
|
||||
// sortDescriptors: [NSSortDescriptor(key: "longName", ascending: true)],
|
||||
// animation: .default)
|
||||
//
|
||||
// private var users: FetchedResults<UserEntity>
|
||||
//
|
||||
// var body: some View {
|
||||
//
|
||||
// NavigationView {
|
||||
//
|
||||
// List(users) { (user: UserEntity) in
|
||||
//
|
||||
// if user.receivedMessages?.count ?? 0 > 0 {
|
||||
//
|
||||
// let currentUserNum = self.bleManager.connectedPeripheral != nil ? self.bleManager.connectedPeripheral.num : 0
|
||||
//
|
||||
// let mostRecentBC = user.receivedMessages?.array.last as! MessageEntity
|
||||
//
|
||||
// let mostRecentDM = user.receivedMessages?.array.last(where: {($0 as! MessageEntity).toUser!.num == currentUserNum }) as? MessageEntity
|
||||
//
|
||||
// let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64(mostRecentDM?.messageTimestamp ?? mostRecentBC.messageTimestamp)))
|
||||
// let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0
|
||||
// let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0
|
||||
//
|
||||
// if user.num == bleManager.broadcastNodeNum {//user.num != currentUserNum && (user.num == bleManager.broadcastNodeNum || mostRecentDM != nil) {
|
||||
//
|
||||
// NavigationLink(destination: UserMessageList(user: user)) {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// CircleText(text: user.shortName ?? "???", color: Color.blue)
|
||||
// }
|
||||
// .padding([.leading, .trailing])
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// Text(user.longName ?? "Unknown").font(.headline).fixedSize()
|
||||
// }
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// if lastMessageDay == currentDay {
|
||||
//
|
||||
// Text(lastMessageTime, style: .time )
|
||||
// .font(.caption)
|
||||
// .foregroundColor(.gray)
|
||||
//
|
||||
// } else if lastMessageDay == (currentDay - 1) {
|
||||
//
|
||||
// Text("Yesterday")
|
||||
// .font(.callout)
|
||||
// .foregroundColor(.gray)
|
||||
//
|
||||
// } else if lastMessageDay < (currentDay - 1) && lastMessageDay > (currentDay - 5) {
|
||||
//
|
||||
// Text(lastMessageTime, style: .date)
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// Text(lastMessageTime, style: .date)
|
||||
// }
|
||||
// }.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
// }
|
||||
// .listRowSeparator(.hidden).frame(height: 5)
|
||||
//
|
||||
// HStack(alignment: .top) {
|
||||
// Text(mostRecentDM != nil ? mostRecentDM?.messagePayload as! String : (mostRecentBC.messagePayload ?? "Unknown" ))
|
||||
// .frame(height: 60)
|
||||
// .truncationMode(.tail)
|
||||
// .foregroundColor(Color.gray)
|
||||
// .frame(maxWidth: .infinity, alignment: .leading)
|
||||
// }
|
||||
// }.padding(.top, 15)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } else if false {// self.bleManager.connectedPeripheral == nil || ((self.bleManager.connectedPeripheral != nil ? self.bleManager.connectedPeripheral.num : 0) != user.num) {
|
||||
//
|
||||
// NavigationLink(destination: UserMessageList(user: user)) {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// CircleText(text: user.shortName ?? "???", color: Color.blue)
|
||||
// }
|
||||
// .padding(.trailing)
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// Text(user.longName ?? "Unknown").font(.headline).fixedSize()
|
||||
// }
|
||||
//
|
||||
// VStack {
|
||||
// Text(" ")
|
||||
// }
|
||||
// .frame(maxWidth: .infinity, alignment: .trailing)
|
||||
// }
|
||||
// .listRowSeparator(.hidden).frame(height: 5)
|
||||
// }
|
||||
// }.padding()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .navigationTitle("Contacts")
|
||||
// .navigationBarTitleDisplayMode(.inline)
|
||||
// }
|
||||
// .listStyle(PlainListStyle())
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//struct Contacts_Previews: PreviewProvider {
|
||||
// static var previews: some View {
|
||||
// Contacts()
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,202 +1,206 @@
|
|||
////
|
||||
//// UserMessageList.swift
|
||||
//// MeshtasticClient
|
||||
////
|
||||
//// Created by Garth Vander Houwen on 12/24/21.
|
||||
////
|
||||
//
|
||||
// UserMessageList.swift
|
||||
// MeshtasticClient
|
||||
//import SwiftUI
|
||||
//import CoreData
|
||||
//
|
||||
// Created by Garth Vander Houwen on 12/24/21.
|
||||
//struct UserMessageList: View {
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
|
||||
struct UserMessageList: View {
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
||||
enum Field: Hashable {
|
||||
case messageText
|
||||
}
|
||||
// Keyboard State
|
||||
@State var typingMessage: String = ""
|
||||
@State private var totalBytes = 0
|
||||
var maxbytes = 228
|
||||
@State var lastTypingMessage = ""
|
||||
@FocusState var focusedField: Field?
|
||||
|
||||
var user: UserEntity
|
||||
|
||||
@State var showDeleteMessageAlert = false
|
||||
@State private var deleteMessageId: Int64 = 0
|
||||
|
||||
var body: some View {
|
||||
|
||||
HStack {
|
||||
|
||||
VStack {
|
||||
|
||||
List {
|
||||
|
||||
ScrollViewReader { _ in
|
||||
|
||||
ScrollView {
|
||||
|
||||
if user.receivedMessages?.count ?? 0 > 0 {
|
||||
|
||||
ForEach( user.receivedMessages?.array as! [MessageEntity], id: \.self) { (message: MessageEntity) in
|
||||
|
||||
HStack {
|
||||
let currentUser: Bool = (bleManager.connectedPeripheral == nil) ? false : ((bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.num == message.fromUser?.num) ? true : false )
|
||||
|
||||
|
||||
if message.toUser!.num == Int64(bleManager.broadcastNodeNum) || ((bleManager.connectedPeripheral) != nil && bleManager.connectedPeripheral.num == message.fromUser?.num) ? true : true {
|
||||
|
||||
|
||||
|
||||
VStack {
|
||||
|
||||
HStack (alignment: .top) {
|
||||
|
||||
CircleText(text: (message.fromUser?.shortName ?? "???"), color: currentUser ? .accentColor : Color(.darkGray)).padding(.all, 5)
|
||||
.gesture(LongPressGesture(minimumDuration: 2)
|
||||
.onEnded {_ in
|
||||
|
||||
print("I want to delete message: \(message.messageId)")
|
||||
self.showDeleteMessageAlert = true
|
||||
self.deleteMessageId = message.messageId
|
||||
|
||||
print(deleteMessageId)
|
||||
})
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
|
||||
Text(message.messagePayload ?? "EMPTY MESSAGE")
|
||||
.textSelection(.enabled)
|
||||
.padding(10)
|
||||
.foregroundColor(.white)
|
||||
.background(currentUser ? Color.blue : Color(.darkGray))
|
||||
.cornerRadius(10)
|
||||
|
||||
HStack(spacing: 4) {
|
||||
|
||||
let time = Int32(message.messageTimestamp)
|
||||
let messageDate = Date(timeIntervalSince1970: TimeInterval(time))
|
||||
|
||||
if time != 0 {
|
||||
Text(messageDate, style: .date).font(.caption2).foregroundColor(.gray)
|
||||
Text(messageDate, style: .time).font(.caption2).foregroundColor(.gray)
|
||||
} else {
|
||||
Text("Unknown").font(.caption2).foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 10)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HStack(alignment: .top) {
|
||||
|
||||
ZStack {
|
||||
|
||||
let kbType = UIKeyboardType(rawValue: UserDefaults.standard.object(forKey: "keyboardType") as? Int ?? 0)
|
||||
TextEditor(text: $typingMessage)
|
||||
.onChange(of: typingMessage, perform: { value in
|
||||
|
||||
let size = value.utf8.count
|
||||
totalBytes = size
|
||||
if totalBytes <= maxbytes {
|
||||
// Allow the user to type
|
||||
lastTypingMessage = typingMessage
|
||||
} else {
|
||||
// Set the message back and remove the bytes over the count
|
||||
self.typingMessage = lastTypingMessage
|
||||
}
|
||||
})
|
||||
.keyboardType(kbType!)
|
||||
.toolbar {
|
||||
ToolbarItemGroup(placement: .keyboard) {
|
||||
|
||||
Button("Dismiss Keyboard") {
|
||||
focusedField = nil
|
||||
}
|
||||
.font(.subheadline)
|
||||
|
||||
Spacer()
|
||||
|
||||
ProgressView("Bytes: \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
.frame(width: 130)
|
||||
.padding(5)
|
||||
.font(.subheadline)
|
||||
.accentColor(.accentColor)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.focused($focusedField, equals: .messageText)
|
||||
.multilineTextAlignment(.leading)
|
||||
.frame(minHeight: 100, maxHeight: 160)
|
||||
|
||||
Text(typingMessage).opacity(0).padding(.all, 0)
|
||||
|
||||
}
|
||||
.overlay(RoundedRectangle(cornerRadius: 20).stroke(.tertiary, lineWidth: 1))
|
||||
.padding(.bottom, 15)
|
||||
|
||||
Button(action: {
|
||||
if bleManager.sendMessage(message: typingMessage, toUserNum: user.num) {
|
||||
typingMessage = ""
|
||||
focusedField = nil
|
||||
} else {
|
||||
|
||||
_ = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { (_) in
|
||||
|
||||
if bleManager.sendMessage(message: typingMessage, toUserNum: user.num) {
|
||||
typingMessage = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}) {
|
||||
Image(systemName: "arrow.up.circle.fill").font(.largeTitle).foregroundColor(.blue)
|
||||
}
|
||||
|
||||
}
|
||||
.padding(.all, 15)
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(.stack)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .principal) {
|
||||
|
||||
HStack {
|
||||
|
||||
CircleText(text: user.shortName ?? "???", color: .blue).fixedSize()
|
||||
Text(user.longName ?? "Unknown").foregroundColor(.gray).font(.caption2).fixedSize()
|
||||
}
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???")
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear(perform: {
|
||||
|
||||
self.bleManager.context = context
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
// @Environment(\.managedObjectContext) var context
|
||||
// @EnvironmentObject var bleManager: BLEManager
|
||||
//
|
||||
// enum Field: Hashable {
|
||||
// case messageText
|
||||
// }
|
||||
// // Keyboard State
|
||||
// @State var typingMessage: String = ""
|
||||
// @State private var totalBytes = 0
|
||||
// var maxbytes = 228
|
||||
// @State var lastTypingMessage = ""
|
||||
// @FocusState var focusedField: Field?
|
||||
//
|
||||
// var user: UserEntity
|
||||
//
|
||||
// @State var showDeleteMessageAlert = false
|
||||
// @State private var deleteMessageId: Int64 = 0
|
||||
//
|
||||
// var body: some View {
|
||||
//
|
||||
//// HStack {
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// // List {
|
||||
//
|
||||
// ScrollViewReader { _ in
|
||||
//
|
||||
// ScrollView {
|
||||
//
|
||||
// if user.receivedMessages?.count ?? 0 > 0 {
|
||||
//
|
||||
// ForEach( user.receivedMessages?.array as! [MessageEntity], id: \.self) { (message: MessageEntity) in
|
||||
//
|
||||
// // HStack {
|
||||
// let currentUser: Bool = (bleManager.connectedPeripheral == nil) ? false : ((bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.num == message.fromUser?.num) ? true : false )
|
||||
//
|
||||
//
|
||||
// if message.toUser!.num == Int64(bleManager.broadcastNodeNum) || ((bleManager.connectedPeripheral) != nil && bleManager.connectedPeripheral.num == message.fromUser?.num) ? true : true {
|
||||
//
|
||||
//
|
||||
// HStack (alignment: .top) {
|
||||
//
|
||||
// if currentUser { Spacer(minLength:50) }
|
||||
//
|
||||
// if !currentUser {
|
||||
//
|
||||
// CircleText(text: (message.fromUser?.shortName ?? "???"), color: currentUser ? .accentColor : Color(.darkGray)).padding(.all, 5)
|
||||
// .gesture(LongPressGesture(minimumDuration: 2).onEnded {_ in
|
||||
//
|
||||
// print("I want to delete message: \(message.messageId)")
|
||||
// self.showDeleteMessageAlert = true
|
||||
// self.deleteMessageId = message.messageId
|
||||
// print(deleteMessageId)
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// VStack(alignment: currentUser ? .trailing : .leading) {
|
||||
//
|
||||
// Text(message.messagePayload ?? "EMPTY MESSAGE")
|
||||
// .textSelection(.enabled)
|
||||
// .padding(10)
|
||||
// .foregroundColor(.white)
|
||||
// .background(currentUser ? Color.blue : Color(.darkGray))
|
||||
// .cornerRadius(15)
|
||||
//
|
||||
// HStack(spacing: 4) {
|
||||
//
|
||||
// let time = Int32(message.messageTimestamp)
|
||||
// let messageDate = Date(timeIntervalSince1970: TimeInterval(time))
|
||||
//
|
||||
// if time != 0 {
|
||||
// Text(messageDate, style: .date).font(.caption2).foregroundColor(.gray)
|
||||
// Text(messageDate, style: .time).font(.caption2).foregroundColor(.gray)
|
||||
// } else {
|
||||
// Text("Unknown").font(.caption2).foregroundColor(.gray)
|
||||
// }
|
||||
// }
|
||||
// .padding(.bottom, 10)
|
||||
// }
|
||||
// if !currentUser {
|
||||
// Spacer(minLength:50)
|
||||
// }
|
||||
// }
|
||||
// .padding(.trailing)
|
||||
// .frame(maxWidth: .infinity)
|
||||
// }
|
||||
// // }
|
||||
// }
|
||||
// .listRowSeparator(.hidden)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // }
|
||||
// // .padding(.top)
|
||||
//
|
||||
// HStack(alignment: .top) {
|
||||
//
|
||||
// ZStack {
|
||||
//
|
||||
// let kbType = UIKeyboardType(rawValue: UserDefaults.standard.object(forKey: "keyboardType") as? Int ?? 0)
|
||||
// TextEditor(text: $typingMessage)
|
||||
// .onChange(of: typingMessage, perform: { value in
|
||||
//
|
||||
// let size = value.utf8.count
|
||||
// totalBytes = size
|
||||
// if totalBytes <= maxbytes {
|
||||
// // Allow the user to type
|
||||
// lastTypingMessage = typingMessage
|
||||
// } else {
|
||||
// // Set the message back and remove the bytes over the count
|
||||
// self.typingMessage = lastTypingMessage
|
||||
// }
|
||||
// })
|
||||
// .keyboardType(kbType!)
|
||||
// .toolbar {
|
||||
// ToolbarItemGroup(placement: .keyboard) {
|
||||
//
|
||||
// Button("Dismiss Keyboard") {
|
||||
// focusedField = nil
|
||||
// }
|
||||
// .font(.subheadline)
|
||||
//
|
||||
// Spacer()
|
||||
//
|
||||
// ProgressView("Bytes: \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
// .frame(width: 130)
|
||||
// .padding(5)
|
||||
// .font(.subheadline)
|
||||
// .accentColor(.accentColor)
|
||||
// }
|
||||
// }
|
||||
// .padding(.horizontal, 8)
|
||||
// .focused($focusedField, equals: .messageText)
|
||||
// .multilineTextAlignment(.leading)
|
||||
// .frame(minHeight: 100, maxHeight: 160)
|
||||
//
|
||||
// Text(typingMessage).opacity(0).padding(.all, 0)
|
||||
//
|
||||
// }
|
||||
// .overlay(RoundedRectangle(cornerRadius: 20).stroke(.tertiary, lineWidth: 1))
|
||||
// .padding(.bottom, 15)
|
||||
//
|
||||
// Button(action: {
|
||||
// if bleManager.sendMessage(message: typingMessage, toUserNum: user.num) {
|
||||
// typingMessage = ""
|
||||
// focusedField = nil
|
||||
// } else {
|
||||
//
|
||||
// _ = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { (_) in
|
||||
//
|
||||
// if bleManager.sendMessage(message: typingMessage, toUserNum: user.num) {
|
||||
// typingMessage = ""
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }) {
|
||||
// Image(systemName: "arrow.up.circle.fill").font(.largeTitle).foregroundColor(.blue)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// .padding(.all, 15)
|
||||
// }
|
||||
//// }
|
||||
// .navigationViewStyle(.stack)
|
||||
// .navigationBarTitleDisplayMode(.inline)
|
||||
// .toolbar {
|
||||
// ToolbarItem(placement: .principal) {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// CircleText(text: user.shortName ?? "???", color: .blue).fixedSize()
|
||||
// Text(user.longName ?? "Unknown").foregroundColor(.gray).font(.caption2).fixedSize()
|
||||
// }
|
||||
// }
|
||||
// ToolbarItem(placement: .navigationBarTrailing) {
|
||||
// ZStack {
|
||||
//
|
||||
// ConnectedDevice(
|
||||
// bluetoothOn: bleManager.isSwitchedOn,
|
||||
// deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
// name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .onAppear(perform: {
|
||||
//
|
||||
// self.bleManager.context = context
|
||||
//
|
||||
// })
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -175,7 +175,11 @@ struct NodeDetail: View {
|
|||
}
|
||||
Text(String(node.num)).font(.title3).foregroundColor(.gray)
|
||||
}
|
||||
}.padding()
|
||||
}.padding(5)
|
||||
HStack {
|
||||
Text("MAC Address: ")
|
||||
Text(String(node.user?.macaddr?.macAddressString ?? "not a valid mac address")).foregroundColor(.gray)
|
||||
}
|
||||
|
||||
if node.positions?.count ?? 0 > 1 {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue