This commit is contained in:
anlicheng 2025-04-14 14:43:41 +08:00
parent 5083375194
commit 2f56bc7e74
6 changed files with 96 additions and 108 deletions

View File

@ -95,19 +95,21 @@ final class DetailModel {
print(code) print(code)
print(message) print(message)
case .result(let detail): case .result(let detail):
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.flatMap { s in
if let status = DramaStatus(s) { if let status = DramaStatus(s) {
return [status] return [status]
} else { } else {
return [] return []
} }
}) }
self.channels = detail.channels
self.channels = detail.channels
self.selectedChannelIdx = 0 self.selectedChannelIdx = 0
self.selectedEpisodes = detail.channels[0].episodes self.selectedEpisodes = detail.channels[0].episodes
} }
@ -136,4 +138,15 @@ final class DetailModel {
} }
} }
//
private func preloadImages(channels: [Channel]) {
let cacheManager = CacheManager.shared
channels.forEach { channel in
let urls = channel.episodes.map { $0.thumb }
Task.detached {
try? await cacheManager.preloadImages(urls: urls)
}
}
}
} }

View File

@ -168,39 +168,21 @@ extension DetailView {
var body: some View { var body: some View {
VStack(alignment: .center) { VStack(alignment: .center) {
FlexImage(urlString: episode.thumb, width: 90, height: 70, placeholder: "ph_img_small")
AsyncImage(url: URL(string: episode.thumb)) { phase in .frame(width: 90, height: 70)
switch phase { .overlay(alignment: .topLeading) {
case .empty: if !episode.num_name.isEmpty {
ProgressView() Text(episode.num_name)
case .success(let image): .font(.system(size: 12))
image .foregroundColor(.white)
.resizable() .padding(3)
.aspectRatio(contentMode: .fill) .background(Color.black.opacity(0.5))
.frame(width: 90, height: 70) .cornerRadius(3)
.clipped() .padding(3)
default: } else {
Image("ph_img_small") EmptyView()
.resizable() }
.aspectRatio(contentMode: .fill)
.clipped()
} }
}
.frame(width: 90, height: 70)
.overlay(alignment: .topLeading) {
if !episode.num_name.isEmpty {
Text(episode.num_name)
.font(.system(size: 12))
.foregroundColor(.white)
.padding(3)
.background(Color.black.opacity(0.5))
.cornerRadius(3)
.padding(3)
} else {
EmptyView()
}
}
Text(episode.name) Text(episode.name)
.font(.system(size: 12)) .font(.system(size: 12))

View File

@ -45,9 +45,23 @@ final class FollowListModel {
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):
self.preloadImages(dramas: result.dramas)
await MainActor.run { await MainActor.run {
self.dramas = result.dramas self.dramas = result.dramas
} }
} }
} }
private func preloadImages(dramas: [DramaItem]) {
let cacheManager = CacheManager.shared
dramas.forEach { dramaItem in
let urls = dramaItem.episodes.map { $0.thumb }
if urls.count > 0 {
Task.detached(priority: .medium) {
try? await cacheManager.preloadImages(urls: urls)
}
}
}
}
} }

View File

@ -83,44 +83,28 @@ extension FollowListView {
var body: some View { var body: some View {
VStack(alignment: .center) { VStack(alignment: .center) {
GeometryReader { geometry in GeometryReader { geometry in
let width = geometry.frame(in: .local).width
AsyncImage(url: URL(string: item.thumb)) { phase in FlexImage(urlString: item.thumb, width: width, height: 80, placeholder: "ph_img_medium")
switch phase { .frame(width: width, height: 80)
case .empty: .overlay(alignment: .topLeading) {
ProgressView() if !item.num_name.isEmpty {
case .success(let image): HStack(alignment: .center) {
image Text(item.num_name)
.resizable() .font(.system(size: 12))
.aspectRatio(contentMode: .fill) .foregroundColor(.white)
.frame(width: geometry.frame(in: .local).width, height: 80) .lineLimit(1)
.clipped() }
default: .padding(3)
Image("ph_img_medium") .background(
.resizable() Color.black.opacity(0.6)
.aspectRatio(contentMode: .fill) )
.frame(width: geometry.frame(in: .local).width, height: 80) .cornerRadius(3)
.clipped() .padding(3)
} } else {
} EmptyView()
.frame(width: geometry.frame(in: .local).width, height: 80)
.overlay(alignment: .topLeading) {
if !item.num_name.isEmpty {
HStack(alignment: .center) {
Text(item.num_name)
.font(.system(size: 12))
.foregroundColor(.white)
.lineLimit(1)
} }
.padding(3)
.background(
Color.black.opacity(0.6)
)
.cornerRadius(3)
.padding(3)
} else {
EmptyView()
} }
}
} }
Text(item.name) Text(item.name)

View File

@ -52,6 +52,8 @@ final class ListModel {
print(code) print(code)
print(message) print(message)
case .result(let detail): case .result(let detail):
self.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) ?? ""
@ -69,4 +71,14 @@ final class ListModel {
self.selectedEpisodes = self.channels[channelIdx].episodes self.selectedEpisodes = self.channels[channelIdx].episodes
} }
private func preloadImages(channels: [Channel]) {
let cacheManager = CacheManager.shared
channels.forEach { channel in
let urls = channel.episodes.map { $0.thumb }
Task.detached {
try? await cacheManager.preloadImages(urls: urls)
}
}
}
} }

View File

@ -12,47 +12,30 @@ struct SearchDramaGroupView: View {
let group: SearchModel.DramaGroup let group: SearchModel.DramaGroup
var body: some View { var body: some View {
VStack(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)) {
AsyncImage(url: URL(string: item.thumb)) { phase in FlexImage(urlString: item.thumb, width: 370, height: 180, placeholder: "ph_img_big")
switch phase { .frame(width: 370, height: 180)
case .empty: .overlay(alignment: .topLeading) {
ProgressView() VStack(alignment: .leading, spacing: 8) {
case .success(let image): Text(item.name)
image .font(.system(size: 16))
.resizable() .foregroundColor(.white)
.aspectRatio(contentMode: .fill) .lineLimit(1)
.frame(height: 180)
.clipped() Text(item.status)
default: .font(.system(size: 12))
Image("ph_img_big") .foregroundColor(.white)
.resizable() .lineLimit(1)
.aspectRatio(contentMode: .fill) }
.clipped() .padding(5)
.background(
Color.black.opacity(0.6)
)
.cornerRadius(5)
.padding(8)
} }
}
.frame(width: 370, height: 180)
.overlay(alignment: .topLeading) {
VStack(alignment: .leading, spacing: 8) {
Text(item.name)
.font(.system(size: 16))
.foregroundColor(.white)
.lineLimit(1)
Text(item.status)
.font(.system(size: 12))
.foregroundColor(.white)
.lineLimit(1)
}
.padding(5)
.background(
Color.black.opacity(0.6)
)
.cornerRadius(5)
.padding(8)
}
} }
} }
} }