解决系统通知时候的跳转问题

This commit is contained in:
anlicheng 2025-08-18 13:09:03 +08:00
parent add63e503f
commit c84ee6d630
10 changed files with 54 additions and 61 deletions

View File

@ -13,14 +13,17 @@ final class AppNavigation: ObservableObject {
static var shared = AppNavigation() static var shared = AppNavigation()
enum Destination: Hashable { enum Destination: Hashable {
case detail(id: Int) case detail(id: Int, channelName: String?)
case followList(num: Int) case followList(num: Int)
case search case search
} }
@Published var path = NavigationPath() @Published var path = NavigationPath()
let userId: String
@Published var targetDetailId: Int = 0 init() {
self.userId = KeychainHelper.getPersistentUserId()
}
func append(dest: Destination) { func append(dest: Destination) {
path.append(dest) path.append(dest)
@ -33,12 +36,15 @@ final class AppNavigation: ObservableObject {
return return
} }
path = NavigationPath() DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [unowned self] in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [self] in
switch target { switch target {
case "detail": case "detail":
if let dramaId = params["drama_id"] as? Int { if let dramaId = params["drama_id"] as? Int,
self.targetDetailId = dramaId let channelName = params["channel_name"] as? String {
self.append(dest: .detail(id: dramaId, channelName: channelName))
Task {
await Self.updateUserUnreadNum(userId: self.userId, dramaId: dramaId)
}
} }
default: default:
() ()
@ -46,4 +52,16 @@ final class AppNavigation: ObservableObject {
} }
} }
private static func updateUserUnreadNum(userId: String, dramaId: Int) async {
let response = await API.updateUserUnreadNum(userId: userId, dramaId: dramaId, as: Int.self)
switch response {
case .result(let newUnreadNum):
NSLog("updateUserUnreadNum success, new unread_num:\(newUnreadNum)")
Task {@MainActor in
try? await UNUserNotificationCenter.current().setBadgeCount(newUnreadNum)
}
case .error(let errorCode, let error):
NSLog("updateUserUnreadNum error: \(error), error_code: \(errorCode)")
}
}
} }

View File

@ -21,7 +21,7 @@ final class CacheManager {
// //
func preloadImages(urls: [String]) async throws { func preloadImages(urls: [String]) async throws {
let preloadUrls = urls.filter { url in !self.fileExists(urlString: url)} let preloadUrls = urls.filter { url in !self.fileExists(urlString: url)}
guard preloadUrls.count > 0 else { guard preloadUrls.count > 0 else {
return return

View File

@ -88,30 +88,28 @@ final class DetailModel {
var selectedChannelIdx: Int = 0 var selectedChannelIdx: Int = 0
var selectedEpisodes: [Episode] = [] var selectedEpisodes: [Episode] = []
func loadData(userId: String, id: Int) async { func loadData(userId: String, id: Int, channelName: String?) async {
let response = await API.getDramaDetail(userId: userId, id: id, as: DramaDetailResponse.self) let response = await API.getDramaDetail(userId: userId, id: id, as: DramaDetailResponse.self)
switch response { switch response {
case .error(let code, let message): case .error(let code, let message):
print(code) print(code)
print(message) print(message)
case .result(let detail): case .result(let detail):
preloadImages(channels: detail.channels) //preloadImages(channels: detail.channels)
await MainActor.run { await MainActor.run {
self.name = detail.name self.name = detail.name
self.summary = Utils.converHtmlToString(html: detail.summary) ?? "" self.summary = Utils.converHtmlToString(html: detail.summary) ?? ""
self.thumb = detail.thumb self.thumb = detail.thumb
self.statuses = detail.status.flatMap { s in self.statuses = detail.status.compactMap { DramaStatus($0) }
if let status = DramaStatus(s) {
return [status] let selectedIndex = channelName.flatMap { name in
} else { detail.channels.firstIndex(where: {$0.name == name})
return [] } ?? 0
}
}
self.channels = detail.channels self.channels = detail.channels
self.selectedChannelIdx = 0 self.selectedChannelIdx = selectedIndex
self.selectedEpisodes = detail.channels[0].episodes self.selectedEpisodes = detail.channels[selectedIndex].episodes
} }
} }
} }

View File

@ -17,6 +17,7 @@ struct DetailView: View {
@State var errorInfo: (String, String) = ("", "") @State var errorInfo: (String, String) = ("", "")
let id: Int let id: Int
let channelName: String?
var body: some View { var body: some View {
VStack(alignment: .center) { VStack(alignment: .center) {
@ -118,7 +119,7 @@ struct DetailView: View {
Alert(title: Text(self.errorInfo.0), message: Text(self.errorInfo.1), dismissButton: .default(Text("OK"))) Alert(title: Text(self.errorInfo.0), message: Text(self.errorInfo.1), dismissButton: .default(Text("OK")))
} }
.task { .task {
await detailModel.loadData(userId: self.userId, id: self.id) await detailModel.loadData(userId: self.userId, id: self.id, channelName: self.channelName)
} }
} }
@ -201,5 +202,5 @@ extension DetailView {
} }
#Preview { #Preview {
DetailView(id: 19625) DetailView(id: 19625, channelName: nil)
} }

View File

@ -71,7 +71,7 @@ extension FollowListView {
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 8) { VStack(alignment: .leading, spacing: 8) {
NavigationLink(destination: DetailView(id: dramaModel.drama.id)) { NavigationLink(destination: DetailView(id: dramaModel.drama.id, channelName: nil)) {
HStack { HStack {
Text(dramaModel.drama.title) Text(dramaModel.drama.title)
.font(.system(size: 20)) .font(.system(size: 20))

View File

@ -314,7 +314,7 @@ extension IndexMainView {
} }
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture { .onTapGesture {
appNav.append(dest: .detail(id: item.id)) appNav.append(dest: .detail(id: item.id, channelName: nil))
} }
} }
} }

View File

@ -192,7 +192,7 @@ final class IndexModel {
case .error(let code, let message): case .error(let code, let message):
print("index load data get error_code: \(code), message: \(message)") print("index load data get error_code: \(code), message: \(message)")
case .result(let result): case .result(let result):
preloadGroupImages(groups: result.update_dramas) preloadGroupImages(groups: result.update_dramas, skipNum: 4)
self.updateDramaGroups = result.update_dramas self.updateDramaGroups = result.update_dramas
self.fixedDramaGroup = result.update_dramas.first self.fixedDramaGroup = result.update_dramas.first
@ -233,7 +233,7 @@ final class IndexModel {
let response = await API.loadMoreUpdateDramas(userId: userId, mode: .next, id: lastId, as: [UpdateDramaGroup].self) let response = await API.loadMoreUpdateDramas(userId: userId, mode: .next, id: lastId, as: [UpdateDramaGroup].self)
if case let .result(groups) = response { if case let .result(groups) = response {
if groups.count > 0 { if groups.count > 0 {
preloadGroupImages(groups: groups) preloadGroupImages(groups: groups, skipNum: 0)
displayDramaGroups(self.updateDramaGroups, label: "before") displayDramaGroups(self.updateDramaGroups, label: "before")
self.updateDramaGroups = appendMergeDramaGroups(groups: self.updateDramaGroups, mergeGroups: groups) self.updateDramaGroups = appendMergeDramaGroups(groups: self.updateDramaGroups, mergeGroups: groups)
@ -261,7 +261,7 @@ final class IndexModel {
let response = await API.loadMoreUpdateDramas(userId: userId, mode: .prev, id: firstId, as: [UpdateDramaGroup].self) let response = await API.loadMoreUpdateDramas(userId: userId, mode: .prev, id: firstId, as: [UpdateDramaGroup].self)
if case let .result(groups) = response { if case let .result(groups) = response {
if groups.count > 0 { if groups.count > 0 {
preloadGroupImages(groups: groups) preloadGroupImages(groups: groups, skipNum: 0)
displayDramaGroups(self.updateDramaGroups, label: "before") displayDramaGroups(self.updateDramaGroups, label: "before")
@ -313,7 +313,7 @@ final class IndexModel {
let response = await API.loadDateUpdateDramas(userId: userId, date: date, as: [UpdateDramaGroup].self) let response = await API.loadDateUpdateDramas(userId: userId, date: date, as: [UpdateDramaGroup].self)
if case let .result(groups) = response { if case let .result(groups) = response {
preloadGroupImages(groups: groups) preloadGroupImages(groups: groups, skipNum: 4)
self.updateDramaGroups = groups self.updateDramaGroups = groups
self.dramaGroupElements = transformUpdateDramaGroups(groups: self.updateDramaGroups) self.dramaGroupElements = transformUpdateDramaGroups(groups: self.updateDramaGroups)
@ -362,7 +362,7 @@ final class IndexModel {
} }
// //
private func preloadGroupImages(groups: [UpdateDramaGroup]) { private func preloadGroupImages(groups: [UpdateDramaGroup], skipNum: Int) {
let urls = groups.flatMap { group in let urls = groups.flatMap { group in
return group.items.map {item in item.thumb} return group.items.map {item in item.thumb}
} }
@ -371,8 +371,11 @@ final class IndexModel {
return return
} }
Task.detached { if urls.count > skipNum {
try? await CacheManager.shared.preloadImages(urls: urls) let preloadUrls = urls.suffix(from: skipNum)
Task.detached {
try? await CacheManager.shared.preloadImages(urls: Array(preloadUrls))
}
} }
} }

View File

@ -52,7 +52,7 @@ final class ListModel {
print(code) print(code)
print(message) print(message)
case .result(let detail): case .result(let detail):
self.preloadImages(channels: detail.channels) //self.preloadImages(channels: detail.channels)
await MainActor.run { await MainActor.run {
self.name = detail.name self.name = detail.name

View File

@ -101,7 +101,7 @@ struct SearchDramaGroupView: View {
var body: some View { var body: some View {
LazyVStack(alignment: .center, spacing: 10) { LazyVStack(alignment: .center, spacing: 10) {
ForEach(group.items, id: \.id) { item in ForEach(group.items, id: \.id) { item in
NavigationLink(destination: DetailView(id: item.id)) { NavigationLink(destination: DetailView(id: item.id, channelName: nil)) {
FlexImage(urlString: item.thumb, width: 370, height: 180, placeholder: "ph_img_big") FlexImage(urlString: item.thumb, width: 370, height: 180, placeholder: "ph_img_big")
.frame(width: 370, height: 180) .frame(width: 370, height: 180)
.overlay(alignment: .topLeading) { .overlay(alignment: .topLeading) {

View File

@ -49,29 +49,14 @@ struct dimensionhubApp: App {
IndexView() IndexView()
.navigationDestination(for: AppNavigation.Destination.self) { dest in .navigationDestination(for: AppNavigation.Destination.self) { dest in
switch dest { switch dest {
case .detail(id: let id): case .detail(id: let id, channelName: let channelName):
DetailView(id: id) DetailView(id: id, channelName: channelName)
case .followList(num: let num): case .followList(num: let num):
FollowListView(num: num) FollowListView(num: num)
case .search: case .search:
SearchView() SearchView()
} }
} }
.onChange(of: appNav.targetDetailId) { _, dramaId in
if dramaId > 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
withAnimation {
appNav.append(dest: .detail(id: dramaId))
}
Task {
await self.updateUserUnreadNum(userId: self.userId, dramaId: dramaId)
}
appNav.targetDetailId = 0
}
}
}
} }
.navigationViewStyle(.stack) .navigationViewStyle(.stack)
.tint(.black) .tint(.black)
@ -82,18 +67,6 @@ struct dimensionhubApp: App {
.modelContainer(sharedModelContainer) .modelContainer(sharedModelContainer)
} }
private func updateUserUnreadNum(userId: String, dramaId: Int) async {
let response = await API.updateUserUnreadNum(userId: userId, dramaId: dramaId, as: Int.self)
switch response {
case .result(let newUnreadNum):
NSLog("updateUserUnreadNum success, new unread_num:\(newUnreadNum)")
Task {@MainActor in
try? await UNUserNotificationCenter.current().setBadgeCount(newUnreadNum)
}
case .error(let errorCode, let error):
NSLog("updateUserUnreadNum error: \(error), error_code: \(errorCode)")
}
}
} }
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {