Adding list of vehicles
This commit is contained in:
parent
7d1811171e
commit
d90fbfc5f0
@ -18,11 +18,14 @@
|
||||
6841A8FF53F0AADF96B138C1 /* UIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6841AFE790F6FC06838B1E2C /* UIControl.swift */; };
|
||||
6841ABD5E4B126DEF3612BBD /* PNKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6841AB0052E9DB6914901EA3 /* PNKeyboard.swift */; };
|
||||
6841AF924E165F1B3A3B5FB5 /* AuthController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6841ABEA0314E3B4E438C311 /* AuthController.swift */; };
|
||||
7A024AAE28BD5B450010D3D1 /* RoadNumbers.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7A024AAC28BD5B450010D3D1 /* RoadNumbers.otf */; };
|
||||
7A024AAF28BD5B450010D3D1 /* RoadNumbers2.0.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7A024AAD28BD5B450010D3D1 /* RoadNumbers2.0.otf */; };
|
||||
7A0391D6285933EF000EE522 /* AutoCatCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */; };
|
||||
7A0391D7285933EF000EE522 /* AutoCatCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
7A0391DD28593DBC000EE522 /* SidebarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0391DC28593DBC000EE522 /* SidebarController.swift */; };
|
||||
7A054FD928C4BE560002C386 /* PlateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A054FD828C4BE560002C386 /* PlateView.swift */; };
|
||||
7A054FDA28C4C24B0002C386 /* CenterTextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A24C19E27EE26B900049E7F /* CenterTextLayer.swift */; };
|
||||
7A163BF128BBE9ED0005A0A4 /* VehiclesListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A163BF028BBE9ED0005A0A4 /* VehiclesListView.swift */; };
|
||||
7A163BF328BBEAFC0005A0A4 /* PlateNumberView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A163BF228BBEAFC0005A0A4 /* PlateNumberView.swift */; };
|
||||
7A1D80E027F1F275007BD64F /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7A1D80DF27F1F275007BD64F /* DifferenceKit */; };
|
||||
7A1D80E627F20FCB007BD64F /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7A1D80E527F20FCB007BD64F /* DifferenceKit */; };
|
||||
7A1D80E827F30399007BD64F /* VModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1D80E727F30399007BD64F /* VModel.swift */; };
|
||||
@ -87,6 +90,7 @@
|
||||
7A49F51527D40C6100AEAAE0 /* AutoCat2.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */; };
|
||||
7A558AB027FA3CCF001A18EE /* SettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA527FA3CCF001A18EE /* SettingsTests.swift */; };
|
||||
7A558AB127FA3CCF001A18EE /* ApiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA627FA3CCF001A18EE /* ApiTests.swift */; };
|
||||
7A9471BD28C52DD80054CB0A /* PlateViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9471BC28C52DD80054CB0A /* PlateViewItem.swift */; };
|
||||
7A9F2AC327E71531006492A9 /* ACTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9F2AC227E71531006492A9 /* ACTabBarController.swift */; };
|
||||
7A9FD4072857AF590057ECFA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FD4062857AF590057ECFA /* AppDelegate.swift */; };
|
||||
7A9FD4092857AF590057ECFA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FD4082857AF590057ECFA /* ViewController.swift */; };
|
||||
@ -100,6 +104,7 @@
|
||||
7AE32D6927F06536004EF6E0 /* CoreDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE32D6827F06536004EF6E0 /* CoreDataSource.swift */; };
|
||||
7AE32D6E27F06D2D004EF6E0 /* SwiftDate in Frameworks */ = {isa = PBXBuildFile; productRef = 7AE32D6D27F06D2D004EF6E0 /* SwiftDate */; };
|
||||
7AE32D7127F06DA4004EF6E0 /* DateSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE32D7027F06DA4004EF6E0 /* DateSection.swift */; };
|
||||
7AE9F20428CDFCC600ABF6DF /* VehicleDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE9F20328CDFCC600ABF6DF /* VehicleDetailView.swift */; };
|
||||
7AF1D0D828BB577E004E19F7 /* CheckNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF1D0D728BB577E004E19F7 /* CheckNumber.swift */; };
|
||||
7AF1D0DA28BB5BF5004E19F7 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF1D0D928BB5BF5004E19F7 /* View.swift */; };
|
||||
7AFD7AE02871823E00BCCD37 /* SidebarSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFD7ADF2871823E00BCCD37 /* SidebarSection.swift */; };
|
||||
@ -220,9 +225,12 @@
|
||||
6841ADEEC165FA9124C5EF40 /* UITextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextField.swift; sourceTree = "<group>"; };
|
||||
6841AFB465BF16E122875D9A /* ACButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ACButton.swift; sourceTree = "<group>"; };
|
||||
6841AFE790F6FC06838B1E2C /* UIControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIControl.swift; sourceTree = "<group>"; };
|
||||
7A024AAC28BD5B450010D3D1 /* RoadNumbers.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers.otf; sourceTree = "<group>"; };
|
||||
7A024AAD28BD5B450010D3D1 /* RoadNumbers2.0.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers2.0.otf; sourceTree = "<group>"; };
|
||||
7A024AB028BD5BB30010D3D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
7A0391DC28593DBC000EE522 /* SidebarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarController.swift; sourceTree = "<group>"; };
|
||||
7A054FD828C4BE560002C386 /* PlateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateView.swift; sourceTree = "<group>"; };
|
||||
7A163BF028BBE9ED0005A0A4 /* VehiclesListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehiclesListView.swift; sourceTree = "<group>"; };
|
||||
7A163BF228BBEAFC0005A0A4 /* PlateNumberView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateNumberView.swift; sourceTree = "<group>"; };
|
||||
7A1D80E727F30399007BD64F /* VModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VModel.swift; sourceTree = "<group>"; };
|
||||
7A24C19527EE212E00049E7F /* RoadNumbers.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers.otf; sourceTree = "<group>"; };
|
||||
7A24C19627EE212E00049E7F /* RoadNumbers2.0.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers2.0.otf; sourceTree = "<group>"; };
|
||||
@ -286,6 +294,7 @@
|
||||
7A558AAC27FA3CCF001A18EE /* login_success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = login_success.json; sourceTree = "<group>"; };
|
||||
7A558AAE27FA3CCF001A18EE /* MockURLProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockURLProtocol.swift; sourceTree = "<group>"; };
|
||||
7A558AAF27FA3CCF001A18EE /* ApiMethodMockProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiMethodMockProtocol.swift; sourceTree = "<group>"; };
|
||||
7A9471BC28C52DD80054CB0A /* PlateViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateViewItem.swift; sourceTree = "<group>"; };
|
||||
7A9F2AC227E71531006492A9 /* ACTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACTabBarController.swift; sourceTree = "<group>"; };
|
||||
7A9FD4042857AF590057ECFA /* AutoCat2Mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoCat2Mac.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7A9FD4062857AF590057ECFA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
@ -299,6 +308,7 @@
|
||||
7AE32D6527F063A1004EF6E0 /* UIEdgeInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsets.swift; sourceTree = "<group>"; };
|
||||
7AE32D6827F06536004EF6E0 /* CoreDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataSource.swift; sourceTree = "<group>"; };
|
||||
7AE32D7027F06DA4004EF6E0 /* DateSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateSection.swift; sourceTree = "<group>"; };
|
||||
7AE9F20328CDFCC600ABF6DF /* VehicleDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleDetailView.swift; sourceTree = "<group>"; };
|
||||
7AF1D0D728BB577E004E19F7 /* CheckNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckNumber.swift; sourceTree = "<group>"; };
|
||||
7AF1D0D928BB5BF5004E19F7 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = "<group>"; };
|
||||
7AFD7ADF2871823E00BCCD37 /* SidebarSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarSection.swift; sourceTree = "<group>"; };
|
||||
@ -431,6 +441,15 @@
|
||||
path = Components;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7A024AAB28BD5B450010D3D1 /* Fonts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7A024AAC28BD5B450010D3D1 /* RoadNumbers.otf */,
|
||||
7A024AAD28BD5B450010D3D1 /* RoadNumbers2.0.otf */,
|
||||
);
|
||||
path = Fonts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7A0391DB28593DAB000EE522 /* Controllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -441,6 +460,15 @@
|
||||
path = Controllers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7A054FD728C4BB700002C386 /* PlateView */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7A054FD828C4BE560002C386 /* PlateView.swift */,
|
||||
7A9471BC28C52DD80054CB0A /* PlateViewItem.swift */,
|
||||
);
|
||||
path = PlateView;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7A163BEF28BBE9DA0005A0A4 /* VehiclesList */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -498,6 +526,8 @@
|
||||
7A4951B5288D3A6100C644B6 /* AutoCat2SUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7A024AB028BD5BB30010D3D1 /* Info.plist */,
|
||||
7A024AAB28BD5B450010D3D1 /* Fonts */,
|
||||
7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */,
|
||||
7A4951D6288D5EE700C644B6 /* Extensions */,
|
||||
7A4951CF288D5C2100C644B6 /* Views */,
|
||||
@ -520,6 +550,7 @@
|
||||
7A4951C3288D3AF000C644B6 /* Screens */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7AE9F20228CDFCAB00ABF6DF /* VehicleDetail */,
|
||||
7A163BEF28BBE9DA0005A0A4 /* VehiclesList */,
|
||||
7AF1D0D628BB5768004E19F7 /* CheckNumber */,
|
||||
7A4951CE288D5C1300C644B6 /* Main */,
|
||||
@ -548,9 +579,9 @@
|
||||
7A4951CF288D5C2100C644B6 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7A054FD728C4BB700002C386 /* PlateView */,
|
||||
7A4951B8288D3A6100C644B6 /* RootView.swift */,
|
||||
7A4951D0288D5C4300C644B6 /* ACProgressView.swift */,
|
||||
7A163BF228BBEAFC0005A0A4 /* PlateNumberView.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
@ -778,6 +809,14 @@
|
||||
path = DataSource;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7AE9F20228CDFCAB00ABF6DF /* VehicleDetail */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7AE9F20328CDFCC600ABF6DF /* VehicleDetailView.swift */,
|
||||
);
|
||||
path = VehicleDetail;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7AF1D0D628BB5768004E19F7 /* CheckNumber */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1054,6 +1093,8 @@
|
||||
files = (
|
||||
7A4951BF288D3A6300C644B6 /* Preview Assets.xcassets in Resources */,
|
||||
7A4951BB288D3A6300C644B6 /* Assets.xcassets in Resources */,
|
||||
7A024AAE28BD5B450010D3D1 /* RoadNumbers.otf in Resources */,
|
||||
7A024AAF28BD5B450010D3D1 /* RoadNumbers2.0.otf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1116,13 +1157,16 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7A4951D3288D5E2800C644B6 /* AuthVM.swift in Sources */,
|
||||
7A054FDA28C4C24B0002C386 /* CenterTextLayer.swift in Sources */,
|
||||
7A163BF128BBE9ED0005A0A4 /* VehiclesListView.swift in Sources */,
|
||||
7A054FD928C4BE560002C386 /* PlateView.swift in Sources */,
|
||||
7A4951B9288D3A6100C644B6 /* RootView.swift in Sources */,
|
||||
7A4951C7288D3BDD00C644B6 /* MainView.swift in Sources */,
|
||||
7AE9F20428CDFCC600ABF6DF /* VehicleDetailView.swift in Sources */,
|
||||
7AF1D0D828BB577E004E19F7 /* CheckNumber.swift in Sources */,
|
||||
7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */,
|
||||
7A9471BD28C52DD80054CB0A /* PlateViewItem.swift in Sources */,
|
||||
7AF1D0DA28BB5BF5004E19F7 /* View.swift in Sources */,
|
||||
7A163BF328BBEAFC0005A0A4 /* PlateNumberView.swift in Sources */,
|
||||
7A4951D1288D5C4300C644B6 /* ACProgressView.swift in Sources */,
|
||||
7A4951C5288D3BCF00C644B6 /* AuthView.swift in Sources */,
|
||||
7A4951D5288D5ED000C644B6 /* Alert.swift in Sources */,
|
||||
@ -1328,6 +1372,7 @@
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = AutoCat2SUI/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = AutoCat2;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||
@ -1367,6 +1412,7 @@
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = AutoCat2SUI/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = AutoCat2;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<key>AutoCat2.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>AutoCat2Mac.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
@ -22,7 +22,7 @@
|
||||
<key>AutoCat2SUI.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>AutoCat2UITests.testExample.xcscheme</key>
|
||||
<dict>
|
||||
|
||||
@ -26,13 +26,13 @@ class SidebarFilterItem: SidebarItem {
|
||||
|
||||
SidebarFilterItem(iconName: "internaldrive",
|
||||
title: "Local history",
|
||||
filter: Filter(dataSource: .local))
|
||||
filter: Filter.allLocal)
|
||||
}
|
||||
|
||||
static var remote: SidebarFilterItem {
|
||||
|
||||
SidebarFilterItem(iconName: "externaldrive.connected.to.line.below",
|
||||
title: "Remote DB",
|
||||
filter: Filter(dataSource: .remote))
|
||||
filter: Filter.allRemote)
|
||||
}
|
||||
}
|
||||
|
||||
6
AutoCat2SUI/Assets.xcassets/Colors/Contents.json
Normal file
6
AutoCat2SUI/Assets.xcassets/Colors/Contents.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"platform" : "ios",
|
||||
"reference" : "systemGray2Color"
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.290",
|
||||
"green" : "0.282",
|
||||
"red" : "0.282"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "1.000",
|
||||
"green" : "1.000",
|
||||
"red" : "1.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "0.300",
|
||||
"blue" : "1.000",
|
||||
"green" : "1.000",
|
||||
"red" : "1.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "1.000",
|
||||
"green" : "1.000",
|
||||
"red" : "1.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "display-p3",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.152",
|
||||
"green" : "0.152",
|
||||
"red" : "0.152"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "display-p3",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.000",
|
||||
"green" : "0.000",
|
||||
"red" : "1.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "display-p3",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.182",
|
||||
"green" : "0.225",
|
||||
"red" : "1.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.000",
|
||||
"green" : "0.000",
|
||||
"red" : "0.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "display-p3",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.866",
|
||||
"green" : "0.866",
|
||||
"red" : "0.866"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -6,11 +6,14 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AppKit
|
||||
import AutoCatCore
|
||||
|
||||
@main
|
||||
struct AutoCat2SUIApp: App {
|
||||
|
||||
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
||||
|
||||
let storageService = StorageService.sharedNotWait
|
||||
|
||||
var body: some Scene {
|
||||
@ -41,3 +44,24 @@ struct AutoCat2SUIApp: App {
|
||||
return settings
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||
true
|
||||
}
|
||||
|
||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||
NSApp.keyWindow?.toolbar?.insertItem(withItemIdentifier: .sidebarTrackingSeparator, at: 2)
|
||||
//NSApplication.shared.keyWindow
|
||||
}
|
||||
|
||||
// func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||
// let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
|
||||
// if connectingSceneSession.role == .windowApplication {
|
||||
// configuration.delegateClass = SceneDelegate.self
|
||||
// }
|
||||
// return configuration
|
||||
// }
|
||||
}
|
||||
|
||||
@ -8,43 +8,60 @@
|
||||
import SwiftUI
|
||||
import AutoCatCore
|
||||
|
||||
struct SidebarSection: Identifiable {
|
||||
|
||||
let name: String
|
||||
let filters: [Filter]
|
||||
let id = UUID()
|
||||
|
||||
func contains(filter id: UUID) -> Bool {
|
||||
filters.contains { $0.id == id }
|
||||
}
|
||||
}
|
||||
|
||||
struct MainView: View {
|
||||
|
||||
@FetchRequest(entity: CDVehicle.entity(), sortDescriptors: []) var vehicles: FetchedResults<CDVehicle>
|
||||
|
||||
@State private var selectedFilter: Filter?
|
||||
@State private var selectedFilterId: UUID?
|
||||
@State var selectedVehicle: CDVehicle?
|
||||
@State private var checkSheetPresented = false
|
||||
|
||||
private var historyFilters: [Filter] = [
|
||||
@State var columnVisibility = NavigationSplitViewVisibility.all
|
||||
|
||||
private let sections: [SidebarSection] = [
|
||||
SidebarSection(name: "History", filters: [
|
||||
.allLocal,
|
||||
.unrecognized,
|
||||
.outdated
|
||||
]),
|
||||
SidebarSection(name: "Remote", filters: [
|
||||
.allRemote
|
||||
])
|
||||
]
|
||||
|
||||
private var remoteFilters: [Filter] = [
|
||||
.allRemote
|
||||
]
|
||||
var selectedFilter: Filter? {
|
||||
guard let filterId = selectedFilterId else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return sections.first(where: { $0.contains(filter: filterId) })?
|
||||
.filters.first(where: { $0.id == filterId })
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationSplitView {
|
||||
List(selection: $selectedFilter) {
|
||||
Section("History") {
|
||||
ForEach(historyFilters) { filter in
|
||||
NavigationLink(value: filter) {
|
||||
Label(filter.name, systemImage: filter.iconName)
|
||||
.badge(vehicles.count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section("Remote") {
|
||||
ForEach(remoteFilters) { filter in
|
||||
NavigationLink(value: filter) {
|
||||
NavigationSplitView(columnVisibility: $columnVisibility) {
|
||||
List(selection: $selectedFilterId) {
|
||||
ForEach(sections) { section in
|
||||
Section(section.name) {
|
||||
ForEach(section.filters) { filter in
|
||||
Label(filter.name, systemImage: filter.iconName)
|
||||
.badge(vehicles.filter(filter.match).count)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationSplitViewColumnWidth(180)
|
||||
.toolbar {
|
||||
ToolbarItemGroup(placement: .primaryAction) {
|
||||
Spacer()
|
||||
@ -59,14 +76,42 @@ struct MainView: View {
|
||||
|
||||
}
|
||||
}
|
||||
.navigationDestination(for: Filter.self) { filter in
|
||||
VehiclesListView(vehicles: [], selection: nil)
|
||||
}
|
||||
} content: {
|
||||
Text("Content")
|
||||
} detail: {
|
||||
Text("Detail")
|
||||
if let filter = selectedFilter {
|
||||
let filtered = vehicles.filter(filter.match)
|
||||
if filtered.isEmpty {
|
||||
VStack {
|
||||
Image(systemName: filter.iconName)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 64)
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
Text("Nothing here")
|
||||
.font(.system(size: 18))
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
} else {
|
||||
VehiclesListView(vehicles: filtered, selection: $selectedVehicle)
|
||||
.toolbar {
|
||||
ToolbarItem {
|
||||
Button(action: {}) {
|
||||
Image(systemName: "trash")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
} detail: {
|
||||
if let vehicle = selectedVehicle {
|
||||
VehicleDetailView(vehicle: vehicle)
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
.navigationSplitViewStyle(.balanced)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
63
AutoCat2SUI/Screens/VehicleDetail/VehicleDetailView.swift
Normal file
63
AutoCat2SUI/Screens/VehicleDetail/VehicleDetailView.swift
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// VehicleDetailView.swift
|
||||
// AutoCat2SUI
|
||||
//
|
||||
// Created by Selim Mustafaev on 11.09.2022.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AutoCatCore
|
||||
|
||||
struct ReportTextItem: View {
|
||||
|
||||
let name: String
|
||||
let value: String?
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
Text(name)
|
||||
Spacer()
|
||||
Text(value ?? "")
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct VehicleDetailView: View {
|
||||
|
||||
let vehicle: CDVehicle
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
Section(header: Text("General")) {
|
||||
ReportTextItem(name: "Year", value: String(vehicle.year))
|
||||
ReportTextItem(name: "Color", value: vehicle.color)
|
||||
ReportTextItem(name: "Category", value: vehicle.category)
|
||||
ReportTextItem(name: "Steering wheel position", value: vehicle.isRightWheel ? "Right": "Left")
|
||||
ReportTextItem(name: "Japanese", value: vehicle.isJapanese ? "Yes" : "No")
|
||||
}
|
||||
Section(header: Text("Identifiers")) {
|
||||
ReportTextItem(name: "Plate number", value: vehicle.number)
|
||||
ReportTextItem(name: "VIN", value: vehicle.vin1)
|
||||
ReportTextItem(name: "STS", value: vehicle.sts)
|
||||
ReportTextItem(name: "PTS", value: vehicle.pts)
|
||||
}
|
||||
}
|
||||
.formStyle(.grouped)
|
||||
}
|
||||
}
|
||||
|
||||
struct VehicleDetailView_Previews: PreviewProvider {
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
let test1 = Vehicle(number: "Н282СН61",
|
||||
brandName: "KIA ОПТИМА",
|
||||
addedDate: Date().timeIntervalSince1970,
|
||||
updatedDate: Date().timeIntervalSince1970)
|
||||
|
||||
return VehicleDetailView(vehicle: CDVehicle(vehicle: test1,
|
||||
context: NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)))
|
||||
}
|
||||
}
|
||||
@ -11,20 +11,23 @@ import AutoCatCore
|
||||
struct VehiclesListView: View {
|
||||
|
||||
var vehicles: [CDVehicle]
|
||||
@State var selection: CDVehicle?
|
||||
@Binding var selection: CDVehicle?
|
||||
|
||||
var body: some View {
|
||||
List(selection: $selection) {
|
||||
ForEach(vehicles, id: \.self) { vehicle in
|
||||
let number = PlateNumber(vehicle.number ?? "")
|
||||
PlateNumberView(number: number, unrecognized: vehicle.unrecognized, outdated: vehicle.outdated)
|
||||
PlateViewItem(vehicle: vehicle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VehiclesListView_Previews: PreviewProvider {
|
||||
|
||||
@State var selection: CDVehicle?
|
||||
|
||||
static var previews: some View {
|
||||
VehiclesListView(vehicles: [])
|
||||
VehiclesListView(vehicles: [
|
||||
], selection: .constant(nil))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
//
|
||||
// PlateNumberView.swift
|
||||
// AutoCat2SUI
|
||||
//
|
||||
// Created by Selim Mustafaev on 28.08.2022.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AutoCatCore
|
||||
|
||||
struct PlateNumberView: View {
|
||||
|
||||
let number: PlateNumber
|
||||
let unrecognized: Bool
|
||||
let outdated: Bool
|
||||
|
||||
private var fgColor: Color {
|
||||
if unrecognized {
|
||||
return Color("PlateBackgroundError")
|
||||
} else {
|
||||
return Color("PlateForeground")
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.fill(fgColor)
|
||||
GeometryReader { geometry in
|
||||
HStack(alignment: .center, spacing: 2) {
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: 4)
|
||||
.fill(Color("PlateBackground"))
|
||||
Text(number.mainPart())
|
||||
.font(Font.custom("RoadNumbers", size: geometry.size.height*0.9))
|
||||
}
|
||||
.frame(width: geometry.size.width*0.73 - 1)
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: 4)
|
||||
.fill(Color("PlateBackground"))
|
||||
VStack(spacing: 0) {
|
||||
Text(number.region())
|
||||
.frame(height: geometry.size.height*0.65, alignment: .center)
|
||||
HStack {
|
||||
|
||||
}
|
||||
.frame(height: geometry.size.height*0.35, alignment: .center)
|
||||
}
|
||||
}
|
||||
.frame(width: geometry.size.width*0.27 - 1)
|
||||
}
|
||||
}
|
||||
.padding(2)
|
||||
}
|
||||
.aspectRatio(520.0/112.0, contentMode: .fit)
|
||||
}
|
||||
}
|
||||
|
||||
struct PlateNumberView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group {
|
||||
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: false, outdated: false)
|
||||
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: true, outdated: false)
|
||||
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: false, outdated: true)
|
||||
}
|
||||
.previewLayout(.fixed(width: 200, height: 50))
|
||||
}
|
||||
}
|
||||
232
AutoCat2SUI/Views/PlateView/PlateView.swift
Normal file
232
AutoCat2SUI/Views/PlateView/PlateView.swift
Normal file
@ -0,0 +1,232 @@
|
||||
#if os(macOS)
|
||||
|
||||
import AppKit
|
||||
import AutoCatCore
|
||||
import SwiftUI
|
||||
|
||||
extension CGRect {
|
||||
|
||||
func inset(by insets: NSEdgeInsets) -> CGRect {
|
||||
|
||||
CGRect(origin: CGPoint(x: origin.x + insets.left,
|
||||
y: origin.y + insets.bottom),
|
||||
size: CGSize(width: size.width - insets.left - insets.right,
|
||||
height: size.height - insets.top - insets.bottom))
|
||||
}
|
||||
}
|
||||
|
||||
extension NSScreen {
|
||||
|
||||
static var mainScreenScale: CGFloat {
|
||||
main?.backingScaleFactor ?? 1
|
||||
}
|
||||
}
|
||||
|
||||
class FlagLayer: CALayer {
|
||||
let pixelWidth = 1/NSScreen.mainScreenScale
|
||||
|
||||
// Flag colors - https://ru.wikipedia.org/wiki/%D0%A4%D0%BB%D0%B0%D0%B3_%D0%A0%D0%BE%D1%81%D1%81%D0%B8%D0%B8
|
||||
let blue = NSColor(srgbRed: 0, green: 57/256.0, blue: 166/256.0, alpha: 1)
|
||||
let red = NSColor(srgbRed: 213/256.0, green: 43/256.0, blue: 30/256.0, alpha: 1)
|
||||
|
||||
override func draw(in ctx: CGContext) {
|
||||
ctx.saveGState()
|
||||
super.draw(in: ctx)
|
||||
|
||||
ctx.setStrokeColor(NSColor.black.cgColor)
|
||||
ctx.setLineWidth(0)
|
||||
|
||||
ctx.setFillColor(NSColor.white.cgColor)
|
||||
ctx.fill(bounds.inset(by: NSEdgeInsets(top: 0, left: 0, bottom: bounds.height*2/3, right: 0)))
|
||||
|
||||
ctx.setFillColor(self.blue.cgColor)
|
||||
ctx.fill(bounds.insetBy(dx: 0, dy: bounds.height/3))
|
||||
|
||||
ctx.setFillColor(self.red.cgColor)
|
||||
ctx.fill(bounds.inset(by: NSEdgeInsets(top: bounds.height*2/3, left: 0, bottom: 0, right: 0)))
|
||||
|
||||
ctx.setLineWidth(pixelWidth)
|
||||
ctx.stroke(bounds.insetBy(dx: pixelWidth/2, dy: pixelWidth/2))
|
||||
|
||||
ctx.restoreGState()
|
||||
}
|
||||
}
|
||||
|
||||
class PlateView: NSView {
|
||||
// Some driver plate parameters from "ГОСТ Р 50577-93"
|
||||
// http://docs.cntd.ru/document/gost-r-50577-93
|
||||
private static let aspectRatio: CGFloat = 112.0/520.0
|
||||
private static let fontHeightCoeff: CGFloat = 58.0/76.0
|
||||
|
||||
private var bgLayer = CALayer()
|
||||
private var mainBgLayer = CALayer()
|
||||
private var regionBgLayer = CALayer()
|
||||
private var numberLayer = CenterTextLayer(coeff: fontHeightCoeff)
|
||||
private var regionLayer = CenterTextLayer(coeff: fontHeightCoeff)
|
||||
private var countryLayer = CenterTextLayer()
|
||||
private var flagLayer = FlagLayer()
|
||||
|
||||
var number: PlateNumber? {
|
||||
didSet {
|
||||
self.layout()
|
||||
self.setAccessibilityLabel(number?.asString())
|
||||
}
|
||||
}
|
||||
|
||||
var foreground: NSColor? {
|
||||
didSet {
|
||||
self.layout()
|
||||
}
|
||||
}
|
||||
|
||||
var fontSize: CGFloat = 10 {
|
||||
didSet {
|
||||
self.layout()
|
||||
}
|
||||
}
|
||||
|
||||
var onChange: (() -> Void)?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setup()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setup()
|
||||
}
|
||||
|
||||
func setup() {
|
||||
self.wantsLayer = true
|
||||
self.layer?.backgroundColor = NSColor.clear.cgColor
|
||||
|
||||
self.bgLayer.cornerRadius = 6 //self.bounds.height/8
|
||||
self.layer?.addSublayer(self.bgLayer)
|
||||
|
||||
self.mainBgLayer.cornerRadius = 4
|
||||
self.layer?.addSublayer(self.mainBgLayer)
|
||||
|
||||
self.regionBgLayer.cornerRadius = 4
|
||||
self.layer?.addSublayer(self.regionBgLayer)
|
||||
|
||||
self.numberLayer.alignmentMode = .center
|
||||
self.numberLayer.contentsScale = NSScreen.mainScreenScale
|
||||
self.layer?.addSublayer(self.numberLayer)
|
||||
|
||||
self.regionLayer.alignmentMode = .center
|
||||
self.regionLayer.contentsScale = NSScreen.mainScreenScale
|
||||
self.layer?.addSublayer(self.regionLayer)
|
||||
|
||||
self.countryLayer.contentsScale = NSScreen.mainScreenScale
|
||||
self.countryLayer.string = "RUS"
|
||||
self.countryLayer.alignmentMode = .center
|
||||
self.layer?.addSublayer(self.countryLayer)
|
||||
|
||||
self.flagLayer.contentsScale = NSScreen.mainScreenScale
|
||||
self.layer?.addSublayer(self.flagLayer)
|
||||
|
||||
self.setAccessibilityElement(true)
|
||||
}
|
||||
|
||||
private func pathForFlag(in rect: CGRect) -> CGPath {
|
||||
let path = CGMutablePath()
|
||||
let rect = CGPath(rect: rect, transform: nil)
|
||||
path.addPath(rect)
|
||||
return path
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
|
||||
guard let number = self.number else { return }
|
||||
guard let fgColorMain = NSColor(named: "PlateForeground")?.cgColor else { return }
|
||||
guard let bgColor = NSColor(named: "PlateBackground")?.cgColor else { return }
|
||||
|
||||
let fgColor = self.foreground?.cgColor ?? fgColorMain
|
||||
|
||||
self.bgLayer.backgroundColor = fgColor
|
||||
self.bgLayer.frame = self.bounds
|
||||
|
||||
self.mainBgLayer.backgroundColor = bgColor
|
||||
self.regionBgLayer.backgroundColor = bgColor
|
||||
self.mainBgLayer.frame = self.bounds.inset(by: NSEdgeInsets(top: 2, left: 2, bottom: 2, right: self.bounds.width*0.27 + 1))
|
||||
self.regionBgLayer.frame = self.bounds.inset(by: NSEdgeInsets(top: 2, left: self.bounds.width*0.73 + 1, bottom: 2, right: 2))
|
||||
|
||||
self.numberLayer.frame = self.mainBgLayer.frame.insetBy(dx: 4, dy: 0)
|
||||
let font = NSFont(name: "RoadNumbers", size: self.mainBgLayer.frame.height*1.1) ?? NSFont.boldSystemFont(ofSize: 24)
|
||||
let attributes: [NSAttributedString.Key: Any] = [
|
||||
.kern: 3,
|
||||
.font: font,
|
||||
.foregroundColor: fgColor
|
||||
]
|
||||
let attributed = NSAttributedString(string: number.mainPart(), attributes: attributes)
|
||||
self.numberLayer.string = attributed
|
||||
|
||||
let rbgSize = self.regionBgLayer.frame.size
|
||||
|
||||
self.regionLayer.frame = self.regionBgLayer.frame.inset(by: NSEdgeInsets(top: 2, left: 2, bottom: rbgSize.height*0.35, right: 2))
|
||||
let regionFont = NSFont(name: "RoadNumbers", size: rbgSize.height*0.8) ?? NSFont.boldSystemFont(ofSize: 24)
|
||||
let regionAttrs: [NSAttributedString.Key: Any] = [
|
||||
.kern: 1,
|
||||
.font: regionFont,
|
||||
.foregroundColor: fgColor
|
||||
]
|
||||
let attributedRegion = NSAttributedString(string: number.region(), attributes: regionAttrs)
|
||||
self.regionLayer.string = attributedRegion
|
||||
|
||||
self.countryLayer.foregroundColor = fgColor
|
||||
self.countryLayer.frame = self.regionBgLayer.frame.inset(by: NSEdgeInsets(top: rbgSize.height*0.64,
|
||||
left: rbgSize.width*0.08,
|
||||
bottom: rbgSize.height*0.07,
|
||||
right: rbgSize.width*0.42))
|
||||
self.countryLayer.fontSize = self.countryLayer.frame.size.height
|
||||
|
||||
let top = (self.regionBgLayer.frame.origin.y + rbgSize.height*0.04).rounded(.toNearestOrAwayFromZero)
|
||||
let left = (self.regionBgLayer.frame.origin.x + rbgSize.width*0.62).rounded(.toNearestOrAwayFromZero)
|
||||
let w = (rbgSize.width*0.34).rounded(.toNearestOrAwayFromZero)
|
||||
let h = (rbgSize.height*0.28).rounded(.toNearestOrAwayFromZero)
|
||||
self.flagLayer.frame = CGRect(x: left, y: top, width: w, height: h)
|
||||
self.flagLayer.setNeedsDisplay()
|
||||
}
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
|
||||
let height = fontSize/1.1 + 4
|
||||
let width = height/PlateView.aspectRatio
|
||||
return CGSize(width: width, height: height)
|
||||
}
|
||||
}
|
||||
|
||||
struct PlateNumberView: NSViewRepresentable {
|
||||
|
||||
var number: PlateNumber
|
||||
var unrecognized: Bool
|
||||
var outdated: Bool
|
||||
var fontSize: CGFloat
|
||||
|
||||
func makeNSView(context: Context) -> PlateView {
|
||||
let view = PlateView(frame: .zero)
|
||||
view.fontSize = fontSize
|
||||
return view
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: PlateView, context: Context) {
|
||||
nsView.number = number
|
||||
nsView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||
nsView.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||
}
|
||||
}
|
||||
|
||||
struct PlateNumberView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group {
|
||||
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: false, outdated: false, fontSize: 50)
|
||||
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: true, outdated: false, fontSize: 50)
|
||||
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: false, outdated: true, fontSize: 50)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
40
AutoCat2SUI/Views/PlateView/PlateViewItem.swift
Normal file
40
AutoCat2SUI/Views/PlateView/PlateViewItem.swift
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// PlateViewItem.swift
|
||||
// AutoCat2SUI
|
||||
//
|
||||
// Created by Selim Mustafaev on 04.09.2022.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AutoCatCore
|
||||
|
||||
struct PlateViewItem: View {
|
||||
|
||||
let vehicle: CDVehicle
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(vehicle.brand?.name?.original ?? "")
|
||||
|
||||
PlateNumberView(number: PlateNumber(vehicle.number ?? ""),
|
||||
unrecognized: vehicle.unrecognized,
|
||||
outdated: vehicle.outdated,
|
||||
fontSize: 30)
|
||||
}
|
||||
.padding(.vertical, 2)
|
||||
}
|
||||
}
|
||||
|
||||
struct PlateViewItem_Previews: PreviewProvider {
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
let test1 = Vehicle(number: "Н282СН61",
|
||||
brandName: "KIA ОПТИМА",
|
||||
addedDate: Date().timeIntervalSince1970,
|
||||
updatedDate: Date().timeIntervalSince1970)
|
||||
|
||||
return PlateViewItem(vehicle: CDVehicle(vehicle: test1,
|
||||
context: NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)))
|
||||
}
|
||||
}
|
||||
@ -28,7 +28,7 @@ public enum DataSource: CaseIterable, Identifiable {
|
||||
|
||||
public struct Filter: Hashable, Identifiable {
|
||||
|
||||
public let id = UUID().uuidString
|
||||
public let id = UUID()
|
||||
public let name: String
|
||||
public let iconName: String
|
||||
|
||||
@ -48,6 +48,11 @@ public struct Filter: Hashable, Identifiable {
|
||||
self.unrecognized = unrecognized
|
||||
self.outdated = outdated
|
||||
}
|
||||
|
||||
public func match(vehicle: CDVehicle) -> Bool {
|
||||
return unrecognized == vehicle.unrecognized
|
||||
&& outdated == vehicle.outdated
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Presets
|
||||
|
||||
@ -4,30 +4,39 @@ import DifferenceKit
|
||||
|
||||
public struct Vehicle: Decodable {
|
||||
|
||||
public let number: String
|
||||
public let currentNumber: String?
|
||||
public let brand: VBrand?
|
||||
public let model: VModel?
|
||||
public let addedDate: TimeInterval
|
||||
public let updatedDate: TimeInterval
|
||||
public let color: String?
|
||||
public let year: Int64?
|
||||
public let category: String?
|
||||
public let vin1: String?
|
||||
public let vin2: String?
|
||||
public let sts: String?
|
||||
public let pts: String?
|
||||
public let isRightWheel: Bool?
|
||||
public let isJapanese: Bool?
|
||||
public let addedBy: String?
|
||||
public let engine: VEngine?
|
||||
public let photos: [VPhoto]?
|
||||
public let ownershipPeriods: [VOwnershipPeriod]?
|
||||
public let events: [VEvent]?
|
||||
public let osagoContracts: [VOsago]?
|
||||
public let ads: [VAd]?
|
||||
public let notes: [VNote]?
|
||||
public let debugInfo: DebugInfo?
|
||||
public var number: String
|
||||
public var currentNumber: String?
|
||||
public var brand: VBrand?
|
||||
public var model: VModel?
|
||||
public var addedDate: TimeInterval
|
||||
public var updatedDate: TimeInterval
|
||||
public var color: String?
|
||||
public var year: Int64?
|
||||
public var category: String?
|
||||
public var vin1: String?
|
||||
public var vin2: String?
|
||||
public var sts: String?
|
||||
public var pts: String?
|
||||
public var isRightWheel: Bool?
|
||||
public var isJapanese: Bool?
|
||||
public var addedBy: String?
|
||||
public var engine: VEngine?
|
||||
public var photos: [VPhoto]?
|
||||
public var ownershipPeriods: [VOwnershipPeriod]?
|
||||
public var events: [VEvent]?
|
||||
public var osagoContracts: [VOsago]?
|
||||
public var ads: [VAd]?
|
||||
public var notes: [VNote]?
|
||||
public var debugInfo: DebugInfo?
|
||||
|
||||
public init(number: String, brandName: String, addedDate: TimeInterval, updatedDate: TimeInterval) {
|
||||
self.number = number
|
||||
self.currentNumber = number
|
||||
self.addedDate = addedDate
|
||||
self.updatedDate = updatedDate
|
||||
|
||||
self.brand = VBrand(name: VName(original: brandName))
|
||||
}
|
||||
}
|
||||
|
||||
extension CDVehicle: Dated {
|
||||
@ -54,7 +63,7 @@ extension CDVehicle: Differentiable {
|
||||
|
||||
extension CDVehicle {
|
||||
|
||||
convenience init(vehicle: Vehicle, context: NSManagedObjectContext) {
|
||||
public convenience init(vehicle: Vehicle, context: NSManagedObjectContext) {
|
||||
|
||||
self.init(context: context)
|
||||
self.number = vehicle.number
|
||||
|
||||
@ -3,8 +3,8 @@ import CoreData
|
||||
|
||||
public struct VBrand: Decodable {
|
||||
|
||||
let logo: String?
|
||||
let name: VName?
|
||||
public var logo: String?
|
||||
public var name: VName?
|
||||
}
|
||||
|
||||
extension CDVBrand {
|
||||
|
||||
@ -3,8 +3,8 @@ import CoreData
|
||||
|
||||
public struct VName: Decodable {
|
||||
|
||||
let normalized: String?
|
||||
let original: String?
|
||||
public var normalized: String?
|
||||
public var original: String?
|
||||
}
|
||||
|
||||
extension CDVName {
|
||||
|
||||
@ -3,8 +3,8 @@ import Foundation
|
||||
public struct Constants {
|
||||
public static var baseUrl: String {
|
||||
#if DEBUG
|
||||
//return "http://127.0.0.1:3000/"
|
||||
return "http://192.168.1.1:3000/"
|
||||
return "http://127.0.0.1:3000/"
|
||||
//return "http://192.168.1.1:3000/"
|
||||
//return "https://vps.aliencat.pro:8443/"
|
||||
#else
|
||||
return "https://vps.aliencat.pro:8443/"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user