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