wireguard-apple/Sources/WireGuardApp/UI/macOS/StatusItemController.swift

65 lines
2.1 KiB
Swift
Raw Normal View History

// SPDX-License-Identifier: MIT
// Copyright © 2018-2023 WireGuard LLC. All Rights Reserved.
import Cocoa
class StatusItemController {
var currentTunnel: TunnelContainer? {
didSet {
updateStatusItemImage()
}
}
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
private let statusBarImageWhenActive = NSImage(named: "StatusBarIcon")!
private let statusBarImageWhenInactive = NSImage(named: "StatusBarIconDimmed")!
private let animationImages = [
NSImage(named: "StatusBarIconDot1")!,
NSImage(named: "StatusBarIconDot2")!,
NSImage(named: "StatusBarIconDot3")!
]
private var animationImageIndex: Int = 0
private var animationTimer: Timer?
init() {
updateStatusItemImage()
}
func updateStatusItemImage() {
guard let currentTunnel = currentTunnel else {
stopActivatingAnimation()
statusItem.button?.image = statusBarImageWhenInactive
return
}
switch currentTunnel.status {
case .inactive:
stopActivatingAnimation()
statusItem.button?.image = statusBarImageWhenInactive
case .active:
stopActivatingAnimation()
statusItem.button?.image = statusBarImageWhenActive
case .activating, .waiting, .reasserting, .restarting, .deactivating:
startActivatingAnimation()
}
}
func startActivatingAnimation() {
guard animationTimer == nil else { return }
let timer = Timer(timeInterval: 0.3, repeats: true) { [weak self] _ in
guard let self = self else { return }
self.statusItem.button?.image = self.animationImages[self.animationImageIndex]
self.animationImageIndex = (self.animationImageIndex + 1) % self.animationImages.count
}
RunLoop.main.add(timer, forMode: .common)
animationTimer = timer
}
func stopActivatingAnimation() {
guard let timer = self.animationTimer else { return }
timer.invalidate()
animationTimer = nil
animationImageIndex = 0
}
}