Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/SM-004-Streak'
Browse files Browse the repository at this point in the history
Conflicts:
	Bilbary for iPhone/Bilbary.swift
  • Loading branch information
Zahlkovsk1 committed Jul 13, 2024
2 parents 6642a16 + b730cca commit dc86b3c
Show file tree
Hide file tree
Showing 15 changed files with 176 additions and 117 deletions.
2 changes: 1 addition & 1 deletion Bilbary for iPad/Views/BookInformationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct BookInformationView: View {
GenericInfoCard(onTap: {}, title: "Odes & Ballades", subTitle: "1802 - 1885", contentText: "\"Le Géant\" is a poem by Victor Hugo in which the speaker is a giant, metaphorically representing great individual power. The giant recounts his life of strength and adventure, from his upbringing in harsh environments, through bouts with nature's elements and beasts, to his enjoyment of warfare. He proudly describes his ability to wield power without any armored protection. In the end, he acknowledges the inevitability of his own death and expresses a wish to be buried among majestic mountains so sublime that people will wonder which one serves as his tomb.", nameImage: "person.fill", number: 0)

Text("")
.padding(.horizontal, 30)
.padding(.horizontal, 30)
}
.frame(minWidth: BConstants.libraryOpenWidth)
.frame(maxWidth: BConstants.libraryOpenWidth)
Expand Down
4 changes: 2 additions & 2 deletions Bilbary for iPad/Views/BookPlaceholder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import Foundation

struct BookPlaceholder: Hashable {
struct BookPlaceholder: Hashable {

let url: URL?

init(from url: URL?) {
Expand Down
4 changes: 2 additions & 2 deletions Bilbary for iPad/Views/GeneralLibraryStructs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ struct CustomButton: View {
.foregroundColor(colorScheme == .dark ? .white : .black) // Foreground color
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
RoundedRectangle(cornerRadius: 8)
.stroke(Color.primary, lineWidth: 0.2)
)
)
.padding(.all, 7)
}
}
Expand Down
42 changes: 42 additions & 0 deletions Bilbary for iPhone/AppModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// AppModel.swift
// Bilbary for iPhone
//
// Created by Guillaume Coquard on 11/07/24.
//

import Foundation
import SwiftUI
import SwiftData

@Model
class ReadSession: Identifiable {

typealias ID = UUID

@Attribute(.unique)
let id: ID = ID()

let startTime: Date
private(set) var endTime: Date?

init() {
self.startTime = .now
}

func end() -> Self {
self.endTime = .now
return self
}

}

@MainActor
let AppModelContainer: ModelContainer = {
do {
let container = try ModelContainer(for: ReadSession.self)
return container
} catch {
fatalError("Failed to create container")
}
}()
38 changes: 11 additions & 27 deletions Bilbary for iPhone/Bilbary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,17 @@
import SwiftUI

@main
@MainActor
struct Bilbary: App {
@StateObject private var appUsageTracker = AppUsageTracker()

@Environment(\.scenePhase) private var scenePhase
@State
private var appUsageTracker = AppUsageTracker()

var body: some Scene {
WindowGroup {
TimerView()
.environmentObject(appUsageTracker)
.onAppear {
appUsageTracker.startSession()
}
.onDisappear {
appUsageTracker.endSession()
}
}
.onChange(of: scenePhase) {
switch scenePhase {
case .active:
appUsageTracker.resumeSession()
case .inactive:
appUsageTracker.pauseSession()
case .background:
appUsageTracker.pauseSession()
@unknown default:
break
}
}
}
}
var body: some Scene {
WindowGroup {
BilbaryView()
.environment(appUsageTracker)
}
.modelContainer(AppModelContainer)
}
}
45 changes: 44 additions & 1 deletion Bilbary for iPhone/BilbaryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,33 @@
//

import SwiftUI
import SwiftData

struct BilbaryView: View {

@Environment(\.modelContext)
private var context

@Environment(AppUsageTracker.self)
private var appUsageTracker

@State
private var detent: PresentationDetent = .height(64)

@State
private var tabBarShown: Bool = false

@Environment(\.scenePhase)
private var scenePhase

@Query
private var sessions: [ReadSession]

private var timer = Timer.publish(every: 0.1, on: .main, in: .default).autoconnect()

@State
private var timeSpent: TimeInterval?

let columns: [GridItem] = [
.init(.flexible(minimum: 0, maximum: .infinity), alignment: .center),
.init(.flexible(minimum: 0, maximum: .infinity), alignment: .center),
Expand Down Expand Up @@ -70,7 +88,16 @@ struct BilbaryView: View {
.clipShape(RoundedRectangle(cornerRadius: 8))

ScrollView {

VStack {
if let timeSpent = timeSpent {
VStack {
Text(timeSpent, format: .number.rounded(rule: .toNearestOrEven, increment: 1))
.padding()
Text("\(sessions.count) sessions")
.padding()
}
}
HStack {
Text("Library")
.font(.largeTitle)
Expand Down Expand Up @@ -98,7 +125,23 @@ struct BilbaryView: View {
.presentationCompactAdaptation(.automatic)
.interactiveDismissDisabled()
}

.onReceive(self.timer) { _ in
timeSpent = appUsageTracker.computeTimeSpentToday(sessions)
}
.onAppear {
appUsageTracker.startSession(to: context)
}
.onDisappear {
appUsageTracker.endSession(to: context)
}
.onChange(of: scenePhase) { _, newPhase in
switch newPhase {
case .active:
appUsageTracker.startSession(to: context)
default:
appUsageTracker.endSession(to: context)
}
}
}
}

Expand Down
83 changes: 33 additions & 50 deletions Bilbary for iPhone/determineHigherValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,45 @@
//
import SwiftUI
import Combine
import SwiftData

class AppUsageTracker: ObservableObject {
private var timer: Timer?
private var startDate: Date?
private var accumulatedTime: TimeInterval = 0

@Published var totalTimeSpent: TimeInterval = 0

func startSession() {
startDate = Date()
startTimer()
}

func endSession() {
stopTimer()
saveAccumulatedTime()
@Observable
class AppUsageTracker {

var currentSession: ReadSession?

func startSession(to context: ModelContext) {
guard currentSession == nil else { return }
currentSession = .init()
}

func resumeSession() {
if let startDate = startDate {
accumulatedTime += Date().timeIntervalSince(startDate)

func endSession(to context: ModelContext) {
if let currentSession = currentSession {
context.insert(currentSession.end())
do {
try context.save()
} catch {
print(error.localizedDescription)
}
}
startTimer()
self.currentSession = nil
}

func pauseSession() {
if let startDate = startDate {
accumulatedTime += Date().timeIntervalSince(startDate)
}
stopTimer()

func computeTimeSpentToday(_ sessions: ReadSession...) -> TimeInterval {
self.computeTimeSpentToday(sessions)
}

private func startTimer() {
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
self?.updateTotalTime()

func computeTimeSpentToday(_ sessions: [ReadSession]) -> TimeInterval {
var duration: TimeInterval = 0
for session in sessions {
if let endTime = session.endTime {
duration += session.startTime.distance(to: endTime)
}
}
}

private func stopTimer() {
timer?.invalidate()
timer = nil
}

private func updateTotalTime() {
if let startDate = startDate {
totalTimeSpent = accumulatedTime + Date().timeIntervalSince(startDate)
if let currentSession = currentSession {
duration += currentSession.startTime.distance(to: .now)
}
return duration
}

private func saveAccumulatedTime() {
let userDefaults = UserDefaults.standard
userDefaults.set(totalTimeSpent, forKey: "totalTimeSpent")
}

func loadTotalTimeSpent() {
let userDefaults = UserDefaults.standard
totalTimeSpent = userDefaults.double(forKey: "totalTimeSpent")
}

}
30 changes: 15 additions & 15 deletions Bilbary for iPhone/timerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@

import SwiftUI

struct TimerView: View {
@EnvironmentObject var appUsageTracker: AppUsageTracker

var body: some View {
VStack {
Text("Total Time Spent: \(appUsageTracker.totalTimeSpent, specifier: "%.2f") seconds")
.padding()
}
.onAppear {
appUsageTracker.loadTotalTimeSpent()
}
}
}
// struct TimerView: View {
// @Environment(AppUsageTracker.self) var appUsageTracker: AppUsageTracker
//
// var body: some View {
// VStack {
// Text("Total Time Spent: \(appUsageTracker.totalTimeSpent, specifier: "%.2f") seconds")
// .padding()
// }
// .onAppear {
// appUsageTracker.loadTotalTimeSpent()
// }
// }
// }

//struct timerView: PreviewProvider {
// struct timerView: PreviewProvider {
// static var previews: some View {
// timerView()
// .environmentObject(AppUsageTracker())
// }
//}
// }
Loading

0 comments on commit dc86b3c

Please sign in to comment.