From dba903f102a0cf35878f7de7a5eac14906096bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Wed, 28 Aug 2024 11:54:24 +0200 Subject: [PATCH] Migrate widgets from [OpenHABWidget] to OrderedDictionary using swift-collections --- OpenHABCore/Package.swift | 6 +- .../Model/OpenHABSitemapPage.swift | 32 +- .../xcshareddata/swiftpm/Package.resolved | 449 +++++++++--------- ...HABSelectionCollectionViewController.swift | 10 +- openHAB/OpenHABSitemapViewController.swift | 84 ++-- 5 files changed, 304 insertions(+), 277 deletions(-) diff --git a/OpenHABCore/Package.swift b/OpenHABCore/Package.swift index 007d40c6..6ef11ec1 100644 --- a/OpenHABCore/Package.swift +++ b/OpenHABCore/Package.swift @@ -16,7 +16,8 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.0.0"), - .package(url: "https://github.com/onevcat/Kingfisher.git", from: "7.0.0") + .package(url: "https://github.com/onevcat/Kingfisher.git", from: "7.0.0"), + .package(url: "https://github.com/apple/swift-collections.git", .upToNextMajor(from: "1.1.0")) ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. @@ -25,7 +26,8 @@ let package = Package( name: "OpenHABCore", dependencies: [ .product(name: "Alamofire", package: "Alamofire", condition: .when(platforms: [.iOS, .watchOS])), - .product(name: "Kingfisher", package: "Kingfisher", condition: .when(platforms: [.iOS, .watchOS])) + .product(name: "Kingfisher", package: "Kingfisher", condition: .when(platforms: [.iOS, .watchOS])), + .product(name: "Collections", package: "swift-collections") ] ), .testTarget( diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapPage.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapPage.swift index bc16248a..2c18aedd 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapPage.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapPage.swift @@ -9,18 +9,36 @@ // // SPDX-License-Identifier: EPL-2.0 +import Collections import Foundation import os.log -public class OpenHABSitemapPage: NSObject { +public class OpenHABSitemapPage: NSObject, ObservableObject { public var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? - public var widgets: [OpenHABWidget] = [] + public var widgets = OrderedDictionary() public var pageId = "" public var title = "" public var link = "" public var leaf = false public var icon = "" + public init(pageId: String, title: String, link: String, leaf: Bool, widgets: OrderedDictionary, icon: String) { + super.init() + self.pageId = pageId + self.title = title + self.link = link + self.leaf = leaf + + self.widgets = widgets + + for (_, widget) in self.widgets { + widget.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } + } + self.icon = icon + } + public init(pageId: String, title: String, link: String, leaf: Bool, widgets: [OpenHABWidget], icon: String) { super.init() self.pageId = pageId @@ -29,8 +47,12 @@ public class OpenHABSitemapPage: NSObject { self.leaf = leaf var tempWidgets = [OpenHABWidget]() tempWidgets.flatten(widgets) - self.widgets = tempWidgets - for widget in self.widgets { + + self.widgets = OrderedDictionary( + uniqueKeysWithValues: tempWidgets.map { ($0.id, $0) } + ) + + for (_, widget) in self.widgets { widget.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) } @@ -47,7 +69,7 @@ public class OpenHABSitemapPage: NSObject { } public extension OpenHABSitemapPage { - func filter(_ isIncluded: (OpenHABWidget) throws -> Bool) rethrows -> OpenHABSitemapPage { + func filter(_ isIncluded: (String, OpenHABWidget) throws -> Bool) rethrows -> OpenHABSitemapPage { let filteredOpenHABSitemapPage = try OpenHABSitemapPage( pageId: pageId, title: title, diff --git a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved index 12b4092c..352b2730 100644 --- a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,223 +1,230 @@ { - "object": { - "pins": [ - { - "package": "abseil", - "repositoryURL": "https://github.com/google/abseil-cpp-binary.git", - "state": { - "branch": null, - "revision": "748c7837511d0e6a507737353af268484e1745e2", - "version": "1.2024011601.1" - } - }, - { - "package": "Alamofire", - "repositoryURL": "https://github.com/Alamofire/Alamofire.git", - "state": { - "branch": null, - "revision": "f455c2975872ccd2d9c81594c658af65716e9b9a", - "version": "5.9.1" - } - }, - { - "package": "AlamofireNetworkActivityIndicator", - "repositoryURL": "https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git", - "state": { - "branch": null, - "revision": "392bed083e8d193aca16bfa684ee24e4bcff0510", - "version": "3.1.0" - } - }, - { - "package": "AppCheck", - "repositoryURL": "https://github.com/google/app-check.git", - "state": { - "branch": null, - "revision": "076b241a625e25eac22f8849be256dfb960fcdfe", - "version": "10.19.1" - } - }, - { - "package": "CocoaLumberjack", - "repositoryURL": "https://github.com/CocoaLumberjack/CocoaLumberjack.git", - "state": { - "branch": null, - "revision": "4b8714a7fb84d42393314ce897127b3939885ec3", - "version": "3.8.5" - } - }, - { - "package": "DeviceKit", - "repositoryURL": "https://github.com/devicekit/DeviceKit.git", - "state": { - "branch": null, - "revision": "d37e70cb2646666dcf276d7d3d4a9760a41ff8a6", - "version": "4.9.0" - } - }, - { - "package": "Firebase", - "repositoryURL": "https://github.com/firebase/firebase-ios-sdk.git", - "state": { - "branch": null, - "revision": "9d17b500cd98d9a7009751ad62f802e152e97021", - "version": "10.26.0" - } - }, - { - "package": "FlexColorPicker", - "repositoryURL": "https://github.com/RastislavMirek/FlexColorPicker.git", - "state": { - "branch": null, - "revision": "72a5c2c5e28074e6c5f13efe3c98eb780ae2f906", - "version": "1.4.4" - } - }, - { - "package": "GoogleAppMeasurement", - "repositoryURL": "https://github.com/google/GoogleAppMeasurement.git", - "state": { - "branch": null, - "revision": "16244d177c4e989f87b25e9db1012b382cfedc55", - "version": "10.25.0" - } - }, - { - "package": "GoogleDataTransport", - "repositoryURL": "https://github.com/google/GoogleDataTransport.git", - "state": { - "branch": null, - "revision": "a637d318ae7ae246b02d7305121275bc75ed5565", - "version": "9.4.0" - } - }, - { - "package": "GoogleUtilities", - "repositoryURL": "https://github.com/google/GoogleUtilities.git", - "state": { - "branch": null, - "revision": "57a1d307f42df690fdef2637f3e5b776da02aad6", - "version": "7.13.3" - } - }, - { - "package": "grpc-binary", - "repositoryURL": "https://github.com/google/grpc-binary.git", - "state": { - "branch": null, - "revision": "e9fad491d0673bdda7063a0341fb6b47a30c5359", - "version": "1.62.2" - } - }, - { - "package": "GTMSessionFetcher", - "repositoryURL": "https://github.com/google/gtm-session-fetcher.git", - "state": { - "branch": null, - "revision": "0382ca27f22fb3494cf657d8dc356dc282cd1193", - "version": "3.4.1" - } - }, - { - "package": "interop-ios-for-google-sdks", - "repositoryURL": "https://github.com/google/interop-ios-for-google-sdks.git", - "state": { - "branch": null, - "revision": "2d12673670417654f08f5f90fdd62926dc3a2648", - "version": "100.0.0" - } - }, - { - "package": "Kingfisher", - "repositoryURL": "https://github.com/onevcat/Kingfisher.git", - "state": { - "branch": null, - "revision": "5b92f029fab2cce44386d28588098b5be0824ef5", - "version": "7.11.0" - } - }, - { - "package": "leveldb", - "repositoryURL": "https://github.com/firebase/leveldb.git", - "state": { - "branch": null, - "revision": "a0bc79961d7be727d258d33d5a6b2f1023270ba1", - "version": "1.22.5" - } - }, - { - "package": "nanopb", - "repositoryURL": "https://github.com/firebase/nanopb.git", - "state": { - "branch": null, - "revision": "b7e1104502eca3a213b46303391ca4d3bc8ddec1", - "version": "2.30910.0" - } - }, - { - "package": "promises", - "repositoryURL": "https://github.com/google/promises.git", - "state": { - "branch": null, - "revision": "540318ecedd63d883069ae7f1ed811a2df00b6ac", - "version": "2.4.0" - } - }, - { - "package": "SFSafeSymbols", - "repositoryURL": "https://github.com/SFSafeSymbols/SFSafeSymbols", - "state": { - "branch": null, - "revision": "e2e28f4e56e1769c2ec3c61c9355fc64eb7a535a", - "version": "5.3.0" - } - }, - { - "package": "SideMenu", - "repositoryURL": "https://github.com/jonkykong/SideMenu.git", - "state": { - "branch": null, - "revision": "8bd4fd128923cf5494fa726839af8afe12908ad9", - "version": "6.5.0" - } - }, - { - "package": "SVGKit", - "repositoryURL": "https://github.com/SVGKit/SVGKit.git", - "state": { - "branch": "3.x", - "revision": "02421928cab787faaffb2403d47c39392936fbc7", - "version": null - } - }, - { - "package": "swift-log", - "repositoryURL": "https://github.com/apple/swift-log", - "state": { - "branch": null, - "revision": "e97a6fcb1ab07462881ac165fdbb37f067e205d5", - "version": "1.5.4" - } - }, - { - "package": "SwiftProtobuf", - "repositoryURL": "https://github.com/apple/swift-protobuf.git", - "state": { - "branch": null, - "revision": "9f0c76544701845ad98716f3f6a774a892152bcb", - "version": "1.26.0" - } - }, - { - "package": "SwiftMessages", - "repositoryURL": "https://github.com/SwiftKickMobile/SwiftMessages.git", - "state": { - "branch": null, - "revision": "62e12e138fc3eedf88c7553dd5d98712aa119f40", - "version": "9.0.9" - } - } - ] - }, - "version": 1 + "pins" : [ + { + "identity" : "abseil-cpp-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/abseil-cpp-binary.git", + "state" : { + "revision" : "748c7837511d0e6a507737353af268484e1745e2", + "version" : "1.2024011601.1" + } + }, + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "f455c2975872ccd2d9c81594c658af65716e9b9a", + "version" : "5.9.1" + } + }, + { + "identity" : "alamofirenetworkactivityindicator", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git", + "state" : { + "revision" : "392bed083e8d193aca16bfa684ee24e4bcff0510", + "version" : "3.1.0" + } + }, + { + "identity" : "app-check", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/app-check.git", + "state" : { + "revision" : "076b241a625e25eac22f8849be256dfb960fcdfe", + "version" : "10.19.1" + } + }, + { + "identity" : "cocoalumberjack", + "kind" : "remoteSourceControl", + "location" : "https://github.com/CocoaLumberjack/CocoaLumberjack.git", + "state" : { + "revision" : "4b8714a7fb84d42393314ce897127b3939885ec3", + "version" : "3.8.5" + } + }, + { + "identity" : "devicekit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/devicekit/DeviceKit.git", + "state" : { + "revision" : "d37e70cb2646666dcf276d7d3d4a9760a41ff8a6", + "version" : "4.9.0" + } + }, + { + "identity" : "firebase-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/firebase-ios-sdk.git", + "state" : { + "revision" : "9d17b500cd98d9a7009751ad62f802e152e97021", + "version" : "10.26.0" + } + }, + { + "identity" : "flexcolorpicker", + "kind" : "remoteSourceControl", + "location" : "https://github.com/RastislavMirek/FlexColorPicker.git", + "state" : { + "revision" : "72a5c2c5e28074e6c5f13efe3c98eb780ae2f906", + "version" : "1.4.4" + } + }, + { + "identity" : "googleappmeasurement", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleAppMeasurement.git", + "state" : { + "revision" : "16244d177c4e989f87b25e9db1012b382cfedc55", + "version" : "10.25.0" + } + }, + { + "identity" : "googledatatransport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleDataTransport.git", + "state" : { + "revision" : "a637d318ae7ae246b02d7305121275bc75ed5565", + "version" : "9.4.0" + } + }, + { + "identity" : "googleutilities", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleUtilities.git", + "state" : { + "revision" : "57a1d307f42df690fdef2637f3e5b776da02aad6", + "version" : "7.13.3" + } + }, + { + "identity" : "grpc-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/grpc-binary.git", + "state" : { + "revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359", + "version" : "1.62.2" + } + }, + { + "identity" : "gtm-session-fetcher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/gtm-session-fetcher.git", + "state" : { + "revision" : "0382ca27f22fb3494cf657d8dc356dc282cd1193", + "version" : "3.4.1" + } + }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, + { + "identity" : "kingfisher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/onevcat/Kingfisher.git", + "state" : { + "revision" : "5b92f029fab2cce44386d28588098b5be0824ef5", + "version" : "7.11.0" + } + }, + { + "identity" : "leveldb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/leveldb.git", + "state" : { + "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", + "version" : "1.22.5" + } + }, + { + "identity" : "nanopb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/nanopb.git", + "state" : { + "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", + "version" : "2.30910.0" + } + }, + { + "identity" : "promises", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/promises.git", + "state" : { + "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", + "version" : "2.4.0" + } + }, + { + "identity" : "sfsafesymbols", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SFSafeSymbols/SFSafeSymbols", + "state" : { + "revision" : "e2e28f4e56e1769c2ec3c61c9355fc64eb7a535a", + "version" : "5.3.0" + } + }, + { + "identity" : "sidemenu", + "kind" : "remoteSourceControl", + "location" : "https://github.com/jonkykong/SideMenu.git", + "state" : { + "revision" : "8bd4fd128923cf5494fa726839af8afe12908ad9", + "version" : "6.5.0" + } + }, + { + "identity" : "svgkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SVGKit/SVGKit.git", + "state" : { + "branch" : "3.x", + "revision" : "02421928cab787faaffb2403d47c39392936fbc7" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "9bf03ff58ce34478e66aaee630e491823326fd06", + "version" : "1.1.3" + } + }, + { + "identity" : "swift-log", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-log", + "state" : { + "revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5", + "version" : "1.5.4" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "9f0c76544701845ad98716f3f6a774a892152bcb", + "version" : "1.26.0" + } + }, + { + "identity" : "swiftmessages", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftKickMobile/SwiftMessages.git", + "state" : { + "revision" : "62e12e138fc3eedf88c7553dd5d98712aa119f40", + "version" : "9.0.9" + } + } + ], + "version" : 2 } diff --git a/openHAB/OpenHABSelectionCollectionViewController.swift b/openHAB/OpenHABSelectionCollectionViewController.swift index 17a8499f..5b5fbb4b 100644 --- a/openHAB/OpenHABSelectionCollectionViewController.swift +++ b/openHAB/OpenHABSelectionCollectionViewController.swift @@ -15,7 +15,7 @@ import UIKit // swiftlint:disable:next type_name public protocol OpenHABSelectionTableViewControllerDelegate: NSObjectProtocol { - func didSelectWidgetMapping(_ selectedMapping: Int) + func didSelectWidgetMapping(_ selectedMapping: Int, widget: OpenHABWidget) } class OpenHABSelectionCollectionViewController: UICollectionViewController { @@ -25,7 +25,7 @@ class OpenHABSelectionCollectionViewController: UICollectionViewController { var mappings: [OpenHABWidgetMapping] = [] weak var delegate: OpenHABSelectionTableViewControllerDelegate? - var selectionItem: OpenHABItem? + var selectionWidget: OpenHABWidget? override func viewDidLoad() { super.viewDidLoad() @@ -38,8 +38,8 @@ class OpenHABSelectionCollectionViewController: UICollectionViewController { override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { os_log("Selected mapping %d", log: .viewCycle, type: .info, indexPath.row) - - delegate?.didSelectWidgetMapping(indexPath.row) + guard let selectionWidget else { fatalError("Not known selectionItem") } + delegate?.didSelectWidgetMapping(indexPath.row, widget: selectionWidget) navigationController?.popViewController(animated: true) } } @@ -60,7 +60,7 @@ private extension OpenHABSelectionCollectionViewController { cell.contentConfiguration = content - if self.selectionItem?.state == mapping.command { + if self.selectionWidget?.item?.state == mapping.command { os_log("This item is selected", log: .viewCycle, type: .info) cell.accessories = [.checkmark()] } else { diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index eeac0377..aa66dc2a 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -63,7 +63,6 @@ struct OpenHABImageProcessor: ImageProcessor { class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCellTouchEventDelegate { var pageUrl = "" - private var selectedWidgetRow: Int = 0 private var currentPageOperation: Alamofire.Request? private var commandOperation: Alamofire.Request? private var iconType: IconType = .png @@ -177,7 +176,7 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel // Set self as root view controller appData?.sitemapViewController = self if currentPage != nil { - currentPage?.widgets = [] + currentPage?.widgets = [:] updateUI() } os_log("OpenHABSitemapViewController pageUrl is empty, this is first launch", log: .viewCycle, type: .info) @@ -295,10 +294,6 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel } } - func relevantWidget(indexPath: IndexPath) -> OpenHABWidget? { - relevantPage?.widgets[safe: indexPath.row] - } - private func updateWidgetTableView() { UIView.performWithoutAnimation { tableView.beginUpdates() @@ -493,8 +488,8 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel func filterContentForSearchText(_ searchText: String?, scope: String = "All") { guard let searchText else { return } - filteredPage = currentPage?.filter { - $0.label.lowercased().contains(searchText.lowercased()) && $0.type != .frame + filteredPage = currentPage?.filter { (_, widget) in + widget.label.lowercased().contains(searchText.lowercased()) && widget.type != .frame } filteredPage?.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) @@ -547,10 +542,9 @@ extension OpenHABSitemapViewController: OpenHABTrackerDelegate { extension OpenHABSitemapViewController: OpenHABSelectionTableViewControllerDelegate { // send command on selected selection widget mapping - func didSelectWidgetMapping(_ selectedMappingIndex: Int) { - let selectedWidget: OpenHABWidget? = relevantPage?.widgets[selectedWidgetRow] - let selectedMapping: OpenHABWidgetMapping? = selectedWidget?.mappingsOrItemOptions[selectedMappingIndex] - sendCommand(selectedWidget?.item, commandToSend: selectedMapping?.command) + func didSelectWidgetMapping(_ selectedMappingIndex: Int, widget: OpenHABWidget) { + let selectedMapping: OpenHABWidgetMapping? = widget.mappingsOrItemOptions[selectedMappingIndex] + sendCommand(widget.item, commandToSend: selectedMapping?.command) } } @@ -566,13 +560,14 @@ extension OpenHABSitemapViewController: UISearchResultsUpdating { extension OpenHABSitemapViewController: ColorPickerCellDelegate { func didPressColorButton(_ cell: ColorPickerCell?) { - let colorPickerViewController = storyboard?.instantiateViewController(withIdentifier: "ColorPickerViewController") as? ColorPickerViewController - if let cell { - let widget = relevantPage?.widgets[tableView.indexPath(for: cell)?.row ?? 0] - colorPickerViewController?.title = widget?.labelText - colorPickerViewController?.widget = widget - } - if let colorPickerViewController { + if let colorPickerViewController = storyboard?.instantiateViewController(withIdentifier: "ColorPickerViewController") as? ColorPickerViewController, + let cell, + let indexPath = tableView.indexPath(for: cell), + + let widget = dataSource.itemIdentifier(for: indexPath) { + colorPickerViewController.title = widget.labelText + colorPickerViewController.widget = widget + navigationController?.pushViewController(colorPickerViewController, animated: true) } } @@ -683,14 +678,15 @@ extension OpenHABSitemapViewController { } // Check if this is not the last row in the widgets list - if indexPath.row < (self?.relevantPage?.widgets.count ?? 1) - 1 { - let nextWidget: OpenHABWidget? = self?.relevantPage?.widgets[indexPath.row + 1] - if let type = nextWidget?.type, type.isAny(of: .frame, .image, .video, .webview, .chart) { - cell.separatorInset = UIEdgeInsets.zero - } else if !(widget.type == .frame) { - cell.separatorInset = UIEdgeInsets(top: 0, left: 60, bottom: 0, right: 0) - } - } + // TODO Switch to separator layout guide https://developer.apple.com/videos/play/wwdc2020/10026/ +// if indexPath.row < (self?.relevantPage?.widgets.count ?? 1) - 1 { +// let nextWidget: OpenHABWidget? = self?.relevantPage?.widgets[indexPath.row + 1] +// if let type = nextWidget?.type, type.isAny(of: .frame, .image, .video, .webview, .chart) { +// cell.separatorInset = UIEdgeInsets.zero +// } else if !(widget.type == .frame) { +// cell.separatorInset = UIEdgeInsets(top: 0, left: 60, bottom: 0, right: 0) +// } +// } return cell } @@ -700,7 +696,9 @@ extension OpenHABSitemapViewController { func updateUI(animated: Bool = false) { currentSnapshot = NSDiffableDataSourceSnapshot() currentSnapshot.appendSections([.main]) - currentSnapshot.appendItems(relevantPage?.widgets ?? [], toSection: .main) + if let relevantPage { + currentSnapshot.appendItems(Array(relevantPage.widgets.values), toSection: .main) + } dataSource.apply(currentSnapshot, animatingDifferences: animated) } } @@ -713,14 +711,14 @@ extension OpenHABSitemapViewController: UITableViewDelegate { // }, UITableViewD } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - let widget: OpenHABWidget? = relevantPage?.widgets[indexPath.row] - switch widget?.type { + guard let widget = dataSource.itemIdentifier(for: indexPath) else { return 44.0 } + switch widget.type { case .frame: - return widget?.label.count ?? 0 > 0 ? 35.0 : 0 + return !widget.label.isEmpty ? 35.0 : 0 case .image, .chart, .video: return UITableView.automaticDimension case .webview, .mapview: - if let height = widget?.height { + if let height = widget.height { // calculate webview/mapview height and return it. Limited to UIScreen.main.bounds.height let heightValue = height * 44 os_log("Webview/Mapview height would be %g", log: .viewCycle, type: .info, heightValue) @@ -744,30 +742,28 @@ extension OpenHABSitemapViewController: UITableViewDelegate { // }, UITableViewD } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let widget: OpenHABWidget? = relevantWidget(indexPath: indexPath) - if widget?.linkedPage != nil { - if let link = widget?.linkedPage?.link { + guard let widget = dataSource.itemIdentifier(for: indexPath) else { return } + + if widget.linkedPage != nil { + if let link = widget.linkedPage?.link { os_log("Selected %{PUBLIC}@", log: .viewCycle, type: .info, link) } - selectedWidgetRow = indexPath.row let newViewController = (storyboard?.instantiateViewController(withIdentifier: "OpenHABPageViewController") as? OpenHABSitemapViewController)! - newViewController.title = widget?.linkedPage?.title.components(separatedBy: "[")[0] - newViewController.pageUrl = widget?.linkedPage?.link ?? "" + newViewController.title = widget.linkedPage?.title.components(separatedBy: "[")[0] + newViewController.pageUrl = widget.linkedPage?.link ?? "" newViewController.openHABRootUrl = openHABRootUrl navigationController?.pushViewController(newViewController, animated: true) - } else if widget?.type == .selection { + } else if widget.type == .selection { os_log("Selected selection widget", log: .viewCycle, type: .info) - selectedWidgetRow = indexPath.row let layout = UICollectionViewCompositionalLayout.list( using: UICollectionLayoutListConfiguration(appearance: .insetGrouped) ) let selectionViewController = OpenHABSelectionCollectionViewController(collectionViewLayout: layout) - let selectedWidget: OpenHABWidget? = relevantWidget(indexPath: indexPath) - selectionViewController.title = selectedWidget?.labelText - selectionViewController.mappings = selectedWidget?.mappingsOrItemOptions ?? [] + selectionViewController.title = widget.labelText + selectionViewController.mappings = widget.mappingsOrItemOptions selectionViewController.delegate = self - selectionViewController.selectionItem = selectedWidget?.item + selectionViewController.selectionWidget = widget show(selectionViewController, sender: self) } if let index = tableView.indexPathForSelectedRow {