diff --git a/MTMR/CustomButtonTouchBarItem.swift b/MTMR/CustomButtonTouchBarItem.swift index 238d0cd..5ae98de 100644 --- a/MTMR/CustomButtonTouchBarItem.swift +++ b/MTMR/CustomButtonTouchBarItem.swift @@ -176,12 +176,12 @@ class CustomButtonCell: NSButtonCell { class HapticClickGestureRecognizer: NSClickGestureRecognizer { override func touchesBegan(with event: NSEvent) { - HapticFeedback.shared.tap(strong: 2) + HapticFeedback.shared?.tap(strong: 2) super.touchesBegan(with: event) } override func touchesEnded(with event: NSEvent) { - HapticFeedback.shared.tap(strong: 1) + HapticFeedback.shared?.tap(strong: 1) super.touchesEnded(with: event) } } @@ -226,7 +226,7 @@ class LongPressGestureRecognizer: NSPressGestureRecognizer { @objc private func onTimer() { if let target = self.target, let action = self.action { target.performSelector(onMainThread: action, with: self, waitUntilDone: false) - HapticFeedback.shared.tap(strong: 6) + HapticFeedback.shared?.tap(strong: 6) } } diff --git a/MTMR/HapticFeedback.swift b/MTMR/HapticFeedback.swift index 7bd0b20..38a84d0 100644 --- a/MTMR/HapticFeedback.swift +++ b/MTMR/HapticFeedback.swift @@ -9,7 +9,7 @@ import IOKit class HapticFeedback { - static let shared = HapticFeedback() + static var shared: HapticFeedback? // Here we have list of possible IDs for Haptic Generator Device. They are not constant // To find deviceID, you will need IORegistryExplorer app from Additional Tools for Xcode dmg diff --git a/MTMR/ItemsParsing.swift b/MTMR/ItemsParsing.swift index 8ed9452..d62ae98 100644 --- a/MTMR/ItemsParsing.swift +++ b/MTMR/ItemsParsing.swift @@ -2,11 +2,27 @@ import AppKit import Foundation extension Data { - func barItemDefinitions() -> [BarItemDefinition]? { - return try? JSONDecoder().decode([BarItemDefinition].self, from: utf8string!.stripComments().data(using: .utf8)!) + func mtmrPreset() -> Preset? { + let data = self.utf8string!.stripComments().data(using: .utf8)! + guard let preset = try? JSONDecoder().decode(Preset.self, from: data) else { + if let oldFormat = try? JSONDecoder().decode([BarItemDefinition].self, from: data) { + return Preset(settings: nil, barItems: oldFormat) + } + return nil + } + return preset } } +struct Preset: Decodable { + let settings: GlobalSettings? + let barItems: [BarItemDefinition] +} + +struct GlobalSettings: Decodable { + let hapticFeedback: Bool? +} + struct BarItemDefinition: Decodable { let type: ItemType let action: ActionType diff --git a/MTMR/TouchBarController.swift b/MTMR/TouchBarController.swift index b0c5578..118f0fd 100644 --- a/MTMR/TouchBarController.swift +++ b/MTMR/TouchBarController.swift @@ -172,8 +172,18 @@ class TouchBarController: NSObject, NSTouchBarDelegate { func reloadPreset(path: String) { lastPresetPath = path - let items = path.fileData?.barItemDefinitions() ?? [BarItemDefinition(type: .staticButton(title: "bad preset"), action: .none, longAction: .none, additionalParameters: [:])] - createAndUpdatePreset(newJsonItems: items) + let preset = path.fileData?.mtmrPreset() ?? fallbackPreset() + applySettings(preset.settings ?? GlobalSettings(hapticFeedback: true)) + createAndUpdatePreset(newJsonItems: preset.barItems) + } + + func fallbackPreset() -> Preset { + let items = [BarItemDefinition(type: .staticButton(title: "bad preset"), action: .none, longAction: .none, additionalParameters: [:])] + return Preset(settings: nil, barItems: items) + } + + func applySettings(_ settings: GlobalSettings) { + HapticFeedback.shared = settings.hapticFeedback ?? true ? HapticFeedback() : nil } func loadItemDefinitions(jsonItems: [BarItemDefinition]) { diff --git a/MTMR/Widgets/AppScrubberTouchBarItem.swift b/MTMR/Widgets/AppScrubberTouchBarItem.swift index 5ddfb50..51043da 100644 --- a/MTMR/Widgets/AppScrubberTouchBarItem.swift +++ b/MTMR/Widgets/AppScrubberTouchBarItem.swift @@ -146,12 +146,12 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub ticks += 1 if ticks == minTicks { - HapticFeedback.shared.tap(strong: 2) + HapticFeedback.shared?.tap(strong: 2) } if ticks > maxTicks { stopTimer() - HapticFeedback.shared.tap(strong: 6) + HapticFeedback.shared?.tap(strong: 6) } } @@ -182,7 +182,7 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub NSWorkspace.shared.openFile(bundleIdentifier!.replacingOccurrences(of: "file://", with: "")) } else { NSWorkspace.shared.launchApplication(withBundleIdentifier: bundleIdentifier!, options: [.default], additionalEventParamDescriptor: nil, launchIdentifier: nil) - HapticFeedback.shared.tap(strong: 6) + HapticFeedback.shared?.tap(strong: 6) } updateRunningApplication() @@ -201,7 +201,7 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub } } } else { - HapticFeedback.shared.tap(strong: 6) + HapticFeedback.shared?.tap(strong: 6) if let index = self.persistentAppIdentifiers.index(of: bundleIdentifier!) { persistentAppIdentifiers.remove(at: index) } else { diff --git a/MTMRTests/ParseConfigTests.swift b/MTMRTests/ParseConfigTests.swift index a3321cc..5e674f4 100644 --- a/MTMRTests/ParseConfigTests.swift +++ b/MTMRTests/ParseConfigTests.swift @@ -64,4 +64,32 @@ class ParseConfig: XCTestCase { return } } + + func testParsesOldFormat() { + let fixture = """ + [ { "type": "escape" } ] + """.data(using: .utf8)! + let result = fixture.mtmrPreset() + XCTAssertEqual(result?.barItems.count, 1) + guard case .staticButton("esc")? = result?.barItems.first?.type else { + XCTFail() + return + } + } + + func testParsesHapticFeedbackSettings() { + let fixture = """ + { + "settings": { "hapticFeedback": false }, + "barItems": [ { "type": "escape" } ] + } + """.data(using: .utf8)! + let result = fixture.mtmrPreset() + XCTAssertEqual(result?.barItems.count, 1) + guard case .staticButton("esc")? = result?.barItems.first?.type else { + XCTFail() + return + } + XCTAssertEqual(result?.settings?.hapticFeedback, .some(false)) + } }