Adds SyncStatusViewController to view basic sync status of games
This commit is contained in:
parent
c1fc0d1ce3
commit
5354d779c1
@ -98,6 +98,7 @@
|
||||
BF7AE8081C2E858400B1B5BC /* GridMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8041C2E858400B1B5BC /* GridMenuViewController.swift */; };
|
||||
BF7AE80A1C2E8C7600B1B5BC /* UIColor+Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */; };
|
||||
BF80E1D21F13117000847008 /* ControllerInputsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF616A121F08184A0077F8B2 /* ControllerInputsViewController.swift */; };
|
||||
BF8A333421A484A000A42FD4 /* BadgedTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8A333321A484A000A42FD4 /* BadgedTableViewCell.swift */; };
|
||||
BF8CA9361F5F651900499FDD /* PopoverMenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CA9351F5F651900499FDD /* PopoverMenuController.swift */; };
|
||||
BF8DDD241F4F6C880088A21B /* InputCalloutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8DDD231F4F6C880088A21B /* InputCalloutView.swift */; };
|
||||
BF95E2771E4977BF0030E7AD /* GameMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF95E2761E4977BF0030E7AD /* GameMetadata.swift */; };
|
||||
@ -116,6 +117,7 @@
|
||||
BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */; };
|
||||
BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */; };
|
||||
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; };
|
||||
BFDB3418219E4B1700595A62 /* SyncStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB3417219E4B1700595A62 /* SyncStatusViewController.swift */; };
|
||||
BFDD04F11D5E2C27002D450E /* GameCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDD04F01D5E2C27002D450E /* GameCollectionViewController.swift */; };
|
||||
BFE022A01F5B57FF0052D888 /* PopoverMenuButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE0229F1F5B577D0052D888 /* PopoverMenuButton.swift */; };
|
||||
BFE4269E1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE4269D1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift */; };
|
||||
@ -244,6 +246,7 @@
|
||||
BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILabel+FontSize.swift"; sourceTree = "<group>"; };
|
||||
BF7AE8041C2E858400B1B5BC /* GridMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GridMenuViewController.swift; sourceTree = "<group>"; };
|
||||
BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Delta.swift"; sourceTree = "<group>"; };
|
||||
BF8A333321A484A000A42FD4 /* BadgedTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgedTableViewCell.swift; sourceTree = "<group>"; };
|
||||
BF8CA9351F5F651900499FDD /* PopoverMenuController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopoverMenuController.swift; sourceTree = "<group>"; };
|
||||
BF8DDD231F4F6C880088A21B /* InputCalloutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputCalloutView.swift; sourceTree = "<group>"; };
|
||||
BF95E2761E4977BF0030E7AD /* GameMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameMetadata.swift; sourceTree = "<group>"; };
|
||||
@ -258,6 +261,7 @@
|
||||
BFC6F7B71F435BC500221B96 /* Input+Display.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Input+Display.swift"; sourceTree = "<group>"; };
|
||||
BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheatsViewController.swift; sourceTree = "<group>"; };
|
||||
BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewControllerContextTransitioning+Conveniences.swift"; sourceTree = "<group>"; };
|
||||
BFDB3417219E4B1700595A62 /* SyncStatusViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncStatusViewController.swift; sourceTree = "<group>"; };
|
||||
BFDD04F01D5E2C27002D450E /* GameCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollectionViewController.swift; sourceTree = "<group>"; };
|
||||
BFE0229F1F5B577D0052D888 /* PopoverMenuButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopoverMenuButton.swift; sourceTree = "<group>"; };
|
||||
BFE4269D1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SaveStatesStoryboardSegue.swift; sourceTree = "<group>"; };
|
||||
@ -370,6 +374,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF48F74D219A16DA00BC2FC1 /* SyncingServicesViewController.swift */,
|
||||
BFDB3417219E4B1700595A62 /* SyncStatusViewController.swift */,
|
||||
);
|
||||
path = Syncing;
|
||||
sourceTree = "<group>";
|
||||
@ -520,6 +525,7 @@
|
||||
children = (
|
||||
BFFA4C081E8A24D600D87934 /* GameTableViewCell.swift */,
|
||||
BF71CF891FE904B1001F1613 /* GameTableViewCell.xib */,
|
||||
BF8A333321A484A000A42FD4 /* BadgedTableViewCell.swift */,
|
||||
);
|
||||
path = "Table View";
|
||||
sourceTree = "<group>";
|
||||
@ -941,6 +947,7 @@
|
||||
BF4828841F9027B600028B97 /* Delta.xcdatamodeld in Sources */,
|
||||
BF5942951E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift in Sources */,
|
||||
BF353FF91C5D870B00C1184C /* MenuItem.swift in Sources */,
|
||||
BFDB3418219E4B1700595A62 /* SyncStatusViewController.swift in Sources */,
|
||||
BF18B61F1E2985F900F70067 /* UIAlertController+Importing.swift in Sources */,
|
||||
BFDD04F11D5E2C27002D450E /* GameCollectionViewController.swift in Sources */,
|
||||
BFE4269E1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift in Sources */,
|
||||
@ -977,6 +984,7 @@
|
||||
BF95E2791E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift in Sources */,
|
||||
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */,
|
||||
BF6EE5EB1F7C5F8F0051AD6C /* GameControllerInputMapping.swift in Sources */,
|
||||
BF8A333421A484A000A42FD4 /* BadgedTableViewCell.swift in Sources */,
|
||||
BF3540021C5DA3D500C1184C /* PauseStoryboardSegue.swift in Sources */,
|
||||
BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */,
|
||||
BF59426F1E09BC5D0051894B /* DatabaseManager.swift in Sources */,
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@ -18,7 +17,7 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<label key="tableFooterView" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Delta 0.6.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Str-BY-agW">
|
||||
<rect key="frame" x="0.0" y="773" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="817" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
@ -227,11 +226,11 @@
|
||||
<rect key="frame" x="0.0" y="611" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="bwW-PG-BcV" id="RNA-99-evH">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Service" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="4U1-fe-PIb">
|
||||
<rect key="frame" x="16" y="12" width="54" height="19.5"/>
|
||||
<rect key="frame" x="15" y="12" width="54" height="19.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@ -250,19 +249,46 @@
|
||||
<segue destination="R9m-rV-VgV" kind="show" id="MAM-GM-FlH"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="DetailCell" textLabel="1u0-gh-zP7" detailTextLabel="ncZ-5K-Hrk" style="IBUITableViewCellStyleValue1" id="JPg-6O-DRe">
|
||||
<rect key="frame" x="0.0" y="655" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JPg-6O-DRe" id="zcZ-QR-Nno">
|
||||
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Status" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="1u0-gh-zP7">
|
||||
<rect key="frame" x="15" y="12" width="46.5" height="19.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ncZ-5K-Hrk">
|
||||
<rect key="frame" x="298.5" y="12" width="41.5" height="19.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="vVg-ci-JRa" kind="show" id="Hfy-lJ-4tW"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="3D Touch" id="fdp-8c-oOc">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="c5i-qG-ir9" style="IBUITableViewCellStyleDefault" id="SSL-t4-QZj">
|
||||
<rect key="frame" x="0.0" y="711" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="755" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="SSL-t4-QZj" id="hQB-Iy-bzy">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="App Icon Shortcuts" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="c5i-qG-ir9">
|
||||
<rect key="frame" x="16" y="0.0" width="324" height="43.5"/>
|
||||
<rect key="frame" x="15" y="0.0" width="325" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@ -777,5 +803,42 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2513" y="1872"/>
|
||||
</scene>
|
||||
<!--Sync Status-->
|
||||
<scene sceneID="IYe-DI-U7i">
|
||||
<objects>
|
||||
<tableViewController title="Sync Status" id="vVg-ci-JRa" customClass="SyncStatusViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Nza-ON-XbS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="AWh-ik-Gvu" style="IBUITableViewCellStyleDefault" id="wpv-cf-duw" customClass="BadgedTableViewCell" customModule="Delta" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="wpv-cf-duw" id="ehC-Qx-Zx4">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="AWh-ik-Gvu">
|
||||
<rect key="frame" x="16" y="0.0" width="324" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="vVg-ci-JRa" id="Ch3-KN-Vuq"/>
|
||||
<outlet property="delegate" destination="vVg-ci-JRa" id="WMN-hE-f2P"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="kT7-Ig-nyf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3351" y="1872"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
|
||||
73
Delta/Components/Table View/BadgedTableViewCell.swift
Normal file
73
Delta/Components/Table View/BadgedTableViewCell.swift
Normal file
@ -0,0 +1,73 @@
|
||||
//
|
||||
// BadgedTableViewCell.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 11/20/18.
|
||||
// Copyright © 2018 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class BadgedTableViewCell: UITableViewCell
|
||||
{
|
||||
let badgeLabel = UILabel()
|
||||
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
{
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
self.initialize()
|
||||
}
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
|
||||
{
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
self.initialize()
|
||||
}
|
||||
|
||||
private func initialize()
|
||||
{
|
||||
self.badgeLabel.clipsToBounds = true
|
||||
self.badgeLabel.textAlignment = .center
|
||||
self.badgeLabel.backgroundColor = .red
|
||||
self.badgeLabel.font = UIFont.boldSystemFont(ofSize: 14)
|
||||
self.badgeLabel.textColor = .white
|
||||
self.contentView.addSubview(self.badgeLabel)
|
||||
}
|
||||
|
||||
override func layoutSubviews()
|
||||
{
|
||||
super.layoutSubviews()
|
||||
|
||||
guard let textLabel = self.textLabel else { return }
|
||||
|
||||
let spacing = 8 as CGFloat
|
||||
|
||||
var contentSize = self.badgeLabel.intrinsicContentSize
|
||||
contentSize.width += 10
|
||||
contentSize.height += 10
|
||||
contentSize.width = max(contentSize.width, contentSize.height)
|
||||
|
||||
var frame = CGRect(x: self.contentView.bounds.maxX - contentSize.width,
|
||||
y: self.contentView.bounds.midY - contentSize.height / 2,
|
||||
width: contentSize.width,
|
||||
height: contentSize.height)
|
||||
|
||||
if self.accessoryType == .none
|
||||
{
|
||||
frame.origin.x -= spacing
|
||||
}
|
||||
|
||||
self.badgeLabel.frame = frame
|
||||
self.badgeLabel.layer.cornerRadius = frame.height / 2
|
||||
|
||||
self.badgeLabel.backgroundColor = .red
|
||||
|
||||
let overlap = textLabel.frame.maxX - (frame.minX - spacing)
|
||||
if overlap > 0 && !self.badgeLabel.isHidden
|
||||
{
|
||||
textLabel.frame.size.width -= overlap
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,11 +14,11 @@ import Harmony
|
||||
@objc(GameCollection)
|
||||
public class GameCollection: _GameCollection
|
||||
{
|
||||
var name: String {
|
||||
@objc var name: String {
|
||||
return self.system?.localizedName ?? NSLocalizedString("Unknown", comment: "")
|
||||
}
|
||||
|
||||
var shortName: String {
|
||||
@objc var shortName: String {
|
||||
return self.system?.localizedShortName ?? NSLocalizedString("Unknown", comment: "")
|
||||
}
|
||||
|
||||
|
||||
142
Delta/Settings/Syncing/SyncStatusViewController.swift
Normal file
142
Delta/Settings/Syncing/SyncStatusViewController.swift
Normal file
@ -0,0 +1,142 @@
|
||||
//
|
||||
// SyncStatusViewController.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 11/15/18.
|
||||
// Copyright © 2018 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import Roxas
|
||||
|
||||
class SyncStatusViewController: UITableViewController
|
||||
{
|
||||
private lazy var dataSource = self.makeDataSource()
|
||||
|
||||
private var gameConflictsCount: [URL: Int]?
|
||||
|
||||
override func viewDidLoad()
|
||||
{
|
||||
super.viewDidLoad()
|
||||
|
||||
self.tableView.dataSource = self.dataSource
|
||||
self.navigationItem.searchController = self.dataSource.searchController
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool)
|
||||
{
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
self.fetchConflictedRecords()
|
||||
}
|
||||
}
|
||||
|
||||
private extension SyncStatusViewController
|
||||
{
|
||||
func makeDataSource() -> RSTFetchedResultsTableViewDataSource<Game>
|
||||
{
|
||||
let fetchRequest = Game.fetchRequest() as NSFetchRequest<Game>
|
||||
fetchRequest.returnsObjectsAsFaults = false
|
||||
fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Game.gameCollection?.index, ascending: true), NSSortDescriptor(key: #keyPath(Game.name), ascending: true)]
|
||||
|
||||
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: #keyPath(Game.gameCollection.name), cacheName: nil)
|
||||
|
||||
let dataSource = RSTFetchedResultsTableViewDataSource(fetchedResultsController: fetchedResultsController)
|
||||
dataSource.proxy = self
|
||||
dataSource.searchController.searchableKeyPaths = [#keyPath(Game.name)]
|
||||
dataSource.cellConfigurationHandler = { (cell, game, indexPath) in
|
||||
let cell = cell as! BadgedTableViewCell
|
||||
cell.textLabel?.text = game.name
|
||||
cell.textLabel?.numberOfLines = 0
|
||||
|
||||
if let gameConflictsCount = self.gameConflictsCount
|
||||
{
|
||||
if let count = gameConflictsCount[game.objectID.uriRepresentation()], count > 0
|
||||
{
|
||||
cell.badgeLabel.text = String(describing: count)
|
||||
cell.badgeLabel.isHidden = false
|
||||
}
|
||||
else
|
||||
{
|
||||
cell.badgeLabel.isHidden = true
|
||||
}
|
||||
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.accessoryView = nil
|
||||
}
|
||||
else
|
||||
{
|
||||
let activityIndicatorView = UIActivityIndicatorView(style: .gray)
|
||||
activityIndicatorView.startAnimating()
|
||||
|
||||
cell.accessoryType = .none
|
||||
cell.accessoryView = activityIndicatorView
|
||||
|
||||
cell.badgeLabel.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
return dataSource
|
||||
}
|
||||
|
||||
func fetchConflictedRecords()
|
||||
{
|
||||
DispatchQueue.global().async {
|
||||
do
|
||||
{
|
||||
var gameConflictsCount = [URL: Int]()
|
||||
|
||||
let records = try SyncManager.shared.recordController.fetchConflictedRecords()
|
||||
|
||||
for record in records
|
||||
{
|
||||
guard let recordedObject = record.recordedObject else { continue }
|
||||
|
||||
let conflictedGame: Game?
|
||||
|
||||
switch recordedObject
|
||||
{
|
||||
case let game as Game: conflictedGame = game
|
||||
case let saveState as SaveState: conflictedGame = saveState.game
|
||||
case let cheat as Cheat: conflictedGame = cheat.game
|
||||
default: conflictedGame = nil
|
||||
}
|
||||
|
||||
guard let game = conflictedGame else { continue }
|
||||
|
||||
gameConflictsCount[game.objectID.uriRepresentation(), default: 0] += 1
|
||||
}
|
||||
|
||||
self.gameConflictsCount = gameConflictsCount
|
||||
}
|
||||
catch
|
||||
{
|
||||
print(error)
|
||||
|
||||
self.gameConflictsCount = [:]
|
||||
|
||||
DispatchQueue.main.async {
|
||||
let alertController = UIAlertController(title: NSLocalizedString("Failed to Get Sync Status", comment: ""),
|
||||
message: error.localizedDescription,
|
||||
preferredStyle: .alert)
|
||||
alertController.addAction(.ok)
|
||||
self.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SyncStatusViewController
|
||||
{
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
|
||||
{
|
||||
let section = self.dataSource.fetchedResultsController.sections?[section]
|
||||
return section?.name
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,9 @@
|
||||
import UIKit
|
||||
|
||||
import Harmony
|
||||
import Harmony_Drive
|
||||
|
||||
import Roxas
|
||||
|
||||
enum SyncingService: String, CaseIterable
|
||||
{
|
||||
|
||||
@ -17,6 +17,10 @@ final class SyncManager
|
||||
return self.syncCoordinator.service
|
||||
}
|
||||
|
||||
var recordController: RecordController {
|
||||
return self.syncCoordinator.recordController
|
||||
}
|
||||
|
||||
private(set) var isAuthenticated = false
|
||||
|
||||
private let syncCoordinator = SyncCoordinator(service: DriveService.shared, persistentContainer: DatabaseManager.shared)
|
||||
|
||||
2
External/Harmony
vendored
2
External/Harmony
vendored
@ -1 +1 @@
|
||||
Subproject commit 09255222fd823bc9014a54e5625bdd286001f047
|
||||
Subproject commit 6f5dc280077cee8382ccc6622ee8383aadb59d48
|
||||
Loading…
Reference in New Issue
Block a user