From cac31802b3ed8a0aed3705610c9972e584f373e8 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Tue, 8 Apr 2025 17:08:12 +0800 Subject: [PATCH] fix view --- .../Views/FollowList/FollowListModel.swift | 53 ++++++ .../Views/FollowList/FollowListView.swift | 144 ++++++++++++++ dimensionhub/Views/FollowListView.swift | 179 ------------------ dimensionhub/Views/List/ListModel.swift | 72 +++++++ dimensionhub/Views/{ => List}/ListView.swift | 86 +-------- 5 files changed, 271 insertions(+), 263 deletions(-) create mode 100644 dimensionhub/Views/FollowList/FollowListModel.swift create mode 100644 dimensionhub/Views/FollowList/FollowListView.swift delete mode 100644 dimensionhub/Views/FollowListView.swift create mode 100644 dimensionhub/Views/List/ListModel.swift rename dimensionhub/Views/{ => List}/ListView.swift (57%) diff --git a/dimensionhub/Views/FollowList/FollowListModel.swift b/dimensionhub/Views/FollowList/FollowListModel.swift new file mode 100644 index 0000000..6bc9da7 --- /dev/null +++ b/dimensionhub/Views/FollowList/FollowListModel.swift @@ -0,0 +1,53 @@ +// +// FollowListModel.swift +// dimensionhub +// +// Created by 安礼成 on 2025/4/8. +// + +import Foundation +import Observation + +@Observable +final class FollowListModel { + + struct DramaItem: Codable { + struct Episode: Codable, Identifiable { + let id = UUID().uuidString + let name: String + let thumb: String + let num_name: String + let play: String + + enum CodingKeys: String, CodingKey { + case name, thumb, num_name, play + } + } + + let id: Int + let title: String + let episodes: [Episode] + } + + struct FavorResponse: Codable { + let dramas: [DramaItem] + } + + var dramas: [DramaItem] + + init() { + self.dramas = [] + } + + func loadData(userId: String) async { + let response = await API.getUserFollowList(userId: userId, as: FavorResponse.self) + switch response { + case .error(let code, let message): + print("index load data get error_code: \(code), message: \(message)") + case .result(let result): + await MainActor.run { + self.dramas = result.dramas + } + } + } +} diff --git a/dimensionhub/Views/FollowList/FollowListView.swift b/dimensionhub/Views/FollowList/FollowListView.swift new file mode 100644 index 0000000..ce054d8 --- /dev/null +++ b/dimensionhub/Views/FollowList/FollowListView.swift @@ -0,0 +1,144 @@ +// +// FavorView.swift +// dimensionhub +// +// Created by 安礼成 on 2025/3/18. +// + +import Foundation +import SwiftUI + +struct FollowListView: View { + @AppStorage("userId") private var userId: String = Utils.defaultUserId() + @State var followModel = FollowListModel() + @State var isMoreLoading: Bool = false + + var body: some View { + VStack(alignment: .center) { + Rectangle() + .frame(height: 0) + .background(Color(hex: "#F2F2F2"), ignoresSafeAreaEdges: .top) + .border(.red) + + Group { + if followModel.dramas.count > 0 { + ScrollView(.vertical, showsIndicators: false) { + LazyVStack(alignment: .center) { + ForEach(followModel.dramas, id: \.id) { drama in + DramaCellView(dramaItem: drama) + } + } + } + } else { + VStack { + Spacer() + Text("这里什么都没有") + .font(.system(size: 16)) + .foregroundColor(.black) + Spacer() + } + } + } + .frame(width: 370) + } + .ignoresSafeArea(edges: .bottom) + .navigationTitle("番剧补完计划") + .task { + await self.followModel.loadData(userId: self.userId) + } + } + +} + +extension FollowListView { + + // 显示剧集的列表信息 + struct DramaCellView: View { + let dramaItem: FollowListModel.DramaItem + + var body: some View { + VStack(alignment: .leading) { + + NavigationLink(destination: DetailView(id: dramaItem.id)) { + Text(dramaItem.title) + .font(.system(size: 20)) + .foregroundColor(Color(hex: "#333333")) + .lineLimit(1) + } + + ScrollView(.horizontal, showsIndicators: false) { + LazyHStack(alignment: .center, spacing: 5) { + ForEach(dramaItem.episodes) { item in + DramaCellEpisodeView(item: item) + } + } + } + } + } + } + + struct DramaCellEpisodeView: View { + let item: FollowListModel.DramaItem.Episode + + var body: some View { + VStack(alignment: .center) { + GeometryReader { geometry in + + AsyncImage(url: URL(string: item.thumb)) { phase in + switch phase { + case .empty: + ProgressView() + case .success(let image): + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: geometry.frame(in: .local).width, height: 80) + .clipped() + default: + Image("ph_img_medium") + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: geometry.frame(in: .local).width, height: 80) + .clipped() + } + } + .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) + .font(.system(size: 12)) + .foregroundColor(Color(hex: "#333333")) + .lineLimit(1) + } + .frame(width: 120, height: 100) + .onTapGesture { + if let playUrl = URL(string: item.play) { + UIApplication.shared.open(playUrl) + } + } + } + } + +} + +#Preview { + FollowListView() +} diff --git a/dimensionhub/Views/FollowListView.swift b/dimensionhub/Views/FollowListView.swift deleted file mode 100644 index bf13cc4..0000000 --- a/dimensionhub/Views/FollowListView.swift +++ /dev/null @@ -1,179 +0,0 @@ -// -// FavorView.swift -// dimensionhub -// -// Created by 安礼成 on 2025/3/18. -// - -import Foundation -import SwiftUI -import Observation - -@Observable -final class FollowListModel { - - struct DramaItem: Codable { - struct Episode: Codable, Identifiable { - let id = UUID().uuidString - let name: String - let thumb: String - let num_name: String - let play: String - - enum CodingKeys: String, CodingKey { - case name, thumb, num_name, play - } - } - - let id: Int - let title: String - let episodes: [Episode] - } - - struct FavorResponse: Codable { - let dramas: [DramaItem] - } - - var dramas: [DramaItem] - - init() { - self.dramas = [] - } - - func loadData(userId: String) async { - let response = await API.getUserFollowList(userId: userId, as: FavorResponse.self) - switch response { - case .error(let code, let message): - print("index load data get error_code: \(code), message: \(message)") - case .result(let result): - await MainActor.run { - self.dramas = result.dramas - } - } - } -} - -struct FollowListView: View { - @AppStorage("userId") private var userId: String = Utils.defaultUserId() - @State var followModel = FollowListModel() - @State var isMoreLoading: Bool = false - - var body: some View { - VStack(alignment: .center) { - Rectangle() - .frame(height: 0) - .background(Color(hex: "#F2F2F2"), ignoresSafeAreaEdges: .top) - .border(.red) - - Group { - if followModel.dramas.count > 0 { - ScrollView(.vertical, showsIndicators: false) { - LazyVStack(alignment: .center) { - ForEach(followModel.dramas, id: \.id) { drama in - DramaCellView(dramaItem: drama) - } - } - } - } else { - VStack { - Spacer() - Text("这里什么都没有") - .font(.system(size: 16)) - .foregroundColor(.black) - Spacer() - } - } - } - .frame(width: 370) - } - .ignoresSafeArea(edges: .bottom) - .navigationTitle("番剧补完计划") - .task { - await self.followModel.loadData(userId: self.userId) - } - } - -} - -extension FollowListView { - // 显示剧集的列表信息 - struct DramaCellView: View { - let dramaItem: FollowListModel.DramaItem - - var body: some View { - VStack(alignment: .leading) { - - NavigationLink(destination: DetailView(id: dramaItem.id)) { - Text(dramaItem.title) - .font(.system(size: 20)) - .foregroundColor(Color(hex: "#333333")) - .lineLimit(1) - } - - ScrollView(.horizontal, showsIndicators: false) { - LazyHStack(alignment: .center, spacing: 5) { - ForEach(dramaItem.episodes) { item in - VStack(alignment: .center) { - GeometryReader { geometry in - - AsyncImage(url: URL(string: item.thumb)) { phase in - switch phase { - case .empty: - ProgressView() - case .success(let image): - image - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: geometry.frame(in: .local).width, height: 80) - .clipped() - default: - Image("ph_img_medium") - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: geometry.frame(in: .local).width, height: 80) - .clipped() - } - } - .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) - .font(.system(size: 12)) - .foregroundColor(Color(hex: "#333333")) - .lineLimit(1) - } - .frame(width: 120, height: 100) - .onTapGesture { - if let playUrl = URL(string: item.play) { - UIApplication.shared.open(playUrl) - } - } - } - } - } - } - } - } -} - -#Preview { - FollowListView() -} diff --git a/dimensionhub/Views/List/ListModel.swift b/dimensionhub/Views/List/ListModel.swift new file mode 100644 index 0000000..857ed4c --- /dev/null +++ b/dimensionhub/Views/List/ListModel.swift @@ -0,0 +1,72 @@ +// +// ListModel.swift +// dimensionhub +// +// Created by 安礼成 on 2025/4/8. +// + +import Foundation +import Observation + +@Observable +final class ListModel { + struct Episode: Codable, Identifiable { + let id = UUID().uuidString + let name: String + let num_name: String + let thumb: String + let play: String + + enum CodingKeys: String, CodingKey { + case name, num_name, thumb, play + } + } + + // 渠道 + struct Channel: Codable { + let name: String + let episodes: [Episode] + } + + struct DramaDetailResponse: Codable { + let name: String + let summary: String + let thumb: String + let status: [String] + let channels: [Channel] + } + + var name: String = "" + var summary: String = "" + var thumb: String = "" + var channels: [Channel] = [] + + // 当前选中的channel + var selectedChannelIdx: Int = 0 + var selectedEpisodes: [Episode] = [] + + func loadData(userId: String, id: Int) async { + let response = await API.getDramaDetail(userId: userId, id: id, as: DramaDetailResponse.self) + switch response { + case .error(let code, let message): + print(code) + print(message) + case .result(let detail): + await MainActor.run { + self.name = detail.name + self.summary = Utils.converHtmlToString(html: detail.summary) ?? "" + self.thumb = detail.thumb + self.channels = detail.channels + + self.selectedChannelIdx = 0 + self.selectedEpisodes = detail.channels[0].episodes + } + } + } + + func toggleChannel(channelIdx: Int) { + self.selectedChannelIdx = channelIdx + self.selectedEpisodes = self.channels[channelIdx].episodes + } + +} diff --git a/dimensionhub/Views/ListView.swift b/dimensionhub/Views/List/ListView.swift similarity index 57% rename from dimensionhub/Views/ListView.swift rename to dimensionhub/Views/List/ListView.swift index 387b871..f57a8d1 100644 --- a/dimensionhub/Views/ListView.swift +++ b/dimensionhub/Views/List/ListView.swift @@ -5,77 +5,11 @@ // Created by 安礼成 on 2025/2/21. // import SwiftUI -import Observation - -@Observable -final class ListModel { - - struct Episode: Codable, Identifiable { - let id = UUID().uuidString - let name: String - let num_name: String - let thumb: String - let play: String - - enum CodingKeys: String, CodingKey { - case name, num_name, thumb, play - } - } - - // 渠道 - struct Channel: Codable { - let name: String - let episodes: [Episode] - } - - struct DramaDetailResponse: Codable { - let name: String - let summary: String - let thumb: String - let status: [String] - let channels: [Channel] - } - - var name: String = "" - var summary: String = "" - var thumb: String = "" - var channels: [Channel] = [] - - // 当前选中的channel - var selectedChannelIdx: Int = 0 - var selectedEpisodes: [Episode] = [] - - func loadData(userId: String, id: Int) async { - let response = await API.getDramaDetail(userId: userId, id: id, as: DramaDetailResponse.self) - switch response { - case .error(let code, let message): - print(code) - print(message) - case .result(let detail): - await MainActor.run { - self.name = detail.name - self.summary = Utils.converHtmlToString(html: detail.summary) ?? "" - self.thumb = detail.thumb - self.channels = detail.channels - - self.selectedChannelIdx = 0 - self.selectedEpisodes = detail.channels[0].episodes - } - } - } - - func toggleChannel(channelIdx: Int) { - self.selectedChannelIdx = channelIdx - self.selectedEpisodes = self.channels[channelIdx].episodes - } - -} struct ListView: View { - @Environment(\.presentationMode) var presentationMode @AppStorage("userId") private var userId: String = Utils.defaultUserId() - @State var detailModel = ListModel() + let id: Int var body: some View { @@ -86,7 +20,7 @@ struct ListView: View { .padding([.leading, .top, .bottom], 10) .background(Color(hex: "#F2F2F2"), ignoresSafeAreaEdges: [.top]) - VStack { + VStack(alignment: .center) { // 渠道列表 HStack(alignment: .center, spacing: 15) { ForEach(Array(detailModel.channels.enumerated()), id: \.offset) { idx, channel in @@ -109,22 +43,6 @@ struct ListView: View { } } -// HStack(alignment: .center) { -// Button { -// self.presentationMode.wrappedValue.dismiss() -// } label: { -// Rectangle() -// .frame(width: 200, height: 25) -// .foregroundColor(Color(hex: "#F2F2F2")) -// .overlay { -// Text("收起剧集") -// .font(.system(size: 13)) -// .foregroundColor(Color(hex: "#999999")) -// } -// } -// -// } - Spacer() } .frame(width: 370, alignment: .center)