mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-03-25 08:55:46 +00:00
Update when the app launches or becomes active and it's been a day since last update
This commit is contained in:
parent
9b26688255
commit
b342baff02
4 changed files with 30 additions and 1 deletions
|
|
@ -167,12 +167,22 @@ class AppState: ObservableObject {
|
|||
updatePublisher = update()
|
||||
.sink(
|
||||
receiveCompletion: { [unowned self] _ in
|
||||
Current.defaults.setDate(Current.date(), forKey: "lastUpdated")
|
||||
self.updatePublisher = nil
|
||||
},
|
||||
receiveValue: { _ in }
|
||||
)
|
||||
}
|
||||
|
||||
func updateIfNeeded() {
|
||||
guard
|
||||
let lastUpdated = Current.defaults.date(forKey: "lastUpdated"),
|
||||
// This is bad date math but for this use case it doesn't need to be exact
|
||||
lastUpdated < Current.date().addingTimeInterval(-60 * 60 * 24)
|
||||
else { return }
|
||||
update() as Void
|
||||
}
|
||||
|
||||
private func update() -> AnyPublisher<[Xcode], Never> {
|
||||
signInIfNeeded()
|
||||
.flatMap {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public struct Environment {
|
|||
public var logging = Logging()
|
||||
public var keychain = Keychain()
|
||||
public var defaults = Defaults()
|
||||
public var date: () -> Date = Date.init
|
||||
}
|
||||
|
||||
public var Current = Environment()
|
||||
|
|
@ -153,6 +154,16 @@ public struct Defaults {
|
|||
string(key)
|
||||
}
|
||||
|
||||
public var date: (String) -> Date? = { Date(timeIntervalSince1970: UserDefaults.standard.double(forKey: $0)) }
|
||||
public func date(forKey key: String) -> Date? {
|
||||
date(key)
|
||||
}
|
||||
|
||||
public var setDate: (Date?, String) -> Void = { UserDefaults.standard.set($0?.timeIntervalSince1970, forKey: $1) }
|
||||
public func setDate(_ value: Date?, forKey key: String) {
|
||||
setDate(value, key)
|
||||
}
|
||||
|
||||
public var set: (Any?, String) -> Void = { UserDefaults.standard.set($0, forKey: $1) }
|
||||
public func set(_ value: Any?, forKey key: String) {
|
||||
set(value, key)
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ struct XcodeListView: View {
|
|||
}
|
||||
.navigationSubtitle(Text("Updated \(Date().addingTimeInterval(-600), style: .relative) ago"))
|
||||
.frame(minWidth: 200, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
|
||||
.onAppear(perform: appState.update)
|
||||
.alert(item: $appState.error) { error in
|
||||
Alert(title: Text(error.title),
|
||||
message: Text(verbatim: error.message),
|
||||
|
|
|
|||
|
|
@ -4,12 +4,21 @@ import AppKit
|
|||
@main
|
||||
struct XcodesApp: App {
|
||||
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate: AppDelegate
|
||||
@SwiftUI.Environment(\.scenePhase) private var scenePhase: ScenePhase
|
||||
@StateObject private var appState = AppState()
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup("Xcodes") {
|
||||
XcodeListView()
|
||||
.environmentObject(appState)
|
||||
// This is intentionally used on a View, and not on a WindowGroup,
|
||||
// so that it's triggered when an individual window's phase changes instead of all window phases.
|
||||
// When used on a View it's also invoked on launch, which doesn't occur with a WindowGroup.
|
||||
.onChange(of: scenePhase) { newScenePhase in
|
||||
if case .active = newScenePhase {
|
||||
appState.updateIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
.commands {
|
||||
CommandGroup(replacing: .appInfo) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue