From b226698760fb3bac8a6625268482d3e7f3f34e5a Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Tue, 27 Nov 2018 14:46:38 -0800 Subject: [PATCH] Adds RecordSyncStatusViewController Views local and remote status of a record, and enable/disable syncing --- Delta.xcodeproj/project.pbxproj | 8 + Delta/Base.lproj/Settings.storyboard | 219 ++++++++++++++++++ .../GameSyncStatusViewController.swift | 16 +- .../RecordSyncStatusViewController.swift | 159 +++++++++++++ 4 files changed, 401 insertions(+), 1 deletion(-) create mode 100644 Delta/Settings/Syncing/RecordSyncStatusViewController.swift diff --git a/Delta.xcodeproj/project.pbxproj b/Delta.xcodeproj/project.pbxproj index ed881f9..910f76b 100644 --- a/Delta.xcodeproj/project.pbxproj +++ b/Delta.xcodeproj/project.pbxproj @@ -80,6 +80,8 @@ BF5942951E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5942921E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift */; }; BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E7F431B9A650B00AE44F8 /* SettingsViewController.swift */; }; BF5E7F461B9A652600AE44F8 /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF5E7F451B9A652600AE44F8 /* Settings.storyboard */; }; + BF63A1A321A4AAAE00EE8F61 /* RecordSyncStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63A1A221A4AAAE00EE8F61 /* RecordSyncStatusViewController.swift */; }; + BF63A1B521A4B76E00EE8F61 /* RecordVersionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63A1B421A4B76E00EE8F61 /* RecordVersionsViewController.swift */; }; BF6424831F5B8F3F00D6AB44 /* ListMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6424821F5B8F3F00D6AB44 /* ListMenuViewController.swift */; }; BF6424851F5CBDC900D6AB44 /* UIView+ParentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6424841F5CBDC900D6AB44 /* UIView+ParentViewController.swift */; }; BF6866171DCAC8B900BF2D06 /* ControllerSkin+Configuring.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6866161DCAC8B900BF2D06 /* ControllerSkin+Configuring.swift */; }; @@ -227,6 +229,8 @@ BF5E7F431B9A650B00AE44F8 /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; BF5E7F451B9A652600AE44F8 /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Settings.storyboard; path = Delta/Base.lproj/Settings.storyboard; sourceTree = SOURCE_ROOT; }; BF616A121F08184A0077F8B2 /* ControllerInputsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControllerInputsViewController.swift; sourceTree = ""; }; + BF63A1A221A4AAAE00EE8F61 /* RecordSyncStatusViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordSyncStatusViewController.swift; sourceTree = ""; }; + BF63A1B421A4B76E00EE8F61 /* RecordVersionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordVersionsViewController.swift; sourceTree = ""; }; BF63BDE91D389EEB00FCB040 /* GameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; }; BF6424821F5B8F3F00D6AB44 /* ListMenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListMenuViewController.swift; sourceTree = ""; }; BF6424841F5CBDC900D6AB44 /* UIView+ParentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+ParentViewController.swift"; sourceTree = ""; }; @@ -381,6 +385,8 @@ BF48F74D219A16DA00BC2FC1 /* SyncingServicesViewController.swift */, BFDB3417219E4B1700595A62 /* SyncStatusViewController.swift */, BF8A334521A4926F00A42FD4 /* GameSyncStatusViewController.swift */, + BF63A1A221A4AAAE00EE8F61 /* RecordSyncStatusViewController.swift */, + BF63A1B421A4B76E00EE8F61 /* RecordVersionsViewController.swift */, ); path = Syncing; sourceTree = ""; @@ -938,6 +944,7 @@ BF525EEA1FF6CD12004AA849 /* DeepLink.swift in Sources */, BF8A334621A4926F00A42FD4 /* GameSyncStatusViewController.swift in Sources */, BF59427E1E09BC830051894B /* Game.swift in Sources */, + BF63A1A321A4AAAE00EE8F61 /* RecordSyncStatusViewController.swift in Sources */, BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */, BFA0D1271D3AE1F600565894 /* GameViewController.swift in Sources */, BF59428A1E09BC8B0051894B /* _SaveState.swift in Sources */, @@ -945,6 +952,7 @@ BF59428E1E09BCFB0051894B /* ImportController.swift in Sources */, BF13A7581D5D2FD9000BB055 /* EmulatorCore+Cheats.swift in Sources */, BF48F74E219A16DA00BC2FC1 /* SyncingServicesViewController.swift in Sources */, + BF63A1B521A4B76E00EE8F61 /* RecordVersionsViewController.swift in Sources */, BF6424831F5B8F3F00D6AB44 /* ListMenuViewController.swift in Sources */, BF1020E31F95B05B00313182 /* DeltaToDelta2.xcmappingmodel in Sources */, BF6BF3131EB7E47F008E83CD /* ImportOption.swift in Sources */, diff --git a/Delta/Base.lproj/Settings.storyboard b/Delta/Base.lproj/Settings.storyboard index ccc0c50..ce5cc00 100644 --- a/Delta/Base.lproj/Settings.storyboard +++ b/Delta/Base.lproj/Settings.storyboard @@ -5,6 +5,7 @@ + @@ -862,6 +863,9 @@ + + + @@ -875,5 +879,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Delta/Settings/Syncing/GameSyncStatusViewController.swift b/Delta/Settings/Syncing/GameSyncStatusViewController.swift index b66a7ea..86ca667 100644 --- a/Delta/Settings/Syncing/GameSyncStatusViewController.swift +++ b/Delta/Settings/Syncing/GameSyncStatusViewController.swift @@ -51,6 +51,20 @@ class GameSyncStatusViewController: UITableViewController self.fetchRecords() super.viewWillAppear(animated) + + self.tableView.reloadData() + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) + { + guard segue.identifier == "showRecord" else { return } + + guard let cell = sender as? UITableViewCell, let indexPath = self.tableView.indexPath(for: cell) else { return } + + let recordedObject = self.dataSource.item(at: indexPath) as! SyncableManagedObject + + let recordSyncStatusViewController = segue.destination as! RecordSyncStatusViewController + recordSyncStatusViewController.recordedObject = recordedObject } } @@ -72,7 +86,7 @@ private extension GameSyncStatusViewController let gameDataSource = RSTArrayTableViewDataSource(items: [self.game]) gameDataSource.cellConfigurationHandler = { (cell, game, indexPath) in - cell.textLabel?.text = game.name + cell.textLabel?.text = NSLocalizedString("Game", comment: "") configure(cell, recordedObject: game) } diff --git a/Delta/Settings/Syncing/RecordSyncStatusViewController.swift b/Delta/Settings/Syncing/RecordSyncStatusViewController.swift new file mode 100644 index 0000000..4f8be8e --- /dev/null +++ b/Delta/Settings/Syncing/RecordSyncStatusViewController.swift @@ -0,0 +1,159 @@ +// +// RecordSyncStatusViewController.swift +// Delta +// +// Created by Riley Testut on 11/20/18. +// Copyright © 2018 Riley Testut. All rights reserved. +// + +import UIKit + +import Harmony + +extension RecordStatus +{ + fileprivate var localizedDescription: String { + switch self + { + case .normal: return NSLocalizedString("Normal", comment: "") + case .updated: return NSLocalizedString("Updated", comment: "") + case .deleted: return NSLocalizedString("Deleted", comment: "") + } + } +} + +extension RecordSyncStatusViewController +{ + private enum Section: Int, CaseIterable + { + case syncingEnabled + case localStatus + case remoteStatus + case versions + } +} + +class RecordSyncStatusViewController: UITableViewController +{ + var recordedObject: SyncableManagedObject! + var record: Record? + + private let dateFormatter: DateFormatter = { + let dateFormatter = DateFormatter() + dateFormatter.timeStyle = .short + dateFormatter.dateStyle = .short + + return dateFormatter + }() + + @IBOutlet private var syncingEnabledSwitch: UISwitch! + + @IBOutlet private var localStatusLabel: UILabel! + @IBOutlet private var localDateLabel: UILabel! + + @IBOutlet private var remoteStatusLabel: UILabel! + @IBOutlet private var remoteDateLabel: UILabel! + @IBOutlet private var remoteDeviceLabel: UILabel! + + override func viewWillAppear(_ animated: Bool) + { + super.viewWillAppear(animated) + + self.update() + self.tableView.reloadData() + } +} + +private extension RecordSyncStatusViewController +{ + func update() + { + do + { + let records = try SyncManager.shared.recordController.fetchRecords(for: [self.recordedObject]) + self.record = records.first + } + catch + { + print(error) + } + + if let record = self.record + { + self.syncingEnabledSwitch.isEnabled = !record.isConflicted + self.syncingEnabledSwitch.isOn = record.isSyncingEnabled + + self.localStatusLabel.text = record.localStatus?.localizedDescription ?? "-" + self.remoteStatusLabel.text = record.remoteStatus?.localizedDescription ?? "-" + + self.remoteDeviceLabel.text = record.remoteAuthor ?? "-" + + if let version = record.remoteVersion + { + self.remoteDateLabel.text = self.dateFormatter.string(from: version.date) + } + else + { + self.remoteDateLabel.text = "-" + } + } + else + { + self.syncingEnabledSwitch.isEnabled = false + self.syncingEnabledSwitch.isOn = false + + self.localStatusLabel.text = "-" + self.localDateLabel.text = "-" + + self.remoteStatusLabel.text = "-" + self.remoteDateLabel.text = "-" + self.remoteDeviceLabel.text = "-" + } + } + + @IBAction func toggleSyncingEnabled(_ sender: UISwitch) + { + do + { + try self.record?.setSyncingEnabled(sender.isOn) + } + catch + { + let title = sender.isOn ? NSLocalizedString("Failed to Enable Syncing", comment: "") : NSLocalizedString("Failed to Disable Syncing", comment: "") + + let alertController = UIAlertController(title: title, error: error) + self.present(alertController, animated: true, completion: nil) + } + + self.update() + } +} + +extension RecordSyncStatusViewController +{ + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell + { + let cell = super.tableView(tableView, cellForRowAt: indexPath) + + switch Section.allCases[indexPath.section] + { + case .versions: + cell.textLabel?.alpha = (self.record != nil) ? 1.0 : 0.33 + + if self.record?.isConflicted == true + { + cell.textLabel?.text = NSLocalizedString("Resolve Conflict", comment: "") + cell.textLabel?.textColor = .red + } + else + { + cell.textLabel?.text = NSLocalizedString("View Versions", comment: "") + cell.textLabel?.textColor = .deltaPurple + } + + default: break + } + + return cell + } +}