feat(ios): refine native interface and app icon
Unify bottom actions, selection controls, navigation structure, spacing, and theme colors across iOS pages. Replace the app icon with a higher-contrast native-style asset and include its source SVG.
This commit is contained in:
+67
-63
@@ -2,79 +2,83 @@ import Foundation
|
||||
|
||||
@MainActor
|
||||
final class NotificationsViewModel: ObservableObject {
|
||||
@Published private(set) var overview: NotificationOverview?
|
||||
@Published private(set) var instances: [Instance] = []
|
||||
@Published private(set) var isLoading = false
|
||||
@Published var errorMessage: String?
|
||||
@Published private(set) var actionMessage: String?
|
||||
@Published private(set) var actionSucceeded = true
|
||||
@Published private(set) var busyQueueID: String?
|
||||
@Published private(set) var overview: NotificationOverview?
|
||||
@Published private(set) var instances: [Instance] = []
|
||||
@Published private(set) var isLoading = false
|
||||
@Published var errorMessage: String?
|
||||
@Published private(set) var actionMessage: String?
|
||||
@Published private(set) var actionSucceeded = true
|
||||
@Published private(set) var busyQueueID: String?
|
||||
@Published private(set) var isRetryingAll = false
|
||||
|
||||
private let repository: any InstanceRepository
|
||||
private let service: NotificationService
|
||||
private let repository: any InstanceRepository
|
||||
private let service: NotificationService
|
||||
|
||||
init(repository: any InstanceRepository, service: NotificationService) {
|
||||
self.repository = repository
|
||||
self.service = service
|
||||
init(repository: any InstanceRepository, service: NotificationService) {
|
||||
self.repository = repository
|
||||
self.service = service
|
||||
}
|
||||
|
||||
func refresh() async {
|
||||
isLoading = true
|
||||
errorMessage = nil
|
||||
do {
|
||||
let loaded = try await repository.list(InstanceQuery())
|
||||
instances = loaded
|
||||
overview = try await service.overview(loaded)
|
||||
} catch {
|
||||
errorMessage = "无法加载通知中心。"
|
||||
}
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
func refresh() async {
|
||||
isLoading = true
|
||||
errorMessage = nil
|
||||
do {
|
||||
let loaded = try await repository.list(InstanceQuery())
|
||||
instances = loaded
|
||||
overview = try await service.overview(loaded)
|
||||
} catch {
|
||||
errorMessage = "无法加载通知中心。"
|
||||
}
|
||||
isLoading = false
|
||||
func retryAll() async {
|
||||
guard !isRetryingAll && !isLoading else { return }
|
||||
isRetryingAll = true
|
||||
let result = await service.retryAll(instances)
|
||||
actionSucceeded = result.succeeded > 0
|
||||
if result.succeeded > 0 {
|
||||
actionMessage = "已提交全部队列重试,成功 \(result.succeeded) 个实例。"
|
||||
} else if result.skipped > 0 {
|
||||
actionMessage = "没有可重试的队列接口。"
|
||||
} else {
|
||||
actionMessage = "队列重试失败。"
|
||||
}
|
||||
await refresh()
|
||||
isRetryingAll = false
|
||||
}
|
||||
|
||||
func retryAll() async {
|
||||
let result = await service.retryAll(instances)
|
||||
actionSucceeded = result.succeeded > 0
|
||||
if result.succeeded > 0 {
|
||||
actionMessage = "已提交全部队列重试,成功 \(result.succeeded) 个实例。"
|
||||
} else if result.skipped > 0 {
|
||||
actionMessage = "没有可重试的队列接口。"
|
||||
} else {
|
||||
actionMessage = "队列重试失败。"
|
||||
}
|
||||
await refresh()
|
||||
func retryQueue(_ item: NotificationQueueEntry) async {
|
||||
await queueAction(item) { instance, id in
|
||||
try await self.service.retryQueue(instance, id: id)
|
||||
}
|
||||
}
|
||||
|
||||
func retryQueue(_ item: NotificationQueueEntry) async {
|
||||
await queueAction(item) { instance, id in
|
||||
try await self.service.retryQueue(instance, id: id)
|
||||
}
|
||||
func deleteQueue(_ item: NotificationQueueEntry) async {
|
||||
await queueAction(item) { instance, id in
|
||||
try await self.service.deleteQueueItem(instance, id: id)
|
||||
}
|
||||
await refresh()
|
||||
}
|
||||
|
||||
func deleteQueue(_ item: NotificationQueueEntry) async {
|
||||
await queueAction(item) { instance, id in
|
||||
try await self.service.deleteQueueItem(instance, id: id)
|
||||
}
|
||||
await refresh()
|
||||
private func queueAction(
|
||||
_ item: NotificationQueueEntry,
|
||||
action: (Instance, String) async throws -> Void
|
||||
) async {
|
||||
guard let instance = instances.first(where: { $0.id == item.instanceID }) else {
|
||||
errorMessage = "找不到队列所属实例。"
|
||||
return
|
||||
}
|
||||
|
||||
private func queueAction(
|
||||
_ item: NotificationQueueEntry,
|
||||
action: (Instance, String) async throws -> Void
|
||||
) async {
|
||||
guard let instance = instances.first(where: { $0.id == item.instanceID }) else {
|
||||
errorMessage = "找不到队列所属实例。"
|
||||
return
|
||||
}
|
||||
busyQueueID = item.id
|
||||
do {
|
||||
try await action(instance, item.id)
|
||||
actionMessage = "队列操作已完成。"
|
||||
actionSucceeded = true
|
||||
errorMessage = nil
|
||||
} catch {
|
||||
errorMessage = "队列操作失败。"
|
||||
actionSucceeded = false
|
||||
}
|
||||
busyQueueID = nil
|
||||
busyQueueID = item.id
|
||||
do {
|
||||
try await action(instance, item.id)
|
||||
actionMessage = "队列操作已完成。"
|
||||
actionSucceeded = true
|
||||
errorMessage = nil
|
||||
} catch {
|
||||
errorMessage = "队列操作失败。"
|
||||
actionSucceeded = false
|
||||
}
|
||||
busyQueueID = nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user