diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj
index 6ff8c283..40e9c479 100644
--- a/Meshtastic.xcodeproj/project.pbxproj
+++ b/Meshtastic.xcodeproj/project.pbxproj
@@ -674,8 +674,8 @@
C9483F6B2773016700998F6B /* Map */,
DDC2E18D26CE25CB0042C5E4 /* Helpers */,
DD47E3D726F2F21A00029299 /* Bluetooth */,
- DD47E3CA26F0E50300029299 /* Nodes */,
DDC2E18B26CE25A70042C5E4 /* Messages */,
+ DD47E3CA26F0E50300029299 /* Nodes */,
DD4A911C2708C57100501B7E /* Settings */,
DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */,
);
diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift
index ade1b866..375bf513 100644
--- a/Meshtastic/Helpers/BLEManager.swift
+++ b/Meshtastic/Helpers/BLEManager.swift
@@ -656,8 +656,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
}
-
-
public func sendMessage(message: String, toUserNum: Int64, channel: Int32, isEmoji: Bool, replyID: Int64) -> Bool {
var success = false
diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV17.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV17.xcdatamodel/contents
index 2f6acb17..4a6286e4 100644
--- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV17.xcdatamodel/contents
+++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV17.xcdatamodel/contents
@@ -142,6 +142,7 @@
+
@@ -202,6 +203,8 @@
+
+
@@ -325,6 +328,7 @@
+
diff --git a/Meshtastic/Persistence/UserEntityExtension.swift b/Meshtastic/Persistence/UserEntityExtension.swift
index 6d9f5699..79324752 100644
--- a/Meshtastic/Persistence/UserEntityExtension.swift
+++ b/Meshtastic/Persistence/UserEntityExtension.swift
@@ -18,4 +18,9 @@ extension UserEntity {
self.value(forKey: "adminMessages") as? [MessageEntity] ?? [MessageEntity]()
}
+
+ var unreadMessages: Int {
+ self.receivedMessages?.count ?? 0
+ }
}
+
diff --git a/Meshtastic/Views/ContentView.swift b/Meshtastic/Views/ContentView.swift
index 146badc1..cb294a23 100644
--- a/Meshtastic/Views/ContentView.swift
+++ b/Meshtastic/Views/ContentView.swift
@@ -13,6 +13,7 @@ struct ContentView: View {
Label("messages", systemImage: "message")
}
.tag(Tab.contacts)
+ .badge(42)
Connect()
.tabItem {
Label("bluetooth", systemImage: "antenna.radiowaves.left.and.right")
@@ -23,11 +24,13 @@ struct ContentView: View {
Label("nodes", systemImage: "flipphone")
}
.tag(Tab.nodes)
+ .badge(11)
NodeMap()
.tabItem {
Label("map", systemImage: "map")
}
.tag(Tab.map)
+ .badge(4)
Settings()
.tabItem {
Label("settings", systemImage: "gear")
diff --git a/Meshtastic/Views/Messages/Contacts.swift b/Meshtastic/Views/Messages/Contacts.swift
index 72cfc3de..41b99876 100644
--- a/Meshtastic/Views/Messages/Contacts.swift
+++ b/Meshtastic/Views/Messages/Contacts.swift
@@ -14,7 +14,7 @@ struct Contacts: View {
@EnvironmentObject var bleManager: BLEManager
@FetchRequest(
- sortDescriptors: [NSSortDescriptor(key: "longName", ascending: true)],
+ sortDescriptors: [NSSortDescriptor(key: "lastMessage", ascending: true)],
animation: .default)
private var users: FetchedResults
@@ -139,107 +139,116 @@ struct Contacts: View {
}
Section(header: Text("direct.messages")) {
ForEach(users) { (user: UserEntity) in
+
+ let mostRecent = user.messageList.last
+ let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64((mostRecent?.messageTimestamp ?? 0 ))))
+ let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0
+ let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0
if user.num != bleManager.connectedPeripheral?.num ?? 0 {
+
NavigationLink(destination: UserMessageList(user: user)) {
- let mostRecent = user.messageList.last
- let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64((mostRecent?.messageTimestamp ?? 0 ))))
- let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0
- let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0
- HStack {
- VStack {
- HStack {
- CircleText(text: user.shortName ?? "???", color: Color(UIColor(hex: UInt32(user.num))), circleSize: 60, fontSize: (user.shortName ?? "???").isEmoji() ? 42 : 20, textColor: UIColor(hex: UInt32(user.num)).isLight() ? .black : .white)
- .padding(.trailing, 5)
- VStack {
- HStack {
- Text(user.longName ?? "unknown".localized).font(.headline)
- Spacer()
- if user.messageList.count > 0 {
- VStack(alignment: .trailing) {
- if lastMessageDay == currentDay {
- Text(lastMessageTime, style: .time )
- .font(.subheadline)
- } else if lastMessageDay == (currentDay - 1) {
- Text("Yesterday")
- .font(.subheadline)
- } else if lastMessageDay < (currentDay - 1) && lastMessageDay > (currentDay - 5) {
- Text(lastMessageTime.formattedDate(format: dateFormatString))
- .font(.subheadline)
- } else if lastMessageDay < (currentDay - 1800) {
- Text(lastMessageTime.formattedDate(format: dateFormatString))
- .font(.subheadline)
- }
- }
- .brightness(-0.2)
- }
+ ZStack {
+ Image(systemName: "circle.fill")
+ .opacity(user.unreadMessages > 0 ? 1 : 0)
+ .font(.system(size: 10))
+ .foregroundColor(.accentColor)
+ }
+
+ CircleText(text: user.shortName ?? "???", color: Color(UIColor(hex: UInt32(user.num))), circleSize: 45, fontSize: (user.shortName ?? "???").isEmoji() ? 32 : (user.shortName?.count ?? 0 == 4 ? 14 : (user.shortName?.count ?? 0 == 3 ? 18 : 22)), brightness: 0.0, textColor: UIColor(hex: UInt32(user.num)).isLight() ? .black : .white)
+
+ VStack(alignment: .leading){
+ HStack{
+ Text(user.longName ?? "unknown".localized)
+
+ Spacer()
+
+ if user.messageList.count > 0 {
+ if lastMessageDay == currentDay {
+ Text(lastMessageTime, style: .time )
+ .font(.system(size: 16))
+ .foregroundColor(.secondary)
+ } else if lastMessageDay == (currentDay - 1) {
+ Text("Yesterday")
+ .font(.system(size: 16))
+ .foregroundColor(.secondary)
+ } else if lastMessageDay < (currentDay - 1) && lastMessageDay > (currentDay - 5) {
+ Text(lastMessageTime.formattedDate(format: dateFormatString))
+ .font(.system(size: 16))
+ .foregroundColor(.secondary)
+ } else if lastMessageDay < (currentDay - 1800) {
+ Text(lastMessageTime.formattedDate(format: dateFormatString))
+ .font(.system(size: 16))
+ .foregroundColor(.secondary)
}
- if user.messageList.count > 0 {
- HStack(alignment: .top) {
- Text("\(mostRecent != nil ? mostRecent!.messagePayload! : " ")")
- .truncationMode(.tail)
- .font(.body)
- .frame(maxWidth: .infinity, alignment: .leading)
- .brightness(-0.2)
- }
- }
- }
- .frame(maxWidth: .infinity, maxHeight: 80, alignment: .leading)
- .contextMenu {
- Button {
- user.mute = !user.mute
- do {
- try context.save()
- } catch {
- context.rollback()
- print("💥 Save User Mute Error")
- }
- } label: {
- Label(user.mute ? "Show Alerts" : "Hide Alerts", systemImage: user.mute ? "bell" : "bell.slash")
- }
- Button {
- let success = bleManager.sendTraceRouteRequest(destNum: user.num, wantResponse: true)
- if success {
- isPresentingTraceRouteSentAlert = true
- }
- } label: {
- Label("Trace Route", systemImage: "signpost.right.and.left")
- }
- if user.messageList.count > 0 {
- Button(role: .destructive) {
- isPresentingDeleteUserMessagesConfirm = true
- userSelection = user
- } label: {
- Label("Delete Messages", systemImage: "trash")
- }
- }
- }
- .alert(
- "Trace Route Sent",
- isPresented: $isPresentingTraceRouteSentAlert
- ) {
- Button("OK", role: .cancel) { }
- }
- message: {
- Text("This could take a while, response will appear in the mesh log.")
- }
- .confirmationDialog(
- "This conversation will be deleted.",
- isPresented: $isPresentingDeleteUserMessagesConfirm,
- titleVisibility: .visible
- ) {
- Button(role: .destructive) {
- deleteUserMessages(user: userSelection!, context: context)
- context.refresh(node!.user!, mergeChanges: true)
- } label: {
- Text("delete")
- }
- }
}
+
+// Image(systemName: "chevron.forward")
+// .font(.caption)
+// .foregroundColor(.secondary)
+ }
+
+ if user.messageList.count > 0 {
+ HStack(alignment: .top) {
+ Text("\(mostRecent != nil ? mostRecent!.messagePayload! : " ")")
+ .font(.system(size: 16))
+ .foregroundColor(.secondary)
+ }
+ }
+
+ }
+
+ }
+ .frame(height: 90)
+ .contextMenu {
+ Button {
+ user.mute = !user.mute
+ do {
+ try context.save()
+ } catch {
+ context.rollback()
+ print("💥 Save User Mute Error")
+ }
+ } label: {
+ Label(user.mute ? "Show Alerts" : "Hide Alerts", systemImage: user.mute ? "bell" : "bell.slash")
+ }
+ Button {
+ let success = bleManager.sendTraceRouteRequest(destNum: user.num, wantResponse: true)
+ if success {
+ isPresentingTraceRouteSentAlert = true
+ }
+ } label: {
+ Label("Trace Route", systemImage: "signpost.right.and.left")
+ }
+ if user.messageList.count > 0 {
+ Button(role: .destructive) {
+ isPresentingDeleteUserMessagesConfirm = true
+ userSelection = user
+ } label: {
+ Label("Delete Messages", systemImage: "trash")
}
}
}
- .padding(.top, 10)
- .padding(.bottom, 10)
+ .alert(
+ "Trace Route Sent",
+ isPresented: $isPresentingTraceRouteSentAlert
+ ) {
+ Button("OK", role: .cancel) { }
+ }
+ message: {
+ Text("This could take a while, response will appear in the mesh log.")
+ }
+ .confirmationDialog(
+ "This conversation will be deleted.",
+ isPresented: $isPresentingDeleteUserMessagesConfirm,
+ titleVisibility: .visible
+ ) {
+ Button(role: .destructive) {
+ deleteUserMessages(user: userSelection!, context: context)
+ context.refresh(node!.user!, mergeChanges: true)
+ } label: {
+ Text("delete")
+ }
+ }
}
}
}
@@ -266,8 +275,7 @@ struct Contacts: View {
}
}
}
- }
- detail: {
+ } detail: {
if let user = userSelection {
UserMessageList(user: user)
diff --git a/pl.lproj/Localizable.strings b/pl.lproj/Localizable.strings
index c8cf4de8..da664afb 100644
--- a/pl.lproj/Localizable.strings
+++ b/pl.lproj/Localizable.strings
@@ -1,8 +1,10 @@
/*
- Localizable.strings
- Meshtastic
+ Localizable.strings
+ Meshtastic
- Created by Shiv Kokroo ( @kokroo ) on 27/08/23, with contributions from @Marek_SP5ISZ
+ Copyright(r) Garth Vander Houwen 12/12/22.
+
+ Created by Shiv Kokroo ( @kokroo ) on 27/08/23, with contributions from @Marek_SP5ISZ
*/
"about"="O programie";