everything changed
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
//
|
||||
// CenterTiledImage.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/13/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct CenterTiledImage: View {
|
||||
let imageName: String
|
||||
let imageSize: CGSize
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geoReader in
|
||||
let horizontalTilesNeeded = ceil(geoReader.size.width / imageSize.width / 2) * 2 + 1
|
||||
let verticalTilesNeeded = ceil(geoReader.size.height / imageSize.height / 2) * 2 + 1
|
||||
|
||||
Image(imageName)
|
||||
.resizable(resizingMode: .tile)
|
||||
.frame(
|
||||
width: horizontalTilesNeeded * imageSize.width,
|
||||
height: verticalTilesNeeded * imageSize.height
|
||||
)
|
||||
.position(x: geoReader.size.width * 0.5, y: geoReader.size.height * 0.5)
|
||||
}
|
||||
}
|
||||
|
||||
init?(imageName: String) {
|
||||
guard let imageSize = UIImage(named: imageName)?.size else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.imageName = imageName
|
||||
self.imageSize = imageSize
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
//
|
||||
// ContentModeViewModel.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/20/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
|
||||
class ContentModeViewModel: ObservableObject {
|
||||
@Published var grouped = [Int: [Int: [MoodEntry]]]()
|
||||
@Published var numberOfItems = 0
|
||||
|
||||
let addMonthStartWeekdayPadding: Bool
|
||||
|
||||
var hasNoData: Bool {
|
||||
grouped.isEmpty
|
||||
}
|
||||
|
||||
private var numberOfEntries: Int {
|
||||
var num = 0
|
||||
grouped.keys.forEach({
|
||||
let year = grouped[$0]
|
||||
let monthKeys = year?.keys
|
||||
monthKeys?.forEach({
|
||||
num += year![$0]!.count
|
||||
})
|
||||
})
|
||||
return num
|
||||
|
||||
// grouped.keys.map{
|
||||
// grouped[$0]!.values.reduce(0) { sum, array in
|
||||
// sum + array.count
|
||||
// }
|
||||
// }.reduce(0, +)
|
||||
}
|
||||
|
||||
init(addMonthStartWeekdayPadding: Bool) {
|
||||
self.addMonthStartWeekdayPadding = addMonthStartWeekdayPadding
|
||||
|
||||
PersistenceController.shared.switchContainerListeners.append {
|
||||
self.getGroupedData(addMonthStartWeekdayPadding: self.addMonthStartWeekdayPadding)
|
||||
|
||||
}
|
||||
updateData()
|
||||
}
|
||||
|
||||
private func getGroupedData(addMonthStartWeekdayPadding: Bool) {
|
||||
grouped = PersistenceController.shared.splitIntoYearMonth()
|
||||
|
||||
if addMonthStartWeekdayPadding {
|
||||
var newGrouped = [Int: [Int: [MoodEntry]]]()
|
||||
|
||||
let allYears = grouped.keys.sorted(by: > )
|
||||
for year in allYears {
|
||||
var newMonth = [Int: [MoodEntry]]()
|
||||
|
||||
let oldMonths = grouped[year]!
|
||||
let monthKeys = oldMonths.keys.sorted(by: > )
|
||||
for key in monthKeys {
|
||||
if let entries = oldMonths[key] {
|
||||
let sortedEntries = entries.sorted(by: { $0.forDate! < $1.forDate! })
|
||||
var mutableEntries = sortedEntries
|
||||
|
||||
if let firstDate = sortedEntries.first {
|
||||
let date = firstDate.forDate!
|
||||
let weekday = Int16(Calendar.current.component(.weekday, from: date))
|
||||
for _ in 1..<weekday {
|
||||
mutableEntries.insert(PersistenceController.shared.generateObjectNotInArray(), at: 0)
|
||||
}
|
||||
}
|
||||
|
||||
newMonth[key] = mutableEntries
|
||||
}
|
||||
newGrouped[year] = newMonth
|
||||
}
|
||||
}
|
||||
grouped = newGrouped
|
||||
}
|
||||
|
||||
numberOfItems = numberOfEntries
|
||||
}
|
||||
|
||||
|
||||
|
||||
public func updateData() {
|
||||
getGroupedData(addMonthStartWeekdayPadding: self.addMonthStartWeekdayPadding)
|
||||
}
|
||||
|
||||
public func add(mood: Mood, forDate date: Date, entryType: EntryType) {
|
||||
PersistenceController.shared.add(mood: mood, forDate: date, entryType: entryType)
|
||||
updateData()
|
||||
}
|
||||
|
||||
public func update(entry: MoodEntry, toMood mood: Mood) {
|
||||
if PersistenceController.shared.update(entryDate: entry.forDate!, withModd: mood) {
|
||||
updateData()
|
||||
}
|
||||
}
|
||||
|
||||
public func delete(offsets: IndexSet, inMonth month: Int, inYear year: Int) {
|
||||
if let monthEntries = grouped[year],
|
||||
let entries = monthEntries[month] {
|
||||
var mutableEntries = entries.sorted(by: {
|
||||
$0.forDate! > $1.forDate!
|
||||
})
|
||||
var entriesToDelete = [MoodEntry]()
|
||||
for idx in offsets {
|
||||
let obj = mutableEntries.remove(at: idx)
|
||||
entriesToDelete.append(obj)
|
||||
}
|
||||
entriesToDelete.forEach({ entry in
|
||||
let entryDate = entry.forDate!
|
||||
PersistenceController.shared.viewContext.delete(entry)
|
||||
self.add(mood: .missing, forDate: entryDate, entryType: .listView)
|
||||
})
|
||||
}
|
||||
|
||||
do {
|
||||
try PersistenceController.shared.viewContext.save()
|
||||
updateData()
|
||||
} 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)")
|
||||
}
|
||||
}
|
||||
|
||||
static func updateTitleHeader(forEntry entry: MoodEntry?) -> String {
|
||||
guard let entry = entry else {
|
||||
return ""
|
||||
}
|
||||
|
||||
guard let forDate = entry.forDate else {
|
||||
return ""
|
||||
}
|
||||
|
||||
let components = Calendar.current.dateComponents([.day, .month, .year], from: forDate)
|
||||
// let day = components.day!
|
||||
let month = components.month!
|
||||
let year = components.year!
|
||||
|
||||
let monthName = Random.monthName(fromMonthInt: month)
|
||||
let weekday = Random.weekdayName(fromDate:entry.forDate!)
|
||||
let dayz = Random.dayFormat(fromDate:entry.forDate!)
|
||||
|
||||
let string = weekday + " " + monthName + " " + dayz + " " + String(year)
|
||||
|
||||
return String(format: String(localized: "content_view_fill_in_missing_entry"), string)
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
//
|
||||
// CustomIcon.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/13/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
class CustomIcon: ObservableObject {
|
||||
static let numberOfBGItems = 99
|
||||
|
||||
static let defaultCustomIcon = CustomIcon(leftEye: EyeOptions.defaultOption,
|
||||
rightEye: EyeOptions.defaultOption,
|
||||
mouth: MouthOptions.defaultOption,
|
||||
background: IconView_Previews.backgrounds,
|
||||
bgColor: .red,
|
||||
innerColor: .green,
|
||||
bgOverlayColor: .orange,
|
||||
rightEyeColor: .orange,
|
||||
leftEyeColor: .yellow,
|
||||
mouthColor: .green,
|
||||
circleStrokeColor: .pink)
|
||||
|
||||
|
||||
init(leftEye: EyeOptions,
|
||||
rightEye: EyeOptions,
|
||||
mouth: MouthOptions,
|
||||
background: [(BackGroundOptions, UUID)],
|
||||
bgColor: Color,
|
||||
innerColor: Color,
|
||||
bgOverlayColor: Color,
|
||||
rightEyeColor: Color,
|
||||
leftEyeColor: Color,
|
||||
mouthColor: Color,
|
||||
circleStrokeColor: Color
|
||||
) {
|
||||
self.leftEye = leftEye
|
||||
self.rightEye = rightEye
|
||||
self.mouth = mouth
|
||||
self.background = background
|
||||
self.bgColor = bgColor
|
||||
self.innerColor = innerColor
|
||||
self.bgOverlayColor = bgOverlayColor
|
||||
self.rightEyeColor = rightEyeColor
|
||||
self.leftEyeColor = leftEyeColor
|
||||
self.mouthColor = mouthColor
|
||||
self.circleStrokeColor = circleStrokeColor
|
||||
}
|
||||
|
||||
@Published var leftEye: EyeOptions
|
||||
@Published var rightEye: EyeOptions
|
||||
@Published var mouth: MouthOptions
|
||||
|
||||
@Published var background: [(BackGroundOptions, UUID)]
|
||||
@Published var bgColor: Color
|
||||
@Published var innerColor: Color
|
||||
@Published var bgOverlayColor: Color
|
||||
|
||||
@Published var leftEyeColor: Color
|
||||
@Published var rightEyeColor: Color
|
||||
@Published var mouthColor: Color
|
||||
|
||||
@Published var circleStrokeColor: Color
|
||||
}
|
||||
|
||||
enum BackGroundOptions: String, CaseIterable, Codable {
|
||||
case horrible
|
||||
case bad
|
||||
case average
|
||||
case good
|
||||
case great
|
||||
case random
|
||||
|
||||
static var selectable: [BackGroundOptions] {
|
||||
return [.great, .good, .average, .bad, .horrible]
|
||||
}
|
||||
|
||||
static public var defaultOption: BackGroundOptions {
|
||||
BackGroundOptions.random
|
||||
}
|
||||
|
||||
public var image: Image {
|
||||
return Image(self.rawValue, bundle: .main)
|
||||
}
|
||||
}
|
||||
|
||||
enum Eyes: String, Codable {
|
||||
case left
|
||||
case right
|
||||
}
|
||||
|
||||
enum EyeOptions: String, CaseIterable, Codable {
|
||||
case fire = "fire"
|
||||
case bolt = "bolt2"
|
||||
case dollar = "dollar"
|
||||
case bell = "bell"
|
||||
case btc = "btc"
|
||||
case code = "code"
|
||||
case crown = "crown"
|
||||
case divide = "divide"
|
||||
case exclamation = "exclamation"
|
||||
case fan = "fan"
|
||||
case floppy = "floppy"
|
||||
case x = "x"
|
||||
case skull = "skull"
|
||||
case covid = "covid"
|
||||
case bomb = "bomb"
|
||||
case skull2 = "skull2"
|
||||
case poo = "poo"
|
||||
|
||||
static public var defaultOption: EyeOptions {
|
||||
EyeOptions.fire
|
||||
}
|
||||
|
||||
public var image: Image {
|
||||
return Image(self.rawValue, bundle: .main)
|
||||
}
|
||||
}
|
||||
|
||||
enum MouthOptions: String, CaseIterable, Codable {
|
||||
case fire = "fire"
|
||||
case bolt = "bolt2"
|
||||
case dollar = "dollar"
|
||||
case bell = "bell"
|
||||
case btc = "btc"
|
||||
case code = "code"
|
||||
case crown = "crown"
|
||||
case divide = "divide"
|
||||
case exclamation = "exclamation"
|
||||
case fan = "fan"
|
||||
case floppy = "floppy"
|
||||
case x = "x"
|
||||
case skull = "skull"
|
||||
case covid = "covid"
|
||||
case bomb = "bomb"
|
||||
case skull2 = "skull2"
|
||||
case poo = "poo"
|
||||
|
||||
static public var defaultOption: MouthOptions {
|
||||
MouthOptions.bomb
|
||||
}
|
||||
|
||||
public var image: Image {
|
||||
return Image(self.rawValue, bundle: .main)
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
//
|
||||
// CircleView.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/13/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct DayChartView: ChartViewItemBuildable, View, Hashable {
|
||||
var color: Color
|
||||
var weekDay: Int
|
||||
var viewType: ViewType
|
||||
|
||||
var body: some View {
|
||||
switch viewType {
|
||||
case .cicle:
|
||||
Circle()
|
||||
.fill(color)
|
||||
.frame(minWidth: 5, idealWidth: 50, maxWidth: 50, minHeight: 5, idealHeight: 20, maxHeight: 50, alignment: .center)
|
||||
.opacity(color == Mood.missing.color ? 0.5 : 1.0)
|
||||
case .square:
|
||||
Rectangle()
|
||||
.fill(color)
|
||||
.frame(minWidth: 5, idealWidth: 50, maxWidth: 50, minHeight: 5, idealHeight: 20, maxHeight: 50, alignment: .center)
|
||||
case .text(let value):
|
||||
Text(value)
|
||||
.font(.footnote)
|
||||
.frame(minWidth: 5, idealWidth: 50, maxWidth: 50, minHeight: 5, idealHeight: 20, maxHeight: 50, alignment: .center)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
//
|
||||
// FilterViewModel.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 1/17/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class FilterViewModel: ObservableObject {
|
||||
@Published public var entryStartDate: Date = Date()
|
||||
@Published public var entryEndDate: Date = Date()
|
||||
@Published var selectedDays = [Int]()
|
||||
|
||||
// year, month, items
|
||||
@Published public private(set) var data = [Int: [Int: [DayChartView]]]()
|
||||
@Published public private(set) var numberOfRatings: Int = 0
|
||||
public private(set) var uncategorizedData = [MoodEntry]() {
|
||||
didSet {
|
||||
self.numberOfRatings = uncategorizedData.count
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
let filteredEntries = PersistenceController.shared.getData(startDate: Date(timeIntervalSince1970: 0),
|
||||
endDate: Date(),
|
||||
includedDays: selectedDays)
|
||||
|
||||
if let fuckingDAte = filteredEntries.sorted(by: { $0.forDate! < $1.forDate! }).first?.forDate {
|
||||
self.entryStartDate = fuckingDAte
|
||||
}
|
||||
self.entryEndDate = Date()
|
||||
}
|
||||
|
||||
private let chartViewBuilder = DayChartViewChartBuilder()
|
||||
|
||||
public func filterEntries(startDate: Date, endDate: Date) {
|
||||
let filteredEntries = PersistenceController.shared.getData(startDate: startDate,
|
||||
endDate: endDate,
|
||||
includedDays: selectedDays)
|
||||
data.removeAll()
|
||||
let filledOutData = chartViewBuilder.buildGridData(withData: filteredEntries)
|
||||
data = filledOutData
|
||||
uncategorizedData = filteredEntries
|
||||
}
|
||||
}
|
||||
@@ -37,22 +37,8 @@ enum Mood: Int {
|
||||
}
|
||||
|
||||
var color: Color {
|
||||
switch self {
|
||||
case .horrible:
|
||||
return .red
|
||||
case .bad:
|
||||
return .orange
|
||||
case .average:
|
||||
return .blue
|
||||
case .good:
|
||||
return .yellow
|
||||
case .great:
|
||||
return .green
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .placeholder:
|
||||
return .clear
|
||||
}
|
||||
let moodTint: MoodTintable.Type = UserDefaultsStore.moodTintable()
|
||||
return moodTint.color(forMood: self)
|
||||
}
|
||||
|
||||
static var allValues: [Mood] {
|
||||
@@ -60,23 +46,8 @@ enum Mood: Int {
|
||||
}
|
||||
|
||||
var icon: Image {
|
||||
switch self {
|
||||
|
||||
case .horrible:
|
||||
return Image("horrible", bundle: .main)
|
||||
case .bad:
|
||||
return Image("bad", bundle: .main)
|
||||
case .average:
|
||||
return Image("average", bundle: .main)
|
||||
case .good:
|
||||
return Image("good", bundle: .main)
|
||||
case .great:
|
||||
return Image("great", bundle: .main)
|
||||
case .missing:
|
||||
return Image("missing", bundle: .main)
|
||||
case .placeholder:
|
||||
return Image("missing", bundle: .main)
|
||||
}
|
||||
let moodImages: MoodImagable.Type = UserDefaultsStore.moodMoodImagable()
|
||||
return moodImages.icon(forMood: self)
|
||||
}
|
||||
|
||||
var graphic: Image {
|
||||
|
||||
104
Shared/Models/MoodImagable.swift
Normal file
104
Shared/Models/MoodImagable.swift
Normal file
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// MoodImagable.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
protocol MoodImagable {
|
||||
static func icon(forMood mood: Mood) -> Image
|
||||
}
|
||||
|
||||
enum MoodImages: Int, CaseIterable {
|
||||
case FontAwesome
|
||||
case Emoji
|
||||
case HandEmjoi
|
||||
|
||||
func icon(forMood mood: Mood) -> Image {
|
||||
switch self {
|
||||
|
||||
case .FontAwesome:
|
||||
return FontAwesomeMoodImages.icon(forMood: mood)
|
||||
case .Emoji:
|
||||
return EmojiMoodImages.icon(forMood: mood)
|
||||
case .HandEmjoi:
|
||||
return HandEmojiMoodImages.icon(forMood: mood)
|
||||
}
|
||||
}
|
||||
|
||||
var moodImages: MoodImagable.Type {
|
||||
switch self {
|
||||
case .FontAwesome:
|
||||
return FontAwesomeMoodImages.self
|
||||
case .Emoji:
|
||||
return EmojiMoodImages.self
|
||||
case .HandEmjoi:
|
||||
return HandEmojiMoodImages.self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class FontAwesomeMoodImages: MoodImagable {
|
||||
static func icon(forMood mood: Mood) -> Image {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Image("horrible", bundle: .main)
|
||||
case .bad:
|
||||
return Image("bad", bundle: .main)
|
||||
case .average:
|
||||
return Image("average", bundle: .main)
|
||||
case .good:
|
||||
return Image("good", bundle: .main)
|
||||
case .great:
|
||||
return Image("great", bundle: .main)
|
||||
case .missing:
|
||||
return Image("missing", bundle: .main)
|
||||
case .placeholder:
|
||||
return Image("missing", bundle: .main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class EmojiMoodImages: MoodImagable {
|
||||
static func icon(forMood mood: Mood) -> Image {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Image(uiImage: "💩".textToImage()!)
|
||||
case .bad:
|
||||
return Image(uiImage: "😕".textToImage()!)
|
||||
case .average:
|
||||
return Image(uiImage: "😑".textToImage()!)
|
||||
case .good:
|
||||
return Image(uiImage: "🙂".textToImage()!)
|
||||
case .great:
|
||||
return Image(uiImage: "😀".textToImage()!)
|
||||
case .missing:
|
||||
return Image(uiImage: "x".textToImage()!)
|
||||
case .placeholder:
|
||||
return Image(uiImage: "x".textToImage()!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class HandEmojiMoodImages: MoodImagable {
|
||||
static func icon(forMood mood: Mood) -> Image {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Image(uiImage: "🖕".textToImage()!)
|
||||
case .bad:
|
||||
return Image(uiImage: "👎".textToImage()!)
|
||||
case .average:
|
||||
return Image(uiImage: "🖖".textToImage()!)
|
||||
case .good:
|
||||
return Image(uiImage: "👍".textToImage()!)
|
||||
case .great:
|
||||
return Image(uiImage: "🙏".textToImage()!)
|
||||
case .missing:
|
||||
return Image(uiImage: "x".textToImage()!)
|
||||
case .placeholder:
|
||||
return Image(uiImage: "x".textToImage()!)
|
||||
}
|
||||
}
|
||||
}
|
||||
266
Shared/Models/MoodTintable.swift
Normal file
266
Shared/Models/MoodTintable.swift
Normal file
@@ -0,0 +1,266 @@
|
||||
//
|
||||
// MoodTintable.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
protocol MoodTintable {
|
||||
static func color(forMood mood: Mood) -> Color
|
||||
static func secondary(forMood mood: Mood) -> Color
|
||||
}
|
||||
|
||||
enum MoodTints: Int, CaseIterable {
|
||||
case Default
|
||||
case AllRed
|
||||
case Neon
|
||||
case MonoChrome
|
||||
case Pastel
|
||||
|
||||
func color(forMood mood: Mood) -> Color {
|
||||
switch self {
|
||||
case .Default:
|
||||
return DefaultMoodTint.color(forMood: mood)
|
||||
case .AllRed:
|
||||
return AllRedMoodTint.color(forMood: mood)
|
||||
case .Neon:
|
||||
return NeonMoodTint.color(forMood: mood)
|
||||
case .MonoChrome:
|
||||
return MonoChromeTint.color(forMood: mood)
|
||||
case .Pastel:
|
||||
return PastelTint.color(forMood: mood)
|
||||
}
|
||||
}
|
||||
|
||||
func secondary(forMood mood: Mood) -> Color {
|
||||
switch self {
|
||||
case .Default:
|
||||
return DefaultMoodTint.secondary(forMood: mood)
|
||||
case .AllRed:
|
||||
return AllRedMoodTint.secondary(forMood: mood)
|
||||
case .Neon:
|
||||
return NeonMoodTint.secondary(forMood: mood)
|
||||
case .MonoChrome:
|
||||
return MonoChromeTint.secondary(forMood: mood)
|
||||
case .Pastel:
|
||||
return PastelTint.secondary(forMood: mood)
|
||||
}
|
||||
}
|
||||
|
||||
var moodTints: MoodTintable.Type {
|
||||
switch self {
|
||||
case .Default:
|
||||
return DefaultMoodTint.self
|
||||
case .AllRed:
|
||||
return AllRedMoodTint.self
|
||||
case .Neon:
|
||||
return NeonMoodTint.self
|
||||
case .MonoChrome:
|
||||
return MonoChromeTint.self
|
||||
case .Pastel:
|
||||
return PastelTint.self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class DefaultMoodTint: MoodTintable {
|
||||
static func color(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Color(hex: "ff453a")
|
||||
case .bad:
|
||||
return Color(hex: "ff9e0b")
|
||||
case .average:
|
||||
return Color(hex: "0b84ff")
|
||||
case .good:
|
||||
return Color(hex: "ffd709")
|
||||
case .great:
|
||||
return Color(hex: "31d158")
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.systemGray4)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.systemGray4)
|
||||
}
|
||||
}
|
||||
|
||||
static func secondary(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Color(hex: "a92b26")
|
||||
case .bad:
|
||||
return Color(hex: "a06407")
|
||||
case .average:
|
||||
return Color(hex: "074f9a")
|
||||
case .good:
|
||||
return Color(hex: "9d8405")
|
||||
case .great:
|
||||
return Color(hex: "208939")
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.label)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class AllRedMoodTint: MoodTintable {
|
||||
static func color(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return .red
|
||||
case .bad:
|
||||
return .red
|
||||
case .average:
|
||||
return .red
|
||||
case .good:
|
||||
return .red
|
||||
case .great:
|
||||
return .red
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
}
|
||||
}
|
||||
|
||||
static func secondary(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return .red
|
||||
case .bad:
|
||||
return .red
|
||||
case .average:
|
||||
return .red
|
||||
case .good:
|
||||
return .red
|
||||
case .great:
|
||||
return .red
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.label)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class NeonMoodTint: MoodTintable {
|
||||
static func color(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Color(hex: "#ff1818")
|
||||
case .bad:
|
||||
return Color(hex: "#FF5F1F")
|
||||
case .average:
|
||||
return Color(hex: "#1F51FF")
|
||||
case .good:
|
||||
return Color(hex: "#FFF01F")
|
||||
case .great:
|
||||
return Color(hex: "#39FF14")
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
}
|
||||
}
|
||||
|
||||
static func secondary(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Color(hex: "#8b1113")
|
||||
case .bad:
|
||||
return Color(hex: "#893315")
|
||||
case .average:
|
||||
return Color(hex: "#0f2a85")
|
||||
case .good:
|
||||
return Color(hex: "#807a18")
|
||||
case .great:
|
||||
return Color(hex: "#218116")
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.label)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class MonoChromeTint: MoodTintable {
|
||||
static func color(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return .black
|
||||
case .bad:
|
||||
return Color(uiColor: UIColor.systemGray)
|
||||
case .average:
|
||||
return Color(uiColor: UIColor.systemGray)
|
||||
case .good:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .great:
|
||||
return Color(uiColor: UIColor.systemGray3)
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.systemGray4)
|
||||
}
|
||||
}
|
||||
|
||||
static func secondary(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return .black
|
||||
case .bad:
|
||||
return Color(uiColor: UIColor.systemGray)
|
||||
case .average:
|
||||
return Color(uiColor: UIColor.systemGray)
|
||||
case .good:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .great:
|
||||
return Color(uiColor: UIColor.systemGray3)
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.systemGray4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class PastelTint: MoodTintable {
|
||||
static func color(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Color(hex: "#FF6961")
|
||||
case .bad:
|
||||
return Color(hex: "#ffb347")
|
||||
case .average:
|
||||
return Color(hex: "#A7C7E7")
|
||||
case .good:
|
||||
return Color(hex: "#fdfd96")
|
||||
case .great:
|
||||
return Color(hex: "#C1E1C1")
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.systemGray4)
|
||||
}
|
||||
}
|
||||
|
||||
static func secondary(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return Color(hex: "#893734")
|
||||
case .bad:
|
||||
return Color(hex: "#855d28")
|
||||
case .average:
|
||||
return Color(hex: "#5d6e83")
|
||||
case .good:
|
||||
return Color(hex: "#7f804f")
|
||||
case .great:
|
||||
return Color(hex: "#6b7e6d")
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.systemGray4)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,13 +7,14 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
final class OnboardingDataDataManager {
|
||||
final class OnboardingDataDataManager: ObservableObject {
|
||||
static let shared = OnboardingDataDataManager()
|
||||
|
||||
@Published public private(set) var savedOnboardingData = UserDefaultsStore.getOnboarding()
|
||||
|
||||
|
||||
public func updateOnboardingData(onboardingData: OnboardingData) {
|
||||
let onboardingData = UserDefaultsStore.saveOnboarding(onboardingData: onboardingData)
|
||||
savedOnboardingData = onboardingData
|
||||
LocalNotification.scheduleReminder(atTime: onboardingData.date, withTitle: onboardingData.title)
|
||||
}
|
||||
}
|
||||
|
||||
91
Shared/Models/PersonalityPackable.swift
Normal file
91
Shared/Models/PersonalityPackable.swift
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// NotificationTitles.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol PersonalityPackable {
|
||||
static var notificationTitlesToday: [String] { get }
|
||||
static var notificationTitlesYesterday: [String] { get }
|
||||
static var notificationTitlesTwoDaysAgo: [String] { get }
|
||||
|
||||
static var title: String { get }
|
||||
}
|
||||
|
||||
enum PersonalityPack: Int, CaseIterable {
|
||||
case Default
|
||||
case Rude
|
||||
|
||||
func randomPushNotificationTitle() -> String {
|
||||
switch self {
|
||||
case .Default:
|
||||
return DefaultTitles.notificationTitlesToday.randomElement()!
|
||||
case .Rude:
|
||||
return RudeTitles.notificationTitlesToday.randomElement()!
|
||||
}
|
||||
}
|
||||
|
||||
func title() -> String {
|
||||
switch self {
|
||||
case .Default:
|
||||
return DefaultTitles.title
|
||||
case .Rude:
|
||||
return RudeTitles.title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class DefaultTitles: PersonalityPackable {
|
||||
static var title = "Nice"
|
||||
|
||||
static var notificationTitlesToday: [String] {
|
||||
[
|
||||
"How was your day",
|
||||
"Don't forget to rate your day",
|
||||
"Please rate your day"
|
||||
]
|
||||
}
|
||||
|
||||
static var notificationTitlesYesterday: [String] {
|
||||
[
|
||||
"How was your day",
|
||||
"Don't forget to rate your day"
|
||||
]
|
||||
}
|
||||
|
||||
static var notificationTitlesTwoDaysAgo: [String] {
|
||||
[
|
||||
"How was your day",
|
||||
"Don't forget to rate your day"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
final class RudeTitles: PersonalityPackable {
|
||||
static var title = "Rude"
|
||||
|
||||
static var notificationTitlesToday: [String] {
|
||||
[
|
||||
"How the fuck was your day",
|
||||
"Hey asshat, tell me how your day was",
|
||||
"Hey, lazy dickbag, rate your day"
|
||||
]
|
||||
}
|
||||
|
||||
static var notificationTitlesYesterday: [String] {
|
||||
[
|
||||
"How was your day",
|
||||
"Don't forget to rate your day"
|
||||
]
|
||||
}
|
||||
|
||||
static var notificationTitlesTwoDaysAgo: [String] {
|
||||
[
|
||||
"How was your day",
|
||||
"Don't forget to rate your day"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ struct ThemeConstants {
|
||||
enum Theme: Int, CaseIterable {
|
||||
case system
|
||||
case iFeel
|
||||
case dark
|
||||
case light
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
@@ -21,6 +23,10 @@ enum Theme: Int, CaseIterable {
|
||||
return SystemTheme.title
|
||||
case .iFeel:
|
||||
return IFeelTheme.title
|
||||
case .dark:
|
||||
return AlwaysDark.title
|
||||
case .light:
|
||||
return AlwaysLight.title
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,24 +37,33 @@ enum Theme: Int, CaseIterable {
|
||||
return SystemTheme()
|
||||
case .iFeel:
|
||||
return IFeelTheme()
|
||||
case .dark:
|
||||
return AlwaysDark()
|
||||
case .light:
|
||||
return AlwaysLight()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol Themeable {
|
||||
static var title: String { get }
|
||||
var secondaryBGColor: UIColor { get }
|
||||
var secondaryBGColor: Color { get }
|
||||
var bg: AnyView { get }
|
||||
var preview: AnyView { get }
|
||||
var labelColor: Color { get }
|
||||
}
|
||||
|
||||
struct IFeelTheme: Themeable {
|
||||
static var title: String {
|
||||
return "iFeel Theme"
|
||||
var labelColor: Color {
|
||||
return Color(uiColor: UIColor.label)
|
||||
}
|
||||
|
||||
var secondaryBGColor: UIColor {
|
||||
return UIColor.systemBackground
|
||||
static var title: String {
|
||||
return "iFeel"
|
||||
}
|
||||
|
||||
var secondaryBGColor: Color {
|
||||
return Color(uiColor: UIColor.systemBackground)
|
||||
}
|
||||
|
||||
var bg: AnyView {
|
||||
@@ -69,12 +84,16 @@ struct IFeelTheme: Themeable {
|
||||
}
|
||||
|
||||
struct SystemTheme: Themeable {
|
||||
var labelColor: Color {
|
||||
return Color(uiColor: UIColor.label)
|
||||
}
|
||||
|
||||
static var title: String {
|
||||
return "System"
|
||||
}
|
||||
|
||||
var secondaryBGColor: UIColor {
|
||||
return UIColor.secondarySystemBackground
|
||||
var secondaryBGColor: Color {
|
||||
return Color(uiColor: UIColor.secondarySystemBackground)
|
||||
}
|
||||
|
||||
var bg: AnyView {
|
||||
@@ -97,3 +116,71 @@ struct SystemTheme: Themeable {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct AlwaysDark: Themeable {
|
||||
var labelColor: Color {
|
||||
return .white
|
||||
}
|
||||
|
||||
static var title: String {
|
||||
return "Dark"
|
||||
}
|
||||
|
||||
var secondaryBGColor: Color {
|
||||
return Color(uiColor: UIColor.secondarySystemBackground.resolvedColor(with: .init(userInterfaceStyle: .dark)))
|
||||
}
|
||||
|
||||
var bg: AnyView {
|
||||
return AnyView(
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color(UIColor.systemBackground.resolvedColor(with: .init(userInterfaceStyle: .dark))))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var preview: AnyView {
|
||||
return AnyView(
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color(UIColor.secondarySystemBackground.resolvedColor(with: .init(userInterfaceStyle: .dark))))
|
||||
.frame(width: ThemeConstants.iconSize, height: ThemeConstants.iconSize)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct AlwaysLight: Themeable {
|
||||
var labelColor: Color {
|
||||
return .black
|
||||
}
|
||||
|
||||
static var title: String {
|
||||
return "Light"
|
||||
}
|
||||
|
||||
var secondaryBGColor: Color {
|
||||
return Color(uiColor: UIColor.secondarySystemBackground.resolvedColor(with: .init(userInterfaceStyle: .light)))
|
||||
}
|
||||
|
||||
var bg: AnyView {
|
||||
return AnyView(
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color(UIColor.systemBackground.resolvedColor(with: .init(userInterfaceStyle: .light))))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var preview: AnyView {
|
||||
return AnyView(
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color(UIColor.secondarySystemBackground.resolvedColor(with: .init(userInterfaceStyle: .light))))
|
||||
.frame(width: ThemeConstants.iconSize, height: ThemeConstants.iconSize)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ class UserDefaultsStore {
|
||||
case deleteEnable
|
||||
case mainViewTopHeaderIndex
|
||||
case theme
|
||||
|
||||
case moodImages
|
||||
case moodTint
|
||||
case personalityPack
|
||||
case customIcon
|
||||
|
||||
case contentViewCurrentSelectedHeaderViewBackDays
|
||||
@@ -43,4 +45,41 @@ class UserDefaultsStore {
|
||||
fatalError("error saving")
|
||||
}
|
||||
}
|
||||
|
||||
static func moodMoodImagable() -> MoodImagable.Type {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.moodImages.rawValue) as? Int,
|
||||
let model = MoodImages.init(rawValue: data) {
|
||||
return model.moodImages
|
||||
} else {
|
||||
return MoodImages.FontAwesome.moodImages
|
||||
}
|
||||
}
|
||||
|
||||
static func moodTintable() -> MoodTintable.Type {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.moodTint.rawValue) as? Int,
|
||||
let model = MoodTints.init(rawValue: data) {
|
||||
return model.moodTints
|
||||
} else {
|
||||
return MoodTints.Default.moodTints
|
||||
}
|
||||
}
|
||||
|
||||
static func personalityPackable() -> PersonalityPack {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.personalityPack.rawValue) as? Int,
|
||||
let model = PersonalityPack.init(rawValue: data) {
|
||||
return model
|
||||
} else {
|
||||
return PersonalityPack.Default
|
||||
}
|
||||
}
|
||||
|
||||
static func theme() -> Theme {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.theme.rawValue) as? Int,
|
||||
let model = Theme.init(rawValue: data) {
|
||||
return model
|
||||
} else {
|
||||
return Theme.system
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user