mirror of
https://github.com/seemoo-lab/openhaystack.git
synced 2026-08-23 21:46:15 +00:00
Added the AccessoryController and the FindMyController to the SwiftUI Environment
141 lines
4.3 KiB
Swift
141 lines
4.3 KiB
Swift
//
|
||
// OpenHaystack – Tracking personal Bluetooth devices via Apple's Find My network
|
||
//
|
||
// Copyright © 2021 Secure Mobile Networking Lab (SEEMOO)
|
||
// Copyright © 2021 The Open Wireless Link Project
|
||
//
|
||
// SPDX-License-Identifier: AGPL-3.0-only
|
||
//
|
||
|
||
import SwiftUI
|
||
|
||
struct ManageAccessoriesView: View {
|
||
|
||
@Environment(\.accessoryController) var accessoryController: AccessoryController
|
||
var accessories: [Accessory] {
|
||
return self.accessoryController.accessories
|
||
}
|
||
|
||
// MARK: Bindings from main View
|
||
@Binding var alertType: OpenHaystackMainView.AlertType?
|
||
@Binding var focusedAccessory: Accessory?
|
||
@Binding var accessoryToDeploy: Accessory?
|
||
@Binding var showESP32DeploySheet: Bool
|
||
|
||
var body: some View {
|
||
VStack {
|
||
Text("Your accessories")
|
||
.font(.title2)
|
||
.padding(.top)
|
||
|
||
if self.accessories.isEmpty {
|
||
Spacer()
|
||
Text("No accessories have been added yet. Go ahead and add one via the '+' icon.")
|
||
.multilineTextAlignment(.center)
|
||
Spacer()
|
||
} else {
|
||
self.accessoryList
|
||
}
|
||
}
|
||
.toolbar(content: {
|
||
Spacer()
|
||
|
||
Button(action: self.importAccessories, label: {
|
||
Label("Export accessories", systemImage: "square.and.arrow.down")
|
||
})
|
||
|
||
Button(action: self.exportAccessories, label: {
|
||
Label("Export accessories", systemImage: "square.and.arrow.up")
|
||
})
|
||
|
||
Button(action: self.addAccessory) {
|
||
Label("Add accessory", systemImage: "plus")
|
||
}
|
||
})
|
||
.sheet(
|
||
isPresented: self.$showESP32DeploySheet,
|
||
content: {
|
||
ESP32InstallSheet(accessory: self.$accessoryToDeploy, alertType: self.$alertType)
|
||
})
|
||
}
|
||
|
||
/// Accessory List view.
|
||
var accessoryList: some View {
|
||
List(self.accessories, id: \.self, selection: $focusedAccessory) { accessory in
|
||
AccessoryListEntry(
|
||
accessory: accessory,
|
||
accessoryIcon: Binding(
|
||
get: { accessory.icon },
|
||
set: { accessory.icon = $0 }
|
||
),
|
||
accessoryColor: Binding(
|
||
get: { accessory.color },
|
||
set: { accessory.color = $0 }
|
||
),
|
||
accessoryName: Binding(
|
||
get: { accessory.name },
|
||
set: { accessory.name = $0 }
|
||
),
|
||
alertType: self.$alertType,
|
||
delete: self.delete(accessory:),
|
||
deployAccessoryToMicrobit: self.deploy(accessory:),
|
||
zoomOn: { self.focusedAccessory = $0 })
|
||
}
|
||
.listStyle(SidebarListStyle())
|
||
|
||
}
|
||
|
||
/// Delete an accessory from the list of accessories.
|
||
func delete(accessory: Accessory) {
|
||
do {
|
||
try self.accessoryController.delete(accessory: accessory)
|
||
} catch {
|
||
self.alertType = .deletionFailed
|
||
}
|
||
}
|
||
|
||
func deploy(accessory: Accessory) {
|
||
self.accessoryToDeploy = accessory
|
||
self.alertType = .selectDepoyTarget
|
||
}
|
||
|
||
/// Add an accessory with the provided details.
|
||
func addAccessory() {
|
||
do {
|
||
_ = try self.accessoryController.addAccessory()
|
||
} catch {
|
||
self.alertType = .keyError
|
||
}
|
||
}
|
||
|
||
func exportAccessories() {
|
||
do {
|
||
_ = try self.accessoryController.export(accessories: self.accessories)
|
||
}catch {
|
||
//TODO: Show alert
|
||
}
|
||
}
|
||
|
||
func importAccessories() {
|
||
do {
|
||
try self.accessoryController.importAccessories()
|
||
}catch {
|
||
//TODO: Show alert
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
struct ManageAccessoriesView_Previews: PreviewProvider {
|
||
|
||
@State static var accessories = PreviewData.accessories
|
||
@State static var alertType: OpenHaystackMainView.AlertType?
|
||
@State static var focussed: Accessory?
|
||
@State static var deploy: Accessory?
|
||
@State static var showESPSheet: Bool = true
|
||
|
||
static var previews: some View {
|
||
ManageAccessoriesView(alertType: self.$alertType, focusedAccessory: self.$focussed, accessoryToDeploy: self.$deploy, showESP32DeploySheet: self.$showESPSheet)
|
||
}
|
||
}
|