Skip to content

Commit

Permalink
update 0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
nodeful committed Jun 21, 2020
1 parent 3355436 commit 36c0180
Show file tree
Hide file tree
Showing 16 changed files with 173 additions and 38 deletions.
Binary file modified native/app/Embedded/eqMac.driver/Contents/MacOS/eqMac
Binary file not shown.
Binary file modified native/app/Embedded/ui.zip
Binary file not shown.
43 changes: 27 additions & 16 deletions native/app/Source/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import SwiftyJSON
import ServiceManagement
import ReSwift
import Sparkle
import AudioKit

enum VolumeChangeDirection: String {
case UP = "UP"
Expand Down Expand Up @@ -71,6 +72,14 @@ class Application {


static public func start () {
// AudioKit Engine fucks with Driver installation, eqMac doesn't use it's engine anyway
try? AudioKit.stop()
try? AudioKit.shutdown()
AKSettings.audioInputEnabled = false
AKSettings.enableRouteChangeHandling = false
AKSettings.notificationsEnabled = false
AudioKit.engine.stop()

setupSettings()

if (!Constants.DEBUG) {
Expand Down Expand Up @@ -117,7 +126,7 @@ class Application {
) { install in
if install {
Driver.install(started: {
UI.showLoadingWindow("Installing eqMac audio driver")
UI.showLoadingWindow("Installing eqMac audio driver\nIf this process takes too long, please restart your Mac")
}) { success in
if (success) {
UI.hideLoadingWindow()
Expand All @@ -131,16 +140,16 @@ class Application {
quit()
}
}
} else if (Driver.isOutdated) {
} else if (Driver.isOutdated && Driver.skipCurrentVersion) {
Alert.confirm(
title: "Audio Driver Update",
message: "There is an optional Audio Driver update that should improve user experience. \nIn order to update eqMac will ask for your System Password. \nPlease close any apps playing audio (Spotify, YouTube etc.) otherwise installation might fail.",
okText: "Update Driver",
cancelText: "Skip update"
cancelText: "Skip Driver update"
) { update in
if update {
Driver.install(started: {
UI.showLoadingWindow("Updating eqMac audio driver")
UI.showLoadingWindow("Updating eqMac audio driver\nIf this process takes too long, please restart your Mac")
}) { success in
if (success) {
UI.hideLoadingWindow()
Expand All @@ -150,6 +159,7 @@ class Application {
}
}
} else {
Driver.skipCurrentVersion = true
completion()
}
}
Expand All @@ -161,7 +171,7 @@ class Application {
private static func driverFailedToInstallPrompt () {
UI.hideLoadingWindow()
Alert.confirm(
title: "Driver failed to install", message: "Unfortunately the audio driver has failed to install. You can restart eqMac and try again or quit.", okText: "Try again", cancelText: "Quit") { restart in
title: "Driver failed to install", message: "Unfortunately the audio driver has failed to install. You can restart eqMac and try again or quit. Alternatively, please try to restart your Mac and running eqMac again.", okText: "Try again", cancelText: "Quit") { restart in
if restart {
return self.restart()
} else {
Expand Down Expand Up @@ -258,7 +268,7 @@ class Application {
try! AudioDeviceEvents.recreateEventEmitters([.isAliveChanged, .volumeChanged, .nominalSampleRateChanged])
self.setupDriverDeviceEvents()
Utilities.delay(500) {
createAudioPipeline()
createAudioPipeline()
}
}
}
Expand Down Expand Up @@ -288,12 +298,12 @@ class Application {
return
}
let gain = Double(Driver.device!.virtualMasterVolume(direction: .playback)!)
Console.log(gain)
if (gain <= 1 && gain != Application.store.state.effects.volume.gain) {
Application.dispatchAction(VolumeAction.setGain(gain, false))
}

}

AudioDeviceEvents.on(.muteChanged, onDevice: Driver.device!) {
if (ignoreNextDriverMuteEvent) {
ignoreNextDriverMuteEvent = false
Expand Down Expand Up @@ -513,29 +523,30 @@ class Application {
updater.checkForUpdates(nil)
}

static func reinstallDriver (_ completion: @escaping () -> Void) {
static func reinstallDriver (_ completion: @escaping (Bool) -> Void) {
Alert.confirm(
title: "Audio Driver Reinstall",
message: "\nIn order to reinstall the driver eqMac we will ask for your System Password. \nPlease close any apps playing audio (Spotify, YouTube etc.) otherwise installation might fail.",
message: "\nIn order to reinstall the driver eqMac we will ask for your System Password. \nPlease close any apps playing audio (Spotify, YouTube etc.) otherwise installation might fail. eqMac will restart after this.",
cancelText: "Cancel"
) { reinstall in
if reinstall {
Driver.install(started: {
UI.showLoadingWindow("Installing eqMac audio driver")
self.stopListeners()
self.stopEngines()
self.switchBackToLastKnownDevice()
UI.close()
Utilities.delay(100) { UI.showLoadingWindow("Reinstalling eqMac driver\nIf this process takes too long, please restart your Mac") }
}) { success in
if (success) {
UI.hideLoadingWindow()
setupAudio()
completion()
completion(true)
Application.restart()
} else {
driverFailedToInstallPrompt()
}
}
} else {
completion()
completion(false)
}
}

Expand All @@ -546,8 +557,8 @@ class Application {
self.stopListeners()
self.stopEngines()
self.switchBackToLastKnownDevice()
UI.hide()
Utilities.delay(100) { UI.showLoadingWindow("Uninstalling eqMac") }
UI.close()
Utilities.delay(100) { UI.showLoadingWindow("Uninstalling eqMac\nIf this process takes too long, please restart your Mac") }
}) { success in
completion(success)
if (success) {
Expand Down
14 changes: 13 additions & 1 deletion native/app/Source/ApplicationDataBus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class ApplicationDataBus: DataBus {
return [
"name": host.localizedName as AnyObject,
"model": Sysctl.model as String,
"version": Bundle.main.infoDictionary?["CFBundleVersion"] as Any
"version": Bundle.main.infoDictionary?["CFBundleVersion"] as Any,
"driverVersion": Driver.lastInstalledVersion
]
}

Expand Down Expand Up @@ -59,6 +60,17 @@ class ApplicationDataBus: DataBus {
return nil
}

self.on(.GET, "/driver/reinstall/available") { _, res in
return "Yes"
}

self.on(.GET, "/driver/reinstall") { _, res in
Application.reinstallDriver { success in
res.send([ "reinstalled": success ])
}
return nil
}

self.on(.GET, "/update") { _, _ in
Application.checkForUpdates()
return "Checking for updates."
Expand Down
48 changes: 35 additions & 13 deletions native/app/Source/Audio/AudioDeviceEvents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ enum AudioDeviceEventType {

class AudioDeviceEvents: EventSubscriber {
static var events = AudioDeviceEvents()
static var listeners: [EmitterKit.EventListener<AudioDevice>] = [] as! [EmitterKit.EventListener<AudioDevice>]

var hashValue: Int = 1
static var listeners: [EmitterKit.EventListener<AudioDevice>] = [] as! [EmitterKit.EventListener<AudioDevice>]

var subscribed = false
// Per Device
let isJackConnectedChangedEvent = EmitterKit.Event<AudioDevice>()
let isRunningSomewhereChangedEvent = EmitterKit.Event<AudioDevice>()
Expand All @@ -63,17 +63,34 @@ class AudioDeviceEvents: EventSubscriber {
let inputChangedEvent = EmitterKit.Event<AudioDevice>()
let systemDeviceChangedEvent = EmitterKit.Event<AudioDevice>()

init () {
NotificationCenter.defaultCenter.subscribe(
self,
eventType: AudioHardwareEvent.self,
dispatchQueue: DispatchQueue.main
)
NotificationCenter.defaultCenter.subscribe(
self,
eventType: AudioDeviceEvent.self,
dispatchQueue: DispatchQueue.main
)
func subscribe () {
if !subscribed {
NotificationCenter.defaultCenter.subscribe(
self,
eventType: AudioHardwareEvent.self,
dispatchQueue: DispatchQueue.main
)
NotificationCenter.defaultCenter.subscribe(
self,
eventType: AudioDeviceEvent.self,
dispatchQueue: DispatchQueue.main
)
subscribed = true
}
}

func unsubscribe () {
NotificationCenter.defaultCenter.unsubscribe(self, eventType: AudioHardwareEvent.self)
NotificationCenter.defaultCenter.unsubscribe(self, eventType: AudioDeviceEvent.self)
subscribed = false
}

static func subscribe () {
events.subscribe()
}

static func unsubscribe () {
events.unsubscribe()
}

internal func eventReceiver(_ event: AMCoreAudio.Event) {
Expand Down Expand Up @@ -102,6 +119,7 @@ class AudioDeviceEvents: EventSubscriber {
}

static func recreateEventEmitters(_ eventsToRecreate: [AudioDeviceEventType]) throws {
subscribe()
for event in eventsToRecreate {
switch event {
case .isAliveChanged:
Expand Down Expand Up @@ -184,6 +202,7 @@ class AudioDeviceEvents: EventSubscriber {

@discardableResult
static func on (_ event: AudioDeviceEventType, retain: Bool = true, _ handler: @escaping (AudioDevice) -> Void) -> EmitterKit.EventListener<AudioDevice> {
events.subscribe()
let emitter = getEventEmitterFromEventType(event)
let listener: EmitterKit.EventListener<AudioDevice> = emitter.on(handler)
if (retain) {
Expand All @@ -199,6 +218,7 @@ class AudioDeviceEvents: EventSubscriber {

@discardableResult
static func once (_ event: AudioDeviceEventType, _ handler: @escaping (AudioDevice) -> Void) -> EmitterKit.EventListener<AudioDevice> {
events.subscribe()
let emitter = getEventEmitterFromEventType(event)
let listener: EmitterKit.EventListener<AudioDevice> = emitter.once(handler: handler)
return listener
Expand All @@ -223,12 +243,14 @@ class AudioDeviceEvents: EventSubscriber {
}

static func start () {
subscribe()
for listener in listeners {
listener.isListening = true
}
}

static func stop () {
unsubscribe()
for listener in listeners {
listener.isListening = false
}
Expand Down
18 changes: 18 additions & 0 deletions native/app/Source/Audio/Sources/System/Driver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@ class Driver {
return info["CFBundleVersion"] as! String
}

static var lastSkippedDriverVersion: String? {
get {
return Storage[.lastSkippedDriverVersion]
}
set {
Storage[.lastSkippedDriverVersion] = newValue
}
}

static var skipCurrentVersion: Bool {
get {
return lastSkippedDriverVersion == bundledVersion
}
set {
lastSkippedDriverVersion = newValue ? bundledVersion : nil
}
}

static var isOutdated: Bool {
get {
return bundledVersion != lastInstalledVersion
Expand Down
1 change: 1 addition & 0 deletions native/app/Source/Helpers/Storage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extension DefaultsKeys {
// Effects - Equalizer - Advanced
static let advancedEqualizerPresets = DefaultsKey<[AdvancedEqualizerPreset]?>("advancedEqualizerPresets")
static let lastInstalledDriverVersion = DefaultsKey<String?>("lastInstalledDriverVersion")
static let lastSkippedDriverVersion = DefaultsKey<String?>("lastSkippedDriverVersion")
}

let Storage = Defaults
Expand Down
32 changes: 31 additions & 1 deletion native/app/Source/UI/UI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ class UI: StoreSubscriber {
load()
}

static func reload () {
viewController.webView.reload()
}

func setupBridge () {
bridge = Bridge(webView: UI.viewController.webView)
}
Expand Down Expand Up @@ -251,7 +255,7 @@ class UI: StoreSubscriber {
}

private func load () {
Networking.isReachable(UI.domain) { reachable in
remoteIsReachable() { reachable in
if reachable {
Console.log("Loading Remote UI")
UI.viewController.load(Constants.UI_ENDPOINT_URL)
Expand All @@ -263,7 +267,33 @@ class UI: StoreSubscriber {
UI.viewController.load(url)
}
}
}

private func remoteIsReachable (_ completion: @escaping (Bool) -> Void) {
var returned = false
AF.request(Constants.UI_ENDPOINT_URL)
.responseData { response in
switch response.result {
case .success:
if !returned {
returned = true
completion(true)
}
case .failure:
Console.log("Failed to load \(Constants.UI_ENDPOINT_URL)", response)
if !returned {
returned = true
completion(false)
}
}
}

Utilities.delay(1000) {
if (!returned) {
returned = true
completion(false)
}
}
}

private func cacheRemote () {
Expand Down
2 changes: 1 addition & 1 deletion native/app/Source/UI/Window.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import Cocoa
class Window: NSWindow, NSWindowDelegate {
override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) {
super.init(contentRect: contentRect, styleMask: style, backing: backingStoreType, defer: flag)

self.isOneShot = false

self.titleVisibility = .hidden
self.titlebarAppearsTransparent = true
self.isMovableByWindowBackground = true
Expand Down
2 changes: 2 additions & 0 deletions native/app/Supporting Files/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
<false/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSExceptionDomains</key>
<dict/>
</dict>
Expand Down
Loading

0 comments on commit 36c0180

Please sign in to comment.