Skip to content

Commit

Permalink
Basic popover UI to change sensor id
Browse files Browse the repository at this point in the history
  • Loading branch information
ayn committed Oct 8, 2020
1 parent de943f5 commit 339b243
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 6 deletions.
8 changes: 8 additions & 0 deletions PurpleMenu.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
3748D197252D505300A758D6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3748D195252D505300A758D6 /* Main.storyboard */; };
3748D1A0252D50F100A758D6 /* LauncherApplication.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3748D18A252D505200A758D6 /* LauncherApplication.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
3748D1A5252D511200A758D6 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3748D1A4252D511200A758D6 /* ServiceManagement.framework */; };
37A3C07F252FB74400C2D12C /* SensorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A3C07E252FB74400C2D12C /* SensorViewModel.swift */; };
37A3C083252FCCA700C2D12C /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A3C082252FCCA700C2D12C /* UserDefaultsExtension.swift */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -56,6 +58,8 @@
3748D198252D505300A758D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3748D199252D505300A758D6 /* LauncherApplication.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LauncherApplication.entitlements; sourceTree = "<group>"; };
3748D1A4252D511200A758D6 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
37A3C07E252FB74400C2D12C /* SensorViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorViewModel.swift; sourceTree = "<group>"; };
37A3C082252FCCA700C2D12C /* UserDefaultsExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtension.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -109,6 +113,8 @@
3726C1E0252CF33000B0B216 /* Sensor.swift */,
3726C1E3252CF44600B0B216 /* Result.swift */,
3726C1E6252CF4CE00B0B216 /* PurpleAirApi.swift */,
37A3C07E252FB74400C2D12C /* SensorViewModel.swift */,
37A3C082252FCCA700C2D12C /* UserDefaultsExtension.swift */,
);
path = PurpleMenu;
sourceTree = "<group>";
Expand Down Expand Up @@ -256,6 +262,8 @@
3726C1E1252CF33000B0B216 /* Sensor.swift in Sources */,
3726C1E7252CF4CE00B0B216 /* PurpleAirApi.swift in Sources */,
3726C1E4252CF44600B0B216 /* Result.swift in Sources */,
37A3C07F252FB74400C2D12C /* SensorViewModel.swift in Sources */,
37A3C083252FCCA700C2D12C /* UserDefaultsExtension.swift in Sources */,
3726C1CD252CEEA900B0B216 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
23 changes: 20 additions & 3 deletions PurpleMenu/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
// Created by Andrew Ng on 10/6/20.
//

import Foundation
import Cocoa
import SwiftUI
import Combine
import ServiceManagement

extension Notification.Name {
Expand All @@ -16,19 +18,23 @@ extension Notification.Name {
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
let statusBarItem = NSStatusBar.system.statusItem(withLength: CGFloat(NSStatusItem.variableLength))
let sensorViewModel = SensorViewModel()
private var subscriptions: Set<AnyCancellable> = []
var window: NSWindow!
lazy var popover: NSPopover = {
let contentView = ContentView()
let popover = NSPopover()

popover.contentSize = NSSize(width: 400, height: 400)
popover.contentSize = NSSize(width: 300, height: 200)
popover.behavior = .transient
popover.contentViewController = NSHostingController(rootView: contentView)

return popover
}()

func applicationDidFinishLaunching(_ aNotification: Notification) {
statusBarItem.button?.action = #selector(togglePopover(_:))
bindDefaults()
refreshAqi()

_ = Timer.scheduledTimer(withTimeInterval: 300, repeats: true, block: { (_) in
Expand All @@ -53,6 +59,17 @@ class AppDelegate: NSObject, NSApplicationDelegate {

// MARK: - Private methods

private func bindDefaults() {
UserDefaults.standard
.publisher(for: \.sensorId)
.handleEvents(receiveOutput: { sensorId in
debugPrint("sensorId is now: \(sensorId)")
self.refreshAqi()
})
.sink { _ in }
.store(in: &subscriptions)
}

@objc func togglePopover(_ sender: AnyObject?) {
guard let button = statusBarItem.button else { return }

Expand All @@ -64,7 +81,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

func refreshAqi() {
PurpleAirApi(sensorId: "67533").getData { (sensor) in
PurpleAirApi(sensorId: UserDefaults.standard.sensorId).getData { (sensor) in
guard let result = sensor.results?.first,
let resultB = sensor.results?.last,
let pm25Str = result.pM2_5Value,
Expand All @@ -77,7 +94,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
let humidity = Float(humidityStr)
else { return }

debugPrint("pm25 = \(pm25), pm25Cf1 = \(pm25Cf1), RH = \(humidity)")
debugPrint("id = \(self.sensorViewModel.sensorId), pm25 = \(pm25), pm25Cf1 = \(pm25Cf1), RH = \(humidity)")

let aqi = self.pmToEPA(paCf1: (pm25Cf1 + pm25Cf1B) * 0.5, humidity: humidity)

Expand Down
27 changes: 25 additions & 2 deletions PurpleMenu/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,32 @@
import SwiftUI

struct ContentView: View {
@ObservedObject var sensor = SensorViewModel()

var body: some View {
Text("Hello, World!")
.frame(maxWidth: .infinity, maxHeight: .infinity)
GeometryReader { g in
VStack {
Spacer()
HStack {
Text("Sensor ID")
.frame(alignment: .trailing)
TextField("Sensor ID", text: $sensor.sensorId, onCommit: {
sensor.update()
})
.frame(width: 80)
}
.frame(width: g.size.width / 2, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
HStack {
Button("Update") {
sensor.update()
}
Button("Quit") {
exit(0)
}
}
Spacer()
}
}
}
}

Expand Down
21 changes: 21 additions & 0 deletions PurpleMenu/SensorViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// SensorViewModel.swift
// PurpleMenu
//
// Created by Andrew Ng on 10/8/20.
//

import Foundation
import Combine

final class SensorViewModel: ObservableObject {
static let userDefaultsKey = "SensorId"

@Published var sensorId = UserDefaults.standard.sensorId

func update() {
if !sensorId.isEmpty {
UserDefaults.standard.sensorId = sensorId
}
}
}
19 changes: 19 additions & 0 deletions PurpleMenu/UserDefaultsExtension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// UserDefaultsExtension.swift
// PurpleMenu
//
// Created by Andrew Ng on 10/8/20.
//

import Foundation

extension UserDefaults {
@objc var sensorId: String {
get {
return string(forKey: "sensor_id") ?? "67533"
}
set {
set(newValue, forKey: "sensor_id")
}
}
}
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ For now you can change the `sensorId` [here](https://github.com/ayn/PurpleMenu/b
## TODOS

* Settings UI
* choose nearby sensor
* choose which conversion (or none) to use

0 comments on commit 339b243

Please sign in to comment.