This commit is contained in:
anlicheng 2025-02-21 00:04:12 +08:00
parent 6b477486c2
commit 070f928d88
5 changed files with 65 additions and 92 deletions

View File

@ -58,11 +58,13 @@ struct API {
do { do {
let result = try JSONDecoder().decode(APISuccessResponse<T>.self, from: data) let result = try JSONDecoder().decode(APISuccessResponse<T>.self, from: data)
return .result(result.result) return .result(result.result)
} catch { } catch let err {
print(err)
let apiError = try JSONDecoder().decode(APIErrorResponse.self, from: data) let apiError = try JSONDecoder().decode(APIErrorResponse.self, from: data)
return .error(apiError.error.code, apiError.error.message) return .error(apiError.error.code, apiError.error.message)
} }
} catch let err { } catch let err {
print(err)
return .error(-1, err.localizedDescription) return .error(-1, err.localizedDescription)
} }
} }

View File

@ -9,13 +9,13 @@ actor DataCache {
public static let shared = DataCache() public static let shared = DataCache()
private var dateModelCache: [DateModel] = [] private var dateModelCache: [DateNavModel.DateModel] = []
func setDateModelCache(_ models: [DateModel]) { func setDateModelCache(_ models: [DateNavModel.DateModel]) {
self.dateModelCache = models self.dateModelCache = models
} }
func getDateModelCache() -> [DateModel] { func getDateModelCache() -> [DateNavModel.DateModel] {
return self.dateModelCache return self.dateModelCache
} }

View File

@ -9,12 +9,4 @@
// //
struct DateModel: Codable {
struct Month: Codable {
let name: String
let disabled: Bool
}
let year: String
let months: [Month]
}

View File

@ -10,23 +10,22 @@ import SwiftUI
import Observation import Observation
struct DateNavView: View { struct DateNavView: View {
@AppStorage("selectedDate") var selectedDate: String = "" @State var navModel = DateNavModel()
@State var navData = DateNavData(dateCells: []) let selectGroupId: String
@Binding var showDateNavPopover: Bool @Binding var showDateNavPopover: Bool
var body: some View { var body: some View {
//let _ = Self._printChanges()
VStack(alignment: .center) { VStack(alignment: .center) {
ForEach(navData.dateCells, id: \.year) { cell in ForEach(navModel.dateModels, id: \.year) { model in
VStack(alignment: .leading, spacing: 10) { VStack(alignment: .leading, spacing: 10) {
Text(cell.year) Text(model.year)
HStack { HStack {
ForEach(cell.items, id: \.id) { item in ForEach(model.months, id: \.id) { month in
if item.disabled { if month.disabled {
DateDisabledItemView(datetime: item.name) DateDisabledItemView(datetime: month.name)
} else { } else {
DateItemView(id: item.id, datetime: item.name, selected: false, showDateNavPopover: $showDateNavPopover) DateItemView(datetime: month.name, selected: month.id == selectGroupId, showDateNavPopover: $showDateNavPopover)
} }
} }
} }
@ -34,25 +33,7 @@ struct DateNavView: View {
} }
} }
.task { .task {
await self.navData.loadDateCells() await self.navModel.loadDateCells()
}
}
private func getDateModelData() async -> [DateModel] {
let models = await DataCache.shared.getDateModelCache()
if models.count > 0 {
return models
} else {
let response = await API.getDateIndex(as: [DateModel].self)
switch response {
case .error(let code, let message):
print(code)
print(message)
return []
case .result(let models):
await DataCache.shared.setDateModelCache(models)
return models
}
} }
} }
@ -61,7 +42,6 @@ struct DateNavView: View {
extension DateNavView { extension DateNavView {
struct DateItemView: View { struct DateItemView: View {
let id: String
let datetime: String let datetime: String
@State var selected: Bool @State var selected: Bool
@Binding var showDateNavPopover: Bool @Binding var showDateNavPopover: Bool
@ -82,7 +62,6 @@ extension DateNavView {
.onTapGesture { .onTapGesture {
self.selected = true self.selected = true
self.showDateNavPopover = false self.showDateNavPopover = false
UserDefaults.standard.set(id, forKey: "navSelectedDate")
} }
} }
} }
@ -109,40 +88,28 @@ extension DateNavView {
} }
@Observable @Observable
final class DateNavData { final class DateNavModel {
var dateCells: [DateCell] = []
struct DateCell { struct DateModel: Codable {
struct Item: Identifiable { struct Month: Codable {
let id: String let id: String
let name: String let name: String
let disabled: Bool let disabled: Bool
let selected: Bool
} }
let year: String let year: String
let items: [Item] let months: [Month]
} }
init(dateCells: [DateCell]) { var dateModels: [DateModel]
self.dateCells = dateCells
init() {
self.dateModels = []
} }
@MainActor @MainActor
func loadDateCells() async { func loadDateCells() async {
let selectedDate = UserDefaults.standard.value(forKey: "navSelectedDate") as? String ?? "" self.dateModels = await getDateModelData()
let models = await getDateModelData()
var cells: [DateCell] = []
for model in models {
let items = model.months.map { month in
let id = "\(model.year)-\(month.name)"
return DateCell.Item(id: id, name: month.name, disabled: month.disabled, selected: id == selectedDate ? true : false)
}
cells.append(DateCell(year: model.year, items: items))
}
self.dateCells = cells
} }
private func getDateModelData() async -> [DateModel] { private func getDateModelData() async -> [DateModel] {
@ -151,12 +118,14 @@ final class DateNavData {
return models return models
} else { } else {
let response = await API.getDateIndex(as: [DateModel].self) let response = await API.getDateIndex(as: [DateModel].self)
print(response)
switch response { switch response {
case .error(let code, let message): case .error(let code, let message):
print(code) print(code)
print(message) print(message)
return [] return []
case .result(let models): case .result(let models):
print(models)
await DataCache.shared.setDateModelCache(models) await DataCache.shared.setDateModelCache(models)
return models return models
} }

View File

@ -32,26 +32,37 @@ final class IndexModel {
let episodes: [Episode] let episodes: [Episode]
} }
struct UpdateDramaItem: Codable { struct UpdateDramaGroup: Codable {
let id: Int struct Item: Codable {
let name: String let id: Int
let thumb: String let name: String
let desc: String let thumb: String
let datetime: String let desc: String
}
let groupId: String
let groupName: String
let items: [Item]
enum CodingKeys: String, CodingKey {
case groupId = "group_id"
case groupName = "group_name"
case items
}
} }
struct IndexResponse: Codable { struct IndexResponse: Codable {
let updateDramas: [UpdateDramaItem] let updateDramas: [UpdateDramaGroup]
let dramas: [DramaItem] let dramas: [DramaItem]
} }
struct UpdateDramaShowItem: Identifiable { struct UpdateDramaShowItem {
enum Element { enum Element {
case lable(String) case group(UpdateDramaGroup)
case item(UpdateDramaItem) case item(UpdateDramaGroup.Item)
} }
let id = UUID() let id = UUID().uuidString
let element: Element let element: Element
init(element: Element) { init(element: Element) {
@ -75,27 +86,25 @@ final class IndexModel {
print(code) print(code)
print(message) print(message)
case .result(let result): case .result(let result):
print(result)
self.dramas = result.dramas self.dramas = result.dramas
self.showUpdateDramas = groupUpdateDramas(updateDramas: result.updateDramas) self.showUpdateDramas = groupUpdateDramas(updateDramaGroups: result.updateDramas)
} }
} }
@MainActor @MainActor
func loadMoreUpdateDramas() async { func loadMoreUpdateDramas() async {
let response = await API.loadMoreUpdateDramas(as: [UpdateDramaItem].self) let response = await API.loadMoreUpdateDramas(as: [UpdateDramaGroup].self)
if case let .result(items) = response { if case let .result(groups) = response {
let showItems = groupUpdateDramas(updateDramas: items) let showItems = groupUpdateDramas(updateDramaGroups: groups)
self.showUpdateDramas.append(contentsOf: showItems) self.showUpdateDramas.append(contentsOf: showItems)
} }
} }
private func groupUpdateDramas(updateDramas: [UpdateDramaItem]) -> [UpdateDramaShowItem] { private func groupUpdateDramas(updateDramaGroups: [UpdateDramaGroup]) -> [UpdateDramaShowItem] {
let groups = Dictionary(grouping: updateDramas) {$0.datetime}
var updateItems: [UpdateDramaShowItem] = [] var updateItems: [UpdateDramaShowItem] = []
groups.forEach { (key, items) in updateDramaGroups.forEach { group in
updateItems.append(.init(element: .lable(key))) updateItems.append(.init(element: .group(group)))
items.forEach { item in group.items.forEach { item in
updateItems.append(.init(element: .item(item))) updateItems.append(.init(element: .item(item)))
} }
} }
@ -112,6 +121,7 @@ struct IndexView: View {
@State var isLoading: Bool = false @State var isLoading: Bool = false
// //
@State private var selectGroupId: String = ""
@State private var showDateNavPopover: Bool = false @State private var showDateNavPopover: Bool = false
var body: some View { var body: some View {
@ -141,10 +151,11 @@ struct IndexView: View {
LazyVStack { LazyVStack {
ForEach(indexModel.showUpdateDramas, id: \.id) { drama in ForEach(indexModel.showUpdateDramas, id: \.id) { drama in
switch drama.element { switch drama.element {
case .lable(let name): case .group(let group):
Text(name) Text(group.groupName)
.onTapGesture { .onTapGesture {
showDateNavPopover = true showDateNavPopover = true
selectGroupId = group.groupId
} }
case .item(let item): case .item(let item):
VStack(alignment: .center) { VStack(alignment: .center) {
@ -192,7 +203,7 @@ struct IndexView: View {
} }
} }
.popover(isPresented: $showDateNavPopover) { .popover(isPresented: $showDateNavPopover) {
DateNavView(showDateNavPopover: $showDateNavPopover) DateNavView(selectGroupId: self.selectGroupId, showDateNavPopover: $showDateNavPopover)
} }
} }
.task { .task {
@ -256,7 +267,6 @@ extension IndexView {
} }
/*
extension IndexView { extension IndexView {
struct UpdateDramaCellView: View { struct UpdateDramaCellView: View {
@ -265,8 +275,8 @@ extension IndexView {
var body: some View { var body: some View {
switch showItem.element { switch showItem.element {
case .lable(let name): case .group(let group):
Text(name) Text(group.groupName)
.onTapGesture { .onTapGesture {
showDateNavPopover = true showDateNavPopover = true
} }
@ -293,7 +303,7 @@ extension IndexView {
} }
} }
}*/ }
#Preview { #Preview {
IndexView() IndexView()