Link sharing

This commit is contained in:
Selim Mustafaev 2020-06-11 14:34:54 +03:00
parent 81c7ef119b
commit 7b97df4b28
8 changed files with 234 additions and 26 deletions

View File

@ -60,6 +60,7 @@
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */; }; 7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */; };
7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */; }; 7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */; };
7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */; }; 7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */; };
7A8A220E248EF5830073DFD9 /* SwiftJWT in Frameworks */ = {isa = PBXBuildFile; productRef = 7A8A220D248EF5830073DFD9 /* SwiftJWT */; };
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */ = {isa = PBXBuildFile; productRef = 7A96AE29246AFD6200297C33 /* Eureka */; }; 7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */ = {isa = PBXBuildFile; productRef = 7A96AE29246AFD6200297C33 /* Eureka */; };
7A96AE2D246B2B7400297C33 /* GoogleSignInController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */; }; 7A96AE2D246B2B7400297C33 /* GoogleSignInController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */; };
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; }; 7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; };
@ -144,6 +145,7 @@
7A11472123FEA18700B424AF /* RxCocoa in Frameworks */, 7A11472123FEA18700B424AF /* RxCocoa in Frameworks */,
7A0516182414EC1200FC55AC /* RxDataSources in Frameworks */, 7A0516182414EC1200FC55AC /* RxDataSources in Frameworks */,
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */, 7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */,
7A8A220E248EF5830073DFD9 /* SwiftJWT in Frameworks */,
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */, 7A051611241412CA00FC55AC /* SwiftDate in Frameworks */,
7A11472323FEA18700B424AF /* RxBlocking in Frameworks */, 7A11472323FEA18700B424AF /* RxBlocking in Frameworks */,
7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */, 7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */,
@ -220,7 +222,6 @@
7A64AE6E2469DFB600ABE48E /* ATGMediaBrowser */, 7A64AE6E2469DFB600ABE48E /* ATGMediaBrowser */,
7A6DD90724329144009DE740 /* CenterTextLayer.swift */, 7A6DD90724329144009DE740 /* CenterTextLayer.swift */,
7A96AE32246C095700297C33 /* Base64FS.swift */, 7A96AE32246C095700297C33 /* Base64FS.swift */,
7A11474323FF06CA00B424AF /* Api.swift */,
); );
path = ThirdParty; path = ThirdParty;
sourceTree = "<group>"; sourceTree = "<group>";
@ -230,6 +231,7 @@
children = ( children = (
7A96AE30246B2FE400297C33 /* Constants.swift */, 7A96AE30246B2FE400297C33 /* Constants.swift */,
7A43F9F7246C8A6200BA5B49 /* JWT.swift */, 7A43F9F7246C8A6200BA5B49 /* JWT.swift */,
7A11474323FF06CA00B424AF /* Api.swift */,
); );
path = Utils; path = Utils;
sourceTree = "<group>"; sourceTree = "<group>";
@ -356,6 +358,7 @@
7A0516152414EC1200FC55AC /* Differentiator */, 7A0516152414EC1200FC55AC /* Differentiator */,
7A0516172414EC1200FC55AC /* RxDataSources */, 7A0516172414EC1200FC55AC /* RxDataSources */,
7A96AE29246AFD6200297C33 /* Eureka */, 7A96AE29246AFD6200297C33 /* Eureka */,
7A8A220D248EF5830073DFD9 /* SwiftJWT */,
); );
productName = AutoCat; productName = AutoCat;
productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */; productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */;
@ -396,6 +399,7 @@
7A05160F241412CA00FC55AC /* XCRemoteSwiftPackageReference "SwiftDate" */, 7A05160F241412CA00FC55AC /* XCRemoteSwiftPackageReference "SwiftDate" */,
7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */, 7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */,
7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */, 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */,
7A8A220C248EF5830073DFD9 /* XCRemoteSwiftPackageReference "Swift-JWT" */,
); );
productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */; productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */;
projectDirPath = ""; projectDirPath = "";
@ -615,7 +619,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 11; CURRENT_PROJECT_VERSION = 13;
DEVELOPMENT_TEAM = 46DTTB8X4S; DEVELOPMENT_TEAM = 46DTTB8X4S;
INFOPLIST_FILE = AutoCat/Info.plist; INFOPLIST_FILE = AutoCat/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
@ -637,7 +641,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 11; CURRENT_PROJECT_VERSION = 13;
DEVELOPMENT_TEAM = 46DTTB8X4S; DEVELOPMENT_TEAM = 46DTTB8X4S;
INFOPLIST_FILE = AutoCat/Info.plist; INFOPLIST_FILE = AutoCat/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
@ -733,6 +737,14 @@
minimumVersion = 2.0.0; minimumVersion = 2.0.0;
}; };
}; };
7A8A220C248EF5830073DFD9 /* XCRemoteSwiftPackageReference "Swift-JWT" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/IBM-Swift/Swift-JWT.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 3.6.1;
};
};
7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */ = { 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */ = {
isa = XCRemoteSwiftPackageReference; isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/xmartlabs/Eureka"; repositoryURL = "https://github.com/xmartlabs/Eureka";
@ -820,6 +832,11 @@
package = 7A530B89240181F500CBFE6E /* XCRemoteSwiftPackageReference "RxRealm" */; package = 7A530B89240181F500CBFE6E /* XCRemoteSwiftPackageReference "RxRealm" */;
productName = RxRealm; productName = RxRealm;
}; };
7A8A220D248EF5830073DFD9 /* SwiftJWT */ = {
isa = XCSwiftPackageProductDependency;
package = 7A8A220C248EF5830073DFD9 /* XCRemoteSwiftPackageReference "Swift-JWT" */;
productName = SwiftJWT;
};
7A96AE29246AFD6200297C33 /* Eureka */ = { 7A96AE29246AFD6200297C33 /* Eureka */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
package = 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */; package = 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */;

View File

@ -10,6 +10,33 @@
"version": "4.1.0" "version": "4.1.0"
} }
}, },
{
"package": "Cryptor",
"repositoryURL": "https://github.com/IBM-Swift/BlueCryptor.git",
"state": {
"branch": null,
"revision": "12d2bf3ec7207ec3cd004b9582f69ef5fae1da3b",
"version": "1.0.32"
}
},
{
"package": "CryptorECC",
"repositoryURL": "https://github.com/IBM-Swift/BlueECC.git",
"state": {
"branch": null,
"revision": "73f362cb0d9c5f1fd0089240d7b293cd2bff18db",
"version": "1.2.5"
}
},
{
"package": "CryptorRSA",
"repositoryURL": "https://github.com/IBM-Swift/BlueRSA.git",
"state": {
"branch": null,
"revision": "8ea901f2582296837d88f882b0fa5a0601759598",
"version": "1.0.35"
}
},
{ {
"package": "Eureka", "package": "Eureka",
"repositoryURL": "https://github.com/xmartlabs/Eureka", "repositoryURL": "https://github.com/xmartlabs/Eureka",
@ -37,6 +64,24 @@
"version": "5.14.0" "version": "5.14.0"
} }
}, },
{
"package": "KituraContracts",
"repositoryURL": "https://github.com/IBM-Swift/KituraContracts.git",
"state": {
"branch": null,
"revision": "a30e2fb79e926672776a05ec6b919c239870a221",
"version": "1.2.1"
}
},
{
"package": "LoggerAPI",
"repositoryURL": "https://github.com/IBM-Swift/LoggerAPI.git",
"state": {
"branch": null,
"revision": "3357dd9526cdf9436fa63bb792b669e6efdc43da",
"version": "1.9.0"
}
},
{ {
"package": "MagazineLayout", "package": "MagazineLayout",
"repositoryURL": "https://github.com/airbnb/MagazineLayout", "repositoryURL": "https://github.com/airbnb/MagazineLayout",
@ -91,6 +136,24 @@
"version": "5.1.1" "version": "5.1.1"
} }
}, },
{
"package": "SwiftJWT",
"repositoryURL": "https://github.com/IBM-Swift/Swift-JWT.git",
"state": {
"branch": null,
"revision": "0d435423d12e61c0d14adb6d04396c08a6a650f1",
"version": "3.6.1"
}
},
{
"package": "swift-log",
"repositoryURL": "https://github.com/apple/swift-log.git",
"state": {
"branch": null,
"revision": "74d7b91ceebc85daf387ebb206003f78813f71aa",
"version": "1.2.0"
}
},
{ {
"package": "SwiftDate", "package": "SwiftDate",
"repositoryURL": "https://github.com/malcommac/SwiftDate.git", "repositoryURL": "https://github.com/malcommac/SwiftDate.git",

View File

@ -28,7 +28,7 @@
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent <BreakpointContent
uuid = "143FAB5A-C171-426A-A0BA-67C44E72B9D5" uuid = "143FAB5A-C171-426A-A0BA-67C44E72B9D5"
shouldBeEnabled = "Yes" shouldBeEnabled = "No"
ignoreCount = "0" ignoreCount = "0"
continueAfterRunningActions = "No" continueAfterRunningActions = "No"
filePath = "AutoCat/Controllers/GoogleSignInController.swift" filePath = "AutoCat/Controllers/GoogleSignInController.swift"
@ -40,5 +40,21 @@
landmarkType = "7"> landmarkType = "7">
</BreakpointContent> </BreakpointContent>
</BreakpointProxy> </BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "A414E864-679F-4B00-A2DE-6CE024EDCC5C"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AutoCat/Controllers/ReportController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "407"
endingLineNumber = "407"
landmarkName = "onShare(_:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints> </Breakpoints>
</Bucket> </Bucket>

View File

@ -172,14 +172,23 @@
<viewLayoutGuide key="safeArea" id="fbN-WR-iQY"/> <viewLayoutGuide key="safeArea" id="fbN-WR-iQY"/>
</view> </view>
<navigationItem key="navigationItem" id="goK-kc-WCv"> <navigationItem key="navigationItem" id="goK-kc-WCv">
<barButtonItem key="rightBarButtonItem" systemItem="action" id="2MI-Nh-b8L"> <rightBarButtonItems>
<connections> <barButtonItem systemItem="action" id="2MI-Nh-b8L">
<action selector="onShare:" destination="i1k-Y4-pyh" id="SP4-ez-N4e"/> <connections>
</connections> <action selector="onShare:" destination="i1k-Y4-pyh" id="SP4-ez-N4e"/>
</barButtonItem> </connections>
</barButtonItem>
<barButtonItem image="doc.on.doc" catalog="system" id="WZn-dn-wEG">
<connections>
<action selector="onCopy:" destination="i1k-Y4-pyh" id="hOb-Hq-JWH"/>
</connections>
</barButtonItem>
</rightBarButtonItems>
</navigationItem> </navigationItem>
<connections> <connections>
<outlet property="actionBarItem" destination="2MI-Nh-b8L" id="hPg-h1-dgv"/>
<outlet property="collection" destination="rG3-ze-Zre" id="f8S-jh-WSw"/> <outlet property="collection" destination="rG3-ze-Zre" id="f8S-jh-WSw"/>
<outlet property="copyBarItem" destination="WZn-dn-wEG" id="NCX-Xv-vOx"/>
</connections> </connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="gzk-86-k5g" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="gzk-86-k5g" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
@ -214,14 +223,14 @@
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<prototypes> <prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="VehicleCell" id="VEP-QD-i6y" customClass="VehicleCell" customModule="AutoCat" customModuleProvider="target"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="VehicleCell" id="VEP-QD-i6y" customClass="VehicleCell" customModule="AutoCat" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="85"/> <rect key="frame" x="0.0" y="28" width="375" height="85.5"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VEP-QD-i6y" id="8hH-8I-XLB"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VEP-QD-i6y" id="8hH-8I-XLB">
<rect key="frame" x="0.0" y="0.0" width="375" height="85"/> <rect key="frame" x="0.0" y="0.0" width="375" height="85.5"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Kia (JF) Optima" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AQY-7N-q8D"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Kia (JF) Optima" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AQY-7N-q8D">
<rect key="frame" x="8" y="8" width="124" height="21"/> <rect key="frame" x="8" y="8" width="124" height="21.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/> <fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -233,7 +242,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cvf-vM-QnT" customClass="PlateView" customModule="AutoCat" customModuleProvider="target"> <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cvf-vM-QnT" customClass="PlateView" customModule="AutoCat" customModuleProvider="target">
<rect key="frame" x="8" y="37" width="317" height="40"/> <rect key="frame" x="8" y="37.5" width="317" height="40"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="40" id="Xoz-Iw-PCU"/> <constraint firstAttribute="height" constant="40" id="Xoz-Iw-PCU"/>
@ -621,6 +630,7 @@
</scene> </scene>
</scenes> </scenes>
<resources> <resources>
<image name="doc.on.doc" catalog="system" width="117" height="128"/>
<image name="eye" catalog="system" width="128" height="81"/> <image name="eye" catalog="system" width="128" height="81"/>
<image name="eye.fill" catalog="system" width="128" height="78"/> <image name="eye.fill" catalog="system" width="128" height="78"/>
<image name="gear" catalog="system" width="128" height="119"/> <image name="gear" catalog="system" width="128" height="119"/>

View File

@ -2,6 +2,7 @@ import UIKit
import MagazineLayout import MagazineLayout
import Kingfisher import Kingfisher
import LinkPresentation import LinkPresentation
import SwiftJWT
enum ReportSection: Int, CaseIterable, CustomStringConvertible { enum ReportSection: Int, CaseIterable, CustomStringConvertible {
case header = 0 case header = 0
@ -75,9 +76,17 @@ enum ReportEngineSection: Int, CaseIterable, CustomStringConvertible {
} }
} }
struct ReportLinkClaims: Claims {
let exp: Date
let iat: Date
let plateNumber: String
}
class ReportController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateMagazineLayout, MediaBrowserViewControllerDataSource, MediaBrowserViewControllerDelegate, UIActivityItemSource { class ReportController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateMagazineLayout, MediaBrowserViewControllerDataSource, MediaBrowserViewControllerDelegate, UIActivityItemSource {
@IBOutlet weak var collection: UICollectionView! @IBOutlet weak var collection: UICollectionView!
@IBOutlet weak var actionBarItem: UIBarButtonItem!
@IBOutlet weak var copyBarItem: UIBarButtonItem!
private let fullWidth = MagazineLayoutItemSizeMode(widthMode: .fullWidth(respectsHorizontalInsets: true), heightMode: .dynamic) private let fullWidth = MagazineLayoutItemSizeMode(widthMode: .fullWidth(respectsHorizontalInsets: true), heightMode: .dynamic)
private var reportImageUrl: URL? private var reportImageUrl: URL?
@ -345,11 +354,11 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti
@IBAction func onShare(_ sender: UIBarButtonItem) { @IBAction func onShare(_ sender: UIBarButtonItem) {
guard let vehicle = self.vehicle else { return } guard let vehicle = self.vehicle else { return }
let sheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let sheet = UIAlertController(title: "Share report", message: nil, preferredStyle: .actionSheet)
sheet.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem sheet.popoverPresentationController?.barButtonItem = self.actionBarItem
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in sheet.dismiss(animated: true, completion: nil) } let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in sheet.dismiss(animated: true, completion: nil) }
let share = UIAlertAction(title: "Share", style: .default) { _ in let shareImage = UIAlertAction(title: "As one image", style: .default) { _ in
let image = vehicle.reportImage(width: self.collection.contentSize.width) let image = vehicle.reportImage(width: self.collection.contentSize.width)
do { do {
@ -368,12 +377,42 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti
print(error) print(error)
} }
} }
let copyPlateNumber = UIAlertAction(title: "Copy plate number", style: .default) { _ in UIPasteboard.general.string = self.vehicle?.number }
let copyVin = UIAlertAction(title: "Copy VIN", style: .default) { _ in UIPasteboard.general.string = self.vehicle?.vin1 }
sheet.addAction(share) let shareTextAndImage = UIAlertAction(title: "As text and photos", style: .default) { _ in
sheet.addAction(copyPlateNumber) guard let vehicle = self.vehicle else { return }
sheet.addAction(copyVin) var items: [Any] = [vehicle.reportText()]
for photo in vehicle.photos {
if let url = URL(string: photo.url) {
if let image = ImageCache.default.retrieveImageInDiskCache(forKey: url.cacheKey) {
items.append(image)
}
}
}
let controller = UIActivityViewController(activityItems: items, applicationActivities: nil)
controller.popoverPresentationController?.barButtonItem = sender
self.present(controller, animated: true)
}
let shareLink = UIAlertAction(title: "As link", style: .default) { _ in
guard let vehicle = self.vehicle else { return }
let iat = Date()
let exp = Date(timeIntervalSinceNow: 24*60*60)
let claims = ReportLinkClaims(exp: exp, iat: iat, plateNumber: vehicle.number)
let signer = JWTSigner.hs256(key: Constants.reportLinkTokenSecret.data(using: .utf8)!)
var jwt = SwiftJWT.JWT(claims: claims)
if let jwtSigned = try? jwt.sign(using: signer), let url = URL(string: Constants.reportLinkBaseURL + "?token=" + jwtSigned) {
let controller = UIActivityViewController(activityItems: [url], applicationActivities: nil)
controller.popoverPresentationController?.barButtonItem = sender
self.present(controller, animated: true)
}
}
sheet.addAction(shareImage)
sheet.addAction(shareTextAndImage)
sheet.addAction(shareLink)
sheet.addAction(cancel) sheet.addAction(cancel)
self.present(sheet, animated: true, completion: nil) self.present(sheet, animated: true, completion: nil)
} }
@ -397,4 +436,18 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti
metadata.iconProvider = NSItemProvider.init(contentsOf: url) metadata.iconProvider = NSItemProvider.init(contentsOf: url)
return metadata return metadata
} }
// MARK: - Copy
@IBAction func onCopy(_ sender: UIBarButtonItem) {
let sheet = UIAlertController(title: "Copy to pasteboard", message: nil, preferredStyle: .actionSheet)
sheet.popoverPresentationController?.barButtonItem = self.copyBarItem
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in sheet.dismiss(animated: true, completion: nil) }
let copyPlateNumber = UIAlertAction(title: "Plate number", style: .default) { _ in UIPasteboard.general.string = self.vehicle?.number }
let copyVin = UIAlertAction(title: "VIN", style: .default) { _ in UIPasteboard.general.string = self.vehicle?.vin1 }
sheet.addAction(copyPlateNumber)
sheet.addAction(copyVin)
sheet.addAction(cancel)
self.present(sheet, animated: true, completion: nil)
}
} }

View File

@ -64,7 +64,7 @@ extension Vehicle {
let w: CGFloat = width let w: CGFloat = width
var y: CGFloat = 0 var y: CGFloat = 0
UIColor.systemBackground.setFill() UIColor.systemGroupedBackground.setFill()
UIRectFill(rect) UIRectFill(rect)
y += 12 y += 12
@ -106,7 +106,7 @@ extension Vehicle {
y += cellHeight y += cellHeight
self.drawCell(y: y, width: w, height: cellHeight, title: "Fuel type", value: self.engine?.fuelType ?? "<unknown>", context: ctx) self.drawCell(y: y, width: w, height: cellHeight, title: "Fuel type", value: self.engine?.fuelType ?? "<unknown>", context: ctx)
y += cellHeight y += cellHeight
self.drawCell(y: y, width: w, height: cellHeight, title: "Volume", value: String(self.engine?.volume ?? 0), context: ctx) self.drawCell(y: y, width: w, height: cellHeight, title: "Volume (cm³)", value: String(self.engine?.volume ?? 0), context: ctx)
y += cellHeight y += cellHeight
self.drawCell(y: y, width: w, height: cellHeight, title: "Power (HP)", value: String(self.engine?.powerHp ?? 0), context: ctx) self.drawCell(y: y, width: w, height: cellHeight, title: "Power (HP)", value: String(self.engine?.powerHp ?? 0), context: ctx)
y += cellHeight y += cellHeight
@ -172,4 +172,44 @@ extension Vehicle {
return image.cutHeight(to: realHeight) return image.cutHeight(to: realHeight)
} }
func reportText() -> String {
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
var text = (self.brand?.name?.original ?? "<unknown model>") + "\n"
text += "Year: \(self.year)\n"
if let color = self.color { text += "Color: \(color)\n" }
if let category = self.category { text += "Category: \(category)\n" }
text += "Steering wheel position: \(self.isRightWheel ? "right" : "left")\n"
text += "Japanese: \(self.isJapanese ? "yes" : "no")\n"
text += "Plate number: \(self.number)\n"
if let vin = self.vin1 { text += "VIN: \(vin)\n" }
if let sts = self.sts { text += "STS: \(sts)\n" }
if let pts = self.pts { text += "PTS: \(pts)\n" }
if let engineNumber = self.engine?.number { text += "Engine number: \(engineNumber)\n" }
if let fuel = self.engine?.fuelType { text += "Fuel type: \(fuel)\n" }
if let volume = self.engine?.volume { text += "Volume (cm³): \(volume)\n" }
if let powerHp = self.engine?.powerHp { text += "Power (HP): \(powerHp)\n" }
if let powerHp = self.engine?.powerHp { text += "Power (HP): \(powerHp)\n" }
if self.ownershipPeriods.count > 0 {
text += "\n"
text += "Ownership periods: \(self.ownershipPeriods.count)\n"
text += "\n"
for period in self.ownershipPeriods {
text += "Owner type: \(period.ownerType)\n"
let fromDate = Date(timeIntervalSince1970: TimeInterval(period.from/1000))
text += "From: \(formatter.string(from: fromDate))\n"
let toDate = Date(timeIntervalSince1970: TimeInterval(period.to/1000))
let toString = period.to == 0 ? "now" : formatter.string(from: toDate)
text += "To: \(toString)\n"
text += "Last operation: \(period.lastOperation)\n"
text += "\n"
}
}
return text
}
} }

View File

@ -7,7 +7,7 @@ class Api {
} }
private static func createRequest<T>(api: String, method: String, body: [String: T]? = nil) -> URLRequest? where T: LosslessStringConvertible { private static func createRequest<T>(api: String, method: String, body: [String: T]? = nil) -> URLRequest? where T: LosslessStringConvertible {
guard var urlComponents = URLComponents(string: Constants.debugBaseUrl + api) else { return nil } guard var urlComponents = URLComponents(string: Constants.baseUrl + api) else { return nil }
if let body = body, method.uppercased() == "GET" { if let body = body, method.uppercased() == "GET" {
urlComponents.queryItems = body.map { URLQueryItem(name: $0, value: String($1)) } urlComponents.queryItems = body.map { URLQueryItem(name: $0, value: String($1)) }

View File

@ -1,8 +1,14 @@
import Foundation import Foundation
enum Constants { enum Constants {
static let baseUrl = "https://vps.aliencat.pro:8443/" static var baseUrl: String {
static let debugBaseUrl = "http://127.0.0.1:3000/" #if DEBUG
//return "http://127.0.0.1:3000/"
return "https://vps.aliencat.pro:8443/"
#else
return "https://vps.aliencat.pro:8443/"
#endif
}
static let googleAuthURL = "https://accounts.google.com/o/oauth2/v2/auth" static let googleAuthURL = "https://accounts.google.com/o/oauth2/v2/auth"
static let googleTokenURL = "https://oauth2.googleapis.com/token" static let googleTokenURL = "https://oauth2.googleapis.com/token"
@ -17,4 +23,7 @@ enum Constants {
static let fbUserAgent = "FirebaseAuth.iOS/6.5.1 ru.Vin01/1.0 iPhone/13.5 hw/sim" static let fbUserAgent = "FirebaseAuth.iOS/6.5.1 ru.Vin01/1.0 iPhone/13.5 hw/sim"
static let vin01BUndleId = "ru.Vin01" static let vin01BUndleId = "ru.Vin01"
static let reportLinkTokenSecret = "#TheTruthIsOutThere"
static let reportLinkBaseURL = "https://auto.aliencat.pro/report.html"
} }