Replacing IHProgressHUD with PKHUD
@ -46,10 +46,6 @@
|
|||||||
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AA24360DC800E59687 /* Dated.swift */; };
|
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AA24360DC800E59687 /* Dated.swift */; };
|
||||||
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AC2436350B00E59687 /* SearchController.swift */; };
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AC2436350B00E59687 /* SearchController.swift */; };
|
||||||
7A43F9F8246C8A6200BA5B49 /* JWT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A43F9F7246C8A6200BA5B49 /* JWT.swift */; };
|
7A43F9F8246C8A6200BA5B49 /* JWT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A43F9F7246C8A6200BA5B49 /* JWT.swift */; };
|
||||||
7A488C3C24A74B990054D0B2 /* RxTableViewRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A488C3824A74B990054D0B2 /* RxTableViewRealmDataSource.swift */; };
|
|
||||||
7A488C3D24A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A488C3924A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift */; };
|
|
||||||
7A488C3E24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A488C3A24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift */; };
|
|
||||||
7A488C3F24A74B990054D0B2 /* RealmBindObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A488C3B24A74B990054D0B2 /* RealmBindObserver.swift */; };
|
|
||||||
7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7924001D3300CBFE6E /* CheckController.swift */; };
|
7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7924001D3300CBFE6E /* CheckController.swift */; };
|
||||||
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */; };
|
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */; };
|
||||||
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7F2401803A00CBFE6E /* Vehicle.swift */; };
|
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7F2401803A00CBFE6E /* Vehicle.swift */; };
|
||||||
@ -58,12 +54,6 @@
|
|||||||
7A64AE742469DFB600ABE48E /* MediaContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE702469DFB600ABE48E /* MediaContentView.swift */; };
|
7A64AE742469DFB600ABE48E /* MediaContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE702469DFB600ABE48E /* MediaContentView.swift */; };
|
||||||
7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE712469DFB600ABE48E /* MediaBrowserViewController.swift */; };
|
7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE712469DFB600ABE48E /* MediaBrowserViewController.swift */; };
|
||||||
7A64AE762469DFB600ABE48E /* ContentTransformers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE722469DFB600ABE48E /* ContentTransformers.swift */; };
|
7A64AE762469DFB600ABE48E /* ContentTransformers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE722469DFB600ABE48E /* ContentTransformers.swift */; };
|
||||||
7A64AE7E2469E16100ABE48E /* RadialGradientLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE782469E16100ABE48E /* RadialGradientLayer.swift */; };
|
|
||||||
7A64AE7F2469E16100ABE48E /* IndefiniteAnimatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE792469E16100ABE48E /* IndefiniteAnimatedView.swift */; };
|
|
||||||
7A64AE802469E16100ABE48E /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = 7A64AE7A2469E16100ABE48E /* .gitkeep */; };
|
|
||||||
7A64AE812469E16100ABE48E /* ProgressAnimatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE7B2469E16100ABE48E /* ProgressAnimatedView.swift */; };
|
|
||||||
7A64AE822469E16100ABE48E /* IHProgressHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE7C2469E16100ABE48E /* IHProgressHUD.swift */; };
|
|
||||||
7A64AE832469E16100ABE48E /* IHProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 7A64AE7D2469E16100ABE48E /* IHProgressHUD.bundle */; };
|
|
||||||
7A659B5924A2B1BA0043A0F2 /* AudioRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A659B5824A2B1BA0043A0F2 /* AudioRecord.swift */; };
|
7A659B5924A2B1BA0043A0F2 /* AudioRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A659B5824A2B1BA0043A0F2 /* AudioRecord.swift */; };
|
||||||
7A659B5B24A3768A0043A0F2 /* Substrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A659B5A24A3768A0043A0F2 /* Substrings.swift */; };
|
7A659B5B24A3768A0043A0F2 /* Substrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A659B5A24A3768A0043A0F2 /* Substrings.swift */; };
|
||||||
7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD902242BF4A5009DE740 /* PlateView.swift */; };
|
7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD902242BF4A5009DE740 /* PlateView.swift */; };
|
||||||
@ -89,6 +79,7 @@
|
|||||||
7A96AE31246B2FE400297C33 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE30246B2FE400297C33 /* Constants.swift */; };
|
7A96AE31246B2FE400297C33 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE30246B2FE400297C33 /* Constants.swift */; };
|
||||||
7A96AE33246C095700297C33 /* Base64FS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE32246C095700297C33 /* Base64FS.swift */; };
|
7A96AE33246C095700297C33 /* Base64FS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE32246C095700297C33 /* Base64FS.swift */; };
|
||||||
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */; };
|
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */; };
|
||||||
|
7AABDE1D2532F3EB0041AFC6 /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7AABDE1C2532F3EB0041AFC6 /* PKHUD */; };
|
||||||
7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAE6AD224CDDF950023860B /* VehicleEvent.swift */; };
|
7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAE6AD224CDDF950023860B /* VehicleEvent.swift */; };
|
||||||
7AB562BA249C9E9B00473D53 /* Region.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB562B9249C9E9B00473D53 /* Region.swift */; };
|
7AB562BA249C9E9B00473D53 /* Region.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB562B9249C9E9B00473D53 /* Region.swift */; };
|
||||||
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; };
|
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; };
|
||||||
@ -145,10 +136,6 @@
|
|||||||
7A3F07AA24360DC800E59687 /* Dated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dated.swift; sourceTree = "<group>"; };
|
7A3F07AA24360DC800E59687 /* Dated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dated.swift; sourceTree = "<group>"; };
|
||||||
7A3F07AC2436350B00E59687 /* SearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchController.swift; sourceTree = "<group>"; };
|
7A3F07AC2436350B00E59687 /* SearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchController.swift; sourceTree = "<group>"; };
|
||||||
7A43F9F7246C8A6200BA5B49 /* JWT.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWT.swift; sourceTree = "<group>"; };
|
7A43F9F7246C8A6200BA5B49 /* JWT.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWT.swift; sourceTree = "<group>"; };
|
||||||
7A488C3824A74B990054D0B2 /* RxTableViewRealmDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewRealmDataSource.swift; sourceTree = "<group>"; };
|
|
||||||
7A488C3924A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewRealmDataSource.swift; sourceTree = "<group>"; };
|
|
||||||
7A488C3A24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Reactive+RxRealmDataSources.swift"; sourceTree = "<group>"; };
|
|
||||||
7A488C3B24A74B990054D0B2 /* RealmBindObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmBindObserver.swift; sourceTree = "<group>"; };
|
|
||||||
7A530B7924001D3300CBFE6E /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
|
7A530B7924001D3300CBFE6E /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
|
||||||
7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = "<group>"; };
|
7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = "<group>"; };
|
||||||
7A530B7F2401803A00CBFE6E /* Vehicle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = "<group>"; };
|
7A530B7F2401803A00CBFE6E /* Vehicle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = "<group>"; };
|
||||||
@ -157,12 +144,6 @@
|
|||||||
7A64AE702469DFB600ABE48E /* MediaContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaContentView.swift; sourceTree = "<group>"; };
|
7A64AE702469DFB600ABE48E /* MediaContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaContentView.swift; sourceTree = "<group>"; };
|
||||||
7A64AE712469DFB600ABE48E /* MediaBrowserViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaBrowserViewController.swift; sourceTree = "<group>"; };
|
7A64AE712469DFB600ABE48E /* MediaBrowserViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaBrowserViewController.swift; sourceTree = "<group>"; };
|
||||||
7A64AE722469DFB600ABE48E /* ContentTransformers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentTransformers.swift; sourceTree = "<group>"; };
|
7A64AE722469DFB600ABE48E /* ContentTransformers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentTransformers.swift; sourceTree = "<group>"; };
|
||||||
7A64AE782469E16100ABE48E /* RadialGradientLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadialGradientLayer.swift; sourceTree = "<group>"; };
|
|
||||||
7A64AE792469E16100ABE48E /* IndefiniteAnimatedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndefiniteAnimatedView.swift; sourceTree = "<group>"; };
|
|
||||||
7A64AE7A2469E16100ABE48E /* .gitkeep */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitkeep; sourceTree = "<group>"; };
|
|
||||||
7A64AE7B2469E16100ABE48E /* ProgressAnimatedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressAnimatedView.swift; sourceTree = "<group>"; };
|
|
||||||
7A64AE7C2469E16100ABE48E /* IHProgressHUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IHProgressHUD.swift; sourceTree = "<group>"; };
|
|
||||||
7A64AE7D2469E16100ABE48E /* IHProgressHUD.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = IHProgressHUD.bundle; sourceTree = "<group>"; };
|
|
||||||
7A659B5824A2B1BA0043A0F2 /* AudioRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecord.swift; sourceTree = "<group>"; };
|
7A659B5824A2B1BA0043A0F2 /* AudioRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecord.swift; sourceTree = "<group>"; };
|
||||||
7A659B5A24A3768A0043A0F2 /* Substrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Substrings.swift; sourceTree = "<group>"; };
|
7A659B5A24A3768A0043A0F2 /* Substrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Substrings.swift; sourceTree = "<group>"; };
|
||||||
7A6DD902242BF4A5009DE740 /* PlateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateView.swift; sourceTree = "<group>"; };
|
7A6DD902242BF4A5009DE740 /* PlateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateView.swift; sourceTree = "<group>"; };
|
||||||
@ -223,6 +204,7 @@
|
|||||||
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */,
|
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */,
|
||||||
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */,
|
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */,
|
||||||
7A11472323FEA18700B424AF /* RxBlocking in Frameworks */,
|
7A11472323FEA18700B424AF /* RxBlocking in Frameworks */,
|
||||||
|
7AABDE1D2532F3EB0041AFC6 /* PKHUD in Frameworks */,
|
||||||
7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */,
|
7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */,
|
||||||
7A11471F23FEA18700B424AF /* RxRelay in Frameworks */,
|
7A11471F23FEA18700B424AF /* RxRelay in Frameworks */,
|
||||||
7AF58D2F24029C5200CE01A0 /* MagazineLayout in Frameworks */,
|
7AF58D2F24029C5200CE01A0 /* MagazineLayout in Frameworks */,
|
||||||
@ -295,8 +277,6 @@
|
|||||||
7A11472C23FECA3E00B424AF /* ThirdParty */ = {
|
7A11472C23FECA3E00B424AF /* ThirdParty */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7A488C3724A74B990054D0B2 /* RxRealmDataSources */,
|
|
||||||
7A64AE772469E16100ABE48E /* IHProgressHUD */,
|
|
||||||
7A64AE6E2469DFB600ABE48E /* ATGMediaBrowser */,
|
7A64AE6E2469DFB600ABE48E /* ATGMediaBrowser */,
|
||||||
7A6DD90724329144009DE740 /* CenterTextLayer.swift */,
|
7A6DD90724329144009DE740 /* CenterTextLayer.swift */,
|
||||||
7A96AE32246C095700297C33 /* Base64FS.swift */,
|
7A96AE32246C095700297C33 /* Base64FS.swift */,
|
||||||
@ -366,17 +346,6 @@
|
|||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
7A488C3724A74B990054D0B2 /* RxRealmDataSources */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
7A488C3824A74B990054D0B2 /* RxTableViewRealmDataSource.swift */,
|
|
||||||
7A488C3924A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift */,
|
|
||||||
7A488C3A24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift */,
|
|
||||||
7A488C3B24A74B990054D0B2 /* RealmBindObserver.swift */,
|
|
||||||
);
|
|
||||||
path = RxRealmDataSources;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
7A530B7C24017FBE00CBFE6E /* Cells */ = {
|
7A530B7C24017FBE00CBFE6E /* Cells */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -404,19 +373,6 @@
|
|||||||
path = ATGMediaBrowser;
|
path = ATGMediaBrowser;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
7A64AE772469E16100ABE48E /* IHProgressHUD */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
7A64AE782469E16100ABE48E /* RadialGradientLayer.swift */,
|
|
||||||
7A64AE792469E16100ABE48E /* IndefiniteAnimatedView.swift */,
|
|
||||||
7A64AE7A2469E16100ABE48E /* .gitkeep */,
|
|
||||||
7A64AE7B2469E16100ABE48E /* ProgressAnimatedView.swift */,
|
|
||||||
7A64AE7C2469E16100ABE48E /* IHProgressHUD.swift */,
|
|
||||||
7A64AE7D2469E16100ABE48E /* IHProgressHUD.bundle */,
|
|
||||||
);
|
|
||||||
path = IHProgressHUD;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
7A6DD901242BF48D009DE740 /* Views */ = {
|
7A6DD901242BF48D009DE740 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -484,6 +440,7 @@
|
|||||||
7A0516172414EC1200FC55AC /* RxDataSources */,
|
7A0516172414EC1200FC55AC /* RxDataSources */,
|
||||||
7A96AE29246AFD6200297C33 /* Eureka */,
|
7A96AE29246AFD6200297C33 /* Eureka */,
|
||||||
7A813DC02508C4D900CC93B9 /* ExceptionCatcher */,
|
7A813DC02508C4D900CC93B9 /* ExceptionCatcher */,
|
||||||
|
7AABDE1C2532F3EB0041AFC6 /* PKHUD */,
|
||||||
);
|
);
|
||||||
productName = AutoCat;
|
productName = AutoCat;
|
||||||
productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */;
|
productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */;
|
||||||
@ -523,6 +480,7 @@
|
|||||||
7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */,
|
7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */,
|
||||||
7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */,
|
7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */,
|
||||||
7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */,
|
7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */,
|
||||||
|
7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */;
|
productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@ -542,10 +500,8 @@
|
|||||||
7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */,
|
7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */,
|
||||||
7A11470D23FDE7E600B424AF /* LaunchScreen.storyboard in Resources */,
|
7A11470D23FDE7E600B424AF /* LaunchScreen.storyboard in Resources */,
|
||||||
7A6DD90A24329541009DE740 /* RoadNumbers2.0.otf in Resources */,
|
7A6DD90A24329541009DE740 /* RoadNumbers2.0.otf in Resources */,
|
||||||
7A64AE802469E16100ABE48E /* .gitkeep in Resources */,
|
|
||||||
7A11470A23FDE7E600B424AF /* Assets.xcassets in Resources */,
|
7A11470A23FDE7E600B424AF /* Assets.xcassets in Resources */,
|
||||||
7A11470823FDE7E500B424AF /* Main.storyboard in Resources */,
|
7A11470823FDE7E500B424AF /* Main.storyboard in Resources */,
|
||||||
7A64AE832469E16100ABE48E /* IHProgressHUD.bundle in Resources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -560,7 +516,6 @@
|
|||||||
7A96AE33246C095700297C33 /* Base64FS.swift in Sources */,
|
7A96AE33246C095700297C33 /* Base64FS.swift in Sources */,
|
||||||
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */,
|
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */,
|
||||||
7A96AE31246B2FE400297C33 /* Constants.swift in Sources */,
|
7A96AE31246B2FE400297C33 /* Constants.swift in Sources */,
|
||||||
7A64AE822469E16100ABE48E /* IHProgressHUD.swift in Sources */,
|
|
||||||
7A11470123FDE7E500B424AF /* AppDelegate.swift in Sources */,
|
7A11470123FDE7E500B424AF /* AppDelegate.swift in Sources */,
|
||||||
7ADF6C9D250FA96000F237B2 /* SwiftMaskTextfield.swift in Sources */,
|
7ADF6C9D250FA96000F237B2 /* SwiftMaskTextfield.swift in Sources */,
|
||||||
7A27ADF924A09CAD0035F39E /* CocoaError.swift in Sources */,
|
7A27ADF924A09CAD0035F39E /* CocoaError.swift in Sources */,
|
||||||
@ -570,7 +525,6 @@
|
|||||||
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
||||||
7AB562BA249C9E9B00473D53 /* Region.swift in Sources */,
|
7AB562BA249C9E9B00473D53 /* Region.swift in Sources */,
|
||||||
7A659B5924A2B1BA0043A0F2 /* AudioRecord.swift in Sources */,
|
7A659B5924A2B1BA0043A0F2 /* AudioRecord.swift in Sources */,
|
||||||
7A488C3C24A74B990054D0B2 /* RxTableViewRealmDataSource.swift in Sources */,
|
|
||||||
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
||||||
7AE26A3524F31B0700625033 /* EventsController.swift in Sources */,
|
7AE26A3524F31B0700625033 /* EventsController.swift in Sources */,
|
||||||
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */,
|
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */,
|
||||||
@ -590,8 +544,6 @@
|
|||||||
7A11474923FF2B2D00B424AF /* Response.swift in Sources */,
|
7A11474923FF2B2D00B424AF /* Response.swift in Sources */,
|
||||||
7A64AE762469DFB600ABE48E /* ContentTransformers.swift in Sources */,
|
7A64AE762469DFB600ABE48E /* ContentTransformers.swift in Sources */,
|
||||||
7A11471823FDEBFA00B424AF /* ReportController.swift in Sources */,
|
7A11471823FDEBFA00B424AF /* ReportController.swift in Sources */,
|
||||||
7A64AE7E2469E16100ABE48E /* RadialGradientLayer.swift in Sources */,
|
|
||||||
7A64AE7F2469E16100ABE48E /* IndefiniteAnimatedView.swift in Sources */,
|
|
||||||
7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */,
|
7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */,
|
||||||
7A11471A23FE839000B424AF /* AuthController.swift in Sources */,
|
7A11471A23FE839000B424AF /* AuthController.swift in Sources */,
|
||||||
7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */,
|
7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */,
|
||||||
@ -610,18 +562,15 @@
|
|||||||
7A43F9F8246C8A6200BA5B49 /* JWT.swift in Sources */,
|
7A43F9F8246C8A6200BA5B49 /* JWT.swift in Sources */,
|
||||||
7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */,
|
7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */,
|
||||||
7ADF6C9F251201D200F237B2 /* GlobalEventsController.swift in Sources */,
|
7ADF6C9F251201D200F237B2 /* GlobalEventsController.swift in Sources */,
|
||||||
7A488C3F24A74B990054D0B2 /* RealmBindObserver.swift in Sources */,
|
|
||||||
7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */,
|
7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */,
|
||||||
7A11470323FDE7E500B424AF /* SceneDelegate.swift in Sources */,
|
7A11470323FDE7E500B424AF /* SceneDelegate.swift in Sources */,
|
||||||
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */,
|
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */,
|
||||||
7A813DCB250B5DC900CC93B9 /* LocationPickerController.swift in Sources */,
|
7A813DCB250B5DC900CC93B9 /* LocationPickerController.swift in Sources */,
|
||||||
7A11474423FF06CA00B424AF /* Api.swift in Sources */,
|
7A11474423FF06CA00B424AF /* Api.swift in Sources */,
|
||||||
7A488C3D24A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift in Sources */,
|
|
||||||
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */,
|
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */,
|
||||||
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
||||||
7A21112A24FC3D7E003BBF6F /* AudioEngine.swift in Sources */,
|
7A21112A24FC3D7E003BBF6F /* AudioEngine.swift in Sources */,
|
||||||
7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */,
|
7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */,
|
||||||
7A488C3E24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift in Sources */,
|
|
||||||
7ADF6C95250D037700F237B2 /* ShowEventController.swift in Sources */,
|
7ADF6C95250D037700F237B2 /* ShowEventController.swift in Sources */,
|
||||||
7A27ADC7249D43210035F39E /* RegionsController.swift in Sources */,
|
7A27ADC7249D43210035F39E /* RegionsController.swift in Sources */,
|
||||||
7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */,
|
7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */,
|
||||||
@ -630,7 +579,6 @@
|
|||||||
7ADF6C93250B954900F237B2 /* Navigation.swift in Sources */,
|
7ADF6C93250B954900F237B2 /* Navigation.swift in Sources */,
|
||||||
7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */,
|
7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */,
|
||||||
7A64AE732469DFB600ABE48E /* DismissAnimationController.swift in Sources */,
|
7A64AE732469DFB600ABE48E /* DismissAnimationController.swift in Sources */,
|
||||||
7A64AE812469E16100ABE48E /* ProgressAnimatedView.swift in Sources */,
|
|
||||||
7ADF6C97250F41B000F237B2 /* PNKeyboard.swift in Sources */,
|
7ADF6C97250F41B000F237B2 /* PNKeyboard.swift in Sources */,
|
||||||
7A000AA224C2EEDE001F5B00 /* Location.swift in Sources */,
|
7A000AA224C2EEDE001F5B00 /* Location.swift in Sources */,
|
||||||
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */,
|
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */,
|
||||||
@ -897,6 +845,14 @@
|
|||||||
minimumVersion = 5.2.1;
|
minimumVersion = 5.2.1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/pkluz/PKHUD.git";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 5.4.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */ = {
|
7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/airbnb/MagazineLayout";
|
repositoryURL = "https://github.com/airbnb/MagazineLayout";
|
||||||
@ -976,6 +932,11 @@
|
|||||||
package = 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */;
|
package = 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */;
|
||||||
productName = Eureka;
|
productName = Eureka;
|
||||||
};
|
};
|
||||||
|
7AABDE1C2532F3EB0041AFC6 /* PKHUD */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */;
|
||||||
|
productName = PKHUD;
|
||||||
|
};
|
||||||
7AF58D2E24029C5200CE01A0 /* MagazineLayout */ = {
|
7AF58D2E24029C5200CE01A0 /* MagazineLayout */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */;
|
package = 7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */;
|
||||||
|
|||||||
@ -37,6 +37,15 @@
|
|||||||
"version": "1.6.3"
|
"version": "1.6.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"package": "PKHUD",
|
||||||
|
"repositoryURL": "https://github.com/pkluz/PKHUD.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "8fd26f23057c6bebd6695524b1c3e05e93aba571",
|
||||||
|
"version": "5.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"package": "Realm",
|
"package": "Realm",
|
||||||
"repositoryURL": "https://github.com/realm/realm-cocoa",
|
"repositoryURL": "https://github.com/realm/realm-cocoa",
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import RealmSwift
|
|||||||
import RxSwift
|
import RxSwift
|
||||||
import RxCocoa
|
import RxCocoa
|
||||||
import os.log
|
import os.log
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
extension OSLog {
|
extension OSLog {
|
||||||
static let startup = OSLog(subsystem: "pro.aliencat.autocat.startup", category: "startup")
|
static let startup = OSLog(subsystem: "pro.aliencat.autocat.startup", category: "startup")
|
||||||
@ -68,8 +69,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
|
|
||||||
Realm.Configuration.defaultConfiguration = config
|
Realm.Configuration.defaultConfiguration = config
|
||||||
|
|
||||||
IHProgressHUD.set(defaultStyle: .dark)
|
HUD.dimsBackground = true
|
||||||
IHProgressHUD.set(defaultMaskType: .black)
|
HUD.allowsInteraction = false
|
||||||
|
|
||||||
Logging.URLRequests = { _ in false };
|
Logging.URLRequests = { _ in false };
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
class AudioRecordCell: UITableViewCell, ConfigurableCell {
|
class AudioRecordCell: UITableViewCell, ConfigurableCell {
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ class AudioRecordCell: UITableViewCell, ConfigurableCell {
|
|||||||
try AudioPlayer.shared.play(url: url)
|
try AudioPlayer.shared.play(url: url)
|
||||||
} catch {
|
} catch {
|
||||||
print("Error playing audio record: \(error.localizedDescription)")
|
print("Error playing audio record: \(error.localizedDescription)")
|
||||||
IHProgressHUD.showError(withStatus: error.localizedDescription)
|
HUD.show(error: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import RxSwift
|
|||||||
import RxCocoa
|
import RxCocoa
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
import AuthenticationServices
|
import AuthenticationServices
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
||||||
|
|
||||||
@ -35,20 +36,20 @@ class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAut
|
|||||||
@IBAction func loginTapped(_ sender: UIButton) {
|
@IBAction func loginTapped(_ sender: UIButton) {
|
||||||
guard let email = self.username.text, let pass = self.password.text else { return }
|
guard let email = self.username.text, let pass = self.password.text else { return }
|
||||||
|
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
Api.login(email: email, password: pass)
|
Api.login(email: email, password: pass)
|
||||||
.observeOn(MainScheduler.instance)
|
.observeOn(MainScheduler.instance)
|
||||||
.subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:))
|
.subscribe(onSuccess: self.goToMainScreen(user:), onError: HUD.show(error:))
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func signupTapped(_ sender: UIButton) {
|
@IBAction func signupTapped(_ sender: UIButton) {
|
||||||
guard let email = self.username.text, let pass = self.password.text else { return }
|
guard let email = self.username.text, let pass = self.password.text else { return }
|
||||||
|
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
Api.signUp(email: email, password: pass)
|
Api.signUp(email: email, password: pass)
|
||||||
.observeOn(MainScheduler.instance)
|
.observeOn(MainScheduler.instance)
|
||||||
.subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:))
|
.subscribe(onSuccess: self.goToMainScreen(user:), onError: HUD.show(error:))
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,29 +65,24 @@ class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAut
|
|||||||
}
|
}
|
||||||
|
|
||||||
func goToMainScreen(user: User) {
|
func goToMainScreen(user: User) {
|
||||||
// guard let realm = try? Realm() else {
|
guard let realm = try? Realm() else {
|
||||||
// IHProgressHUD.showError(withStatus: "Database error")
|
HUD.flash(.labeledError(title: nil, subtitle: "Database error"))
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
|
|
||||||
IHProgressHUD.dismiss()
|
HUD.hide()
|
||||||
|
|
||||||
// if user.email != Settings.shared.user.email {
|
if user.email != Settings.shared.user.email {
|
||||||
// try? realm.write {
|
try? realm.write {
|
||||||
// realm.deleteAll()
|
realm.deleteAll()
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
Settings.shared.user = user
|
Settings.shared.user = user
|
||||||
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||||
self.view.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController")
|
self.view.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController")
|
||||||
}
|
}
|
||||||
|
|
||||||
func displayError(error: Error) {
|
|
||||||
IHProgressHUD.showError(withStatus: error.localizedDescription)
|
|
||||||
print(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Apple SignIn
|
// MARK: - Apple SignIn
|
||||||
|
|
||||||
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
||||||
@ -97,14 +93,14 @@ class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAut
|
|||||||
switch authorization.credential {
|
switch authorization.credential {
|
||||||
case let appleIDCredential as ASAuthorizationAppleIDCredential:
|
case let appleIDCredential as ASAuthorizationAppleIDCredential:
|
||||||
guard let email = appleIDCredential.email else {
|
guard let email = appleIDCredential.email else {
|
||||||
IHProgressHUD.showError(withStatus: "Cannot get email")
|
HUD.flash(.labeledError(title: nil, subtitle: "Cannot get email"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
Api.signIn(email: email, password: appleIDCredential.user)
|
Api.signIn(email: email, password: appleIDCredential.user)
|
||||||
.observeOn(MainScheduler.instance)
|
.observeOn(MainScheduler.instance)
|
||||||
.subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:))
|
.subscribe(onSuccess: self.goToMainScreen(user:), onError: HUD.show(error:))
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
|
|
||||||
if let tokenData = appleIDCredential.identityToken {
|
if let tokenData = appleIDCredential.identityToken {
|
||||||
@ -116,7 +112,7 @@ class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAut
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
IHProgressHUD.showError(withStatus: "Unsupported authorization credential")
|
HUD.flash(.labeledError(title: nil, subtitle: "Unsupported authorization credential"))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import RealmSwift
|
|||||||
import RxSwift
|
import RxSwift
|
||||||
import SwiftDate
|
import SwiftDate
|
||||||
import RxRealm
|
import RxRealm
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
enum EventAction {
|
enum EventAction {
|
||||||
case doNotSend
|
case doNotSend
|
||||||
@ -99,12 +100,12 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
|
|||||||
self.number.text = nil
|
self.number.text = nil
|
||||||
self.check.isEnabled = false
|
self.check.isEnabled = false
|
||||||
|
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
self.check(number: numberNormalized, action: .receiveAndSend).subscribe { vehicle in
|
self.check(number: numberNormalized, action: .receiveAndSend).subscribe { vehicle in
|
||||||
self.updateDetailController(with: vehicle)
|
self.updateDetailController(with: vehicle)
|
||||||
IHProgressHUD.dismiss()
|
HUD.hide()
|
||||||
} onError: { error in
|
} onError: { error in
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
}
|
}
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
|
|||||||
// MARK: - Contextual actions
|
// MARK: - Contextual actions
|
||||||
|
|
||||||
func update(vehicle: Vehicle) {
|
func update(vehicle: Vehicle) {
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
|
|
||||||
var eventAction: EventAction = .doNotSend
|
var eventAction: EventAction = .doNotSend
|
||||||
if vehicle.unrecognized, let savedEvent = vehicle.events.first {
|
if vehicle.unrecognized, let savedEvent = vehicle.events.first {
|
||||||
@ -207,9 +208,9 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
|
|||||||
|
|
||||||
self.check(number: vehicle.getNumber(), action: eventAction, force: true).subscribe { vehicle in
|
self.check(number: vehicle.getNumber(), action: eventAction, force: true).subscribe { vehicle in
|
||||||
self.updateDetailController(with: vehicle)
|
self.updateDetailController(with: vehicle)
|
||||||
IHProgressHUD.dismiss()
|
HUD.hide()
|
||||||
} onError: { error in
|
} onError: { error in
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
}
|
}
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import UIKit
|
|||||||
import WebKit
|
import WebKit
|
||||||
import CommonCrypto
|
import CommonCrypto
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
struct TokenResponse: Codable {
|
struct TokenResponse: Codable {
|
||||||
var id_token: String
|
var id_token: String
|
||||||
@ -58,7 +59,7 @@ class GoogleSignInController: UIViewController, WKNavigationDelegate {
|
|||||||
.subscribe(onSuccess: { _ in
|
.subscribe(onSuccess: { _ in
|
||||||
self.dismiss(animated: true, completion: self.completion)
|
self.dismiss(animated: true, completion: self.completion)
|
||||||
}, onError: { error in
|
}, onError: { error in
|
||||||
IHProgressHUD.showError(withStatus: error.localizedDescription)
|
HUD.flash(.labeledError(title: nil, subtitle: error.localizedDescription))
|
||||||
})
|
})
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
return
|
return
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import MapKit
|
|||||||
import RxSwift
|
import RxSwift
|
||||||
import Realm
|
import Realm
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
class EventPin: NSObject, MKAnnotation {
|
class EventPin: NSObject, MKAnnotation {
|
||||||
var coordinate: CLLocationCoordinate2D
|
var coordinate: CLLocationCoordinate2D
|
||||||
@ -148,18 +149,18 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele
|
|||||||
|
|
||||||
func deleteEvent(index: Int, completion: @escaping (Bool) -> Void) {
|
func deleteEvent(index: Int, completion: @escaping (Bool) -> Void) {
|
||||||
guard let vehicle = self.vehicle else {
|
guard let vehicle = self.vehicle else {
|
||||||
IHProgressHUD.showError(withStatus: "Unknown vehicle")
|
HUD.flash(.labeledError(title: nil, subtitle: "Unknown vehicle"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let event = vehicle.events[index]
|
let event = vehicle.events[index]
|
||||||
if let eventId = event.id {
|
if let eventId = event.id {
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
Api.remove(event: eventId).observeOn(MainScheduler.instance).subscribe(onSuccess: { vehicle in
|
Api.remove(event: eventId).observeOn(MainScheduler.instance).subscribe(onSuccess: { vehicle in
|
||||||
completion(self.update(vehicle: vehicle))
|
completion(self.update(vehicle: vehicle))
|
||||||
}, onError: { error in
|
}, onError: { error in
|
||||||
completion(false)
|
completion(false)
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
print(error)
|
print(error)
|
||||||
}).disposed(by: self.bag)
|
}).disposed(by: self.bag)
|
||||||
} else {
|
} else {
|
||||||
@ -169,7 +170,7 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele
|
|||||||
|
|
||||||
func editEvent(index: Int) {
|
func editEvent(index: Int) {
|
||||||
guard let vehicle = self.vehicle else {
|
guard let vehicle = self.vehicle else {
|
||||||
IHProgressHUD.showError(withStatus: "Unknown vehicle")
|
HUD.flash(.labeledError(title: nil, subtitle: "Unknown vehicle"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,12 +183,12 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele
|
|||||||
controller.onDone = { newEvent in
|
controller.onDone = { newEvent in
|
||||||
newEvent.id = event.id
|
newEvent.id = event.id
|
||||||
self.navigationController?.popViewController(animated: true, completion: {
|
self.navigationController?.popViewController(animated: true, completion: {
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
Api.edit(event: newEvent)
|
Api.edit(event: newEvent)
|
||||||
.observeOn(MainScheduler.instance)
|
.observeOn(MainScheduler.instance)
|
||||||
.subscribe(onSuccess: { self.update(vehicle: $0) }, onError:
|
.subscribe(onSuccess: { self.update(vehicle: $0) }, onError:
|
||||||
{ error in
|
{ error in
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
})
|
})
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
})
|
})
|
||||||
@ -197,7 +198,7 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele
|
|||||||
|
|
||||||
@objc func addEvent(_ sender: UIBarButtonItem) {
|
@objc func addEvent(_ sender: UIBarButtonItem) {
|
||||||
guard let vehicle = self.vehicle else {
|
guard let vehicle = self.vehicle else {
|
||||||
IHProgressHUD.showError(withStatus: "Unknown vehicle")
|
HUD.flash(.labeledError(title: nil, subtitle: "Unknown vehicle"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,12 +207,12 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele
|
|||||||
controller.title = "Add new event"
|
controller.title = "Add new event"
|
||||||
controller.onDone = { newEvent in
|
controller.onDone = { newEvent in
|
||||||
self.navigationController?.popViewController(animated: true, completion: {
|
self.navigationController?.popViewController(animated: true, completion: {
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
Api.add(event: newEvent, to: vehicle.getNumber())
|
Api.add(event: newEvent, to: vehicle.getNumber())
|
||||||
.observeOn(MainScheduler.instance)
|
.observeOn(MainScheduler.instance)
|
||||||
.subscribe(onSuccess: { self.update(vehicle: $0) }, onError:
|
.subscribe(onSuccess: { self.update(vehicle: $0) }, onError:
|
||||||
{ error in
|
{ error in
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
})
|
})
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
})
|
})
|
||||||
@ -231,10 +232,10 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele
|
|||||||
self.vehicle?.events.append(objectsIn: vehicle.events)
|
self.vehicle?.events.append(objectsIn: vehicle.events)
|
||||||
}
|
}
|
||||||
self.updateInterface()
|
self.updateInterface()
|
||||||
IHProgressHUD.dismiss()
|
HUD.hide()
|
||||||
return true
|
return true
|
||||||
} catch {
|
} catch {
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
print(error)
|
print(error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import MapKit
|
import MapKit
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
class GlobalEventsController: UIViewController {
|
class GlobalEventsController: UIViewController {
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ class GlobalEventsController: UIViewController {
|
|||||||
self.map.showsZoomControls = true
|
self.map.showsZoomControls = true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
Api.events(with: self.filter)
|
Api.events(with: self.filter)
|
||||||
.observeOn(MainScheduler.init())
|
.observeOn(MainScheduler.init())
|
||||||
.subscribe(onSuccess: { events in
|
.subscribe(onSuccess: { events in
|
||||||
@ -25,9 +26,9 @@ class GlobalEventsController: UIViewController {
|
|||||||
self.map.removeAnnotations(self.map.annotations)
|
self.map.removeAnnotations(self.map.annotations)
|
||||||
self.map.addAnnotations(pins)
|
self.map.addAnnotations(pins)
|
||||||
self.map.centerOnPins()
|
self.map.centerOnPins()
|
||||||
IHProgressHUD.dismiss()
|
HUD.hide()
|
||||||
}) { error in
|
}) { error in
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
}
|
}
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import Intents
|
|||||||
import CoreSpotlight
|
import CoreSpotlight
|
||||||
import MobileCoreServices
|
import MobileCoreServices
|
||||||
import os.log
|
import os.log
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
class RecordsController: UIViewController, UITableViewDelegate {
|
class RecordsController: UIViewController, UITableViewDelegate {
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ class RecordsController: UIViewController, UITableViewDelegate {
|
|||||||
|
|
||||||
@objc func onAddVoiceRecord(_ sender: UIBarButtonItem) {
|
@objc func onAddVoiceRecord(_ sender: UIBarButtonItem) {
|
||||||
guard let recorder = self.recorder else {
|
guard let recorder = self.recorder else {
|
||||||
IHProgressHUD.showError(withStatus: "Audio recorder is not available")
|
HUD.flash(.labeledError(title: nil, subtitle: "Audio recorder is not available"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,10 +143,10 @@ class RecordsController: UIViewController, UITableViewDelegate {
|
|||||||
}) { error in
|
}) { error in
|
||||||
if let alert = alert {
|
if let alert = alert {
|
||||||
alert.dismiss(animated: true) {
|
alert.dismiss(animated: true) {
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
}
|
}
|
||||||
self.addButton.isEnabled = true
|
self.addButton.isEnabled = true
|
||||||
}
|
}
|
||||||
@ -274,7 +275,7 @@ class RecordsController: UIViewController, UITableViewDelegate {
|
|||||||
self.present(controller, animated: true)
|
self.present(controller, animated: true)
|
||||||
} catch {
|
} catch {
|
||||||
print("Error sharing audio record: \(error.localizedDescription)")
|
print("Error sharing audio record: \(error.localizedDescription)")
|
||||||
IHProgressHUD.showError(withStatus: error.localizedDescription)
|
HUD.show(error: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let showText = UIAlertAction(title: "Show recognized text", style: .default) { action in
|
let showText = UIAlertAction(title: "Show recognized text", style: .default) { action in
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import RxDataSources
|
|||||||
import RxSwift
|
import RxSwift
|
||||||
import RxCocoa
|
import RxCocoa
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDelegate {
|
class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDelegate {
|
||||||
|
|
||||||
@ -160,9 +161,9 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func update(vehicle: Vehicle, at indexPath: IndexPath) {
|
func update(vehicle: Vehicle, at indexPath: IndexPath) {
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
Api.checkVehicle(by: vehicle.getNumber(), force: true).observeOn(MainScheduler.instance).subscribe { newVehicle in
|
Api.checkVehicle(by: vehicle.getNumber(), force: true).observeOn(MainScheduler.instance).subscribe { newVehicle in
|
||||||
IHProgressHUD.dismiss()
|
HUD.hide()
|
||||||
if let realm = try? Realm() {
|
if let realm = try? Realm() {
|
||||||
if realm.object(ofType: Vehicle.self, forPrimaryKey: vehicle.getNumber()) != nil {
|
if realm.object(ofType: Vehicle.self, forPrimaryKey: vehicle.getNumber()) != nil {
|
||||||
try? realm.write {
|
try? realm.write {
|
||||||
@ -173,7 +174,7 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
self.datasource[indexPath] = newVehicle
|
self.datasource[indexPath] = newVehicle
|
||||||
self.updateDetailController(with: newVehicle)
|
self.updateDetailController(with: newVehicle)
|
||||||
} onError: { err in
|
} onError: { err in
|
||||||
IHProgressHUD.show(error: err)
|
HUD.show(error: err)
|
||||||
}.disposed(by: self.bag)
|
}.disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
extension NSError {
|
extension NSError {
|
||||||
var displayMessage: (title: String, body: String) {
|
var displayMessage: (title: String, body: String) {
|
||||||
@ -50,9 +51,9 @@ extension UIViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension IHProgressHUD {
|
extension HUD {
|
||||||
static func show(error: Error) {
|
static func show(error: Error) {
|
||||||
let msg = (error as NSError).displayMessage
|
let msg = (error as NSError).displayMessage
|
||||||
self.showError(withStatus: msg.title + "\n" + msg.body)
|
self.flash(.labeledError(title: msg.title, subtitle: msg.body), delay: 2.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import UIKit
|
|||||||
import os.log
|
import os.log
|
||||||
import AVFoundation
|
import AVFoundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
import PKHUD
|
||||||
|
|
||||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
func openReport(with number: String) {
|
func openReport(with number: String) {
|
||||||
guard let rootController = self.window?.rootViewController else { return }
|
guard let rootController = self.window?.rootViewController else { return }
|
||||||
|
|
||||||
IHProgressHUD.show()
|
HUD.show(.progress)
|
||||||
_ = Api.getReport(for: number).observeOn(MainScheduler.instance).subscribe { vehicle in
|
_ = Api.getReport(for: number).observeOn(MainScheduler.instance).subscribe { vehicle in
|
||||||
let sb = UIStoryboard(name: "Main", bundle: nil)
|
let sb = UIStoryboard(name: "Main", bundle: nil)
|
||||||
let controller = sb.instantiateViewController(identifier: "ReportController") as ReportController
|
let controller = sb.instantiateViewController(identifier: "ReportController") as ReportController
|
||||||
@ -154,9 +155,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
nav.modalPresentationStyle = .fullScreen
|
nav.modalPresentationStyle = .fullScreen
|
||||||
controller.navigationItem.leftBarButtonItem = BlockBarButtonItem(barButtonSystemItem: .close) { _ in nav.dismiss(animated: true) }
|
controller.navigationItem.leftBarButtonItem = BlockBarButtonItem(barButtonSystemItem: .close) { _ in nav.dismiss(animated: true) }
|
||||||
rootController.present(nav, animated: true)
|
rootController.present(nav, animated: true)
|
||||||
IHProgressHUD.dismiss()
|
HUD.hide()
|
||||||
} onError: { error in
|
} onError: { error in
|
||||||
IHProgressHUD.show(error: error)
|
HUD.show(error: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 409 B |
|
Before Width: | Height: | Size: 873 B |
|
Before Width: | Height: | Size: 752 B |
|
Before Width: | Height: | Size: 662 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 490 B |
|
Before Width: | Height: | Size: 912 B |
|
Before Width: | Height: | Size: 1.3 KiB |
1317
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.swift
vendored
@ -1,197 +0,0 @@
|
|||||||
//
|
|
||||||
// Converted to Swift 4 by Swiftify v4.2.29618 - https://objectivec2swift.com/
|
|
||||||
//
|
|
||||||
// IndefiniteAnimatedView.swift
|
|
||||||
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
|
||||||
//
|
|
||||||
// Original Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved.
|
|
||||||
// Modified Copyright © 2018 Ibrahim Hassan. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class IndefiniteAnimatedView : UIView {
|
|
||||||
|
|
||||||
private var activityIndicator : UIActivityIndicatorView?
|
|
||||||
private var strokeThickness : CGFloat?
|
|
||||||
private var strokeColor : UIColor?
|
|
||||||
private var indefinteAnimatedLayer : CAShapeLayer?
|
|
||||||
private var radius : CGFloat?
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
if self.superview != nil {
|
|
||||||
layoutAnimatedLayer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - Setter Functions
|
|
||||||
extension IndefiniteAnimatedView {
|
|
||||||
|
|
||||||
func setIndefinite(radius: CGFloat) {
|
|
||||||
if (self.radius != radius) {
|
|
||||||
self.radius = radius
|
|
||||||
|
|
||||||
self.getIndefinteAnimatedLayer().removeFromSuperlayer()
|
|
||||||
self.indefinteAnimatedLayer = nil
|
|
||||||
|
|
||||||
if superview != nil {
|
|
||||||
layoutAnimatedLayer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIndefinite(strokeThickness : CGFloat) {
|
|
||||||
self.strokeThickness = strokeThickness
|
|
||||||
if let strkthickness = self.strokeThickness {
|
|
||||||
getIndefinteAnimatedLayer().lineWidth = strkthickness
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIndefinite(strokeColor: UIColor) {
|
|
||||||
self.strokeColor = strokeColor
|
|
||||||
getIndefinteAnimatedLayer().strokeColor = strokeColor.cgColor
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - Getter Functions
|
|
||||||
extension IndefiniteAnimatedView {
|
|
||||||
private func getIndefinteAnimatedLayer() -> CAShapeLayer {
|
|
||||||
if self.indefinteAnimatedLayer != nil {
|
|
||||||
return self.indefinteAnimatedLayer!
|
|
||||||
} else {
|
|
||||||
let localRingRadius : CGFloat = radius ?? 18
|
|
||||||
let localStrokeThickness : CGFloat = strokeThickness ?? 2
|
|
||||||
let localStrokeColor : UIColor = strokeColor ?? UIColor.black
|
|
||||||
|
|
||||||
let arcCenter = CGPoint(x: localRingRadius + localStrokeThickness / 2 + 5, y: localRingRadius + localStrokeThickness / 2 + 5)
|
|
||||||
let smoothedPath = UIBezierPath(arcCenter: arcCenter, radius: localRingRadius, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi + CGFloat.pi / 2, clockwise: true)
|
|
||||||
|
|
||||||
indefinteAnimatedLayer = CAShapeLayer()
|
|
||||||
indefinteAnimatedLayer?.contentsScale = UIScreen.main.scale
|
|
||||||
indefinteAnimatedLayer?.frame = CGRect.init(x: 0, y: 0, width: arcCenter.x * 2, height: arcCenter.y * 2)
|
|
||||||
indefinteAnimatedLayer?.fillColor = UIColor.clear.cgColor
|
|
||||||
indefinteAnimatedLayer?.strokeColor = localStrokeColor.cgColor
|
|
||||||
indefinteAnimatedLayer?.lineWidth = localStrokeThickness
|
|
||||||
indefinteAnimatedLayer?.lineCap = CAShapeLayerLineCap.round
|
|
||||||
indefinteAnimatedLayer?.lineJoin = CAShapeLayerLineJoin.bevel
|
|
||||||
indefinteAnimatedLayer?.path = smoothedPath.cgPath
|
|
||||||
|
|
||||||
let maskLayer = CALayer()
|
|
||||||
let image = loadImageBundle(named: "angle-mask")!
|
|
||||||
maskLayer.contents = image.cgImage
|
|
||||||
maskLayer.frame = indefinteAnimatedLayer!.bounds
|
|
||||||
indefinteAnimatedLayer?.mask = maskLayer
|
|
||||||
|
|
||||||
let animationDuration = TimeInterval.init(1)
|
|
||||||
let linearCurve = CAMediaTimingFunction.init(name: .linear)
|
|
||||||
let animation = CABasicAnimation.init(keyPath: "transform.rotation")
|
|
||||||
animation.fromValue = 0
|
|
||||||
animation.toValue = CGFloat.pi * 2
|
|
||||||
animation.duration = animationDuration
|
|
||||||
animation.timingFunction = linearCurve
|
|
||||||
animation.isRemovedOnCompletion = false
|
|
||||||
animation.repeatCount = .infinity
|
|
||||||
animation.fillMode = .forwards
|
|
||||||
animation.autoreverses = false
|
|
||||||
indefinteAnimatedLayer?.mask?.add(animation, forKey: "rotate")
|
|
||||||
|
|
||||||
|
|
||||||
let animationGroup = CAAnimationGroup.init()
|
|
||||||
animationGroup.duration = animationDuration
|
|
||||||
animationGroup.repeatCount = .infinity
|
|
||||||
animationGroup.isRemovedOnCompletion = false
|
|
||||||
animationGroup.timingFunction = linearCurve
|
|
||||||
|
|
||||||
let strokeStartAnimation = CABasicAnimation.init(keyPath: "strokeStart")
|
|
||||||
strokeStartAnimation.duration = animationDuration
|
|
||||||
strokeStartAnimation.fromValue = 0.015
|
|
||||||
strokeStartAnimation.toValue = 0.0001
|
|
||||||
|
|
||||||
animationGroup.animations = [strokeStartAnimation]
|
|
||||||
indefinteAnimatedLayer?.add(animationGroup, forKey: "progress")
|
|
||||||
}
|
|
||||||
return self.indefinteAnimatedLayer!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - ActivityIndicatorView Functions
|
|
||||||
extension IndefiniteAnimatedView {
|
|
||||||
|
|
||||||
func removeAnimationLayer() {
|
|
||||||
for view in self.subviews {
|
|
||||||
if let activityView = view as? UIActivityIndicatorView {
|
|
||||||
activityView.removeFromSuperview()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getIndefinteAnimatedLayer().removeFromSuperlayer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func startAnimation() {
|
|
||||||
if let activityIndicator = activityIndicator {
|
|
||||||
self.addSubview(activityIndicator)
|
|
||||||
activityIndicator.frame = CGRect.init(x: 8, y: 8, width: self.frame.size.width - 16, height: self.frame.size.height - 16)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func stopActivityIndicator() {
|
|
||||||
activityIndicator?.stopAnimating()
|
|
||||||
}
|
|
||||||
|
|
||||||
func setActivityIndicator(color: UIColor) {
|
|
||||||
activityIndicator = UIActivityIndicatorView.init(style: UIActivityIndicatorView.Style.large)
|
|
||||||
activityIndicator?.hidesWhenStopped = true
|
|
||||||
activityIndicator?.startAnimating()
|
|
||||||
activityIndicator?.color = color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//MARK: -
|
|
||||||
extension IndefiniteAnimatedView {
|
|
||||||
override func willMove(toSuperview newSuperview: UIView?) {
|
|
||||||
if let _ = newSuperview {
|
|
||||||
layoutAnimatedLayer()
|
|
||||||
} else {
|
|
||||||
getIndefinteAnimatedLayer().removeFromSuperlayer()
|
|
||||||
indefinteAnimatedLayer = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func layoutAnimatedLayer() {
|
|
||||||
let calayer = getIndefinteAnimatedLayer()
|
|
||||||
self.layer.addSublayer(calayer)
|
|
||||||
let widthDiff: CGFloat = bounds.width - layer.bounds.width
|
|
||||||
let heightDiff: CGFloat = bounds.height - layer.bounds.height
|
|
||||||
let xPos = bounds.width - layer.bounds.width / 2 - widthDiff / 2
|
|
||||||
let yPos = bounds.height - layer.bounds.height / 2 - heightDiff / 2
|
|
||||||
calayer.position = CGPoint.init(x: xPos, y: yPos)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
|
||||||
let localRadius : CGFloat = radius ?? 18
|
|
||||||
let localStrokeThickness : CGFloat = strokeThickness ?? 2
|
|
||||||
for view in self.subviews {
|
|
||||||
if let _ = view as? UIActivityIndicatorView {
|
|
||||||
return CGSize.init(width: 50, height: 50)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CGSize.init(width: (localRadius + localStrokeThickness / 2 + 5) * 2, height: (localRadius + localStrokeThickness / 2 + 5) * 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func loadImageBundle(named imageName:String) -> UIImage? {
|
|
||||||
var imageBundle = Bundle.init(for: IndefiniteAnimatedView.self)
|
|
||||||
if let resourcePath = imageBundle.path(forResource: "IHProgressHUD", ofType: "bundle") {
|
|
||||||
if let resourcesBundle = Bundle(path: resourcePath) {
|
|
||||||
imageBundle = resourcesBundle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (UIImage(named: imageName, in: imageBundle, compatibleWith: nil))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
//
|
|
||||||
// Converted to Swift 4 by Swiftify v4.2.29618 - https://objectivec2swift.com/
|
|
||||||
//
|
|
||||||
// IndefiniteAnimatedView.swift
|
|
||||||
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
|
||||||
//
|
|
||||||
// Original Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved.
|
|
||||||
// Modified Copyright © 2018 Ibrahim Hassan. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class ProgressAnimatedView: UIView {
|
|
||||||
|
|
||||||
private var radius : CGFloat?
|
|
||||||
private var strokeThickness : CGFloat?
|
|
||||||
private var strokeColor : UIColor?
|
|
||||||
private var strokeEnd : CGFloat?
|
|
||||||
private var ringAnimatedLayer : CAShapeLayer?
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override func willMove(toSuperview newSuperview: UIView?) {
|
|
||||||
if let _ = newSuperview {
|
|
||||||
layoutAnimatedLayer()
|
|
||||||
} else {
|
|
||||||
getRingAnimatedLayer().removeFromSuperlayer()
|
|
||||||
ringAnimatedLayer = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func layoutAnimatedLayer() {
|
|
||||||
let rlayer = getRingAnimatedLayer()
|
|
||||||
layer.addSublayer(rlayer)
|
|
||||||
let widthDiff = bounds.width - layer.bounds.width
|
|
||||||
let heightDiff = bounds.height - layer.bounds.height
|
|
||||||
let layerPositionX = bounds.width - layer.bounds.width / 2 - widthDiff / 2
|
|
||||||
let layerPositionY = bounds.height - layer.bounds.height / 2 - heightDiff / 2
|
|
||||||
rlayer.position = CGPoint.init(x: layerPositionX, y: layerPositionY)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
|
||||||
let localRadius : CGFloat = radius ?? 18
|
|
||||||
let localStrokeThickness : CGFloat = strokeThickness ?? 2
|
|
||||||
return CGSize(width: (localRadius + localStrokeThickness / 2 + 5) * 2, height: (localRadius + localStrokeThickness / 2 + 5) * 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - Setter
|
|
||||||
extension ProgressAnimatedView {
|
|
||||||
@objc public func set(radius: CGFloat) {
|
|
||||||
if radius != self.radius {
|
|
||||||
self.radius = radius
|
|
||||||
|
|
||||||
getRingAnimatedLayer().removeFromSuperlayer()
|
|
||||||
ringAnimatedLayer = nil
|
|
||||||
|
|
||||||
if superview != nil {
|
|
||||||
layoutAnimatedLayer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func set(strokeThickness : CGFloat) {
|
|
||||||
self.strokeThickness = strokeThickness
|
|
||||||
getRingAnimatedLayer().lineWidth = strokeThickness
|
|
||||||
|
|
||||||
if superview != nil {
|
|
||||||
layoutAnimatedLayer()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func set(strokeEnd: CGFloat) {
|
|
||||||
self.strokeEnd = strokeEnd
|
|
||||||
getRingAnimatedLayer().strokeEnd = strokeEnd
|
|
||||||
|
|
||||||
if superview != nil {
|
|
||||||
layoutAnimatedLayer()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func set(strokeColor: UIColor) {
|
|
||||||
|
|
||||||
self.strokeColor = strokeColor
|
|
||||||
self.getRingAnimatedLayer().strokeColor = strokeColor.cgColor
|
|
||||||
|
|
||||||
if superview != nil {
|
|
||||||
layoutAnimatedLayer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - Getter
|
|
||||||
extension ProgressAnimatedView {
|
|
||||||
private func getRingAnimatedLayer() -> CAShapeLayer {
|
|
||||||
if self.ringAnimatedLayer != nil {
|
|
||||||
return self.ringAnimatedLayer!
|
|
||||||
} else {
|
|
||||||
let localStrokeThickness: CGFloat = strokeThickness ?? 2
|
|
||||||
let localRingRadius: CGFloat = radius ?? 18
|
|
||||||
|
|
||||||
let arcCenter = CGPoint(x: localRingRadius + localStrokeThickness / 2 + 5, y: localRingRadius + localStrokeThickness / 2 + 5)
|
|
||||||
let smoothedPath = UIBezierPath(arcCenter: arcCenter, radius: localRingRadius, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi + CGFloat.pi / 2, clockwise: true)
|
|
||||||
|
|
||||||
let _ringAnimatedLayer = CAShapeLayer()
|
|
||||||
_ringAnimatedLayer.contentsScale = UIScreen.main.scale
|
|
||||||
_ringAnimatedLayer.frame = CGRect(x: 0.0, y: 0.0, width: arcCenter.x * 2, height: arcCenter.y * 2)
|
|
||||||
_ringAnimatedLayer.fillColor = UIColor.clear.cgColor
|
|
||||||
_ringAnimatedLayer.strokeColor = strokeColor?.cgColor
|
|
||||||
_ringAnimatedLayer.lineWidth = localStrokeThickness
|
|
||||||
_ringAnimatedLayer.lineCap = .round
|
|
||||||
_ringAnimatedLayer.lineJoin = .bevel
|
|
||||||
_ringAnimatedLayer.path = smoothedPath.cgPath
|
|
||||||
self.ringAnimatedLayer = _ringAnimatedLayer
|
|
||||||
}
|
|
||||||
return self.ringAnimatedLayer!
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
//
|
|
||||||
// Converted to Swift 4 by Swiftify v4.2.29618 - https://objectivec2swift.com/
|
|
||||||
//
|
|
||||||
// IndefiniteAnimatedView.swift
|
|
||||||
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
|
||||||
//
|
|
||||||
// Original Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved.
|
|
||||||
// Modified Copyright © 2018 Ibrahim Hassan. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import QuartzCore
|
|
||||||
|
|
||||||
class RadialGradientLayer: CALayer {
|
|
||||||
var gradientCenter = CGPoint.zero
|
|
||||||
override func draw(in context: CGContext) {
|
|
||||||
super.draw(in: context)
|
|
||||||
let locationsCount = 2
|
|
||||||
let locations : [CGFloat] = [0.0, 1.0]
|
|
||||||
let colors : [CGFloat] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75]
|
|
||||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
|
||||||
if let gradient = CGGradient.init(colorSpace: colorSpace, colorComponents: colors, locations: locations, count: locationsCount) {
|
|
||||||
let radius = min(bounds.size.width, bounds.size.height)
|
|
||||||
|
|
||||||
context.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: 0, endCenter: gradientCenter, endRadius: radius, options: CGGradientDrawingOptions.drawsAfterEndLocation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
//
|
|
||||||
// RxRealm extensions
|
|
||||||
//
|
|
||||||
// Copyright (c) 2016 RxSwiftCommunity. All rights reserved.
|
|
||||||
// Check the LICENSE file for details
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
import RealmSwift
|
|
||||||
import RxSwift
|
|
||||||
import RxCocoa
|
|
||||||
import RxRealm
|
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
// MARK: - iOS / UIKit
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
extension Reactive where Base: UITableView {
|
|
||||||
|
|
||||||
public func realmChanges<E>(_ dataSource: RxTableViewRealmDataSource<E>)
|
|
||||||
-> RealmBindObserver<E, AnyRealmCollection<E>, RxTableViewRealmDataSource<E>> {
|
|
||||||
|
|
||||||
return RealmBindObserver(dataSource: dataSource) {ds, results, changes in
|
|
||||||
if ds.tableView == nil {
|
|
||||||
ds.tableView = self.base
|
|
||||||
}
|
|
||||||
ds.tableView?.dataSource = ds
|
|
||||||
ds.applyChanges(items: AnyRealmCollection<E>(results), changes: changes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func realmModelSelected<E>(_ modelType: E.Type) -> ControlEvent<E> where E: RealmSwift.Object {
|
|
||||||
|
|
||||||
let source: Observable<E> = self.itemSelected.flatMap { [weak view = self.base as UITableView] indexPath -> Observable<E> in
|
|
||||||
guard let view = view, let ds = view.dataSource as? RxTableViewRealmDataSource<E> else {
|
|
||||||
return Observable.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
return Observable.just(ds.model(at: indexPath))
|
|
||||||
}
|
|
||||||
|
|
||||||
return ControlEvent(events: source)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Reactive where Base: UICollectionView {
|
|
||||||
|
|
||||||
public func realmChanges<E>(_ dataSource: RxCollectionViewRealmDataSource<E>)
|
|
||||||
-> RealmBindObserver<E, AnyRealmCollection<E>, RxCollectionViewRealmDataSource<E>> {
|
|
||||||
|
|
||||||
return RealmBindObserver(dataSource: dataSource) {ds, results, changes in
|
|
||||||
if ds.collectionView == nil {
|
|
||||||
ds.collectionView = self.base
|
|
||||||
}
|
|
||||||
ds.collectionView?.dataSource = ds
|
|
||||||
ds.applyChanges(items: AnyRealmCollection<E>(results), changes: changes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func realmModelSelected<E>(_ modelType: E.Type) -> ControlEvent<E> where E: RealmSwift.Object {
|
|
||||||
|
|
||||||
let source: Observable<E> = self.itemSelected.flatMap { [weak view = self.base as UICollectionView] indexPath -> Observable<E> in
|
|
||||||
guard let view = view, let ds = view.dataSource as? RxCollectionViewRealmDataSource<E> else {
|
|
||||||
return Observable.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
return Observable.just(ds.model(at: indexPath))
|
|
||||||
}
|
|
||||||
|
|
||||||
return ControlEvent(events: source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#elseif os(OSX)
|
|
||||||
// MARK: - macOS / Cocoa
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
extension Reactive where Base: NSTableView {
|
|
||||||
|
|
||||||
public func realmChanges<E>(_ dataSource: RxTableViewRealmDataSource<E>)
|
|
||||||
-> RealmBindObserver<E, AnyRealmCollection<E>, RxTableViewRealmDataSource<E>> {
|
|
||||||
|
|
||||||
base.delegate = dataSource
|
|
||||||
base.dataSource = dataSource
|
|
||||||
|
|
||||||
return RealmBindObserver(dataSource: dataSource) {ds, results, changes in
|
|
||||||
if dataSource.tableView == nil {
|
|
||||||
dataSource.tableView = self.base
|
|
||||||
}
|
|
||||||
ds.applyChanges(items: AnyRealmCollection<E>(results), changes: changes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Reactive where Base: NSCollectionView {
|
|
||||||
|
|
||||||
public func realmChanges<E>(_ dataSource: RxCollectionViewRealmDataSource<E>)
|
|
||||||
-> RealmBindObserver<E, AnyRealmCollection<E>, RxCollectionViewRealmDataSource<E>> {
|
|
||||||
|
|
||||||
return RealmBindObserver(dataSource: dataSource) {ds, results, changes in
|
|
||||||
if ds.collectionView == nil {
|
|
||||||
ds.collectionView = self.base
|
|
||||||
}
|
|
||||||
ds.collectionView?.dataSource = ds
|
|
||||||
ds.applyChanges(items: AnyRealmCollection<E>(results), changes: changes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
//
|
|
||||||
// RxRealm extensions
|
|
||||||
//
|
|
||||||
// Copyright (c) 2016 RxSwiftCommunity. All rights reserved.
|
|
||||||
// Check the LICENSE file for details
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
import RealmSwift
|
|
||||||
import RxSwift
|
|
||||||
import RxCocoa
|
|
||||||
import RxRealm
|
|
||||||
|
|
||||||
public class RealmBindObserver<O: Object, C: RealmCollection, DS>: ObserverType {
|
|
||||||
typealias BindingType = (DS, C, RealmChangeset?) -> Void
|
|
||||||
public typealias E = (C, RealmChangeset?)
|
|
||||||
|
|
||||||
let dataSource: DS
|
|
||||||
let binding: BindingType
|
|
||||||
|
|
||||||
init(dataSource: DS, binding: @escaping BindingType) {
|
|
||||||
self.dataSource = dataSource
|
|
||||||
self.binding = binding
|
|
||||||
}
|
|
||||||
|
|
||||||
public func on(_ event: Event<E>) {
|
|
||||||
switch event {
|
|
||||||
case .next(let element):
|
|
||||||
binding(dataSource, element.0, element.1)
|
|
||||||
case .error:
|
|
||||||
return
|
|
||||||
case .completed:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func asObserver() -> AnyObserver<E> {
|
|
||||||
return AnyObserver(eventHandler: on)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,210 +0,0 @@
|
|||||||
//
|
|
||||||
// RxRealm extensions
|
|
||||||
//
|
|
||||||
// Copyright (c) 2016 RxSwiftCommunity. All rights reserved.
|
|
||||||
// Check the LICENSE file for details
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
import RealmSwift
|
|
||||||
import RxSwift
|
|
||||||
import RxCocoa
|
|
||||||
import RxRealm
|
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
// MARK: - iOS / UIKit
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
public typealias CollectionCellFactory<E: Object> = (RxCollectionViewRealmDataSource<E>, UICollectionView, IndexPath, E) -> UICollectionViewCell
|
|
||||||
public typealias CollectionCellConfig<E: Object, CellType: UICollectionViewCell> = (CellType, IndexPath, E) -> Void
|
|
||||||
|
|
||||||
open class RxCollectionViewRealmDataSource <E: Object>: NSObject, UICollectionViewDataSource {
|
|
||||||
private var items: AnyRealmCollection<E>?
|
|
||||||
|
|
||||||
// MARK: - Configuration
|
|
||||||
|
|
||||||
public var collectionView: UICollectionView?
|
|
||||||
public var animated = true
|
|
||||||
|
|
||||||
// MARK: - Init
|
|
||||||
public let cellIdentifier: String
|
|
||||||
public let cellFactory: CollectionCellFactory<E>
|
|
||||||
|
|
||||||
public init(cellIdentifier: String, cellFactory: @escaping CollectionCellFactory<E>) {
|
|
||||||
self.cellIdentifier = cellIdentifier
|
|
||||||
self.cellFactory = cellFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
public init<CellType>(cellIdentifier: String, cellType: CellType.Type, cellConfig: @escaping CollectionCellConfig<E, CellType>) where CellType: UICollectionViewCell {
|
|
||||||
self.cellIdentifier = cellIdentifier
|
|
||||||
self.cellFactory = {ds, cv, ip, model in
|
|
||||||
let cell = cv.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: ip) as! CellType
|
|
||||||
cellConfig(cell, ip, model)
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Data access
|
|
||||||
public func model(at indexPath: IndexPath) -> E {
|
|
||||||
return items![indexPath.row]
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - UICollectionViewDataSource protocol
|
|
||||||
public func numberOfSections(in collectionView: UICollectionView) -> Int {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
|
||||||
return items?.count ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
|
||||||
return cellFactory(self, collectionView, indexPath, items![indexPath.row])
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Applying changeset to the collection view
|
|
||||||
private let fromRow = {(row: Int) in return IndexPath(row: row, section: 0)}
|
|
||||||
|
|
||||||
func applyChanges(items: AnyRealmCollection<E>, changes: RealmChangeset?) {
|
|
||||||
if self.items == nil {
|
|
||||||
self.items = items
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let collectionView = collectionView else {
|
|
||||||
fatalError("You have to bind a collection view to the data source.")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard animated else {
|
|
||||||
collectionView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let changes = changes else {
|
|
||||||
collectionView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let lastItemCount = collectionView.numberOfItems(inSection: 0)
|
|
||||||
guard items.count == lastItemCount + changes.inserted.count - changes.deleted.count else {
|
|
||||||
collectionView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
collectionView.performBatchUpdates({[unowned self] in
|
|
||||||
collectionView.deleteItems(at: changes.deleted.map(self.fromRow))
|
|
||||||
collectionView.reloadItems(at: changes.updated.map(self.fromRow))
|
|
||||||
collectionView.insertItems(at: changes.inserted.map(self.fromRow))
|
|
||||||
}, completion: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#elseif os(OSX)
|
|
||||||
// MARK: - macOS / Cocoa
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
|
|
||||||
public typealias CollectionItemFactory<E: Object> = (RxCollectionViewRealmDataSource<E>, NSCollectionView, IndexPath, E) -> NSCollectionViewItem
|
|
||||||
public typealias CollectionItemConfig<E: Object, ItemType: NSCollectionViewItem> = (ItemType, IndexPath, E) -> Void
|
|
||||||
|
|
||||||
open class RxCollectionViewRealmDataSource <E: Object>: NSObject, NSCollectionViewDataSource {
|
|
||||||
|
|
||||||
private var items: AnyRealmCollection<E>?
|
|
||||||
|
|
||||||
// MARK: - Configuration
|
|
||||||
|
|
||||||
public var collectionView: NSCollectionView?
|
|
||||||
public var animated = true
|
|
||||||
|
|
||||||
// MARK: - Init
|
|
||||||
public let itemIdentifier: String
|
|
||||||
public let itemFactory: CollectionItemFactory<E>
|
|
||||||
|
|
||||||
public weak var delegate: NSCollectionViewDelegate?
|
|
||||||
public weak var dataSource: NSCollectionViewDataSource?
|
|
||||||
|
|
||||||
public init(itemIdentifier: String, itemFactory: @escaping CollectionItemFactory<E>) {
|
|
||||||
self.itemIdentifier = itemIdentifier
|
|
||||||
self.itemFactory = itemFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
public init<ItemType>(itemIdentifier: String, itemType: ItemType.Type, itemConfig: @escaping CollectionItemConfig<E, ItemType>) where ItemType: NSCollectionViewItem {
|
|
||||||
self.itemIdentifier = itemIdentifier
|
|
||||||
self.itemFactory = { ds, cv, ip, model in
|
|
||||||
let item = cv.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: itemIdentifier), for: ip) as! ItemType
|
|
||||||
itemConfig(item, ip, model)
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - NSCollectionViewDataSource protocol
|
|
||||||
public func numberOfSections(in collectionView: NSCollectionView) -> Int {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
|
|
||||||
return items?.count ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(OSX 10.11, *)
|
|
||||||
public func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
|
|
||||||
return itemFactory(self, collectionView, indexPath, items![indexPath.item])
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Proxy unimplemented data source and delegate methods
|
|
||||||
open override func responds(to aSelector: Selector!) -> Bool {
|
|
||||||
if RxCollectionViewRealmDataSource.instancesRespond(to: aSelector) {
|
|
||||||
return true
|
|
||||||
} else if let delegate = delegate {
|
|
||||||
return delegate.responds(to: aSelector)
|
|
||||||
} else if let dataSource = dataSource {
|
|
||||||
return dataSource.responds(to: aSelector)
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func forwardingTarget(for aSelector: Selector!) -> Any? {
|
|
||||||
return delegate ?? dataSource
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Applying changeset to the collection view
|
|
||||||
private let fromRow = {(row: Int) in return IndexPath(item: row, section: 0)}
|
|
||||||
|
|
||||||
func applyChanges(items: AnyRealmCollection<E>, changes: RealmChangeset?) {
|
|
||||||
if self.items == nil {
|
|
||||||
self.items = items
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let collectionView = collectionView else {
|
|
||||||
fatalError("You have to bind a collection view to the data source.")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard animated else {
|
|
||||||
collectionView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let changes = changes else {
|
|
||||||
collectionView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let lastItemCount = collectionView.numberOfItems(inSection: 0)
|
|
||||||
guard items.count == lastItemCount + changes.inserted.count - changes.deleted.count else {
|
|
||||||
collectionView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
collectionView.performBatchUpdates({[unowned self] in
|
|
||||||
//TODO: this should be animated, but doesn't seem to be?
|
|
||||||
collectionView.animator().deleteItems(at: Set(changes.deleted.map(self.fromRow)))
|
|
||||||
collectionView.animator().reloadItems(at: Set(changes.updated.map(self.fromRow)))
|
|
||||||
collectionView.animator().insertItems(at: Set(changes.inserted.map(self.fromRow)))
|
|
||||||
}, completionHandler: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,223 +0,0 @@
|
|||||||
//
|
|
||||||
// RxRealm extensions
|
|
||||||
//
|
|
||||||
// Copyright (c) 2016 RxSwiftCommunity. All rights reserved.
|
|
||||||
// Check the LICENSE file for details
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
import RealmSwift
|
|
||||||
import RxSwift
|
|
||||||
import RxCocoa
|
|
||||||
import RxRealm
|
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
// MARK: - iOS / UIKit
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
public typealias TableCellFactory<E: Object> = (RxTableViewRealmDataSource<E>, UITableView, IndexPath, E) -> UITableViewCell
|
|
||||||
public typealias TableCellConfig<E: Object, CellType: UITableViewCell> = (CellType, IndexPath, E) -> Void
|
|
||||||
|
|
||||||
open class RxTableViewRealmDataSource<E: Object>: NSObject, UITableViewDataSource {
|
|
||||||
|
|
||||||
private var items: AnyRealmCollection<E>?
|
|
||||||
|
|
||||||
// MARK: - Configuration
|
|
||||||
|
|
||||||
public var tableView: UITableView?
|
|
||||||
public var animated = true
|
|
||||||
public var rowAnimations = (
|
|
||||||
insert: UITableView.RowAnimation.automatic,
|
|
||||||
update: UITableView.RowAnimation.automatic,
|
|
||||||
delete: UITableView.RowAnimation.automatic)
|
|
||||||
|
|
||||||
public var headerTitle: String?
|
|
||||||
public var footerTitle: String?
|
|
||||||
|
|
||||||
// MARK: - Init
|
|
||||||
public let cellIdentifier: String
|
|
||||||
public let cellFactory: TableCellFactory<E>
|
|
||||||
|
|
||||||
public init(cellIdentifier: String, cellFactory: @escaping TableCellFactory<E>) {
|
|
||||||
self.cellIdentifier = cellIdentifier
|
|
||||||
self.cellFactory = cellFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
public init<CellType>(cellIdentifier: String, cellType: CellType.Type, cellConfig: @escaping TableCellConfig<E, CellType>) where CellType: UITableViewCell {
|
|
||||||
self.cellIdentifier = cellIdentifier
|
|
||||||
self.cellFactory = {ds, tv, ip, model in
|
|
||||||
let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: ip) as! CellType
|
|
||||||
cellConfig(cell, ip, model)
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Data access
|
|
||||||
public func model(at indexPath: IndexPath) -> E {
|
|
||||||
return items![indexPath.row]
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - UITableViewDataSource protocol
|
|
||||||
public func numberOfSections(in tableView: UITableView) -> Int {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
||||||
return items?.count ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
||||||
return cellFactory(self, tableView, indexPath, items![indexPath.row])
|
|
||||||
}
|
|
||||||
|
|
||||||
public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
|
||||||
return headerTitle
|
|
||||||
}
|
|
||||||
|
|
||||||
public func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
|
|
||||||
return footerTitle
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Applying changeset to the table view
|
|
||||||
private let fromRow = {(row: Int) in return IndexPath(row: row, section: 0)}
|
|
||||||
|
|
||||||
func applyChanges(items: AnyRealmCollection<E>, changes: RealmChangeset?) {
|
|
||||||
if self.items == nil {
|
|
||||||
self.items = items
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let tableView = tableView else {
|
|
||||||
fatalError("You have to bind a table view to the data source.")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard animated else {
|
|
||||||
tableView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let changes = changes else {
|
|
||||||
tableView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let lastItemCount = tableView.numberOfRows(inSection: 0)
|
|
||||||
guard items.count == lastItemCount + changes.inserted.count - changes.deleted.count else {
|
|
||||||
tableView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tableView.beginUpdates()
|
|
||||||
tableView.deleteRows(at: changes.deleted.map(fromRow), with: rowAnimations.delete)
|
|
||||||
tableView.insertRows(at: changes.inserted.map(fromRow), with: rowAnimations.insert)
|
|
||||||
tableView.reloadRows(at: changes.updated.map(fromRow), with: rowAnimations.update)
|
|
||||||
tableView.endUpdates()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#elseif os(OSX)
|
|
||||||
// MARK: - macOS / Cocoa
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
|
|
||||||
public typealias TableCellFactory<E: Object> = (RxTableViewRealmDataSource<E>, NSTableView, Int, E) -> NSTableCellView
|
|
||||||
public typealias TableCellConfig<E: Object, CellType: NSTableCellView> = (CellType, Int, E) -> Void
|
|
||||||
|
|
||||||
open class RxTableViewRealmDataSource<E: Object>: NSObject, NSTableViewDataSource, NSTableViewDelegate {
|
|
||||||
|
|
||||||
private var items: AnyRealmCollection<E>?
|
|
||||||
|
|
||||||
// MARK: - Configuration
|
|
||||||
|
|
||||||
public var tableView: NSTableView?
|
|
||||||
public var animated = true
|
|
||||||
public var rowAnimations = (
|
|
||||||
insert: NSTableView.AnimationOptions.effectFade,
|
|
||||||
update: NSTableView.AnimationOptions.effectFade,
|
|
||||||
delete: NSTableView.AnimationOptions.effectFade)
|
|
||||||
|
|
||||||
public weak var delegate: NSTableViewDelegate?
|
|
||||||
public weak var dataSource: NSTableViewDataSource?
|
|
||||||
|
|
||||||
// MARK: - Init
|
|
||||||
public let cellIdentifier: String
|
|
||||||
public let cellFactory: TableCellFactory<E>
|
|
||||||
|
|
||||||
public init(cellIdentifier: String, cellFactory: @escaping TableCellFactory<E>) {
|
|
||||||
self.cellIdentifier = cellIdentifier
|
|
||||||
self.cellFactory = cellFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
public init<CellType>(cellIdentifier: String, cellType: CellType.Type, cellConfig: @escaping TableCellConfig<E, CellType>) where CellType: NSTableCellView {
|
|
||||||
self.cellIdentifier = cellIdentifier
|
|
||||||
self.cellFactory = { ds, tv, row, model in
|
|
||||||
let cell = tv.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: cellIdentifier), owner: tv) as! CellType
|
|
||||||
cellConfig(cell, row, model)
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - UITableViewDataSource protocol
|
|
||||||
public func numberOfRows(in tableView: NSTableView) -> Int {
|
|
||||||
return items?.count ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
|
||||||
return cellFactory(self, tableView, row, items![row])
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Proxy unimplemented data source and delegate methods
|
|
||||||
open override func responds(to aSelector: Selector!) -> Bool {
|
|
||||||
if RxTableViewRealmDataSource.instancesRespond(to: aSelector) {
|
|
||||||
return true
|
|
||||||
} else if let delegate = delegate {
|
|
||||||
return delegate.responds(to: aSelector)
|
|
||||||
} else if let dataSource = dataSource {
|
|
||||||
return dataSource.responds(to: aSelector)
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func forwardingTarget(for aSelector: Selector!) -> Any? {
|
|
||||||
return delegate ?? dataSource
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Applying changeset to the table view
|
|
||||||
private let fromRow = {(row: Int) in return IndexPath(item: row, section: 0)}
|
|
||||||
|
|
||||||
func applyChanges(items: AnyRealmCollection<E>, changes: RealmChangeset?) {
|
|
||||||
if self.items == nil {
|
|
||||||
self.items = items
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let tableView = tableView else {
|
|
||||||
fatalError("You have to bind a table view to the data source.")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard animated else {
|
|
||||||
tableView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let changes = changes else {
|
|
||||||
tableView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let lastItemCount = tableView.numberOfRows
|
|
||||||
guard items.count == lastItemCount + changes.inserted.count - changes.deleted.count else {
|
|
||||||
tableView.reloadData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tableView.beginUpdates()
|
|
||||||
tableView.removeRows(at: IndexSet(changes.deleted), withAnimation: rowAnimations.delete)
|
|
||||||
tableView.insertRows(at: IndexSet(changes.inserted), withAnimation: rowAnimations.insert)
|
|
||||||
tableView.reloadData(forRowIndexes: IndexSet(changes.updated), columnIndexes: IndexSet([0]))
|
|
||||||
tableView.endUpdates()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||