Skip to content

Commit 5ad92bf

Browse files
committed
feat: updated login process to Stats Remote
1 parent 9fd9ed6 commit 5ad92bf

File tree

5 files changed

+92
-53
lines changed

5 files changed

+92
-53
lines changed

Kit/helpers.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,13 @@ public class PreferencesSection: NSStackView {
13161316
}
13171317

13181318
public func setRowVisibility(_ at: Int, newState: Bool) {
1319+
if at == 0 {
1320+
self.container.subviews[0].isHidden = !newState
1321+
if self.container.subviews.count > 1 {
1322+
self.container.subviews[1].isHidden = !newState
1323+
}
1324+
return
1325+
}
13191326
for i in self.container.subviews.indices where i/2 == at && Double(i).remainder(dividingBy: 2) == 0 {
13201327
self.container.subviews[i-1].isHidden = !newState
13211328
self.container.subviews[i].isHidden = !newState

Kit/plugins/Remote.swift

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,26 @@ import Cocoa
1414

1515
public class Remote {
1616
public static let shared = Remote()
17-
static public var host = URL(string: "https://api.system-stats.com")! // https://api.system-stats.com http://localhost:8008
17+
static public var host = URL(string: "http://localhost:8008")! // https://api.system-stats.com http://localhost:8008
1818

19-
public var state: Bool {
20-
get { Store.shared.bool(key: "remote_state", defaultValue: false) }
19+
public var monitoring: Bool {
20+
get { Store.shared.bool(key: "remote_monitoring", defaultValue: false) }
2121
set {
22-
Store.shared.set(key: "remote_state", value: newValue)
22+
Store.shared.set(key: "remote_monitoring", value: newValue)
2323
if newValue {
2424
self.start()
25-
} else {
25+
} else if !self.control {
26+
self.stop()
27+
}
28+
}
29+
}
30+
public var control: Bool {
31+
get { Store.shared.bool(key: "remote_control", defaultValue: false) }
32+
set {
33+
Store.shared.set(key: "remote_control", value: newValue)
34+
if newValue {
35+
self.start()
36+
} else if !self.monitoring {
2637
self.stop()
2738
}
2839
}
@@ -31,19 +42,18 @@ public class Remote {
3142
public var isAuthorized: Bool = false
3243
public var auth: RemoteAuth = RemoteAuth()
3344

45+
private let log: NextLog
3446
private var ws: WebSocketManager = WebSocketManager()
3547
private var wsURL: URL?
3648
private var isConnecting = false
3749

3850
public init() {
51+
self.log = NextLog.shared.copy(category: "Remote")
3952
self.id = UUID(uuidString: Store.shared.string(key: "telemetry_id", defaultValue: UUID().uuidString)) ?? UUID()
4053

41-
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
42-
if self.state {
43-
self.start()
44-
} else {
45-
self.stop()
46-
}
54+
if self.auth.hasCredentials() {
55+
info("Found auth credentials for remote monitoring, starting Remote...", log: self.log)
56+
self.start()
4757
}
4858

4959
NotificationCenter.default.addObserver(self, selector: #selector(self.successLogin), name: .remoteLoginSuccess, object: nil)
@@ -56,40 +66,41 @@ public class Remote {
5666

5767
public func login() {
5868
self.auth.login { url in
59-
guard let url else { return }
69+
guard let url else {
70+
error("Empty url when try to login", log: self.log)
71+
return
72+
}
73+
debug("Open \(url) to login to Stats Remote", log: self.log)
6074
NSWorkspace.shared.open(url)
6175
}
6276
}
6377

6478
public func logout() {
6579
self.auth.logout()
6680
self.isAuthorized = false
67-
self.state = false
6881
self.ws.disconnect()
69-
NotificationCenter.default.post(name: .remoteState, object: nil, userInfo: ["auth": self.isAuthorized, "state": self.state])
82+
debug("Logout successfully from Stats Remote", log: self.log)
83+
NotificationCenter.default.post(name: .remoteState, object: nil, userInfo: ["auth": self.isAuthorized])
7084
}
7185

7286
public func send(key: String, value: Codable) {
73-
guard self.state && self.isAuthorized,
74-
let blobData = try? JSONEncoder().encode(value) else { return }
87+
guard self.monitoring && self.isAuthorized, let blobData = try? JSONEncoder().encode(value) else { return }
7588
self.ws.send(key: key, data: blobData)
7689
}
7790

7891
@objc private func successLogin() {
7992
self.isAuthorized = true
80-
NotificationCenter.default.post(name: .remoteState, object: nil, userInfo: ["auth": self.isAuthorized, "state": self.state])
81-
82-
if self.state {
83-
self.ws.connect()
84-
}
93+
NotificationCenter.default.post(name: .remoteState, object: nil, userInfo: ["auth": self.isAuthorized])
94+
self.ws.connect()
95+
debug("Login successfully on Stats Remote", log: self.log)
8596
}
8697

8798
public func start() {
8899
self.auth.isAuthorized { [weak self] status in
89100
guard let self else { return }
90101

91102
self.isAuthorized = status
92-
NotificationCenter.default.post(name: .remoteState, object: nil, userInfo: ["auth": self.isAuthorized, "state": self.state])
103+
NotificationCenter.default.post(name: .remoteState, object: nil, userInfo: ["auth": self.isAuthorized])
93104

94105
if status {
95106
self.ws.connect()
@@ -99,7 +110,7 @@ public class Remote {
99110

100111
private func stop() {
101112
self.ws.disconnect()
102-
NotificationCenter.default.post(name: .remoteState, object: nil, userInfo: ["auth": self.isAuthorized, "state": self.state])
113+
NotificationCenter.default.post(name: .remoteState, object: nil, userInfo: ["auth": self.isAuthorized])
103114
}
104115
}
105116

@@ -128,8 +139,15 @@ public class RemoteAuth {
128139
}
129140

130141
public func isAuthorized(completion: @escaping (Bool) -> Void) {
142+
if !self.hasCredentials() {
143+
completion(false)
144+
return
145+
}
131146
self.validate(completion)
132147
}
148+
public func hasCredentials() -> Bool {
149+
return !self.accessToken.isEmpty && !self.refreshToken.isEmpty
150+
}
133151

134152
public func login(completion: @escaping (URL?) -> Void) {
135153
self.registerDevice { device in
@@ -335,14 +353,17 @@ class WebSocketManager: NSObject {
335353
private let reconnectDelay: TimeInterval = 3.0
336354
private var pingTimer: Timer?
337355
private var reachability: Reachability = Reachability(start: true)
356+
private let log: NextLog
338357

339358
override init() {
359+
self.log = NextLog.shared.copy(category: "Remote WS")
360+
340361
super.init()
341362

342363
self.session = URLSession(configuration: .default, delegate: self, delegateQueue: .main)
343364

344365
self.reachability.reachable = {
345-
if Remote.shared.state {
366+
if Remote.shared.isAuthorized {
346367
self.connect()
347368
}
348369
}
@@ -367,19 +388,25 @@ class WebSocketManager: NSObject {
367388
self.webSocket?.resume()
368389
self.receiveMessage()
369390
self.isDisconnected = false
391+
debug("connected successfully", log: self.log)
370392
}
371393
}
372394

373395
public func disconnect() {
396+
if self.webSocket == nil && !self.isConnected { return }
374397
self.isDisconnected = true
375398
self.webSocket?.cancel(with: .normalClosure, reason: nil)
376399
self.webSocket = nil
377400
self.isConnected = false
401+
debug("disconnected gracefully", log: self.log)
378402
}
379403

380404
private func reconnect() {
381405
guard !self.isDisconnected else { return }
382406
DispatchQueue.main.asyncAfter(deadline: .now() + self.reconnectDelay) { [weak self] in
407+
if let log = self?.log {
408+
debug("trying to reconnect after some interruption", log: log)
409+
}
383410
self?.connect()
384411
}
385412
}

Stats/Supporting Files/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundleShortVersionString</key>
1818
<string>$(MARKETING_VERSION)</string>
1919
<key>CFBundleVersion</key>
20-
<string>689</string>
20+
<string>690</string>
2121
<key>Description</key>
2222
<string>Simple macOS system monitor in your menu bar</string>
2323
<key>LSApplicationCategoryType</key>

Stats/Views/AppSettings.swift

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ class ApplicationSettings: NSStackView {
4242
private var updateSelector: NSPopUpButton?
4343
private var startAtLoginBtn: NSSwitch?
4444
private var telemetryBtn: NSSwitch?
45-
private var remoteBtn: NSSwitch?
4645

4746
private var combinedModulesView: PreferencesSection?
4847
private var fanHelperView: PreferencesSection?
@@ -129,17 +128,19 @@ class ApplicationSettings: NSStackView {
129128
self.combinedModulesView?.setRowVisibility(3, newState: self.combinedModulesState)
130129
self.combinedModulesView?.setRowVisibility(4, newState: self.combinedModulesState)
131130

132-
self.remoteBtn = switchView(
133-
action: #selector(self.toggleRemoteState),
134-
state: Remote.shared.state
135-
)
136-
137-
self.remoteView = PreferencesSection(label: localizedString("Stats Remote"), [
138-
PreferencesRow(localizedString("Monitoring"), component: self.remoteBtn!),
131+
self.remoteView = PreferencesSection(label: localizedString("Stats Remote (beta)"), [
132+
PreferencesRow(localizedString("Authorization"), component: buttonView(#selector(self.loginToRemote), text: localizedString("Login"))),
139133
PreferencesRow(localizedString("Identificator"), component: textView(Remote.shared.id.uuidString)),
134+
PreferencesRow(localizedString("Monitoring"), component: switchView(
135+
action: #selector(self.toggleRemoteMonitoringState),
136+
state: Remote.shared.monitoring
137+
)),
140138
PreferencesRow(component: buttonView(#selector(self.logoutFromRemote), text: localizedString("Logout")))
141139
])
142140
scrollView.stackView.addArrangedSubview(self.remoteView!)
141+
self.remoteView?.setRowVisibility(1, newState: false)
142+
self.remoteView?.setRowVisibility(2, newState: false)
143+
self.remoteView?.setRowVisibility(3, newState: false)
143144

144145
scrollView.stackView.addArrangedSubview(PreferencesSection(label: localizedString("Settings"), [
145146
PreferencesRow(
@@ -184,7 +185,7 @@ class ApplicationSettings: NSStackView {
184185
scrollView.stackView.addArrangedSubview(PreferencesSection(label: localizedString("Stress tests"), tests))
185186

186187
NotificationCenter.default.addObserver(self, selector: #selector(self.toggleUninstallHelperButton), name: .fanHelperState, object: nil)
187-
NotificationCenter.default.addObserver(self, selector: #selector(self.remoteState), name: .remoteState, object: nil)
188+
NotificationCenter.default.addObserver(self, selector: #selector(self.handleRemoteState), name: .remoteState, object: nil)
188189
}
189190

190191
required init?(coder: NSCoder) {
@@ -420,34 +421,38 @@ class ApplicationSettings: NSStackView {
420421
}
421422
}
422423

423-
@objc private func logoutFromRemote() {
424-
Remote.shared.logout()
424+
@objc private func toggleRemoteMonitoringState(_ sender: NSButton) {
425+
Remote.shared.monitoring = sender.state == NSControl.StateValue.on
426+
}
427+
428+
@objc private func handleRemoteState(_ notification: Notification) {
429+
guard let auth = notification.userInfo?["auth"] as? Bool else { return }
430+
self.setRemoteSettings(auth)
425431
}
426432

427-
@objc private func remoteState(_ notification: Notification) {
428-
guard let state = notification.userInfo?["state"] as? Bool, let auth = notification.userInfo?["auth"] as? Bool else { return }
429-
self.setRemoteSettings(state, auth)
433+
@objc private func loginToRemote() {
434+
Remote.shared.login()
430435
}
431436

432-
private func setRemoteSettings(_ state: Bool, _ auth: Bool) {
437+
@objc private func logoutFromRemote() {
438+
Remote.shared.logout()
439+
}
440+
441+
private func setRemoteSettings(_ auth: Bool) {
433442
DispatchQueue.main.async {
434-
if state && auth {
435-
self.remoteBtn?.state = .on
443+
if auth {
436444
self.remoteView?.setRowVisibility(1, newState: true)
437445
self.remoteView?.setRowVisibility(2, newState: true)
438-
return
439-
} else if state && !auth {
440-
Remote.shared.login()
446+
self.remoteView?.setRowVisibility(3, newState: true)
447+
self.remoteView?.setRowVisibility(0, newState: false)
448+
} else {
449+
self.remoteView?.setRowVisibility(0, newState: true)
450+
self.remoteView?.setRowVisibility(1, newState: false)
451+
self.remoteView?.setRowVisibility(2, newState: false)
452+
self.remoteView?.setRowVisibility(3, newState: false)
441453
}
442-
self.remoteBtn?.state = .off
443-
self.remoteView?.setRowVisibility(1, newState: false)
444-
self.remoteView?.setRowVisibility(2, newState: false)
445454
}
446455
}
447-
448-
@objc private func toggleRemoteState(_ sender: NSButton) {
449-
Remote.shared.state = sender.state == NSControl.StateValue.on
450-
}
451456
}
452457

453458
private class ModuleSelectorView: NSStackView {

Widgets/Supporting Files/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<key>CFBundleShortVersionString</key>
1414
<string>2.11.37</string>
1515
<key>CFBundleVersion</key>
16-
<string>689</string>
16+
<string>690</string>
1717
<key>NSExtension</key>
1818
<dict>
1919
<key>NSExtensionPointIdentifier</key>

0 commit comments

Comments
 (0)