From bbe40060931c2b153be47af58577fafc6d3769a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Thu, 5 Sep 2024 13:37:12 +0200 Subject: [PATCH] Extend Migration to Drawer and Notifcations --- openHAB.xcodeproj/project.pbxproj | 8 + openHAB/DrawerView.swift | 208 ++++++++++++++++++ openHAB/NotificationsView.swift | 114 ++++++++++ openHAB/OpenHABDrawerItem.swift | 8 + .../OpenHABDrawerTableViewController.swift | 4 +- openHAB/OpenHABNotification.swift | 12 +- openHAB/OpenHABRootViewController.swift | 120 +++++++--- openHAB/OpenHABSitemapViewController.swift | 1 - 8 files changed, 437 insertions(+), 38 deletions(-) create mode 100644 openHAB/DrawerView.swift create mode 100644 openHAB/NotificationsView.swift diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 43025b71..5595a7e0 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -102,6 +102,8 @@ DA5ED9C02C8509C2004875E0 /* ClientCertificatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5ED9BF2C8509C2004875E0 /* ClientCertificatesView.swift */; }; DA65871F236F83CE007E2E7F /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA65871E236F83CD007E2E7F /* UserDefaultsExtension.swift */; }; DA6587222370C9D8007E2E7F /* PreferencesHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6587212370C9D8007E2E7F /* PreferencesHostingController.swift */; }; + DA6B2EEF2C861BC900DF77CF /* DrawerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6B2EEE2C861BC900DF77CF /* DrawerView.swift */; }; + DA6B2EF12C87B59000DF77CF /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6B2EF02C87B59000DF77CF /* NotificationsView.swift */; }; DA7224D223828D3400712D20 /* PreviewConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7224D123828D3300712D20 /* PreviewConstants.swift */; }; DA72E1B8236DEA0900B8EF3A /* AppMessageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA72E1B5236DEA0900B8EF3A /* AppMessageService.swift */; }; DA7649DE23FC81A20085CE46 /* Unwrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7649DD23FC81A20085CE46 /* Unwrap.swift */; }; @@ -392,6 +394,8 @@ DA5ED9BF2C8509C2004875E0 /* ClientCertificatesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientCertificatesView.swift; sourceTree = ""; }; DA65871E236F83CD007E2E7F /* UserDefaultsExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtension.swift; sourceTree = ""; }; DA6587212370C9D8007E2E7F /* PreferencesHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesHostingController.swift; sourceTree = ""; }; + DA6B2EEE2C861BC900DF77CF /* DrawerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DrawerView.swift; sourceTree = ""; }; + DA6B2EF02C87B59000DF77CF /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = ""; }; DA7224D123828D3300712D20 /* PreviewConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewConstants.swift; sourceTree = ""; }; DA72E1B0236DE9F200B8EF3A /* AppState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppState.swift; path = "openHABWatch Extension/app/AppState.swift"; sourceTree = ""; }; DA72E1B5236DEA0900B8EF3A /* AppMessageService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppMessageService.swift; path = "openHABWatch Extension/external/AppMessageService.swift"; sourceTree = ""; }; @@ -860,6 +864,8 @@ DA242C612C83588600AFB10D /* SettingsView.swift */, DA5ED9BF2C8509C2004875E0 /* ClientCertificatesView.swift */, DA9F81862C85020F00B47B72 /* RTFTextView.swift */, + DA6B2EF02C87B59000DF77CF /* NotificationsView.swift */, + DA6B2EEE2C861BC900DF77CF /* DrawerView.swift */, DF4B84101886DA9900F34902 /* Widgets */, DF4A02291CF3157B006C3456 /* Drawer */, DFFD8FCE18EDBD30003B502A /* Util */, @@ -1483,6 +1489,7 @@ DAC65FC7236EDF3900F4501E /* SpinnerViewController.swift in Sources */, DA9F81872C85020F00B47B72 /* RTFTextView.swift in Sources */, DF4A02421CF34096006C3456 /* OpenHABDrawerItem.swift in Sources */, + DA6B2EF12C87B59000DF77CF /* NotificationsView.swift in Sources */, DA50C7BF2B0A65300009F716 /* SliderWithSwitchSupportUITableViewCell.swift in Sources */, DF4A022C1CF315BA006C3456 /* OpenHABDrawerTableViewController.swift in Sources */, DA5ED9BE2C850955004875E0 /* ClientCertificatesViewModel.swift in Sources */, @@ -1490,6 +1497,7 @@ DAF4F6C0222734D300C24876 /* NewImageUITableViewCell.swift in Sources */, DAEAA89B21E2611000267EA3 /* OpenHABNotificationsViewController.swift in Sources */, DF1B302D1CF5C667009C921C /* OpenHABNotification.swift in Sources */, + DA6B2EEF2C861BC900DF77CF /* DrawerView.swift in Sources */, 938BF9D324EFD0B700E6B52F /* UIViewController+Localization.swift in Sources */, DF06F1F618FE7A160011E7B9 /* OpenHABSelectionTableViewController.swift in Sources */, DAA42BA821DC97E000244B2A /* NotificationTableViewCell.swift in Sources */, diff --git a/openHAB/DrawerView.swift b/openHAB/DrawerView.swift new file mode 100644 index 00000000..2f7b6c57 --- /dev/null +++ b/openHAB/DrawerView.swift @@ -0,0 +1,208 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Kingfisher +import OpenHABCore +import os.log +import SafariServices +import SFSafeSymbols +import SwiftUI + +struct DrawerView: View { + @State private var sitemaps: [OpenHABSitemap] = [] + @State private var uiTiles: [OpenHABUiTile] = [] + @State private var drawerItems: [OpenHABDrawerItem] = [] + @State private var selectedSection: Int? + + var openHABUsername = "" + var openHABPassword = "" + + var onDismiss: (TargetController) -> Void + @Environment(\.dismiss) private var dismiss + + // App wide data access + var appData: OpenHABDataObject? { + AppDelegate.appDelegate.appData + } + + @ScaledMetric var openHABIconwidth = 20.0 + @ScaledMetric var tilesIconwidth = 20.0 + @ScaledMetric var sitemapIconwidth = 20.0 + + var body: some View { + List { + Section(header: Text("Main")) { + HStack { + Image("openHABIcon") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: openHABIconwidth) + Text("Home") + } + .onTapGesture { + dismiss() + onDismiss(.webview) + } + } + + Section(header: Text("Tiles")) { + ForEach(uiTiles, id: \.url) { tile in + HStack { + ImageView(url: tile.imageUrl) + .aspectRatio(contentMode: .fit) + .frame(width: tilesIconwidth) + Text(tile.name) + } + .onTapGesture { + dismiss() + onDismiss(.tile(tile.url)) + } + } + } + + Section(header: Text("Sitemaps")) { + ForEach(sitemaps, id: \.name) { sitemap in + HStack { + let url = Endpoint.iconForDrawer(rootUrl: appData?.openHABRootUrl ?? "", icon: sitemap.icon).url + KFImage(url).placeholder { Image("openHABIcon").resizable() } + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: sitemapIconwidth) + Text(sitemap.label) + } + .onTapGesture { + dismiss() + onDismiss(.sitemap(sitemap.name)) + } + } + } + + Section(header: Text("System")) { + HStack { + Image(systemSymbol: .gear) + Text("Settings") + } + .onTapGesture { + dismiss() + onDismiss(.settings) + } + + // check if we are using my.openHAB, add notifications menu item then + // Actually this should better test whether the host of the remoteUrl is on openhab.org + if Preferences.remoteUrl.contains("openhab.org"), !Preferences.demomode { + HStack { + Image(systemSymbol: .bell) + Text("Notifications") + } + .onTapGesture { + dismiss() + onDismiss(.notifications) + } + } + } + } + .listStyle(.inset) + .onAppear(perform: loadData) + } + + private func loadData() { + // TODO: Replace network calls with appropriate @EnvironmentObject or other state management + loadSitemaps() + loadUiTiles() + } + + private func loadSitemaps() { + // Perform network call to load sitemaps and decode + // Update the sitemaps state + + NetworkConnection.sitemaps(openHABRootUrl: appData?.openHABRootUrl ?? "") { response in + switch response.result { + case let .success(data): + os_log("Sitemap response", log: .viewCycle, type: .info) + + sitemaps = deriveSitemaps(data) + + if sitemaps.last?.name == "_default", sitemaps.count > 1 { + sitemaps = Array(sitemaps.dropLast()) + } + + // Sort the sitemaps according to Settings selection. + switch SortSitemapsOrder(rawValue: Preferences.sortSitemapsby) ?? .label { + case .label: sitemaps.sort { $0.label < $1.label } + case .name: sitemaps.sort { $0.name < $1.name } + } + + drawerItems.removeAll() + case let .failure(error): + os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) + drawerItems.removeAll() + } + } + } + + private func loadUiTiles() { + // Perform network call to load UI Tiles and decode + // Update the uiTiles state + NetworkConnection.uiTiles(openHABRootUrl: appData?.openHABRootUrl ?? "") { response in + switch response.result { + case .success: + os_log("ui tiles response", log: .viewCycle, type: .info) + guard let responseData = response.data else { + os_log("Error: did not receive data", log: OSLog.remoteAccess, type: .info) + return + } + do { + uiTiles = try JSONDecoder().decode([OpenHABUiTile].self, from: responseData) + } catch { + os_log("Error: did not receive data %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, error.localizedDescription) + } + case let .failure(error): + os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) + } + } + } + + mutating func loadSettings() { + openHABUsername = Preferences.username + openHABPassword = Preferences.password + } +} + +struct ImageView: View { + let url: String + + // App wide data access + var appData: OpenHABDataObject? { + AppDelegate.appDelegate.appData + } + + var body: some View { + if !url.isEmpty { + switch url { + case _ where url.hasPrefix("data:image"): + let provider = Base64ImageDataProvider(base64String: url.deletingPrefix("data:image/png;base64,"), cacheKey: UUID().uuidString) + return KFImage(source: .provider(provider)).resizable() + case _ where url.hasPrefix("http"): + return KFImage(URL(string: url)).resizable() + default: + let builtURL = Endpoint.resource(openHABRootUrl: appData?.openHABRootUrl ?? "", path: url.prepare()).url + return KFImage(builtURL).resizable() + } + } else { + // This will always fallback to placeholder + return KFImage(URL(string: "bundle://openHABIcon")).placeholder { Image("openHABIcon").resizable() } + } + } +} + +// #Preview { +// DrawerView(onDismiss: {.webview -> Void}) +// } diff --git a/openHAB/NotificationsView.swift b/openHAB/NotificationsView.swift new file mode 100644 index 00000000..eacaf7c6 --- /dev/null +++ b/openHAB/NotificationsView.swift @@ -0,0 +1,114 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Kingfisher +import OpenHABCore +import os.log +import SwiftUI + +struct NotificationsView: View { + @State var notifications: [OpenHABNotification] = [] + + var body: some View { + List(notifications, id: \.id) { notification in + NotificationRow(notification: notification) + } + .refreshable { + loadNotifications() + } + .navigationTitle("Notifications") + .onAppear { + loadNotifications() + } + } + + private func loadNotifications() { + NetworkConnection.notification(urlString: Preferences.remoteUrl) { response in + DispatchQueue.main.async { + switch response.result { + case let .success(data): + do { + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .formatted(DateFormatter.iso8601Full) + let codingDatas = try data.decoded(as: [OpenHABNotification.CodingData].self, using: decoder) + notifications = codingDatas.map(\.openHABNotification) + } catch { + os_log("%{PUBLIC}@ ", log: .default, type: .error, error.localizedDescription) + } + case let .failure(error): + os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) + } + } + } + } +} + +struct NotificationRow: View { + var notification: OpenHABNotification + + // App wide data access + var appData: OpenHABDataObject? { + AppDelegate.appDelegate.appData + } + + var body: some View { + HStack { + KFImage(iconUrl) + .placeholder { + Image("openHABIcon").resizable() + } + .resizable() + .frame(width: 40, height: 40) + .cornerRadius(8) + VStack(alignment: .leading) { + Text(notification.message) + .font(.body) + if let timeStamp = notification.created { + Text(dateString(from: timeStamp)) + .font(.caption) + .foregroundColor(.gray) + } + } + } + + .padding(.vertical, 8) + } + + private var iconUrl: URL? { + if let appData { + return Endpoint.icon( + rootUrl: appData.openHABRootUrl, + version: appData.openHABVersion, + icon: notification.icon, + state: "", + iconType: .png, + iconColor: "" + ).url + } + return nil + } + + private func dateString(from date: Date) -> String { + let formatter = DateFormatter() + formatter.dateStyle = .medium + formatter.timeStyle = .medium + formatter.timeZone = TimeZone.current + return formatter.string(from: date) + } +} + +#Preview { + Group { + NotificationsView(notifications: [OpenHABNotification(message: "message1", created: Date.now, id: UUID().uuidString), OpenHABNotification(message: "message2", created: Date.now, id: UUID().uuidString)]) + + NotificationRow(notification: OpenHABNotification(message: "message3", created: Date.now)) + } +} diff --git a/openHAB/OpenHABDrawerItem.swift b/openHAB/OpenHABDrawerItem.swift index ce8924bf..eaf517e9 100644 --- a/openHAB/OpenHABDrawerItem.swift +++ b/openHAB/OpenHABDrawerItem.swift @@ -10,6 +10,7 @@ // SPDX-License-Identifier: EPL-2.0 import Foundation +import SFSafeSymbols enum OpenHABDrawerItem { case settings @@ -34,4 +35,11 @@ enum OpenHABDrawerItem { OpenHABDrawerItem.settings } } + + var icon: SFSymbol { + switch self { + case .notifications: .bell + case .settings: .gear + } + } } diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index d2f12070..c8f6eefe 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -186,7 +186,7 @@ class OpenHABDrawerTableViewController: UITableViewController { cell.customImageView.image = UIImage(named: "openHABIcon") if let currentView = appData?.currentView { // if we already are on the webview, pressing this again will force a refresh - if currentView == .webview { + if case .webview = currentView { cell.accessoryView = UIImageView(image: UIImage(named: "arrow.triangle.2.circlepath")) } } @@ -287,7 +287,7 @@ class OpenHABDrawerTableViewController: UITableViewController { appData?.sitemapViewController?.pageUrl = "" dismiss(animated: true) { os_log("self delegate %d", log: .viewCycle, type: .info, self.delegate != nil) - self.delegate?.modalDismissed(to: .sitemap) + self.delegate?.modalDismissed(to: .sitemap("")) } } case 3: diff --git a/openHAB/OpenHABNotification.swift b/openHAB/OpenHABNotification.swift index 4970cc65..2862a9d2 100644 --- a/openHAB/OpenHABNotification.swift +++ b/openHAB/OpenHABNotification.swift @@ -16,15 +16,19 @@ class OpenHABNotification: NSObject { var created: Date? var icon = "" var severity = "" + var id = "" - init(message: String, created: Date?) { + init(message: String = "", created: Date? = nil, icon: String = "", severity: String = "", id: String = "") { self.message = message self.created = created + self.icon = icon + self.severity = severity + self.id = id } - init(dictionary: [String: Any]) { + convenience init(dictionary: [String: Any]) { let propertyNames: Set = ["message", "icon", "severity"] - super.init() + self.init() let keyArray = dictionary.keys for key in keyArray { if key as String == "created" { @@ -63,6 +67,6 @@ extension OpenHABNotification { // Convenience method to convert a decoded value into a proper OpenHABNotification instance extension OpenHABNotification.CodingData { var openHABNotification: OpenHABNotification { - OpenHABNotification(message: message, created: created) + OpenHABNotification(message: message, created: created, id: id) } } diff --git a/openHAB/OpenHABRootViewController.swift b/openHAB/OpenHABRootViewController.swift index c4af85ed..046c9f71 100644 --- a/openHAB/OpenHABRootViewController.swift +++ b/openHAB/OpenHABRootViewController.swift @@ -19,10 +19,12 @@ import SwiftUI import UIKit enum TargetController { - case sitemap + case webview case settings + case sitemap(String) case notifications - case webview + case browser(String) + case tile(String) } protocol ModalHandler: AnyObject { @@ -49,6 +51,7 @@ class OpenHABRootViewController: UIViewController { return viewController }() + var appData: OpenHABDataObject? { AppDelegate.appDelegate.appData } @@ -128,13 +131,6 @@ class OpenHABRootViewController: UIViewController { // Define the menus - SideMenuManager.default.rightMenuNavigationController = storyboard!.instantiateViewController(withIdentifier: "RightMenuNavigationController") as? SideMenuNavigationController - - // Enable gestures. The left and/or right menus must be set up above for these to work. - // Note that these continue to work on the Navigation Controller independent of the View Controller it displays! - SideMenuManager.default.addPanGestureToPresent(toView: navigationController!.navigationBar) - SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: navigationController!.view, forMenu: .right) - let presentationStyle: SideMenuPresentationStyle = .viewSlideOutMenuIn presentationStyle.presentingEndAlpha = 1 presentationStyle.onTopShadowOpacity = 0.5 @@ -143,9 +139,74 @@ class OpenHABRootViewController: UIViewController { settings.statusBarEndAlpha = 0 SideMenuManager.default.rightMenuNavigationController?.settings = settings - if let menu = SideMenuManager.default.rightMenuNavigationController { - let drawer = menu.viewControllers.first as? OpenHABDrawerTableViewController - drawer?.delegate = self + + let drawerView = DrawerView { mode in + self.handleDismiss(mode: mode) + } + let hostingController = UIHostingController(rootView: drawerView) + let menu = SideMenuNavigationController(rootViewController: hostingController) + + SideMenuManager.default.rightMenuNavigationController = menu + + // Enable gestures. The left and/or right menus must be set up above for these to work. + // Note that these continue to work on the Navigation Controller independent of the View Controller it displays! + SideMenuManager.default.addPanGestureToPresent(toView: navigationController!.navigationBar) + SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: navigationController!.view, forMenu: .right) + } + + private func openTileURL(_ urlString: String) { + // Use SFSafariViewController in SwiftUI with UIViewControllerRepresentable + // Dependent on $OPENHAB_CONF/services/runtime.cfg + // Can either be an absolute URL, a path (sometimes malformed) + if !urlString.isEmpty { + let url: URL? = if urlString.hasPrefix("http") { + URL(string: urlString) + } else { + Endpoint.resource(openHABRootUrl: appData?.openHABRootUrl ?? "", path: urlString.prepare()).url + } + openURL(url: url) + } + } + + private func openURL(url: URL?) { + if let url { + let config = SFSafariViewController.Configuration() + config.entersReaderIfAvailable = true + let vc = SFSafariViewController(url: url, configuration: config) + present(vc, animated: true) + } + } + + private func handleDismiss(mode: TargetController) { + switch mode { + case .webview: + // Handle webview navigation or state update + print("Dismissed to WebView") + SideMenuManager.default.rightMenuNavigationController?.dismiss(animated: true) + switchView(target: .webview) + case .settings: + print("Dismissed to Settings") + SideMenuManager.default.rightMenuNavigationController?.dismiss(animated: true) { + self.modalDismissed(to: .settings) + } + case let .sitemap(sitemap): + Preferences.defaultSitemap = sitemap + appData?.sitemapViewController?.pageUrl = "" + SideMenuManager.default.rightMenuNavigationController?.dismiss(animated: true) { + self.modalDismissed(to: .sitemap(sitemap)) + } + case .notifications: + SideMenuManager.default.rightMenuNavigationController?.dismiss(animated: true) { + self.modalDismissed(to: .notifications) + } + case let .browser(urlString): + SideMenuManager.default.rightMenuNavigationController?.dismiss(animated: true) { + self.modalDismissed(to: .browser(urlString)) + } + case let .tile(urlString): + SideMenuManager.default.rightMenuNavigationController?.dismiss(animated: true) { + self.modalDismissed(to: .tile(urlString)) + } } } @@ -324,11 +385,9 @@ class OpenHABRootViewController: UIViewController { if let menu = SideMenuManager.default.rightMenuNavigationController { // don't try and push an already visible menu less you crash the app dismiss(animated: false) { - var topMostViewController: UIViewController? = if #available(iOS 13, *) { + var topMostViewController: UIViewController? = UIApplication.shared.connectedScenes.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }.last { $0.isKeyWindow }?.rootViewController - } else { - UIApplication.shared.keyWindow?.rootViewController - } + while let presentedViewController = topMostViewController?.presentedViewController { topMostViewController = presentedViewController } @@ -352,7 +411,12 @@ class OpenHABRootViewController: UIViewController { } private func switchView(target: TargetController) { - let targetView = target == .sitemap ? sitemapViewController : webViewController + let targetView = + if case .sitemap = target { + sitemapViewController + } else { + webViewController + } if currentView != targetView { if currentView != nil { @@ -375,10 +439,10 @@ class OpenHABRootViewController: UIViewController { private func switchToSavedView() { if Preferences.demomode { - switchView(target: .sitemap) + switchView(target: .sitemap("")) } else { os_log("OpenHABRootViewController switchToSavedView %@", log: .viewCycle, type: .info, Preferences.defaultView == "sitemap" ? "sitemap" : "web") - switchView(target: Preferences.defaultView == "sitemap" ? .sitemap : .webview) + switchView(target: Preferences.defaultView == "sitemap" ? .sitemap("") : .webview) } } } @@ -399,23 +463,17 @@ extension OpenHABRootViewController: ModalHandler { case .sitemap: switchView(target: to) case .settings: -// if let newViewController = storyboard?.instantiateViewController(withIdentifier: "OpenHABSettingsViewController") as? OpenHABSettingsViewController { -// navigationController?.pushViewController(newViewController, animated: true) -// } - // let hostingController = SettingsView().embeddedInHostingController() let hostingController = UIHostingController(rootView: SettingsView()) - navigationController?.pushViewController(hostingController, animated: true) case .notifications: - if navigationController?.visibleViewController is OpenHABNotificationsViewController { - os_log("Notifications are already open", log: .notifications, type: .info) - } else { - if let newViewController = storyboard?.instantiateViewController(withIdentifier: "OpenHABNotificationsViewController") as? OpenHABNotificationsViewController { - navigationController?.pushViewController(newViewController, animated: true) - } - } + let hostingController = UIHostingController(rootView: NotificationsView()) + navigationController?.pushViewController(hostingController, animated: true) case .webview: switchView(target: to) + case .browser: + break + case let .tile(urlString): + openTileURL(urlString) } } } diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index c0a329d6..45613f35 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -79,7 +79,6 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel private var filteredPage: OpenHABSitemapPage? private var serverProperties: OpenHABServerProperties? private let search = UISearchController(searchResultsController: nil) - private var webViewController: OpenHABWebViewController? private var isUserInteracting = false private var isWaitingToReload = false