diff --git a/Shared/views/ContentView.swift b/Shared/views/ContentView.swift index 7585e42..7f3fddd 100644 --- a/Shared/views/ContentView.swift +++ b/Shared/views/ContentView.swift @@ -27,6 +27,14 @@ struct ContentView: View { @State private var showUpdateEntryAlert = false @State private var headerHeight: CGFloat = ContentViewConstants.maxHeaderHeight + @State private var switchableViewSelectedIndex = 1 + @State private var headerViewType: MainSwitchableViewType = .total + + @State private var currentSelectedHeaderViewViewType: MainSwitchableViewType = .total + @State private var currentSelectedHeaderViewBackDays: Int = 30 + @State private var firstSwichableHeaderViewType: MainSwitchableViewType = .total + @State private var secondSwichableHeaderViewType: MainSwitchableViewType = .total + let minHeaderHeight = ContentViewConstants.minHeaderHeight let maxHeaderHeight = ContentViewConstants.maxHeaderHeight @State private var headerOpacity: Double = 1.0 @@ -287,19 +295,38 @@ struct ContentView: View { .frame(minWidth: 0, maxWidth: .infinity) } else { // selection hre doesn't work ... - TabView { - SwitchableView(daysBack: 30) + TabView(selection: $switchableViewSelectedIndex) { + SwitchableView(daysBack: 30, headerTypeChanged: { viewType in + firstSwichableHeaderViewType = viewType + currentSelectedHeaderViewViewType = firstSwichableHeaderViewType + }) + .tag(1) .frame(height: headerHeight) .frame(minWidth: 0, maxWidth: .infinity) .contentShape(Rectangle()) - SwitchableView(daysBack: 7) + SwitchableView(daysBack: 7, headerTypeChanged: { viewType in + secondSwichableHeaderViewType = viewType + currentSelectedHeaderViewViewType = secondSwichableHeaderViewType + }) + .tag(2) .frame(height: headerHeight) .frame(minWidth: 0, maxWidth: .infinity) .contentShape(Rectangle()) } .tabViewStyle(.page) .padding([.trailing, .leading]) + .onChange(of: switchableViewSelectedIndex) { value in + if value == 1 { + currentSelectedHeaderViewBackDays = 30 + currentSelectedHeaderViewViewType = firstSwichableHeaderViewType + } + + if value == 2 { + currentSelectedHeaderViewBackDays = 7 + currentSelectedHeaderViewViewType = secondSwichableHeaderViewType + } + } } } } @@ -346,7 +373,9 @@ struct ContentView: View { .opacity(headerOpacity) VStack { - SmallRollUpHeaderView(fakeData: false, backDays: 30, type: .circular) + SmallRollUpHeaderView(fakeData: false, + backDays: $currentSelectedHeaderViewBackDays, + viewType: $currentSelectedHeaderViewViewType) .background( Color(theme.currentTheme.secondaryBGColor) ) diff --git a/Shared/views/HeaderPercView.swift b/Shared/views/HeaderPercView.swift index c77b195..e5f4493 100644 --- a/Shared/views/HeaderPercView.swift +++ b/Shared/views/HeaderPercView.swift @@ -40,12 +40,8 @@ struct HeaderPercView: View { let moodEntries = moodEntries.filter({ Int($0.moodValue) == mood.rawValue }) - let total = moodEntries.count - let perc = (Float(total) / Float(totalEntryCount)) * 100 - - entries.append((mood, total, perc)) } } diff --git a/Shared/views/SmallRollUpHeaderView.swift b/Shared/views/SmallRollUpHeaderView.swift index 32593ad..5b3dbc7 100644 --- a/Shared/views/SmallRollUpHeaderView.swift +++ b/Shared/views/SmallRollUpHeaderView.swift @@ -7,34 +7,40 @@ import SwiftUI -enum SmallRollUpHeaderViewType { - case text - case circular -} - struct SmallRollUpHeaderView: View { - var entries = [(Mood, Int)]() - let backDays: Int - let type: SmallRollUpHeaderViewType + @Binding var viewType: MainSwitchableViewType + @Binding var backDays: Int - init(fakeData: Bool, backDays: Int, type: SmallRollUpHeaderViewType) { - self.type = type - self.backDays = backDays + typealias Model = (mood: Mood, total: Int, percent: Float) + private var entries = [Model]() + + init(fakeData: Bool, backDays: Binding, viewType: Binding) { + self._viewType = viewType + + self._backDays = backDays + var moodEntries: [MoodEntry]? if fakeData { moodEntries = PersistenceController.shared.randomEntries(count: 10) } else { - var daysAgo = Calendar.current.date(byAdding: .day, value: -backDays, to: Date())! + var daysAgo = Calendar.current.date(byAdding: .day, value: -self.backDays, to: Date())! daysAgo = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: daysAgo)! moodEntries = PersistenceController.shared.getData(startDate: daysAgo, endDate: Date(), includedDays: [1,2,3,4,5,6,7]) } + + let totalEntryCount = moodEntries?.count ?? 0 + if let moodEntries = moodEntries { for (_, mood) in Mood.allValues.enumerated() { - entries.append((mood, moodEntries.filter({ + + let moodEntries = moodEntries.filter({ Int($0.moodValue) == mood.rawValue - }).count)) + }) + let total = moodEntries.count + let perc = (Float(total) / Float(totalEntryCount)) * 100 + entries.append((mood, total, perc)) } } @@ -43,13 +49,24 @@ struct SmallRollUpHeaderView: View { }) } + private func textView(forModel model: Model) -> Text { + switch viewType { + case .total: + return Text(String(model.total)) + case .percentageCircle: + return Text("\(model.percent, specifier: "%.0f")%") + case .percentage: + return Text("\(model.percent, specifier: "%.0f")%") + } + } + private var textViews: some View { HStack { - ForEach(entries, id: \.0) { (mood, value) in - Text(String(value)) + ForEach(entries, id: \.0) { model in + textView(forModel: model) .font(.title) .fontWeight(.bold) - .foregroundColor(mood.color) + .foregroundColor(model.mood.color) .frame(maxWidth: .infinity) } } @@ -57,12 +74,12 @@ struct SmallRollUpHeaderView: View { private var circularViews: some View { HStack { - ForEach(entries, id: \.0) { (mood, value) in + ForEach(entries, id: \.0) { model in ZStack { - Circle().fill(mood.color) + Circle().fill(model.mood.color) .frame(width: 50, height: 50) - Text(String(value)) + textView(forModel: model) .font(.title) .fontWeight(.bold) .frame(maxWidth: 50) @@ -78,14 +95,8 @@ struct SmallRollUpHeaderView: View { var body: some View { VStack { - switch self.type { - case .text: - textViews - .padding([.trailing, .leading, .top]) - case .circular: - circularViews - .padding([.trailing, .leading, .top]) - } + circularViews + .padding([.trailing, .leading, .top]) Text(String(format: String(localized: "content_view_header_title"), self.backDays)) .font(.body) @@ -98,8 +109,8 @@ struct SmallRollUpHeaderView: View { struct SmallHeaderView_Previews: PreviewProvider { static var previews: some View { - SmallRollUpHeaderView(fakeData: true, backDays: 30, type: .text) + SmallRollUpHeaderView(fakeData: true, backDays: .constant(30), viewType: .constant(.total)) - SmallRollUpHeaderView(fakeData: true, backDays: 30, type: .circular) + SmallRollUpHeaderView(fakeData: true, backDays: .constant(7), viewType: .constant(.total)) } } diff --git a/Shared/views/SwitchableView.swift b/Shared/views/SwitchableView.swift index dccf2ee..6347552 100644 --- a/Shared/views/SwitchableView.swift +++ b/Shared/views/SwitchableView.swift @@ -7,30 +7,50 @@ import SwiftUI +enum MainSwitchableViewType: Int, CaseIterable { + case total + case percentageCircle + case percentage + + func next() -> MainSwitchableViewType { + let currentValue = self.rawValue + var next = currentValue + 1 + if next == MainSwitchableViewType.allCases.count { + next = 0 + } + return MainSwitchableViewType(rawValue: next) ?? .total + } +} struct SwitchableView: View { - @State var currentViewIdx = 0 + @State var viewType: MainSwitchableViewType = .total + var headerTypeChanged: ((MainSwitchableViewType) -> Void) + let daysBack: Int + @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system - let daysBack: Int + init(daysBack: Int, headerTypeChanged: @escaping ((MainSwitchableViewType) -> Void)) { + self.daysBack = daysBack + self.headerTypeChanged = headerTypeChanged + } var body: some View { VStack { ZStack { - HeaderStatsView(fakeData: false, backDays: daysBack) - .opacity(currentViewIdx == 0 ? 1 : 0) - .padding([.leading, .trailing], -15) - .padding([.top, .bottom], 8) - .allowsHitTesting(false) - - HeaderPercView(fakeData: false, backDays: daysBack, type: .circular) - .opacity(currentViewIdx == 1 ? 1 : 0) - .allowsHitTesting(false) - - HeaderPercView(fakeData: false, backDays: daysBack, type: .text) - .opacity(currentViewIdx == 2 ? 1 : 0) - .allowsHitTesting(false) - + switch viewType { + case .total: + HeaderStatsView(fakeData: false, backDays: daysBack) + .padding([.leading, .trailing], -15) + .padding([.top, .bottom], 8) + .allowsHitTesting(false) + case .percentageCircle: + HeaderPercView(fakeData: false, backDays: daysBack, type: .circular) + .allowsHitTesting(false) + case .percentage: + HeaderPercView(fakeData: false, backDays: daysBack, type: .text) + .allowsHitTesting(false) + } + VStack { HStack { Spacer() @@ -60,16 +80,15 @@ struct SwitchableView: View { .cornerRadius(10, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]) .padding(.bottom, 30) .onTapGesture { - currentViewIdx += 1 - if currentViewIdx == 3 { - currentViewIdx = 0 - } + viewType = viewType.next() + self.headerTypeChanged(viewType) } } } struct SwitchableView_Previews: PreviewProvider { static var previews: some View { - SwitchableView(daysBack: 30) + SwitchableView(daysBack: 30, headerTypeChanged: { _ in + }) } }