Skip to content

Commit

Permalink
Refactor JotaiStore
Browse files Browse the repository at this point in the history
  • Loading branch information
Innei committed Jul 17, 2023
1 parent 21d7460 commit c492445
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 16 deletions.
4 changes: 2 additions & 2 deletions ProcessReporter.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.2.0;
MARKETING_VERSION = 1.2.1;
PRODUCT_BUNDLE_IDENTIFIER = dev.innei.ProcessReporter;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down Expand Up @@ -407,7 +407,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.2.0;
MARKETING_VERSION = 1.2.1;
PRODUCT_BUNDLE_IDENTIFIER = dev.innei.ProcessReporter;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"location" : "https://github.com/unixzii/SwiftJotai",
"state" : {
"branch" : "main",
"revision" : "5cb8daf78f9fc392bbe4abd37046cf0a274427a2"
"revision" : "7a185bf1c0e4d435c4222471a04dea1a6075c21a"
}
}
],
Expand Down
5 changes: 5 additions & 0 deletions ProcessReporter/Atoms.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ enum Atoms {
static let lastReportDataAtom = Atom<PostData?>(nil)

static let currentFrontAppAtom = Atom<String?>(nil)

static let updateIntervalAtom = Atom(userDefaultsKey: "update-interval", defaultValue: 60)

static let apiKeyAtom = Atom(userDefaultsKey: "apiKey", defaultValue: "")
static let endpointAtom = Atom(userDefaultsKey: "endpoint", defaultValue: "")
}

let JotaiStore = SwiftJotai.Store.self
41 changes: 34 additions & 7 deletions ProcessReporter/Reporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import SwiftJotai
class Reporter {
public static var shared = Reporter()

private var disposeReporingSub: Disposable?
// private var disposeReporingSub: Disposable?
private var disposerList = [Disposable]()
init() {
disposeReporingSub = JotaiStore.shared.subscribe(atom: Atoms.isReportingAtom) { [weak self] in
let d1 = JotaiStore.shared.subscribe(atom: Atoms.isReportingAtom) { [weak self] in
let isReporting = JotaiStore.shared.get(Atoms.isReportingAtom)
debugPrint("isReporting: \(isReporting)")
if isReporting {
Expand All @@ -23,10 +24,24 @@ class Reporter {
self?.stopReporting()
}
}

let d2 = JotaiStore.shared.subscribe(atom: Atoms.updateIntervalAtom) { [weak self] in
guard let self = self else { return }
guard let timer = self.timer else { return }
let isReporting = JotaiStore.shared.get(Atoms.isReportingAtom)
if !isReporting {
return
}
self.stopReporting()

self.startReporting()
}

disposerList.append(contentsOf: [d1, d2])
}

deinit {
disposeReporingSub?.dispose()
disposerList.forEach { $0.dispose() }
}

var timer: Timer?
Expand Down Expand Up @@ -56,7 +71,9 @@ class Reporter {
}
}

timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { _ in
let interval = TimeInterval(JotaiStore.shared.get(Atoms.updateIntervalAtom))

timer = Timer.scheduledTimer(withTimeInterval: max(interval, 1.0), repeats: true) { _ in
Task {
await MainActor.run {
self.report()
Expand Down Expand Up @@ -85,7 +102,17 @@ class Reporter {
}

func isInited() -> Bool {
return Store.shared.apiKey != "" && Store.shared.apiKey != ""
let apiKey = getApiKey()
let endpoint = getEndpoint()
return apiKey != "" && endpoint != ""
}

private func getApiKey() -> String {
JotaiStore.shared.get(Atoms.apiKeyAtom)
}

private func getEndpoint() -> String {
JotaiStore.shared.get(Atoms.endpointAtom)
}

private func report() {
Expand All @@ -99,8 +126,8 @@ class Reporter {

let mediaInfo = getCurrnetPlaying()

let endpoint = Store.shared.endpoint
let apiKey = Store.shared.apiKey
let endpoint = getEndpoint()
let apiKey = getApiKey()

if endpoint == "" {
debugPrint("endpoint not define")
Expand Down
2 changes: 0 additions & 2 deletions ProcessReporter/Store.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import Foundation

class Store: ObservableObject {
@Persisted("apiKey") var apiKey: String = ""
@Persisted("endpoint") var endpoint: String = ""
@Persisted("reportType") var reportType: [ReportType] = [.media, .process]

public static let shared = Store()
Expand Down
45 changes: 41 additions & 4 deletions ProcessReporter/Views/SettingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,44 @@
// Created by Innei on 2023/6/24.
//

import Combine
import LaunchAtLogin
import SwiftJotai
import SwiftUI

struct SettingView: View {
@EnvironmentObject var store: Store
@StateObject var apiKey = AtomValue(Atoms.apiKeyAtom)
@StateObject var endpoint = AtomValue(Atoms.endpointAtom)
@State private var launchAtLogin = false
@StateObject var updateInterval = AtomValue(Atoms.updateIntervalAtom)

private enum Tabs: Hashable {
case general
}

let numberFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.minimum = .init(integerLiteral: 1)
formatter.maximum = .init(integerLiteral: Int.max)
formatter.generatesDecimalNumbers = false
formatter.maximumFractionDigits = 0
return formatter
}()

var body: some View {
TabView {
Form {
LaunchAtLogin.Toggle {
Text("Launch at login")
}

SecureField("API Key", text: $store.apiKey)
TextField("Endpoint", text: $store.endpoint)
TextField("Report interval", value: updateInterval.binding, formatter: numberFormatter)

SecureField("API Key", text: apiKey.binding)
TextField("Endpoint", text: endpoint.binding)
}
.padding(20)
.frame(width: 350, height: 100)
.frame(width: 350)
.tabItem {
Label("General", systemImage: "gear")
}
Expand All @@ -41,3 +56,25 @@ struct SettingView_Previews: PreviewProvider {
SettingView()
}
}

struct RangeIntegerStyle: ParseableFormatStyle {
var parseStrategy: RangeIntegerStrategy = .init()
let range: ClosedRange<Int>

func format(_ value: Int) -> String {
let constrainedValue = min(max(value, range.lowerBound), range.upperBound)
return "\(constrainedValue)"
}
}

struct RangeIntegerStrategy: ParseStrategy {
func parse(_ value: String) throws -> Int {
return Int(value) ?? 1
}
}

extension FormatStyle where Self == RangeIntegerStyle {
static func ranged(_ range: ClosedRange<Int>) -> RangeIntegerStyle {
return RangeIntegerStyle(range: range)
}
}

0 comments on commit c492445

Please sign in to comment.