Skip to content

Commit

Permalink
Adding a button that shows if the mail plug-in is active. The button …
Browse files Browse the repository at this point in the history
…turns red if the plug-in is not active.

Architectural changes discussed with @schmittner: Moving the FindMyController out of the environment and using the AccessoryController as the main entry point, also for downloading reports
The AccessoryController is now passed as an Environment Object again
  • Loading branch information
Sn0wfreezeDev committed Mar 12, 2021
1 parent 63300c4 commit 6b3bddf
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 44 deletions.
6 changes: 0 additions & 6 deletions OpenHaystack/OpenHaystack/FindMy/FindMyController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import SwiftUI
class FindMyController: ObservableObject {
@Published var error: Error?
@Published var devices = [FindMyDevice]()
@Environment(\.accessoryController) var accessories: AccessoryController

func loadPrivateKeys(from data: Data, with searchPartyToken: Data, completion: @escaping (Error?) -> Void) {
do {
Expand Down Expand Up @@ -98,11 +97,6 @@ class FindMyController: ObservableObject {

self.fetchReports(with: token) { error in

let reports = self.devices.compactMap({ $0.reports }).flatMap({ $0 })
if reports.isEmpty == false {
self.accessories.updateWithDecryptedReports(devices: self.devices)
}

if let error = error {
completion(.failure(error))
os_log("Error: %@", String(describing: error))
Expand Down
15 changes: 9 additions & 6 deletions OpenHaystack/OpenHaystack/HaystackApp/AccessoryController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ class AccessoryController: ObservableObject {
@Published var accessories: [Accessory]
var selfObserver: AnyCancellable?
var listElementsObserver = [AnyCancellable]()
@Environment(\.findMyController) var findMyController: FindMyController

init(accessories: [Accessory]) {
let findMyController: FindMyController
init(accessories: [Accessory], findMyController: FindMyController) {
self.accessories = accessories
self.findMyController = findMyController
initAccessoryObserver()
initObserver()
}

convenience init() {
self.init(accessories: KeychainController.loadAccessoriesFromKeychain())
self.init(accessories: KeychainController.loadAccessoriesFromKeychain(), findMyController: FindMyController())
}

func initAccessoryObserver() {
Expand Down Expand Up @@ -163,8 +164,9 @@ class AccessoryController: ObservableObject {
case .failure(_):
completion(.failure(.activatePlugin))
case .success(let accountData):
let token = accountData.searchPartyToken
guard token.isEmpty == false else {

guard let token = accountData.searchPartyToken,
token.isEmpty == false else {
completion(.failure(.searchPartyToken))
return
}
Expand All @@ -179,6 +181,7 @@ class AccessoryController: ObservableObject {
if reports.isEmpty {
completion(.failure(.noReportsFound))
}else {
self.updateWithDecryptedReports(devices: devices)
completion(.success(()))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import SwiftUI

struct ManageAccessoriesView: View {

@Environment(\.accessoryController) var accessoryController: AccessoryController
@EnvironmentObject var accessoryController: AccessoryController
var accessories: [Accessory] {
return self.accessoryController.accessories
}
Expand All @@ -21,6 +21,9 @@ struct ManageAccessoriesView: View {
@Binding var focusedAccessory: Accessory?
@Binding var accessoryToDeploy: Accessory?
@Binding var showESP32DeploySheet: Bool
var mailPluginIsActive: Bool

@State var showMailPopup = false

var body: some View {
VStack {
Expand All @@ -40,17 +43,29 @@ struct ManageAccessoriesView: View {
.toolbar(content: {
Spacer()

Button(action: {self.showMailPopup.toggle()}, label: {
Label("Plugin state", systemImage: "envelope")
.foregroundColor(self.mailPluginIsActive ? nil : .red)
})
.help(self.mailPluginIsActive ? "Mail plug-in is active" : "Cannot connect to Mail plug-in")
.popover(isPresented: self.$showMailPopup) {
self.mailStatePopup
}

Button(action: self.importAccessories, label: {
Label("Export accessories", systemImage: "square.and.arrow.down")
Label("Import accessories", systemImage: "square.and.arrow.down")
})
.help("Import accessories from a file")

Button(action: self.exportAccessories, label: {
Label("Export accessories", systemImage: "square.and.arrow.up")
})
.help("Export all accessories to a file")

Button(action: self.addAccessory) {
Label("Add accessory", systemImage: "plus")
}
.help("Add a new accessory")
})
.sheet(
isPresented: self.$showESP32DeploySheet,
Expand Down Expand Up @@ -84,6 +99,23 @@ struct ManageAccessoriesView: View {
.listStyle(SidebarListStyle())

}

var mailStatePopup: some View {
HStack {
Image(systemName: "envelope")
.foregroundColor(self.mailPluginIsActive ? .green : .red)

if self.mailPluginIsActive {
Text("The mail plug-in is up and running")
}else {
Text("Cannot connect to the mail plug-in. Open Apple Mail and make sure the plug-in is enabled")
.lineLimit(10)
.multilineTextAlignment(.leading)
}
}
.frame(maxWidth: 250)
.padding()
}

/// Delete an accessory from the list of accessories.
func delete(accessory: Accessory) {
Expand Down Expand Up @@ -135,6 +167,6 @@ struct ManageAccessoriesView_Previews: PreviewProvider {
@State static var showESPSheet: Bool = true

static var previews: some View {
ManageAccessoriesView(alertType: self.$alertType, focusedAccessory: self.$focussed, accessoryToDeploy: self.$deploy, showESP32DeploySheet: self.$showESPSheet)
ManageAccessoriesView(alertType: self.$alertType, focusedAccessory: self.$focussed, accessoryToDeploy: self.$deploy, showESP32DeploySheet: self.$showESPSheet, mailPluginIsActive: true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ import SwiftUI
struct OpenHaystackMainView: View {

@State var loading = false
@Environment(\.accessoryController) var accessoryController: AccessoryController
@Environment(\.findMyController) var findMyController: FindMyController
@EnvironmentObject var accessoryController: AccessoryController

var accessories: [Accessory] {
return self.accessoryController.accessories
}

@State var showKeyError = false
@State var alertType: AlertType?
@State var popUpAlertType: PopUpAlertType?
@State var errorDescription: String?
Expand All @@ -30,7 +29,9 @@ struct OpenHaystackMainView: View {
@State var isLoading = false
@State var focusedAccessory: Accessory?
@State var accessoryToDeploy: Accessory?


@State var mailPluginIsActive = false

@State var showESP32DeploySheet = false

var body: some View {
Expand All @@ -41,9 +42,10 @@ struct OpenHaystackMainView: View {
alertType: self.$alertType,
focusedAccessory: self.$focusedAccessory,
accessoryToDeploy: self.$accessoryToDeploy,
showESP32DeploySheet: self.$showESP32DeploySheet
showESP32DeploySheet: self.$showESP32DeploySheet,
mailPluginIsActive: self.mailPluginIsActive
)
.frame(minWidth: 240, idealWidth: 250, maxWidth: .infinity, minHeight: 300, idealHeight: 400, maxHeight: .infinity, alignment: .center)
.frame(minWidth: 280, idealWidth: 280, maxWidth: .infinity, minHeight: 300, idealHeight: 400, maxHeight: .infinity, alignment: .center)

ZStack {
AccessoryMapView(accessoryController: self.accessoryController, mapType: self.$mapType, focusedAccessory: self.focusedAccessory)
Expand Down Expand Up @@ -186,30 +188,39 @@ struct OpenHaystackMainView: View {
}
}

func checkPluginIsRunning(_ completion: ((Bool) -> Void)?) {
func checkPluginIsRunning(silent: Bool=false, _ completion: ((Bool) -> Void)?) {
// Check if Mail plugin is active
AnisetteDataManager.shared.requestAnisetteData { (result) in
DispatchQueue.main.async {
switch result {
case .success(let accountData):

withAnimation {
self.searchPartyToken = String(data: accountData.searchPartyToken, encoding: .ascii) ?? ""
if self.searchPartyToken.isEmpty == false {
self.searchPartyTokenLoaded = true
if let token = accountData.searchPartyToken {
self.searchPartyToken = String(data: token, encoding: .ascii) ?? ""
if self.searchPartyToken.isEmpty == false {
self.searchPartyTokenLoaded = true
}
}
}
self.mailPluginIsActive = true
completion?(true)
case .failure(let error):
if let error = error as? AnisetteDataError {
if let error = error as? AnisetteDataError, silent == false {
switch error {
case .pluginNotFound:
self.alertType = .activatePlugin
default:
self.alertType = .activatePlugin
}
}
self.mailPluginIsActive = false
completion?(false)

//Check again in 5s
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
self.checkPluginIsRunning(silent: true, nil)
})
}
}
}
Expand Down Expand Up @@ -330,11 +341,11 @@ struct OpenHaystackMainView: View {
}

struct OpenHaystackMainView_Previews: PreviewProvider {
static var accessoryController = AccessoryControllerPreview(accessories: PreviewData.accessories) as AccessoryController
static var accessoryController = AccessoryControllerPreview(accessories: PreviewData.accessories, findMyController: FindMyController()) as AccessoryController

static var previews: some View {
OpenHaystackMainView()
.environment(\.accessoryController, accessoryController)
.environmentObject(self.accessoryController)
}
}

Expand Down
27 changes: 12 additions & 15 deletions OpenHaystack/OpenHaystack/OpenHaystackApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,22 @@ import SwiftUI

@main
struct OpenHaystackApp: App {
@Environment(\.accessoryController) var accessoryController: AccessoryController
@Environment(\.findMyController) var findMyController: FindMyController
@StateObject var accessoryController: AccessoryController

init() {}
init() {
let accessoryController: AccessoryController
if ProcessInfo().arguments.contains("-preview") {
accessoryController = AccessoryControllerPreview(accessories: PreviewData.accessories, findMyController: FindMyController())
} else {
accessoryController = AccessoryController()
}
self._accessoryController = StateObject(wrappedValue: accessoryController)
}

var body: some Scene {
WindowGroup {
OpenHaystackMainView()
.environmentObject(self.accessoryController)
}
.commands {
SidebarCommands()
Expand All @@ -36,20 +44,9 @@ private struct FindMyControllerEnvironmentKey: EnvironmentKey {
private struct AccessoryControllerEnvironmentKey: EnvironmentKey {
static let defaultValue: AccessoryController = {
if ProcessInfo().arguments.contains("-preview") {
return AccessoryControllerPreview(accessories: PreviewData.accessories)
return AccessoryControllerPreview(accessories: PreviewData.accessories, findMyController: FindMyController())
} else {
return AccessoryController()
}
}()
}

extension EnvironmentValues {
var findMyController: FindMyController {
get {self[FindMyControllerEnvironmentKey]}
}

var accessoryController: AccessoryController {
get{self[AccessoryControllerEnvironmentKey]}
set{self[AccessoryControllerEnvironmentKey] = newValue}
}
}
2 changes: 1 addition & 1 deletion OpenHaystack/OpenHaystackMail/AppleAccountData.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, copy) NSLocale *locale;
@property(nonatomic, copy) NSTimeZone *timeZone;

@property(nonatomic, copy) NSData *searchPartyToken;
@property(nonatomic, copy) NSData * _Nullable searchPartyToken;

- (instancetype)initWithMachineID:(NSString *)machineID
oneTimePassword:(NSString *)oneTimePassword
Expand Down

0 comments on commit 6b3bddf

Please sign in to comment.