parent
b8293b3674
commit
19fca143bc
@ -0,0 +1,141 @@ |
||||
// |
||||
// ActivityView.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 20/02/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
import CoreData |
||||
|
||||
struct ActivityStatsView: View { |
||||
|
||||
@Environment(\.managedObjectContext) private var viewContext |
||||
|
||||
let activity: Activity |
||||
var filter: Filter? = nil |
||||
|
||||
@State var subFilters: [Filter] = [] |
||||
|
||||
var body: some View { |
||||
|
||||
List { |
||||
Section { |
||||
StatisticsView(activity: self.activity, filter: self.filter) { statValues in |
||||
ForEach(statValues) { statValue in |
||||
StatView(statValue: statValue) |
||||
} |
||||
}.environment(\.managedObjectContext, viewContext) |
||||
} |
||||
|
||||
// Picker("Time", selection: $selectedTimeFrame) { |
||||
// ForEach(TimeFrame.allCases) { timeFrame in |
||||
// Text(timeFrame.localizedString).tag(timeFrame) |
||||
// } |
||||
// } |
||||
// .pickerStyle(.segmented) |
||||
// .padding(.horizontal) |
||||
|
||||
|
||||
StatisticsSubView(activity: self.activity, subFilters: self.subFilters) |
||||
.environment(\.managedObjectContext, viewContext) |
||||
|
||||
} |
||||
.navigationTitle(self.filter?.localizedString ?? self.activity.name ?? "no name") |
||||
.onAppear { |
||||
self._load() |
||||
} |
||||
|
||||
} |
||||
|
||||
fileprivate func _load() { |
||||
|
||||
do { |
||||
switch self.filter { |
||||
case nil: |
||||
let years = try CoreDataRequests.years(context: self.viewContext, activity: self.activity) |
||||
self.subFilters = years.map { Filter.year($0) } |
||||
case .some(let filter): |
||||
switch filter { |
||||
case .year(let year): |
||||
let months = try CoreDataRequests.months(context: self.viewContext, activity: self.activity, year: year) |
||||
self.subFilters = months.map { Filter.month(Month(month: $0, year: year)) } |
||||
default: |
||||
break |
||||
} |
||||
} |
||||
} catch { |
||||
Logger.error(error) |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
enum TimeFrame: Int, Identifiable, CaseIterable { |
||||
|
||||
var id: Int { return self.rawValue } |
||||
|
||||
// case all |
||||
case year |
||||
case month |
||||
|
||||
var localizedString: String { |
||||
switch self { |
||||
// case .all: return NSLocalizedString("All", comment: "") |
||||
case .year: return NSLocalizedString("Year", comment: "") |
||||
case .month: return NSLocalizedString("Month", comment: "") |
||||
} |
||||
} |
||||
|
||||
func filters(context: NSManagedObjectContext, activity: Activity) -> [Filter] { |
||||
|
||||
let predicate = NSPredicate(format: "activity = %@", activity) |
||||
|
||||
do { |
||||
switch self { |
||||
// case .all: |
||||
// return [.none] |
||||
case .year: |
||||
let distinct = try context.distinct(entityName: "Record", attributes: ["year"], predicate: predicate) |
||||
if let yearsMap = distinct as? [[String : Int]] { |
||||
let years = yearsMap.compactMap { $0.first?.value } |
||||
return years.map { Filter.year($0) } |
||||
} else { |
||||
Logger.w("Could not cast \(distinct) as [Int]") |
||||
} |
||||
case .month: |
||||
|
||||
let monthes = try CoreDataRequests.months(context: context, activity: activity) |
||||
return monthes.map { Filter.month($0) } |
||||
|
||||
// let distinct = try context.distinct(entityName: "Record", attributes: ["year", "month"], predicate: predicate) |
||||
// if let distinctMonths = distinct as? [[String : Int]] { |
||||
// |
||||
// let months = distinctMonths.compactMap { |
||||
// if let month = $0["month"], |
||||
// let year = $0["year"] { |
||||
// return Month(month: month, year: year) |
||||
// } else { |
||||
// Logger.w("issue with dictionary \($0)") |
||||
// return nil |
||||
// } |
||||
// } |
||||
// return months.map { Filter.month($0) } |
||||
// } else { |
||||
// Logger.w("Could not cast \(distinct) as [Int]") |
||||
// } |
||||
} |
||||
} catch { |
||||
Logger.error(error) |
||||
} |
||||
return [] |
||||
} |
||||
|
||||
} |
||||
|
||||
struct ActivityStatsView_Previews: PreviewProvider { |
||||
static var previews: some View { |
||||
ActivityStatsView(activity: Activity.fake(context: PersistenceController.preview.container.viewContext)) |
||||
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) |
||||
} |
||||
} |
||||
@ -0,0 +1,42 @@ |
||||
// |
||||
// StatisticsSubView.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 12/04/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct StatisticsSubView: View { |
||||
|
||||
@Environment(\.managedObjectContext) private var viewContext |
||||
|
||||
let activity: Activity |
||||
var subFilters: [Filter] = [] |
||||
|
||||
var body: some View { |
||||
Section { |
||||
ForEach(self.subFilters) { filter in |
||||
|
||||
NavigationLink { |
||||
ActivityStatsView(activity: self.activity, filter: filter) |
||||
} label: { |
||||
StatisticsView(activity: self.activity, filter: filter) { statValues in |
||||
HStack { |
||||
if let count = statValues.first(where: { $0.stat == .count }) { |
||||
LabeledContent(filter.localizedString, value: count.formattedValue) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
struct StatisticsSubView_Previews: PreviewProvider { |
||||
static var previews: some View { |
||||
StatisticsSubView(activity: ActivityView_Previews.activity) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue