从 iOS 17 Observation 迁移至 iOS 16 兼容的 Combine 架构
将最低部署版本降至 iOS 16,以 ObservableObject 替换 @Observable,新增导航与 UI 兼容层,并补充登录冒烟 UI 测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
import Combine
|
||||
|
||||
/// 消息中心服务协议,定义消息列表、已读和删除能力。
|
||||
@MainActor
|
||||
@ -22,10 +22,9 @@ protocol MessageCenterServing {
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Observable
|
||||
/// 消息中心 API,封装消息相关网络请求。
|
||||
final class MessageCenterAPI {
|
||||
@ObservationIgnored private let client: APIClient
|
||||
private let client: APIClient
|
||||
|
||||
/// 初始化消息中心 API,并注入共享网络客户端。
|
||||
init(client: APIClient) {
|
||||
|
||||
@ -6,22 +6,21 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
@Observable
|
||||
/// 消息中心 ViewModel,负责消息分页、筛选、已读和删除。
|
||||
final class MessageCenterViewModel {
|
||||
var messages: [MessageItem] = []
|
||||
var selectedFilter: MessageFilter = .all
|
||||
var isLoading = false
|
||||
var isLoadingMore = false
|
||||
var loadFailed = false
|
||||
var loadFailureReason: String?
|
||||
var message: String?
|
||||
final class MessageCenterViewModel: ObservableObject {
|
||||
@Published var messages: [MessageItem] = []
|
||||
@Published var selectedFilter: MessageFilter = .all
|
||||
@Published var isLoading = false
|
||||
@Published var isLoadingMore = false
|
||||
@Published var loadFailed = false
|
||||
@Published var loadFailureReason: String?
|
||||
@Published var message: String?
|
||||
|
||||
private(set) var hasMoreMessages = false
|
||||
private(set) var lastId = 0
|
||||
@Published private(set) var hasMoreMessages = false
|
||||
@Published private(set) var lastId = 0
|
||||
private let pageSize = 20
|
||||
|
||||
/// 未读消息数量。
|
||||
|
||||
@ -9,9 +9,9 @@ import SwiftUI
|
||||
|
||||
/// 消息中心页面,展示消息列表、筛选、已读和删除入口。
|
||||
struct MessageCenterView: View {
|
||||
@Environment(MessageCenterAPI.self) private var messageAPI
|
||||
@Environment(ToastCenter.self) private var toastCenter
|
||||
@State private var viewModel = MessageCenterViewModel()
|
||||
@Environment(\.messageCenterAPI) private var messageAPI
|
||||
@EnvironmentObject private var toastCenter: ToastCenter
|
||||
@StateObject private var viewModel = MessageCenterViewModel()
|
||||
@State private var selectedMessage: MessageItem?
|
||||
@State private var processingMessageId: String?
|
||||
|
||||
@ -80,7 +80,7 @@ struct MessageCenterView: View {
|
||||
ProgressView("加载中...")
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
} else if viewModel.loadFailed {
|
||||
ContentUnavailableView {
|
||||
AppContentUnavailableView {
|
||||
Label("消息加载失败", systemImage: "exclamationmark.triangle")
|
||||
} description: {
|
||||
Text(viewModel.loadFailureReason ?? "请稍后重试")
|
||||
@ -92,7 +92,7 @@ struct MessageCenterView: View {
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
} else if viewModel.messages.isEmpty {
|
||||
ContentUnavailableView("暂无消息", systemImage: "bell", description: Text("暂无可查看的系统消息"))
|
||||
AppContentUnavailableView("暂无消息", systemImage: "bell", description: Text("暂无可查看的系统消息"))
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
} else {
|
||||
ScrollView {
|
||||
|
||||
Reference in New Issue
Block a user