Created card UI and added sleep debt functionality, still needs some polishing
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
6CD7B4BB2B49AA5100D1D8B8 /* SleepDebtTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD7B4BA2B49AA5100D1D8B8 /* SleepDebtTabView.swift */; };
|
6CD7B4BB2B49AA5100D1D8B8 /* SleepDebtTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD7B4BA2B49AA5100D1D8B8 /* SleepDebtTabView.swift */; };
|
||||||
6CD7B4BD2B49AB3F00D1D8B8 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD7B4BC2B49AB3F00D1D8B8 /* SettingsView.swift */; };
|
6CD7B4BD2B49AB3F00D1D8B8 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD7B4BC2B49AB3F00D1D8B8 /* SettingsView.swift */; };
|
||||||
6CD7B4C12B49C45400D1D8B8 /* SettingsNumberFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD7B4C02B49C45400D1D8B8 /* SettingsNumberFieldView.swift */; };
|
6CD7B4C12B49C45400D1D8B8 /* SettingsNumberFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD7B4C02B49C45400D1D8B8 /* SettingsNumberFieldView.swift */; };
|
||||||
|
6CD7B4C52B49D3BB00D1D8B8 /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD7B4C42B49D3BB00D1D8B8 /* CardView.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
6CD7B4BA2B49AA5100D1D8B8 /* SleepDebtTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepDebtTabView.swift; sourceTree = "<group>"; };
|
6CD7B4BA2B49AA5100D1D8B8 /* SleepDebtTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepDebtTabView.swift; sourceTree = "<group>"; };
|
||||||
6CD7B4BC2B49AB3F00D1D8B8 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
6CD7B4BC2B49AB3F00D1D8B8 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||||
6CD7B4C02B49C45400D1D8B8 /* SettingsNumberFieldView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsNumberFieldView.swift; sourceTree = "<group>"; };
|
6CD7B4C02B49C45400D1D8B8 /* SettingsNumberFieldView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsNumberFieldView.swift; sourceTree = "<group>"; };
|
||||||
|
6CD7B4C42B49D3BB00D1D8B8 /* CardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -64,6 +66,7 @@
|
|||||||
6C560B842B495DED00FDB70C /* SleepDebtApp.swift */,
|
6C560B842B495DED00FDB70C /* SleepDebtApp.swift */,
|
||||||
6C560B862B495DED00FDB70C /* HomeView.swift */,
|
6C560B862B495DED00FDB70C /* HomeView.swift */,
|
||||||
6CD7B4BA2B49AA5100D1D8B8 /* SleepDebtTabView.swift */,
|
6CD7B4BA2B49AA5100D1D8B8 /* SleepDebtTabView.swift */,
|
||||||
|
6CD7B4C42B49D3BB00D1D8B8 /* CardView.swift */,
|
||||||
6CD7B4BC2B49AB3F00D1D8B8 /* SettingsView.swift */,
|
6CD7B4BC2B49AB3F00D1D8B8 /* SettingsView.swift */,
|
||||||
6CD7B4C02B49C45400D1D8B8 /* SettingsNumberFieldView.swift */,
|
6CD7B4C02B49C45400D1D8B8 /* SettingsNumberFieldView.swift */,
|
||||||
6C560B922B495E3A00FDB70C /* HealthKitManager.swift */,
|
6C560B922B495E3A00FDB70C /* HealthKitManager.swift */,
|
||||||
@@ -151,6 +154,7 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
6CD7B4C52B49D3BB00D1D8B8 /* CardView.swift in Sources */,
|
||||||
6C560B872B495DED00FDB70C /* HomeView.swift in Sources */,
|
6C560B872B495DED00FDB70C /* HomeView.swift in Sources */,
|
||||||
6CD7B4C12B49C45400D1D8B8 /* SettingsNumberFieldView.swift in Sources */,
|
6CD7B4C12B49C45400D1D8B8 /* SettingsNumberFieldView.swift in Sources */,
|
||||||
6CD7B4BB2B49AA5100D1D8B8 /* SleepDebtTabView.swift in Sources */,
|
6CD7B4BB2B49AA5100D1D8B8 /* SleepDebtTabView.swift in Sources */,
|
||||||
|
|||||||
74
SleepDebt/CardView.swift
Normal file
74
SleepDebt/CardView.swift
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// CardView.swift
|
||||||
|
// SleepDebt
|
||||||
|
//
|
||||||
|
// Created by Oliver Hnát on 06.01.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
extension Int {
|
||||||
|
var toHoursMinuteString: String {
|
||||||
|
return "\(self / 60 / 60)h \(self / 60 % 60)m"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Color {
|
||||||
|
init(hex: String) {
|
||||||
|
var cleanHexCode = hex.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
cleanHexCode = cleanHexCode.replacingOccurrences(of: "#", with: "")
|
||||||
|
var rgb: UInt64 = 0
|
||||||
|
|
||||||
|
Scanner(string: cleanHexCode).scanHexInt64(&rgb)
|
||||||
|
|
||||||
|
let redValue = Double((rgb >> 16) & 0xFF) / 255.0
|
||||||
|
let greenValue = Double((rgb >> 8) & 0xFF) / 255.0
|
||||||
|
let blueValue = Double(rgb & 0xFF) / 255.0
|
||||||
|
self.init(red: redValue, green: greenValue, blue: blueValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CardView: View {
|
||||||
|
var topText: String
|
||||||
|
var value: Int
|
||||||
|
var image: String
|
||||||
|
var bottomText: String?
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
Color.init(hex: "#0b1d2e")
|
||||||
|
.cornerRadius(20)
|
||||||
|
.scaledToFill()
|
||||||
|
VStack {
|
||||||
|
VStack {
|
||||||
|
Image(systemName: image)
|
||||||
|
.font(.title)
|
||||||
|
Text(topText)
|
||||||
|
.font(.title3)
|
||||||
|
.padding()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
}
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
Text(value.toHoursMinuteString)
|
||||||
|
.font(.largeTitle)
|
||||||
|
.padding()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
if (bottomText != nil) {
|
||||||
|
Text(bottomText ?? "You're not supposed to see this")
|
||||||
|
.font(.title3)
|
||||||
|
.padding(.horizontal)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
VStack {
|
||||||
|
CardView(topText: "Your sleep debt for the last 7 days is", value: 876750 - 8 * 30 * 60 * 60, image: "moon.zzz") // sleep debt of ~15.5h
|
||||||
|
CardView(topText: "You should sleep at least", value: 8 * 60 * 60 - 876750 / 30 , image: "moon.zzz.fill", bottomText: "per day to catch up on your sleep in 7 days")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,13 +10,19 @@ import SwiftUI
|
|||||||
struct HomeView: View {
|
struct HomeView: View {
|
||||||
@EnvironmentObject var manager: HealthKitManager
|
@EnvironmentObject var manager: HealthKitManager
|
||||||
@EnvironmentObject var settings: SleepDebtSettings
|
@EnvironmentObject var settings: SleepDebtSettings
|
||||||
var desiredAmountOfSleep = 8
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
ZStack {
|
||||||
Image(systemName: "globe")
|
LazyHGrid(rows: Array(repeating: GridItem(spacing: 20), count: 2)) {
|
||||||
.imageScale(.large)
|
CardView(
|
||||||
.foregroundStyle(.tint)
|
topText: "Your sleep debt for the last \(settings.sleepDebtPeriod.rawValue) days is",
|
||||||
Text(String(manager.sleepForLastXDays[settings.sleepDebtPeriod] ?? 0))
|
value: self.getTotalSleepDebt(),
|
||||||
|
image: "moon.zzz")
|
||||||
|
CardView(topText: "You should sleep at least",
|
||||||
|
value: self.getDailyRepaymentSleep(),
|
||||||
|
image: "moon.zzz.fill",
|
||||||
|
bottomText: "per day to catch up on your sleep in \(settings.repaymentPeriod) days")
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
.onAppear {
|
.onAppear {
|
||||||
@@ -26,10 +32,22 @@ struct HomeView: View {
|
|||||||
manager.updateSleep()
|
manager.updateSleep()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func getTotalSleepDebt() -> Int {
|
||||||
|
let totalSleep = manager.sleepForLastXDays[settings.sleepDebtPeriod] ?? 0
|
||||||
|
let desiredSleep = settings.desiredHoursOfSleep * settings.sleepDebtPeriod.rawValue * 60 * 60
|
||||||
|
return max(desiredSleep - totalSleep, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func getDailyRepaymentSleep() -> Int {
|
||||||
|
let sleepDebtPerDay = self.getTotalSleepDebt() / settings.repaymentPeriod
|
||||||
|
return settings.desiredHoursOfSleep * 60 * 60 + sleepDebtPerDay
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
HomeView()
|
HomeView()
|
||||||
.environmentObject(HealthKitManager())
|
.environmentObject(HealthKitManager())
|
||||||
.environmentObject(SleepDebtSettings())
|
.environmentObject(SleepDebtSettings())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ struct SettingsView: View {
|
|||||||
@FocusState private var focusItem: Bool
|
@FocusState private var focusItem: Bool
|
||||||
private var repaymentString = "Repayment period (days)"
|
private var repaymentString = "Repayment period (days)"
|
||||||
private var sleepDebtString = "Sleep debt period (days)"
|
private var sleepDebtString = "Sleep debt period (days)"
|
||||||
private var desiredHoursOfSleepString = "Desired hours of sleep"
|
private var desiredHoursOfSleepString = "Desired hours of sleep per day"
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ struct SleepDebtApp: App {
|
|||||||
SleepDebtTabView()
|
SleepDebtTabView()
|
||||||
.environmentObject(healthKitManager)
|
.environmentObject(healthKitManager)
|
||||||
.environmentObject(settings)
|
.environmentObject(settings)
|
||||||
|
.preferredColorScheme(.dark)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user