feat(ios): refine native ui controls
This commit is contained in:
@@ -2,6 +2,7 @@ import SwiftUI
|
||||
|
||||
struct MessagesView: View {
|
||||
@StateObject private var model: MessagesViewModel
|
||||
@State private var pendingDeleteMessage: SMSMessage?
|
||||
|
||||
init(model: MessagesViewModel? = nil) {
|
||||
_model = StateObject(wrappedValue: model ?? DefaultContainer.makeMessagesModel())
|
||||
@@ -54,6 +55,20 @@ struct MessagesView: View {
|
||||
.buttonStyle(AIButtonStyle(kind: .primary, size: .regular))
|
||||
}
|
||||
}
|
||||
.confirmationDialog(
|
||||
"删除这条消息?操作不可恢复。",
|
||||
isPresented: Binding(
|
||||
get: { pendingDeleteMessage != nil },
|
||||
set: { if !$0 { pendingDeleteMessage = nil } }
|
||||
),
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("删除消息", role: .destructive) {
|
||||
guard let message = pendingDeleteMessage else { return }
|
||||
Task { await model.delete(message) }
|
||||
}
|
||||
Button("取消", role: .cancel) {}
|
||||
}
|
||||
.refreshable {
|
||||
await model.refresh()
|
||||
}
|
||||
@@ -83,16 +98,7 @@ struct MessagesView: View {
|
||||
}
|
||||
.pickerStyle(.menu)
|
||||
|
||||
TextField("搜索号码或内容", text: $model.searchText)
|
||||
.textFieldStyle(.plain)
|
||||
.padding(.horizontal, 12)
|
||||
.frame(minHeight: AITheme.buttonHeight)
|
||||
.background(AITheme.canvas)
|
||||
.clipShape(RoundedRectangle(cornerRadius: AITheme.buttonRadius))
|
||||
.overlay {
|
||||
RoundedRectangle(cornerRadius: AITheme.buttonRadius)
|
||||
.strokeBorder(AITheme.line)
|
||||
}
|
||||
AISearchField("搜索号码或内容", text: $model.searchText)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +121,7 @@ struct MessagesView: View {
|
||||
.foregroundStyle(AITheme.muted)
|
||||
Spacer()
|
||||
Button("删除") {
|
||||
Task { await model.delete(message) }
|
||||
pendingDeleteMessage = message
|
||||
}
|
||||
.buttonStyle(AIButtonStyle(kind: .danger, size: .compact))
|
||||
}
|
||||
|
||||
@@ -7,6 +7,18 @@ struct SendMessageFormView: View {
|
||||
@State private var content = ""
|
||||
@State private var validationMessage: String?
|
||||
|
||||
private var trimmedPhoneNumber: String {
|
||||
phoneNumber.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
private var trimmedContent: String {
|
||||
content.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
private var canSend: Bool {
|
||||
!trimmedPhoneNumber.isEmpty && !trimmedContent.isEmpty
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
ZStack {
|
||||
@@ -26,16 +38,19 @@ struct SendMessageFormView: View {
|
||||
.pickerStyle(.menu)
|
||||
|
||||
TextField("收件号码", text: $phoneNumber)
|
||||
.textFieldStyle(AIFieldStyle())
|
||||
|
||||
TextField("消息内容", text: $content, axis: .vertical)
|
||||
.textFieldStyle(.plain)
|
||||
.padding(.horizontal, 12)
|
||||
.frame(minHeight: AITheme.buttonHeight)
|
||||
.background(AITheme.canvas)
|
||||
.clipShape(RoundedRectangle(cornerRadius: AITheme.buttonRadius))
|
||||
|
||||
TextField("消息内容", text: $content, axis: .vertical)
|
||||
.overlay {
|
||||
RoundedRectangle(cornerRadius: AITheme.buttonRadius)
|
||||
.strokeBorder(AITheme.line)
|
||||
}
|
||||
.lineLimit(4...8)
|
||||
.padding(12)
|
||||
.background(AITheme.canvas)
|
||||
.clipShape(RoundedRectangle(cornerRadius: AITheme.buttonRadius))
|
||||
}
|
||||
}
|
||||
if let validationMessage {
|
||||
@@ -57,6 +72,7 @@ struct SendMessageFormView: View {
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
Button("发送") { send() }
|
||||
.buttonStyle(AIButtonStyle(kind: .primary, size: .regular))
|
||||
.disabled(!canSend)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +81,7 @@ struct SendMessageFormView: View {
|
||||
private func send() {
|
||||
Task {
|
||||
do {
|
||||
try await model.send(phoneNumber: phoneNumber, content: content)
|
||||
try await model.send(phoneNumber: trimmedPhoneNumber, content: trimmedContent)
|
||||
phoneNumber = ""
|
||||
content = ""
|
||||
validationMessage = nil
|
||||
|
||||
Reference in New Issue
Block a user