Files
Reflect/Shared/views/ContentView.swift
Trey t 0109aee8f8 switch db between debug and release
on widgets if its before the voting time show yesterdays vote, if after either show no vote or current vote

user shared user defaults
2022-01-28 10:27:33 -06:00

275 lines
9.9 KiB
Swift

//
// ContentView.swift
// Shared
//
// Created by Trey Tartt on 1/5/22.
//
import SwiftUI
import CoreData
import Charts
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@AppStorage(UserDefaultsStore.Keys.needsOnboarding.rawValue, store: GroupUserDefaults.groupDefaults) private var needsOnboarding = true
@State private var showingSheet = false
@State private var showTodayInput = true
@State private var selectedEntry: MoodEntry?
@State private var showUpdateEntryAlert = false
@ObservedObject var viewModel = ContentModeViewModel()
init(){
UITabBar.appearance().backgroundColor = UIColor.systemBackground
}
var body: some View {
TabView {
mainView
.tabItem {
Label(String(localized: "content_view_tab_main"), systemImage: "list.dash")
}
FilterView()
.tabItem {
Label(String(localized: "content_view_tab_filter"), systemImage: "calendar.circle")
}
GraphView()
.tabItem {
Label(String(localized: "content_view_tab_stats"), systemImage: "chart.line.uptrend.xyaxis")
}
}.sheet(isPresented: $needsOnboarding, onDismiss: {
}, content: {
OnboardingMain(onboardingData: viewModel.savedOnboardingData,
updateBoardingDataClosure: { onboardingData in
needsOnboarding = false
viewModel.updateOnboardingData(onboardingData: onboardingData)
})
}).alert(String(localized: "content_view_fill_in_missing_entry"), isPresented: $showUpdateEntryAlert) {
ForEach(Mood.allValues) { mood in
Button(mood.strValue, action: {
if let selectedMissingEntry = selectedEntry {
viewModel.update(entry: selectedMissingEntry, toMood: mood)
}
showUpdateEntryAlert = false
})
}
Button(String(localized: "content_view_fill_in_missing_entry_cancel"), role: .cancel, action: {
selectedEntry = nil
showUpdateEntryAlert = false
})
}
}
private var settingsButtonView: some View {
HStack {
Spacer()
Button(action: {
showingSheet.toggle()
}, label: {
Image(systemName: "gear")
.foregroundColor(Color(UIColor.darkGray))
.font(.system(size: 20))
}).sheet(isPresented: $showingSheet) {
SettingsView(editedDataClosure: {
withAnimation{
viewModel.updateData()
}
}, updateBoardingDataClosure: { onboardingData in
viewModel.updateOnboardingData(onboardingData: onboardingData)
})
}.padding(.trailing)
}
}
private func weekdayName(fromDate date: Date) -> String {
let weekday = Calendar.current.component(.weekday, from: date)
let calendar = Calendar.current
let dayIndex = ((weekday - 1) + (calendar.firstWeekday - 1)) % 7
return calendar.weekdaySymbols[dayIndex]
}
private func monthName(fromMonthInt: Int) -> String {
let monthName = DateFormatter().monthSymbols[fromMonthInt-1]
return monthName
}
private func dayFormat(fromDate date: Date) -> String {
let components = Calendar.current.dateComponents([.day], from: date)
let day = components.day!
let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
return formatter.string(from: NSNumber(integerLiteral: day)) ?? ""
}
private var listView: some View {
VStack {
List {
// for reach year
ForEach(viewModel.grouped.sorted(by: {
$0.key > $1.key
}), id: \.key) { year, months in
// for reach month
ForEach(months.sorted(by: {
$0.key > $1.key
}), id: \.key) { month, entries in
Section(header:
HStack{
Text(monthName(fromMonthInt: month))
.font(.title2)
.foregroundColor(Color(UIColor.label))
Text(String(year))
.font(.title2)
.foregroundColor(Color(UIColor.label))
}) {
// for reach all entries
ForEach(entries.sorted(by: {
return $0.forDate! > $1.forDate!
}), id: \.self) { entry in
entryListView(entry: entry)
.onTapGesture(perform: {
selectedEntry = entry
showUpdateEntryAlert = true
})
}.onDelete(perform: { offsets in
withAnimation {
viewModel.delete(offsets: offsets, inMonth: month, inYear: year)
}
})
}
}
}
}
.background(Color.clear.ignoresSafeArea())
.onAppear {
// Set the default to clear
UITableView.appearance().backgroundColor = .clear
}
}
}
private func entryListView(entry: MoodEntry) -> some View {
HStack {
entry.mood.icon
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40, alignment: .center)
.foregroundColor(entry.mood.color)
VStack {
HStack {
Text(weekdayName(fromDate:entry.forDate!))
.font(.title3)
.foregroundColor(Color(UIColor.label))
Text(" - ")
.padding([.leading, .trailing], -10)
Text(dayFormat(fromDate:entry.forDate!))
.font(.title3)
.foregroundColor(Color(UIColor.label))
Spacer()
}
.multilineTextAlignment(.leading)
Text("\(entry.moodString)")
.font(.body)
.foregroundColor(Color(UIColor.systemGray))
.frame(maxWidth: .infinity, alignment: .leading)
}
}
}
private var headerView: some View {
VStack {
if viewModel.shouldShowVotingHeader() {
AddMoodHeaderView(addItemHeaderClosure: { (mood, date) in
withAnimation {
viewModel.add(mood: mood, forDate: date)
}
})
.frame(height: 180)
.frame(minWidth: 0, maxWidth: .infinity)
} else {
HeaderStatsView(fakeData: false, backDays: 30)
.frame(height: 180)
// should match backDays above
Text(String(format: String(localized: "content_view_header_title"), 30))
.font(.body)
.foregroundColor(Color(UIColor.systemGray))
.frame(maxWidth: .infinity, alignment: .center)
}
}
}
private var emptyView: some View {
ZStack {
Color(UIColor.systemBackground)
VStack {
Text(String(localized: "content_view_empty_title"))
.font(.title)
.foregroundColor(Color(UIColor.label))
.padding()
Text(String(localized: "content_view_empty_title"))
.font(.body)
.foregroundColor(Color(UIColor.label))
.padding()
AddMoodHeaderView(addItemHeaderClosure: { (mood, date) in
withAnimation {
viewModel.add(mood: mood, forDate: date)
}
}, overrideDay: viewModel.shouldShowVotingHeader() ? .Today : .Previous)
}
}
.fixedSize(horizontal: false, vertical: true)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
.padding()
}
private var mainView: some View {
ZStack {
BGView().equatable()
VStack{
settingsButtonView
.padding(.top, 50)
if viewModel.hasNoData {
Spacer()
emptyView
Spacer()
} else {
headerView
listView
}
}
.padding(.bottom)
}
}
}
private let itemFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .medium
return formatter
}()
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environment(\.managedObjectContext, PersistenceController.shared.viewContext)
.onAppear(perform: {
PersistenceController.shared.populateMemory()
})
ContentView()
.preferredColorScheme(.dark)
.environment(\.managedObjectContext, PersistenceController.shared.viewContext)
}
}