mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
V 1.25.10 Message long press delete UI, only works for received messages with an actual ID
This commit is contained in:
parent
49e19a4a76
commit
614d9f0f9e
4 changed files with 100 additions and 9 deletions
|
|
@ -660,7 +660,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.25.9;
|
||||
MARKETING_VERSION = 1.25.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -687,7 +687,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.25.9;
|
||||
MARKETING_VERSION = 1.25.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
import SwiftUI
|
||||
|
||||
struct MessageBubble: View {
|
||||
|
||||
@State var showAlert = false
|
||||
var contentMessage: String
|
||||
var isCurrentUser: Bool
|
||||
var time: Int32
|
||||
var shortName: String
|
||||
|
||||
var id: UInt32
|
||||
|
||||
var body: some View {
|
||||
|
||||
|
||||
|
||||
|
||||
HStack (alignment: .top) {
|
||||
|
||||
CircleText(text: shortName, color: isCurrentUser ? Color.blue : Color(.darkGray)).padding(.all, 5)
|
||||
.gesture(LongPressGesture(minimumDuration: 2)
|
||||
.onEnded {_ in
|
||||
print("I want to delete message: \(id)")
|
||||
self.showAlert = true
|
||||
})
|
||||
|
||||
|
||||
VStack (alignment: .leading) {
|
||||
Text(contentMessage)
|
||||
.textSelection(.enabled)
|
||||
|
|
@ -37,13 +44,24 @@ struct MessageBubble: View {
|
|||
}
|
||||
Spacer()
|
||||
}
|
||||
.alert(isPresented: $showAlert) {
|
||||
Alert(title: Text("Are you sure you want to delete this message?"), message: Text("This action is permanent."),
|
||||
primaryButton: .destructive (Text("OK")) {
|
||||
print("OK button tapped")
|
||||
//let messageIndex = meshData.nodes.firstIndex(where: { $0.id == node.id })
|
||||
//meshData.nodes.remove(at: nodeIndex!)
|
||||
//meshData.save()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MessageBubble_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group {
|
||||
MessageBubble(contentMessage: "this is the best text ever", isCurrentUser: true, time: 0, shortName: "EB")
|
||||
MessageBubble(contentMessage: "this is the best text ever", isCurrentUser: true, time: 0, shortName: "EB", id: 12)
|
||||
}
|
||||
.previewLayout(.fixed(width: 300, height: 100))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ struct Messages: View {
|
|||
@FocusState private var focusedField: Field?
|
||||
@Namespace var topId
|
||||
@Namespace var bottomId
|
||||
@State var showDeleteMessageAlert = false
|
||||
@State private var deleteMessageId : UInt32 = 0
|
||||
|
||||
// Message Data and Bluetooth
|
||||
@EnvironmentObject var messageData: MessageData
|
||||
|
|
@ -44,7 +46,61 @@ struct Messages: View {
|
|||
|
||||
let currentUser: Bool = (bleManager.connectedNode != nil) && ((bleManager.connectedNode.id) == message.fromUserId)
|
||||
|
||||
MessageBubble(contentMessage: message.messagePayload, isCurrentUser: currentUser, time: Int32(message.messageTimestamp), shortName: message.fromUserShortName)
|
||||
//MessageBubble(contentMessage: message.messagePayload, isCurrentUser: currentUser, time: Int32(message.messageTimestamp), shortName: message.fromUserShortName, id: message.messageId)
|
||||
|
||||
HStack (alignment: .top) {
|
||||
|
||||
CircleText(text: message.fromUserShortName, color: currentUser ? Color.blue : 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
|
||||
|
||||
})
|
||||
|
||||
|
||||
VStack (alignment: .leading) {
|
||||
Text(message.messagePayload)
|
||||
.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()
|
||||
}
|
||||
.alert(isPresented: $showDeleteMessageAlert) {
|
||||
Alert(title: Text("Are you sure you want to delete this message?"), message: Text("This action is permanent."),
|
||||
primaryButton: .destructive (Text("Delete")) {
|
||||
print("OK button tapped")
|
||||
if deleteMessageId > 0 {
|
||||
|
||||
let messageIndex = messageData.messages.firstIndex(where: { $0.messageId == deleteMessageId })
|
||||
messageData.messages.remove(at: messageIndex!)
|
||||
messageData.save()
|
||||
print("Deleted message: \(message.messageId)")
|
||||
showDeleteMessageAlert = false
|
||||
deleteMessageId = 0
|
||||
}
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
}
|
||||
.onAppear(perform: { scrollView.scrollTo(bottomId) } )
|
||||
Text("Hidden Bottom Anchor").hidden().frame(height: 0).id(bottomId)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ enum KeyboardType: Int, CaseIterable, Identifiable {
|
|||
case .defaultKeyboard:
|
||||
return "Default"
|
||||
case .asciiCapable:
|
||||
return "ascii Capable"
|
||||
return "ASCII Capable"
|
||||
case .twitter:
|
||||
return "Twitter"
|
||||
case .emailAddress:
|
||||
|
|
@ -36,6 +36,16 @@ class UserSettings: ObservableObject {
|
|||
UserDefaults.standard.set(username, forKey: "username")
|
||||
}
|
||||
}
|
||||
@Published var preferredPeripheralName: String {
|
||||
didSet {
|
||||
UserDefaults.standard.set(preferredPeripheralName, forKey: "preferredPeripheralName")
|
||||
}
|
||||
}
|
||||
@Published var preferredPeripheralId: String {
|
||||
didSet {
|
||||
UserDefaults.standard.set(preferredPeripheralId, forKey: "preferredPeripheralId")
|
||||
}
|
||||
}
|
||||
@Published var provideLocation: Bool {
|
||||
didSet {
|
||||
UserDefaults.standard.set(provideLocation, forKey: "provideLocation")
|
||||
|
|
@ -49,6 +59,8 @@ class UserSettings: ObservableObject {
|
|||
|
||||
init() {
|
||||
self.username = UserDefaults.standard.object(forKey: "username") as? String ?? ""
|
||||
self.preferredPeripheralName = UserDefaults.standard.object(forKey: "preferredPeripheralName") as? String ?? ""
|
||||
self.preferredPeripheralId = UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? ""
|
||||
self.provideLocation = UserDefaults.standard.object(forKey: "provideLocation") as? Bool ?? false
|
||||
self.keyboardType = UserDefaults.standard.object(forKey: "keyboardType") as? Int ?? 0
|
||||
}
|
||||
|
|
@ -76,6 +88,11 @@ struct AppSettings: View {
|
|||
Text("Provide location to mesh")
|
||||
}
|
||||
}
|
||||
Section(header: Text("PREFERRED PERIPHERAL")) {
|
||||
Text("The preferred peripheral will automatically reconnect if it becomes disconnected and is still within range. This device is assumed to be the primary messaging device for the app.").font(.caption).foregroundColor(.gray)
|
||||
Text(userSettings.preferredPeripheralName)
|
||||
|
||||
}
|
||||
Section(header: Text("MESSAGING OPTIONS")) {
|
||||
|
||||
Picker("Keyboard Type", selection: $userSettings.keyboardType) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue