Improve Home Assistant connection reliability
This commit is contained in:
@@ -10,7 +10,7 @@ import Darwin
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
protocol SwitchesViewControllerDelegate: class
|
||||
protocol SwitchesViewControllerDelegate: AnyObject
|
||||
{
|
||||
func switchesViewControllerDidToggleDevices(_ controller: SwitchesViewController, devices: [AnyDevice])
|
||||
}
|
||||
@@ -29,9 +29,8 @@ class SwitchesViewController: UIViewController,
|
||||
fileprivate var _collectionView: UICollectionView = UICollectionView(frame: CGRect.zero,
|
||||
collectionViewLayout: UICollectionViewFlowLayout())
|
||||
|
||||
fileprivate var _collectionViewDataSource: UICollectionViewDiffableDataSource<Int, Int>!
|
||||
|
||||
fileprivate var _currentDevicesHash: Int = 0
|
||||
fileprivate var _collectionViewDataSource:
|
||||
UICollectionViewDiffableDataSource<Int, ItemIdentifier>!
|
||||
|
||||
fileprivate let _label = UILabel(frame: .zero)
|
||||
|
||||
@@ -42,7 +41,7 @@ class SwitchesViewController: UIViewController,
|
||||
static fileprivate let actionCellsSectionIdentifier = 0
|
||||
static fileprivate let switchCellsSectionIdentifier = 1
|
||||
|
||||
fileprivate enum ActionCell: Int, CaseIterable
|
||||
fileprivate enum ActionCell: Int, CaseIterable, Hashable
|
||||
{
|
||||
case allOn
|
||||
case allOff
|
||||
@@ -59,6 +58,12 @@ class SwitchesViewController: UIViewController,
|
||||
|
||||
static let count: Int = { return ActionCell.allCases.count }()
|
||||
}
|
||||
|
||||
fileprivate enum ItemIdentifier: Hashable
|
||||
{
|
||||
case action(ActionCell)
|
||||
case device(String)
|
||||
}
|
||||
|
||||
public enum ActionCellLayout
|
||||
{
|
||||
@@ -85,8 +90,8 @@ class SwitchesViewController: UIViewController,
|
||||
|
||||
// Action cells
|
||||
snapshot.appendItems([
|
||||
SwitchesViewController.ActionCell.allOn.rawValue,
|
||||
SwitchesViewController.ActionCell.allOff.rawValue
|
||||
.action(.allOn),
|
||||
.action(.allOff)
|
||||
], toSection: SwitchesViewController.actionCellsSectionIdentifier)
|
||||
|
||||
_collectionViewDataSource.apply(snapshot, animatingDifferences: false)
|
||||
@@ -158,7 +163,10 @@ class SwitchesViewController: UIViewController,
|
||||
|
||||
var snapshot = _collectionViewDataSource.snapshot()
|
||||
snapshot.deleteItems(snapshot.itemIdentifiers(inSection: SwitchesViewController.switchCellsSectionIdentifier))
|
||||
snapshot.appendItems(self.devices.map { $0.hashValue }, toSection: SwitchesViewController.switchCellsSectionIdentifier)
|
||||
snapshot.appendItems(
|
||||
self.devices.map { .device($0.serial) },
|
||||
toSection: SwitchesViewController.switchCellsSectionIdentifier
|
||||
)
|
||||
snapshot.reloadSections([Self.actionCellsSectionIdentifier])
|
||||
_collectionViewDataSource.apply(snapshot, animatingDifferences: false)
|
||||
}
|
||||
@@ -168,9 +176,14 @@ class SwitchesViewController: UIViewController,
|
||||
{
|
||||
var snapshot = _collectionViewDataSource.snapshot()
|
||||
changedDevices.forEach { changedDevice in
|
||||
if let existingDevice = (self.devices.first { $0.hashValue == changedDevice.hashValue }) {
|
||||
if let existingDevice = self.devices.first(where: {
|
||||
$0.serial == changedDevice.serial
|
||||
}) {
|
||||
existingDevice.state = changedDevice.state
|
||||
snapshot.reloadItems([ existingDevice.hashValue ])
|
||||
let identifier = ItemIdentifier.device(existingDevice.serial)
|
||||
if snapshot.indexOfItem(identifier) != nil {
|
||||
snapshot.reloadItems([identifier])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,29 +192,36 @@ class SwitchesViewController: UIViewController,
|
||||
|
||||
// MARK: UICollectionView
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath, identifier: Int) -> UICollectionViewCell?
|
||||
fileprivate func collectionView(
|
||||
_ collectionView: UICollectionView,
|
||||
cellForItemAt indexPath: IndexPath,
|
||||
identifier: ItemIdentifier
|
||||
) -> UICollectionViewCell?
|
||||
{
|
||||
if (indexPath.section == SwitchesViewController.actionCellsSectionIdentifier) {
|
||||
switch identifier {
|
||||
case .action(let action):
|
||||
let reuseID = SwitchesViewController.collectionViewActionCellReuseIdentifier
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseID, for: indexPath) as! WemoActionCellView
|
||||
cell.textLabel.text = ActionCell(rawValue: identifier)?.name().uppercased()
|
||||
cell.textLabel.text = action.name().uppercased()
|
||||
cell.accessibilityIdentifier = "action.\(action.rawValue)"
|
||||
cell.accessibilityLabel = action.name()
|
||||
cell.enabled = (self.devices.count > 0)
|
||||
|
||||
return cell
|
||||
} else if (indexPath.section == SwitchesViewController.switchCellsSectionIdentifier) {
|
||||
|
||||
case .device(let serial):
|
||||
let reuseID = SwitchesViewController.collectionViewDeviceSwitchCellReuseIdentifier
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseID, for: indexPath) as! WemoDeviceCellView
|
||||
|
||||
if let device = (self.devices.first { $0.hashValue == identifier }) {
|
||||
if let device = self.devices.first(where: { $0.serial == serial }) {
|
||||
cell.deviceName = device.name
|
||||
cell.toggled = (device.state == .on)
|
||||
cell.ordinal = indexPath.row
|
||||
cell.accessibilityIdentifier = "device.\(device.serial)"
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView,
|
||||
@@ -252,9 +272,12 @@ class SwitchesViewController: UIViewController,
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
|
||||
{
|
||||
if (indexPath.section == SwitchesViewController.actionCellsSectionIdentifier) {
|
||||
let tappedActionCell = ActionCell(rawValue: indexPath.item)
|
||||
|
||||
guard let identifier = _collectionViewDataSource.itemIdentifier(for: indexPath) else {
|
||||
return
|
||||
}
|
||||
|
||||
switch identifier {
|
||||
case .action(let tappedActionCell):
|
||||
for cell in collectionView.visibleCells {
|
||||
if collectionView.indexPath(for: cell)?.section == SwitchesViewController.switchCellsSectionIdentifier {
|
||||
let switchCell = cell as! WemoDeviceCellView
|
||||
@@ -272,13 +295,17 @@ class SwitchesViewController: UIViewController,
|
||||
}
|
||||
|
||||
self.delegate?.switchesViewControllerDidToggleDevices(self, devices: self.devices)
|
||||
} else if (indexPath.section == SwitchesViewController.switchCellsSectionIdentifier) {
|
||||
let cell = collectionView.cellForItem(at: indexPath) as! WemoDeviceCellView
|
||||
|
||||
case .device(let serial):
|
||||
guard
|
||||
let cell = collectionView.cellForItem(at: indexPath) as? WemoDeviceCellView,
|
||||
let device = self.devices.first(where: { $0.serial == serial })
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
cell.toggled = !cell.toggled
|
||||
|
||||
let device = self.devices[indexPath.row]
|
||||
device.state = (cell.toggled ? .on : .off)
|
||||
|
||||
self.delegate?.switchesViewControllerDidToggleDevices(self, devices: [device])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user