add ability to rate a missing day
made bgview equatable so it doesn't get redrawn each time a sheet is shown add more string to localization fill in missing data on launch ... incase they have bgfetch turned off
This commit is contained in:
@@ -17,7 +17,7 @@ struct FeelsApp: App {
|
|||||||
let persistenceController = PersistenceController.shared
|
let persistenceController = PersistenceController.shared
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// persistenceController.fillInMissingDates()
|
persistenceController.fillInMissingDates()
|
||||||
BGTaskScheduler.shared.cancelAllTaskRequests()
|
BGTaskScheduler.shared.cancelAllTaskRequests()
|
||||||
BGTaskScheduler.shared.register(forTaskWithIdentifier: BGTask.updateDBMissingID, using: nil) { (task) in
|
BGTaskScheduler.shared.register(forTaskWithIdentifier: BGTask.updateDBMissingID, using: nil) { (task) in
|
||||||
BGTask.runFillInMissingDatesTask(task: task as! BGProcessingTask)
|
BGTask.runFillInMissingDatesTask(task: task as! BGProcessingTask)
|
||||||
|
|||||||
@@ -63,6 +63,36 @@ class ContentModeViewModel: ObservableObject {
|
|||||||
getGroupedData()
|
getGroupedData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func update(entry: MoodEntry, toMood mood: Mood) {
|
||||||
|
let forDate = entry.forDate!
|
||||||
|
|
||||||
|
if let entry = PersistenceController.shared.getEntry(byDate: entry.forDate!) {
|
||||||
|
PersistenceController.shared.viewContext.delete(entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
try PersistenceController.shared.viewContext.save()
|
||||||
|
getGroupedData()
|
||||||
|
} catch {
|
||||||
|
// Replace this implementation with code to handle the error appropriately.
|
||||||
|
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||||||
|
let nsError = error as NSError
|
||||||
|
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
|
||||||
|
}
|
||||||
|
|
||||||
|
PersistenceController.shared.add(mood: mood, forDate: forDate)
|
||||||
|
|
||||||
|
do {
|
||||||
|
try PersistenceController.shared.viewContext.save()
|
||||||
|
getGroupedData()
|
||||||
|
} catch {
|
||||||
|
// Replace this implementation with code to handle the error appropriately.
|
||||||
|
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||||||
|
let nsError = error as NSError
|
||||||
|
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func delete(offsets: IndexSet, inMonth month: Int, inYear year: Int) {
|
public func delete(offsets: IndexSet, inMonth month: Int, inYear year: Int) {
|
||||||
if let monthEntries = grouped[year],
|
if let monthEntries = grouped[year],
|
||||||
let entries = monthEntries[month] {
|
let entries = monthEntries[month] {
|
||||||
|
|||||||
@@ -29,6 +29,17 @@ class PersistenceController {
|
|||||||
return PersistenceController.shared.container.viewContext
|
return PersistenceController.shared.container.viewContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func getEntry(byDate date: Date) -> MoodEntry? {
|
||||||
|
let predicate = NSPredicate(format: "forDate == %@",
|
||||||
|
date as NSDate)
|
||||||
|
|
||||||
|
let fetchRequest = NSFetchRequest<MoodEntry>(entityName: "MoodEntry")
|
||||||
|
fetchRequest.predicate = predicate
|
||||||
|
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "forDate", ascending: true)]
|
||||||
|
let data = try! viewContext.fetch(fetchRequest)
|
||||||
|
return data.first
|
||||||
|
}
|
||||||
|
|
||||||
public func add(mood: Mood, forDate date: Date) {
|
public func add(mood: Mood, forDate date: Date) {
|
||||||
let newItem = MoodEntry(context: viewContext)
|
let newItem = MoodEntry(context: viewContext)
|
||||||
newItem.timestamp = Date()
|
newItem.timestamp = Date()
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ struct BGViewItem: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BGView: View {
|
struct BGView: View, Equatable {
|
||||||
var numAcross: Int
|
var numAcross: Int
|
||||||
var numDown: Int
|
var numDown: Int
|
||||||
let iconSize = 35
|
let iconSize = 35
|
||||||
@@ -61,6 +61,10 @@ struct BGView: View {
|
|||||||
}
|
}
|
||||||
.padding(.top, -50)
|
.padding(.top, -50)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func == (lhs: BGView, rhs: BGView) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BGView_Previews: PreviewProvider {
|
struct BGView_Previews: PreviewProvider {
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ struct ContentView: View {
|
|||||||
|
|
||||||
@State private var showingSheet = false
|
@State private var showingSheet = false
|
||||||
@State private var showTodayInput = true
|
@State private var showTodayInput = true
|
||||||
|
@State private var selectedMissingEntry: MoodEntry?
|
||||||
|
@State private var showMissingAlert = false
|
||||||
|
|
||||||
@ObservedObject var viewModel = ContentModeViewModel()
|
@ObservedObject var viewModel = ContentModeViewModel()
|
||||||
|
|
||||||
@@ -46,8 +48,21 @@ struct ContentView: View {
|
|||||||
needsOnboarding = false
|
needsOnboarding = false
|
||||||
viewModel.updateOnboardingData(onboardingData: onboardingData)
|
viewModel.updateOnboardingData(onboardingData: onboardingData)
|
||||||
})
|
})
|
||||||
|
}).alert(String(localized: "content_view_fill_in_missing_entry"), isPresented: $showMissingAlert) {
|
||||||
|
ForEach(Mood.allValues) { mood in
|
||||||
|
Button(mood.strValue, action: {
|
||||||
|
if let selectedMissingEntry = selectedMissingEntry {
|
||||||
|
viewModel.update(entry: selectedMissingEntry, toMood: mood)
|
||||||
|
}
|
||||||
|
showMissingAlert = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Button(String(localized: "content_view_fill_in_missing_entry_cancel"), role: .cancel, action: {
|
||||||
|
selectedMissingEntry = nil
|
||||||
|
showMissingAlert = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var settingsButtonView: some View {
|
private var settingsButtonView: some View {
|
||||||
HStack {
|
HStack {
|
||||||
@@ -114,9 +129,15 @@ struct ContentView: View {
|
|||||||
}) {
|
}) {
|
||||||
// for reach all entries
|
// for reach all entries
|
||||||
ForEach(entries.sorted(by: {
|
ForEach(entries.sorted(by: {
|
||||||
$0.forDate! > $1.forDate!
|
return $0.forDate! > $1.forDate!
|
||||||
}), id: \.self) { entry in
|
}), id: \.self) { entry in
|
||||||
entryListView(entry: entry)
|
entryListView(entry: entry)
|
||||||
|
.onTapGesture(perform: {
|
||||||
|
if entry.moodValue == Mood.missing.rawValue {
|
||||||
|
selectedMissingEntry = entry
|
||||||
|
showMissingAlert = true
|
||||||
|
}
|
||||||
|
})
|
||||||
}.onDelete(perform: { offsets in
|
}.onDelete(perform: { offsets in
|
||||||
withAnimation {
|
withAnimation {
|
||||||
viewModel.delete(offsets: offsets, inMonth: month, inYear: year)
|
viewModel.delete(offsets: offsets, inMonth: month, inYear: year)
|
||||||
@@ -167,7 +188,9 @@ struct ContentView: View {
|
|||||||
|
|
||||||
private var mainView: some View {
|
private var mainView: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
BGView()
|
|
||||||
|
BGView().equatable()
|
||||||
|
|
||||||
VStack{
|
VStack{
|
||||||
settingsButtonView
|
settingsButtonView
|
||||||
if viewModel.shouldShowVotingHeader() {
|
if viewModel.shouldShowVotingHeader() {
|
||||||
@@ -182,7 +205,7 @@ struct ContentView: View {
|
|||||||
HeaderStatsView(fakeData: false, backDays: 30)
|
HeaderStatsView(fakeData: false, backDays: 30)
|
||||||
.frame(height: 180)
|
.frame(height: 180)
|
||||||
// should match backDays above
|
// should match backDays above
|
||||||
Text("Past \(30) days")
|
Text(String(format: String(localized: "content_view_header_title"), 30))
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.foregroundColor(Color(UIColor.systemGray))
|
.foregroundColor(Color(UIColor.systemGray))
|
||||||
.frame(maxWidth: .infinity, alignment: .center)
|
.frame(maxWidth: .infinity, alignment: .center)
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
"content_view_tab_main" = "Main";
|
"content_view_tab_main" = "Main";
|
||||||
"content_view_tab_filter" = "Filter";
|
"content_view_tab_filter" = "Filter";
|
||||||
"content_view_tab_stats" = "Stats";
|
"content_view_tab_stats" = "Stats";
|
||||||
|
"content_view_fill_in_missing_entry" = "Fill in missing entry";
|
||||||
|
"content_view_fill_in_missing_entry_cancel" = "Cancel";
|
||||||
|
"content_view_header_title" = "Past %d days";
|
||||||
|
|
||||||
"filter_view_total" = "Total";
|
"filter_view_total" = "Total";
|
||||||
"filter_view_show_filters" = "Show Filters";
|
"filter_view_show_filters" = "Show Filters";
|
||||||
|
|||||||
Reference in New Issue
Block a user