wip
This commit is contained in:
31
Shared/Models/DaysFilterClass.swift
Normal file
31
Shared/Models/DaysFilterClass.swift
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// DaysFilterClass.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 3/31/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
class DaysFilterClass: ObservableObject {
|
||||
static let shared = DaysFilterClass()
|
||||
|
||||
@Published public var currentFilters = [Int]()
|
||||
|
||||
init() {
|
||||
let storedDays = UserDefaultsStore.getDaysFilter()
|
||||
currentFilters = storedDays
|
||||
}
|
||||
|
||||
func addFilter(newFilter: Int) {
|
||||
currentFilters.append(newFilter)
|
||||
currentFilters = UserDefaultsStore.saveDaysFilter(days: currentFilters)
|
||||
}
|
||||
|
||||
func removeFilter(filter: Int) {
|
||||
if let index = currentFilters.firstIndex(of: filter) {
|
||||
currentFilters.remove(at: index)
|
||||
}
|
||||
currentFilters = UserDefaultsStore.saveDaysFilter(days: currentFilters)
|
||||
}
|
||||
}
|
||||
31
Shared/Models/DiamondView.swift
Normal file
31
Shared/Models/DiamondView.swift
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// DiamondView.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 3/20/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct Diamond:Shape {
|
||||
|
||||
func path(in rect: CGRect) -> Path {
|
||||
var path = Path()
|
||||
// get the center of the rect
|
||||
let center = CGPoint(x: rect.midX, y: rect.midY)
|
||||
// get the starting of our drawing the right side of our diamond
|
||||
let startingPoint = CGPoint(x: rect.maxX, y: center.y)
|
||||
// move our start of drawing to the beggining point
|
||||
path.move(to: startingPoint)
|
||||
// distance / 2 is our height
|
||||
// create all our points
|
||||
let secondPoint = CGPoint(x: center.x, y: rect.maxY)
|
||||
let thirdPoint = CGPoint(x: rect.minX , y: center.y)
|
||||
let fourthPoint = CGPoint(x: center.x, y: rect.minY)
|
||||
path.addLine(to: secondPoint)
|
||||
path.addLine(to: thirdPoint)
|
||||
path.addLine(to: fourthPoint)
|
||||
path.addLine(to: startingPoint)
|
||||
return path
|
||||
}
|
||||
}
|
||||
87
Shared/Models/Mood.swift
Normal file
87
Shared/Models/Mood.swift
Normal file
@@ -0,0 +1,87 @@
|
||||
//
|
||||
// Mood.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 1/5/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
enum Mood: Int {
|
||||
case horrible
|
||||
case bad
|
||||
case average
|
||||
case good
|
||||
case great
|
||||
case missing
|
||||
case placeholder
|
||||
|
||||
var next: Mood {
|
||||
var moodValue = self.rawValue
|
||||
moodValue -= 1
|
||||
if moodValue < 0 {
|
||||
moodValue = 4
|
||||
}
|
||||
return Mood.init(rawValue: moodValue) ?? Mood.horrible
|
||||
}
|
||||
|
||||
var strValue: String {
|
||||
switch self {
|
||||
case .horrible:
|
||||
return String(localized: "mood_value_horrible")
|
||||
case .bad:
|
||||
return String(localized: "mood_value_bad")
|
||||
case .average:
|
||||
return String(localized: "mood_value_average")
|
||||
case .good:
|
||||
return String(localized: "mood_value_good")
|
||||
case .great:
|
||||
return String(localized: "mood_value_great")
|
||||
case .missing:
|
||||
return String(localized: "mood_value_missing")
|
||||
case .placeholder:
|
||||
return String("placeholder")
|
||||
}
|
||||
}
|
||||
|
||||
var color: Color {
|
||||
let moodTint: MoodTintable.Type = UserDefaultsStore.moodTintable()
|
||||
return moodTint.color(forMood: self)
|
||||
}
|
||||
|
||||
static var allValues: [Mood] {
|
||||
return [Mood.horrible, Mood.bad, Mood.average, Mood.good, Mood.great].reversed()
|
||||
}
|
||||
|
||||
var icon: Image {
|
||||
let moodImages: MoodImagable.Type = UserDefaultsStore.moodMoodImagable()
|
||||
return moodImages.icon(forMood: self)
|
||||
}
|
||||
|
||||
var graphic: Image {
|
||||
switch self {
|
||||
|
||||
case .horrible:
|
||||
return Image("HorribleGraphic", bundle: .main)
|
||||
case .bad:
|
||||
return Image("BadGraphic", bundle: .main)
|
||||
case .average:
|
||||
return Image("AverageGraphic", bundle: .main)
|
||||
case .good:
|
||||
return Image("GoodGraphic", bundle: .main)
|
||||
case .great:
|
||||
return Image("GreatGraphic", bundle: .main)
|
||||
case .missing:
|
||||
return Image("MissingGraphic", bundle: .main)
|
||||
case .placeholder:
|
||||
return Image("MissingGraphic", bundle: .main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Mood: Identifiable {
|
||||
var id: Int {
|
||||
rawValue
|
||||
}
|
||||
}
|
||||
26
Shared/Models/MoodEntryExtension.swift
Normal file
26
Shared/Models/MoodEntryExtension.swift
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// MoodEntryExtension.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 1/5/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum EntryType: Int {
|
||||
case notification
|
||||
case header
|
||||
case listView
|
||||
case filledInMissing
|
||||
case widget
|
||||
}
|
||||
|
||||
extension MoodEntry {
|
||||
var moodString: String {
|
||||
return Mood.init(rawValue: Int(self.moodValue))?.strValue ?? "NA"
|
||||
}
|
||||
|
||||
var mood: Mood {
|
||||
return Mood.init(rawValue: Int(self.moodValue))!
|
||||
}
|
||||
}
|
||||
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("xmark-solid", bundle: .main)
|
||||
case .placeholder:
|
||||
return Image("xmark-solid", 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("xmark-solid", bundle: .main)
|
||||
case .placeholder:
|
||||
return Image("xmark-solid", bundle: .main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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("xmark-solid", bundle: .main)
|
||||
case .placeholder:
|
||||
return Image("xmark-solid", bundle: .main)
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Shared/Models/MoodMetrics.swift
Normal file
15
Shared/Models/MoodMetrics.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// MoodMetrics.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 2/12/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct MoodMetrics: Identifiable {
|
||||
let id = UUID()
|
||||
let mood: Mood
|
||||
let total: Int
|
||||
let percent: Float
|
||||
}
|
||||
347
Shared/Models/MoodTintable.swift
Normal file
347
Shared/Models/MoodTintable.swift
Normal file
@@ -0,0 +1,347 @@
|
||||
//
|
||||
// MoodTintable.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct DefaultTextColor {
|
||||
static var textColor: Color {
|
||||
Color(UIColor.label)
|
||||
}
|
||||
}
|
||||
|
||||
protocol MoodTintable {
|
||||
static func color(forMood mood: Mood) -> Color
|
||||
static func secondary(forMood mood: Mood) -> Color
|
||||
}
|
||||
|
||||
enum MoodTints: Int, CaseIterable {
|
||||
case Default
|
||||
case Neon
|
||||
case Pastel
|
||||
case Custom
|
||||
|
||||
static var defaultOptions: [MoodTints] {
|
||||
return [Default, Neon, Pastel]
|
||||
}
|
||||
|
||||
func color(forMood mood: Mood) -> Color {
|
||||
switch self {
|
||||
case .Default:
|
||||
return DefaultMoodTint.color(forMood: mood)
|
||||
case .Custom:
|
||||
return CustomMoodTint.color(forMood: mood)
|
||||
case .Neon:
|
||||
return NeonMoodTint.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 .Custom:
|
||||
return CustomMoodTint.secondary(forMood: mood)
|
||||
case .Neon:
|
||||
return NeonMoodTint.secondary(forMood: mood)
|
||||
case .Pastel:
|
||||
return PastelTint.secondary(forMood: mood)
|
||||
}
|
||||
}
|
||||
|
||||
var moodTints: MoodTintable.Type {
|
||||
switch self {
|
||||
case .Default:
|
||||
return DefaultMoodTint.self
|
||||
case .Custom:
|
||||
return CustomMoodTint.self
|
||||
case .Neon:
|
||||
return NeonMoodTint.self
|
||||
case .Pastel:
|
||||
return PastelTint.self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class SavedMoodTint: NSObject, ObservableObject, Codable {
|
||||
@Published var colorOne: Color
|
||||
@Published var colorTwo: Color
|
||||
@Published var colorThree: Color
|
||||
@Published var colorFour: Color
|
||||
@Published var colorFive: Color
|
||||
|
||||
override init() {
|
||||
colorOne = Color(hex: "a92b26")
|
||||
colorTwo = Color(hex: "a92b26")
|
||||
colorThree = Color(hex: "a92b26")
|
||||
colorFour = Color(hex: "a92b26")
|
||||
colorFive = Color(hex: "a92b26")
|
||||
}
|
||||
|
||||
enum CodingKeys: CodingKey {
|
||||
case colorOne, colorTwo, colorThree, colorFour, colorFive
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
colorOne = try container.decode(Color.self, forKey: .colorOne)
|
||||
colorTwo = try container.decode(Color.self, forKey: .colorTwo)
|
||||
colorThree = try container.decode(Color.self, forKey: .colorThree)
|
||||
colorFour = try container.decode(Color.self, forKey: .colorFour)
|
||||
colorFive = try container.decode(Color.self, forKey: .colorFive)
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(colorOne, forKey: .colorOne)
|
||||
try container.encode(colorTwo, forKey: .colorTwo)
|
||||
try container.encode(colorThree, forKey: .colorThree)
|
||||
try container.encode(colorFour, forKey: .colorFour)
|
||||
try container.encode(colorFive, forKey: .colorFive)
|
||||
}
|
||||
}
|
||||
|
||||
final class CustomMoodTint: MoodTintable {
|
||||
static func color(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorFive
|
||||
case .bad:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorFour
|
||||
case .average:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorThree
|
||||
case .good:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorTwo
|
||||
case .great:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorOne
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.lightGray)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.lightGray)
|
||||
}
|
||||
}
|
||||
|
||||
static func secondary(forMood mood: Mood) -> Color {
|
||||
switch mood {
|
||||
case .horrible:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorFive.darker(by: 40)
|
||||
case .bad:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorFour.darker(by: 40)
|
||||
case .average:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorThree.darker(by: 40)
|
||||
case .good:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorTwo.darker(by: 40)
|
||||
case .great:
|
||||
return UserDefaultsStore.getCustomMoodTint().colorOne.darker(by: 40)
|
||||
case .missing:
|
||||
return Color(uiColor: UIColor.lightGray).darker(by: 40)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.lightGray).darker(by: 40)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.systemGray2)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.systemGray2)
|
||||
}
|
||||
}
|
||||
|
||||
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 Color(hex: "#000000")
|
||||
case .bad:
|
||||
return Color(hex: "#47474a")
|
||||
case .average:
|
||||
return Color(hex: "#7b7b81")
|
||||
case .good:
|
||||
return Color(hex: "#a3a3ab")
|
||||
case .great:
|
||||
return Color(hex: "#c2c1cb")
|
||||
case .missing:
|
||||
return Color(hex: "#ff0000")
|
||||
case .placeholder:
|
||||
return Color(hex: "#efeffb")
|
||||
}
|
||||
}
|
||||
|
||||
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.systemGray2)
|
||||
}
|
||||
}
|
||||
|
||||
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.label)
|
||||
case .placeholder:
|
||||
return Color(uiColor: UIColor.label)
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Shared/Models/OnboardingDataDataManager.swift
Normal file
20
Shared/Models/OnboardingDataDataManager.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// OnboardingDataDataManager.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/18/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
108
Shared/Models/PersonalityPackable.swift
Normal file
108
Shared/Models/PersonalityPackable.swift
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// NotificationTitles.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol PersonalityPackable {
|
||||
static var notificationTitles: [String] { get }
|
||||
static var notificationBodyToday: [String] { get }
|
||||
static var notificationBodyYesterday: [String] { get }
|
||||
|
||||
static var title: String { get }
|
||||
}
|
||||
|
||||
enum PersonalityPack: Int, CaseIterable {
|
||||
case Default
|
||||
case Rude
|
||||
|
||||
func randomPushNotificationStrings() -> (title: String, body: String) {
|
||||
let onboarding = UserDefaultsStore.getOnboarding()
|
||||
|
||||
switch (self, onboarding.inputDay) {
|
||||
case (.Default, .Today):
|
||||
return (DefaultTitles.notificationTitles.randomElement()!,
|
||||
DefaultTitles.notificationBodyToday.randomElement()!)
|
||||
case (.Default, .Previous):
|
||||
return (DefaultTitles.notificationTitles.randomElement()!,
|
||||
DefaultTitles.notificationBodyYesterday.randomElement()!)
|
||||
case (.Rude, .Today):
|
||||
return (RudeTitles.notificationTitles.randomElement()!,
|
||||
RudeTitles.notificationBodyToday.randomElement()!)
|
||||
case (.Rude, .Previous):
|
||||
return (RudeTitles.notificationTitles.randomElement()!,
|
||||
RudeTitles.notificationBodyYesterday.randomElement()!)
|
||||
}
|
||||
}
|
||||
|
||||
func title() -> String {
|
||||
switch self {
|
||||
case .Default:
|
||||
return DefaultTitles.title
|
||||
case .Rude:
|
||||
return RudeTitles.title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class DefaultTitles: PersonalityPackable {
|
||||
static var title = String(localized: "nice")
|
||||
|
||||
static var notificationTitles: [String] {
|
||||
[
|
||||
String(localized: "default_notif_title_one"),
|
||||
String(localized: "default_notif_title_two"),
|
||||
String(localized: "default_notif_title_three")
|
||||
]
|
||||
}
|
||||
|
||||
static var notificationBodyToday: [String] {
|
||||
[
|
||||
String(localized: "default_notif_body_today_one"),
|
||||
String(localized: "default_notif_body_today_two"),
|
||||
String(localized: "default_notif_body_today_three"),
|
||||
String(localized: "default_notif_body_today_four")
|
||||
]
|
||||
}
|
||||
|
||||
static var notificationBodyYesterday: [String] {
|
||||
[
|
||||
String(localized: "default_notif_body_yesterday_one"),
|
||||
String(localized: "default_notif_body_yesterday_two"),
|
||||
String(localized: "default_notif_body_yesterday_three"),
|
||||
String(localized: "default_notif_body_yesterday_four")
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
final class RudeTitles: PersonalityPackable {
|
||||
static var title = String(localized: "rude")
|
||||
|
||||
static var notificationTitles: [String] {
|
||||
[
|
||||
String(localized: "rude_notif_title_one"),
|
||||
String(localized: "rude_notif_title_two"),
|
||||
String(localized: "rude_notif_title_three"),
|
||||
String(localized: "rude_notif_title_four")
|
||||
]
|
||||
}
|
||||
|
||||
static var notificationBodyToday: [String] {
|
||||
[
|
||||
String(localized: "rude_notif_body_today_one"),
|
||||
String(localized: "rude_notif_body_today_two"),
|
||||
String(localized: "rude_notif_body_today_three")
|
||||
]
|
||||
}
|
||||
|
||||
static var notificationBodyYesterday: [String] {
|
||||
[
|
||||
String(localized: "rude_notif_body_yesterday_one"),
|
||||
String(localized: "rude_notif_body_yesterday_two"),
|
||||
String(localized: "rude_notif_body_yesterday_three")
|
||||
]
|
||||
}
|
||||
}
|
||||
95
Shared/Models/Shapes.swift
Normal file
95
Shared/Models/Shapes.swift
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// Shapes.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 3/20/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
enum BGShape: Int, CaseIterable {
|
||||
case circle
|
||||
case diamond
|
||||
case rectangle
|
||||
case roundedRectangle
|
||||
|
||||
func view(withText text: Text, bgColor: Color, textColor: Color) -> some View{
|
||||
return AnyView(
|
||||
ZStack {
|
||||
switch self {
|
||||
case .circle:
|
||||
Circle()
|
||||
.fill(bgColor)
|
||||
.frame(minWidth: 5,
|
||||
maxWidth: 500,
|
||||
minHeight: 5,
|
||||
maxHeight: 500,
|
||||
alignment: .center)
|
||||
.overlay(
|
||||
text
|
||||
.font(.title2)
|
||||
.fontWeight(.bold)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(textColor)
|
||||
.minimumScaleFactor(0.2)
|
||||
.padding(10)
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
)
|
||||
case .diamond:
|
||||
Diamond()
|
||||
.fill(bgColor)
|
||||
.frame(minWidth: 5,
|
||||
maxWidth: 500,
|
||||
minHeight: 5,
|
||||
maxHeight: 500)
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.overlay(
|
||||
text
|
||||
.font(.title2)
|
||||
.fontWeight(.bold)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(textColor)
|
||||
.minimumScaleFactor(0.2)
|
||||
.padding(10)
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
)
|
||||
case .rectangle:
|
||||
Rectangle()
|
||||
.fill(bgColor)
|
||||
.frame(minWidth: 5,
|
||||
maxWidth: 500,
|
||||
minHeight: 5,
|
||||
maxHeight: 500,
|
||||
alignment: .center)
|
||||
.overlay(
|
||||
text
|
||||
.font(.title2)
|
||||
.fontWeight(.bold)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(textColor)
|
||||
.minimumScaleFactor(0.2)
|
||||
.padding(10)
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
)
|
||||
case .roundedRectangle:
|
||||
RoundedRectangle(cornerRadius: 8, style: .continuous)
|
||||
.fill(bgColor)
|
||||
.frame(minWidth: 5,
|
||||
maxWidth: 500,
|
||||
minHeight: 5,
|
||||
maxHeight: 500,
|
||||
alignment: .center)
|
||||
.overlay(
|
||||
text
|
||||
.font(.title2)
|
||||
.fontWeight(.bold)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(textColor)
|
||||
.minimumScaleFactor(0.2)
|
||||
.padding(10)
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
59
Shared/Models/SharingImageModels.swift
Normal file
59
Shared/Models/SharingImageModels.swift
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// SharingImageModels.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 2/24/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import LinkPresentation
|
||||
|
||||
class StupidAssShareObservableObject: ObservableObject {
|
||||
@Published var fuckingWrappedShrable: UIImage? = nil
|
||||
@Published var showFuckingSheet = false
|
||||
}
|
||||
|
||||
class ShareActivityItemSource: NSObject, UIActivityItemSource {
|
||||
var shareText: String
|
||||
var shareImage: UIImage
|
||||
var linkMetaData = LPLinkMetadata()
|
||||
|
||||
init(shareText: String, shareImage: UIImage) {
|
||||
self.shareText = shareText
|
||||
self.shareImage = shareImage
|
||||
linkMetaData.title = shareText
|
||||
super.init()
|
||||
}
|
||||
|
||||
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
|
||||
return UIImage(named: "AppIcon") as Any
|
||||
}
|
||||
|
||||
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
|
||||
return linkMetaData
|
||||
}
|
||||
}
|
||||
|
||||
struct ShareSheet: UIViewControllerRepresentable {
|
||||
let photo: UIImage
|
||||
|
||||
func makeUIViewController(context: Context) -> UIActivityViewController {
|
||||
let text = "ifeel"
|
||||
let itemSource = ShareActivityItemSource(shareText: text, shareImage: photo)
|
||||
|
||||
let activityItems: [Any] = [photo, text, itemSource]
|
||||
|
||||
let controller = UIActivityViewController(
|
||||
activityItems: activityItems,
|
||||
applicationActivities: nil)
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
|
||||
}
|
||||
}
|
||||
13
Shared/Models/StupidAssCustomWidgetObservableObject.swift
Normal file
13
Shared/Models/StupidAssCustomWidgetObservableObject.swift
Normal file
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// StupidAssCustomWidgetObservableObject.swift
|
||||
// Feels
|
||||
//
|
||||
// Created by Trey Tartt on 3/31/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class StupidAssCustomWidgetObservableObject: ObservableObject {
|
||||
@Published var fuckingWrapped: CustomWidgetModel? = nil
|
||||
@Published var showFuckingSheet = false
|
||||
}
|
||||
203
Shared/Models/Theme.swift
Normal file
203
Shared/Models/Theme.swift
Normal file
@@ -0,0 +1,203 @@
|
||||
//
|
||||
// theme.currentTheme.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/4/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ThemeConstants {
|
||||
static let iconSize: CGFloat = 50
|
||||
}
|
||||
|
||||
enum Theme: Int, CaseIterable {
|
||||
case system
|
||||
case iFeel
|
||||
case dark
|
||||
case light
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .system:
|
||||
return SystemTheme.title
|
||||
case .iFeel:
|
||||
return IFeelTheme.title
|
||||
case .dark:
|
||||
return AlwaysDark.title
|
||||
case .light:
|
||||
return AlwaysLight.title
|
||||
}
|
||||
}
|
||||
|
||||
var currentTheme: Themeable {
|
||||
switch self {
|
||||
|
||||
case .system:
|
||||
return SystemTheme()
|
||||
case .iFeel:
|
||||
return IFeelTheme()
|
||||
case .dark:
|
||||
return AlwaysDark()
|
||||
case .light:
|
||||
return AlwaysLight()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol Themeable {
|
||||
static var title: String { get }
|
||||
var secondaryBGColor: Color { get }
|
||||
var bgColor: Color { get }
|
||||
var bg: AnyView { get }
|
||||
var preview: AnyView { get }
|
||||
var labelColor: Color { get }
|
||||
}
|
||||
|
||||
struct IFeelTheme: Themeable {
|
||||
var bgColor: Color {
|
||||
return Color(uiColor: UIColor.systemBackground)
|
||||
}
|
||||
|
||||
var labelColor: Color {
|
||||
return Color(uiColor: UIColor.label)
|
||||
}
|
||||
|
||||
static var title: String {
|
||||
return "iFeel"
|
||||
}
|
||||
|
||||
var secondaryBGColor: Color {
|
||||
return Color(uiColor: UIColor.secondarySystemBackground)
|
||||
}
|
||||
|
||||
var bg: AnyView {
|
||||
return AnyView(
|
||||
BGView().equatable()
|
||||
)
|
||||
}
|
||||
|
||||
var preview: AnyView {
|
||||
return AnyView(
|
||||
ZStack {
|
||||
BGView().equatable()
|
||||
.frame(width: ThemeConstants.iconSize, height: ThemeConstants.iconSize)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct SystemTheme: Themeable {
|
||||
var bgColor: Color {
|
||||
return Color(uiColor: UIColor.systemBackground)
|
||||
}
|
||||
|
||||
var labelColor: Color {
|
||||
return Color(uiColor: UIColor.label)
|
||||
}
|
||||
|
||||
static var title: String {
|
||||
return "System"
|
||||
}
|
||||
|
||||
var secondaryBGColor: Color {
|
||||
return Color(uiColor: UIColor.secondarySystemBackground)
|
||||
}
|
||||
|
||||
var bg: AnyView {
|
||||
return AnyView(
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color(UIColor.systemBackground))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var preview: AnyView {
|
||||
return AnyView(
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color(UIColor.secondarySystemBackground))
|
||||
.frame(width: ThemeConstants.iconSize, height: ThemeConstants.iconSize)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct AlwaysDark: Themeable {
|
||||
var bgColor: Color {
|
||||
return Color(uiColor: UIColor.systemBackground.resolvedColor(with: .init(userInterfaceStyle: .dark)))
|
||||
}
|
||||
|
||||
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 bgColor: Color {
|
||||
return Color(uiColor: UIColor.systemBackground)
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
233
Shared/Models/UserDefaultsStore.swift
Normal file
233
Shared/Models/UserDefaultsStore.swift
Normal file
@@ -0,0 +1,233 @@
|
||||
//
|
||||
// UserDefaultsStore.swift
|
||||
// Feels (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/22/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class UserDefaultsStore {
|
||||
enum Keys: String {
|
||||
case savedOnboardingData
|
||||
case needsOnboarding
|
||||
case useCloudKit
|
||||
case deleteEnable
|
||||
case mainViewTopHeaderIndex
|
||||
case theme
|
||||
case moodImages
|
||||
case moodTint
|
||||
case personalityPack
|
||||
case customWidget
|
||||
case customMoodTint
|
||||
case customMoodTintUpdateNumber
|
||||
case textColor
|
||||
case showNSFW
|
||||
case shape
|
||||
case daysFilter
|
||||
case firstLaunchDate
|
||||
case hasActiveSubscription
|
||||
case lastVotedDate
|
||||
|
||||
case contentViewCurrentSelectedHeaderViewBackDays
|
||||
case contentViewHeaderTag
|
||||
case contentViewHeaderTagViewOneViewType
|
||||
case contentViewHeaderTagViewTwoViewType
|
||||
case currentSelectedHeaderViewViewType
|
||||
}
|
||||
|
||||
static func getOnboarding() -> OnboardingData {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.savedOnboardingData.rawValue) as? Data,
|
||||
let model = try? JSONDecoder().decode(OnboardingData.self, from: data) {
|
||||
return model
|
||||
} else {
|
||||
return OnboardingData()
|
||||
}
|
||||
}
|
||||
|
||||
static func saveOnboarding(onboardingData: OnboardingData) -> OnboardingData {
|
||||
do {
|
||||
let data = try JSONEncoder().encode(onboardingData)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.savedOnboardingData.rawValue)
|
||||
return UserDefaultsStore.getOnboarding()
|
||||
} catch {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
static func getCustomWidgets() -> [CustomWidgetModel] {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customWidget.rawValue) as? Data,
|
||||
let model = try? JSONDecoder().decode([CustomWidgetModel].self, from: data) {
|
||||
return model
|
||||
} else {
|
||||
GroupUserDefaults.groupDefaults.removeObject(forKey: UserDefaultsStore.Keys.customWidget.rawValue)
|
||||
|
||||
let widget = CustomWidgetModel.randomWidget
|
||||
widget.isSaved = true
|
||||
let widgets = [widget]
|
||||
let data = try! JSONEncoder().encode(widgets)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue)
|
||||
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customWidget.rawValue) as? Data,
|
||||
let models = try? JSONDecoder().decode([CustomWidgetModel].self, from: data) {
|
||||
let sorted = models.sorted(by: {
|
||||
$0.createdDate < $1.createdDate
|
||||
})
|
||||
return sorted
|
||||
} else {
|
||||
fatalError("error getting widgets")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
static func saveCustomWidget(widgetModel: CustomWidgetModel, inUse: Bool) -> [CustomWidgetModel] {
|
||||
do {
|
||||
var existingWidgets = getCustomWidgets()
|
||||
|
||||
if let exisitingWidget = existingWidgets.firstIndex(where: {
|
||||
$0.uuid == widgetModel.uuid
|
||||
}) {
|
||||
existingWidgets.remove(at: exisitingWidget)
|
||||
// give it differnet uuid so the view updates
|
||||
widgetModel.uuid = UUID().uuidString
|
||||
}
|
||||
|
||||
if inUse {
|
||||
existingWidgets.forEach({
|
||||
$0.inUse = false
|
||||
})
|
||||
|
||||
widgetModel.inUse = true
|
||||
}
|
||||
|
||||
existingWidgets.append(widgetModel)
|
||||
existingWidgets.forEach({
|
||||
$0.isSaved = true
|
||||
})
|
||||
let data = try JSONEncoder().encode(existingWidgets)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue)
|
||||
return UserDefaultsStore.getCustomWidgets()
|
||||
} catch {
|
||||
fatalError("error saving")
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
static func deleteCustomWidget(withUUID uuid: String) -> [CustomWidgetModel] {
|
||||
do {
|
||||
var existingWidgets = getCustomWidgets()
|
||||
|
||||
if let exisitingWidget = existingWidgets.firstIndex(where: {
|
||||
$0.uuid == uuid
|
||||
}) {
|
||||
existingWidgets.remove(at: exisitingWidget)
|
||||
}
|
||||
|
||||
if existingWidgets.count == 0 {
|
||||
let widget = CustomWidgetModel.randomWidget
|
||||
widget.isSaved = true
|
||||
widget.inUse = true
|
||||
existingWidgets.append(widget)
|
||||
}
|
||||
|
||||
if let _ = existingWidgets.first(where: {
|
||||
$0.inUse == true
|
||||
}) {} else {
|
||||
if let first = existingWidgets.first {
|
||||
first.inUse = true
|
||||
}
|
||||
}
|
||||
|
||||
let data = try JSONEncoder().encode(existingWidgets)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue)
|
||||
return UserDefaultsStore.getCustomWidgets()
|
||||
} catch {
|
||||
fatalError("error saving")
|
||||
}
|
||||
}
|
||||
|
||||
static func getCustomMoodTint() -> SavedMoodTint {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customMoodTint.rawValue) as? Data{
|
||||
do {
|
||||
let model = try JSONDecoder().decode(SavedMoodTint.self, from: data)
|
||||
return model
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
return SavedMoodTint()
|
||||
}
|
||||
|
||||
static func getCustomBGShape() -> BGShape {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.shape.rawValue) as? Int,
|
||||
let model = BGShape.init(rawValue: data) {
|
||||
return model
|
||||
} else {
|
||||
return BGShape.circle
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
static func saveCustomMoodTint(customTint: SavedMoodTint) -> SavedMoodTint {
|
||||
do {
|
||||
let data = try JSONEncoder().encode(customTint)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customMoodTint.rawValue)
|
||||
return UserDefaultsStore.getCustomMoodTint()
|
||||
} catch {
|
||||
print(error)
|
||||
fatalError("error saving")
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
static func saveDaysFilter(days: [Int]) -> [Int] {
|
||||
GroupUserDefaults.groupDefaults.set(days, forKey: UserDefaultsStore.Keys.daysFilter.rawValue)
|
||||
return UserDefaultsStore.getDaysFilter()
|
||||
}
|
||||
|
||||
static func getDaysFilter() -> [Int] {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.daysFilter.rawValue) as? [Int] {
|
||||
return data
|
||||
} else {
|
||||
return [1,2,3,4,5,6,7]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user