From e7a9f25845191b34734a2c937b653784958992cb Mon Sep 17 00:00:00 2001 From: Selim Mustafaev Date: Sat, 19 Apr 2025 17:43:38 +0300 Subject: [PATCH] Switch to SwiftUI TabView --- AutoCat.xcodeproj/project.pbxproj | 44 ++----- AutoCat/Base.lproj/Main.storyboard | 30 +---- AutoCat/Controllers/DummyNewController.swift | 6 - AutoCat/Controllers/MainSplitController.swift | 64 --------- AutoCat/Controllers/MainTabController.swift | 123 ------------------ AutoCat/SceneDelegate.swift | 6 +- .../Screens/AuthScreen/AuthCoordinator.swift | 3 +- .../Screens/FiltersScreen/FiltersScreen.swift | 1 + .../HistoryScreen/HistoryCoordinator.swift | 30 ----- .../Screens/HistoryScreen/HistoryScreen.swift | 15 +++ .../HistoryScreen/HistoryViewModel.swift | 3 +- .../Screens/MainTabScreen/MainTabScreen.swift | 121 +++++++++++++++++ AutoCat/Screens/MapScreen/MapScreen.swift | 1 + .../RecordsScreen/RecordScreenOutput.swift | 15 --- .../RecordsScreen/RecordsCoordinator.swift | 30 ----- .../Screens/RecordsScreen/RecordsScreen.swift | 15 +++ .../RecordsScreen/RecordsViewModel.swift | 5 +- .../Screens/ReportScreen/ReportScreen.swift | 1 + .../SearchScreen/SearchCoordinator.swift | 27 ---- .../Screens/SearchScreen/SearchScreen.swift | 9 ++ .../SettingsScreen/SettingsCoordinator.swift | 38 ------ .../SettingsScreen/SettingsScreen.swift | 6 + .../SettingsScreen/SettingsViewModel.swift | 16 ++- .../SettingsService/SettingsService.swift | 4 +- 24 files changed, 209 insertions(+), 404 deletions(-) delete mode 100644 AutoCat/Controllers/DummyNewController.swift delete mode 100644 AutoCat/Controllers/MainSplitController.swift delete mode 100644 AutoCat/Controllers/MainTabController.swift delete mode 100644 AutoCat/Screens/HistoryScreen/HistoryCoordinator.swift create mode 100644 AutoCat/Screens/MainTabScreen/MainTabScreen.swift delete mode 100644 AutoCat/Screens/RecordsScreen/RecordScreenOutput.swift delete mode 100644 AutoCat/Screens/RecordsScreen/RecordsCoordinator.swift delete mode 100644 AutoCat/Screens/SearchScreen/SearchCoordinator.swift delete mode 100644 AutoCat/Screens/SettingsScreen/SettingsCoordinator.swift diff --git a/AutoCat.xcodeproj/project.pbxproj b/AutoCat.xcodeproj/project.pbxproj index 2cb8ee6..1344095 100644 --- a/AutoCat.xcodeproj/project.pbxproj +++ b/AutoCat.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 7A06E0AC2C7065AC005731AC /* SettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A06E0AB2C7065AB005731AC /* SettingsScreen.swift */; }; 7A06E0AE2C7065C7005731AC /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A06E0AD2C7065C7005731AC /* SettingsViewModel.swift */; }; - 7A06E0B02C7065D8005731AC /* SettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A06E0AF2C7065D8005731AC /* SettingsCoordinator.swift */; }; 7A06E0B32C707E13005731AC /* SettingsServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A06E0B22C707E13005731AC /* SettingsServiceProtocol.swift */; }; 7A06E0B52C707E2B005731AC /* SettingsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A06E0B42C707E2B005731AC /* SettingsService.swift */; }; 7A10226C2C551EC500B84627 /* LocationEditScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A10226B2C551EC500B84627 /* LocationEditScreen.swift */; }; @@ -23,11 +22,8 @@ 7A11470823FDE7E500B424AF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7A11470623FDE7E500B424AF /* Main.storyboard */; }; 7A11470A23FDE7E600B424AF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A11470923FDE7E600B424AF /* Assets.xcassets */; }; 7A11470D23FDE7E600B424AF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7A11470B23FDE7E600B424AF /* LaunchScreen.storyboard */; }; - 7A11471623FDEB2A00B424AF /* MainSplitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11471523FDEB2A00B424AF /* MainSplitController.swift */; }; - 7A123C742D9DC40A00781F24 /* RecordScreenOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A123C732D9DC40A00781F24 /* RecordScreenOutput.swift */; }; 7A131FD32D37B75500DC7755 /* HistoryScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A131FD22D37B75500DC7755 /* HistoryScreen.swift */; }; 7A131FD52D37B76A00DC7755 /* HistoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A131FD42D37B76A00DC7755 /* HistoryViewModel.swift */; }; - 7A131FD72D37B77E00DC7755 /* HistoryCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A131FD62D37B77E00DC7755 /* HistoryCoordinator.swift */; }; 7A1441662C297EDE00E79018 /* NotesScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1441652C297EDE00E79018 /* NotesScreen.swift */; }; 7A1441682C297EFD00E79018 /* NotesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1441672C297EFD00E79018 /* NotesViewModel.swift */; }; 7A14416E2C297F7C00E79018 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A14416D2C297F7C00E79018 /* Coordinator.swift */; }; @@ -57,7 +53,6 @@ 7A589E0F2D6B6E8E00EF3FBE /* NumberEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A589E0E2D6B6E8E00EF3FBE /* NumberEditView.swift */; }; 7A5911EE2D63226F00EC51BA /* SearchScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5911ED2D63226F00EC51BA /* SearchScreen.swift */; }; 7A5911F02D63266B00EC51BA /* SearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5911EF2D63266B00EC51BA /* SearchViewModel.swift */; }; - 7A5911F22D63268400EC51BA /* SearchCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5911F12D63268400EC51BA /* SearchCoordinator.swift */; }; 7A599C362C18AC7F00D47C18 /* ApiError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A599C352C18AC7F00D47C18 /* ApiError.swift */; }; 7A599C392C18B22900D47C18 /* FbRefreshTokenModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A599C382C18B22900D47C18 /* FbRefreshTokenModel.swift */; }; 7A599C3B2C18B36A00D47C18 /* FbVerifyTokenModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A599C3A2C18B36A00D47C18 /* FbVerifyTokenModel.swift */; }; @@ -124,7 +119,6 @@ 7A95197D2D80B43D00E69883 /* AudioRecordError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A95197C2D80B43D00E69883 /* AudioRecordError.swift */; }; 7A9519802D80B6C100E69883 /* RecordsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A95197F2D80B6C100E69883 /* RecordsScreen.swift */; }; 7A9519822D80B6E500E69883 /* RecordsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9519812D80B6E500E69883 /* RecordsViewModel.swift */; }; - 7A9519842D80B72B00E69883 /* RecordsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9519832D80B72B00E69883 /* RecordsCoordinator.swift */; }; 7A961C6C2C4C3C8600CE2211 /* TextRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A961C6B2C4C3C8600CE2211 /* TextRowView.swift */; }; 7A961C6E2C4C3C9E00CE2211 /* LinkRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A961C6D2C4C3C9E00CE2211 /* LinkRowView.swift */; }; 7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; }; @@ -167,13 +161,12 @@ 7ABDA80D2D8721B10083C715 /* Substrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ABDA80C2D8721B10083C715 /* Substrings.swift */; }; 7ABDA80F2D8723F90083C715 /* StorageService+AudioRecords.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ABDA80E2D8723F90083C715 /* StorageService+AudioRecords.swift */; }; 7AC3554A2969652F00889457 /* SwiftEntryKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7AC355492969652F00889457 /* SwiftEntryKit */; }; - 7AC3554C29696A1C00889457 /* MainTabController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3554B29696A1C00889457 /* MainTabController.swift */; }; - 7AC3554E29696C4500889457 /* DummyNewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3554D29696C4500889457 /* DummyNewController.swift */; }; 7AC3555029696D5A00889457 /* NewNumberController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3554F29696D5A00889457 /* NewNumberController.swift */; }; 7AC3555229696E3F00889457 /* UIView+layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3555129696E3F00889457 /* UIView+layout.swift */; }; 7AC35554296973E100889457 /* ACButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC35553296973E100889457 /* ACButton.swift */; }; 7AC355592969746600889457 /* UIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC355582969746600889457 /* UIControl.swift */; }; 7AC3555B296995B200889457 /* UIEdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3555A296995B200889457 /* UIEdgeInsets.swift */; }; + 7AC44B822DB390B900ADC026 /* MainTabScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC44B812DB390B900ADC026 /* MainTabScreen.swift */; }; 7AC76D7B270083AE0084DB27 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC76D7A270083AE0084DB27 /* TextView.swift */; }; 7AC8B2762D6A01C700190706 /* UISearchTextField+Dumb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC8B2752D6A01C700190706 /* UISearchTextField+Dumb.swift */; }; 7ACBB91E2CB9B155005A5168 /* Mockable in Frameworks */ = {isa = PBXBuildFile; productRef = 7ACBB91D2CB9B155005A5168 /* Mockable */; }; @@ -274,7 +267,6 @@ 7A0516192414FF0900FC55AC /* DateSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateSection.swift; sourceTree = ""; }; 7A06E0AB2C7065AB005731AC /* SettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = ""; }; 7A06E0AD2C7065C7005731AC /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; - 7A06E0AF2C7065D8005731AC /* SettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCoordinator.swift; sourceTree = ""; }; 7A06E0B22C707E13005731AC /* SettingsServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsServiceProtocol.swift; sourceTree = ""; }; 7A06E0B42C707E2B005731AC /* SettingsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsService.swift; sourceTree = ""; }; 7A10226B2C551EC500B84627 /* LocationEditScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationEditScreen.swift; sourceTree = ""; }; @@ -290,15 +282,12 @@ 7A11470923FDE7E600B424AF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 7A11470C23FDE7E600B424AF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 7A11470E23FDE7E600B424AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 7A11471523FDEB2A00B424AF /* MainSplitController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSplitController.swift; sourceTree = ""; }; 7A11474323FF06CA00B424AF /* ApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiService.swift; sourceTree = ""; }; 7A11474623FF2AA500B424AF /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; 7A11474823FF2B2D00B424AF /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = ""; }; 7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SVProgressHUD.framework; path = Carthage/Build/iOS/SVProgressHUD.framework; sourceTree = ""; }; - 7A123C732D9DC40A00781F24 /* RecordScreenOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordScreenOutput.swift; sourceTree = ""; }; 7A131FD22D37B75500DC7755 /* HistoryScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryScreen.swift; sourceTree = ""; }; 7A131FD42D37B76A00DC7755 /* HistoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryViewModel.swift; sourceTree = ""; }; - 7A131FD62D37B77E00DC7755 /* HistoryCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryCoordinator.swift; sourceTree = ""; }; 7A1441652C297EDE00E79018 /* NotesScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesScreen.swift; sourceTree = ""; }; 7A1441672C297EFD00E79018 /* NotesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesViewModel.swift; sourceTree = ""; }; 7A14416D2C297F7C00E79018 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = ""; }; @@ -333,7 +322,6 @@ 7A589E0E2D6B6E8E00EF3FBE /* NumberEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberEditView.swift; sourceTree = ""; }; 7A5911ED2D63226F00EC51BA /* SearchScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchScreen.swift; sourceTree = ""; }; 7A5911EF2D63266B00EC51BA /* SearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewModel.swift; sourceTree = ""; }; - 7A5911F12D63268400EC51BA /* SearchCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchCoordinator.swift; sourceTree = ""; }; 7A599C352C18AC7F00D47C18 /* ApiError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiError.swift; sourceTree = ""; }; 7A599C382C18B22900D47C18 /* FbRefreshTokenModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FbRefreshTokenModel.swift; sourceTree = ""; }; 7A599C3A2C18B36A00D47C18 /* FbVerifyTokenModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FbVerifyTokenModel.swift; sourceTree = ""; }; @@ -402,7 +390,6 @@ 7A95197C2D80B43D00E69883 /* AudioRecordError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecordError.swift; sourceTree = ""; }; 7A95197F2D80B6C100E69883 /* RecordsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordsScreen.swift; sourceTree = ""; }; 7A9519812D80B6E500E69883 /* RecordsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordsViewModel.swift; sourceTree = ""; }; - 7A9519832D80B72B00E69883 /* RecordsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordsCoordinator.swift; sourceTree = ""; }; 7A961C6B2C4C3C8600CE2211 /* TextRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRowView.swift; sourceTree = ""; }; 7A961C6D2C4C3C9E00CE2211 /* LinkRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkRowView.swift; sourceTree = ""; }; 7A96AE2E246B2BCD00297C33 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; }; @@ -445,13 +432,12 @@ 7ABDA80A2D8715DC0083C715 /* VehicleRecordError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleRecordError.swift; sourceTree = ""; }; 7ABDA80C2D8721B10083C715 /* Substrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Substrings.swift; sourceTree = ""; }; 7ABDA80E2D8723F90083C715 /* StorageService+AudioRecords.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StorageService+AudioRecords.swift"; sourceTree = ""; }; - 7AC3554B29696A1C00889457 /* MainTabController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabController.swift; sourceTree = ""; }; - 7AC3554D29696C4500889457 /* DummyNewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DummyNewController.swift; sourceTree = ""; }; 7AC3554F29696D5A00889457 /* NewNumberController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewNumberController.swift; sourceTree = ""; }; 7AC3555129696E3F00889457 /* UIView+layout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+layout.swift"; sourceTree = ""; }; 7AC35553296973E100889457 /* ACButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACButton.swift; sourceTree = ""; }; 7AC355582969746600889457 /* UIControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIControl.swift; sourceTree = ""; }; 7AC3555A296995B200889457 /* UIEdgeInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsets.swift; sourceTree = ""; }; + 7AC44B812DB390B900ADC026 /* MainTabScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabScreen.swift; sourceTree = ""; }; 7AC76D7A270083AE0084DB27 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; 7AC8B2752D6A01C700190706 /* UISearchTextField+Dumb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UISearchTextField+Dumb.swift"; sourceTree = ""; }; 7ADF6C92250B954900F237B2 /* Navigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Navigation.swift; sourceTree = ""; }; @@ -552,7 +538,6 @@ children = ( 7A06E0AB2C7065AB005731AC /* SettingsScreen.swift */, 7A06E0AD2C7065C7005731AC /* SettingsViewModel.swift */, - 7A06E0AF2C7065D8005731AC /* SettingsCoordinator.swift */, ); path = SettingsScreen; sourceTree = ""; @@ -637,9 +622,6 @@ 7A11471423FDEAF800B424AF /* Controllers */ = { isa = PBXGroup; children = ( - 7A11471523FDEB2A00B424AF /* MainSplitController.swift */, - 7AC3554B29696A1C00889457 /* MainTabController.swift */, - 7AC3554D29696C4500889457 /* DummyNewController.swift */, 7AC3554F29696D5A00889457 /* NewNumberController.swift */, ); path = Controllers; @@ -696,7 +678,6 @@ children = ( 7A131FD22D37B75500DC7755 /* HistoryScreen.swift */, 7A131FD42D37B76A00DC7755 /* HistoryViewModel.swift */, - 7A131FD62D37B77E00DC7755 /* HistoryCoordinator.swift */, 7A4955812D58CCF900912E66 /* HistoryFilter.swift */, ); path = HistoryScreen; @@ -705,6 +686,7 @@ 7A1441632C297E9800E79018 /* Screens */ = { isa = PBXGroup; children = ( + 7AC44B802DB390A500ADC026 /* MainTabScreen */, 7ADFC9552DAD026C001A43E3 /* GoogleAuthScreen */, 7A386A3E2DABDBFF0051676A /* MapScreen */, 7AF231912DA1C26C00AE5EB3 /* AuthScreen */, @@ -809,7 +791,6 @@ children = ( 7A5911ED2D63226F00EC51BA /* SearchScreen.swift */, 7A5911EF2D63266B00EC51BA /* SearchViewModel.swift */, - 7A5911F12D63268400EC51BA /* SearchCoordinator.swift */, ); path = SearchScreen; sourceTree = ""; @@ -973,8 +954,6 @@ 7A6C65202D99930C001240C2 /* AudioRecordView */, 7A95197F2D80B6C100E69883 /* RecordsScreen.swift */, 7A9519812D80B6E500E69883 /* RecordsViewModel.swift */, - 7A9519832D80B72B00E69883 /* RecordsCoordinator.swift */, - 7A123C732D9DC40A00781F24 /* RecordScreenOutput.swift */, ); path = RecordsScreen; sourceTree = ""; @@ -1101,6 +1080,14 @@ path = Extensions; sourceTree = ""; }; + 7AC44B802DB390A500ADC026 /* MainTabScreen */ = { + isa = PBXGroup; + children = ( + 7AC44B812DB390B900ADC026 /* MainTabScreen.swift */, + ); + path = MainTabScreen; + sourceTree = ""; + }; 7ADFC9552DAD026C001A43E3 /* GoogleAuthScreen */ = { isa = PBXGroup; children = ( @@ -1424,10 +1411,8 @@ 7A3399AB299063370087DF98 /* SearchControllerExt.swift in Sources */, 7A14416E2C297F7C00E79018 /* Coordinator.swift in Sources */, 7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */, - 7AC3554C29696A1C00889457 /* MainTabController.swift in Sources */, 7A1441682C297EFD00E79018 /* NotesViewModel.swift in Sources */, 7AFBE8C02C3024E5003C491D /* ACHud.swift in Sources */, - 7A9519842D80B72B00E69883 /* RecordsCoordinator.swift in Sources */, 7AAAFADA2C4D1AFE0050410D /* Zoomable.swift in Sources */, 7ADFC9572DAD0288001A43E3 /* GoogleAuthScreen.swift in Sources */, 7AC8B2762D6A01C700190706 /* UISearchTextField+Dumb.swift in Sources */, @@ -1451,7 +1436,7 @@ 7A961C6E2C4C3C9E00CE2211 /* LinkRowView.swift in Sources */, 7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */, 7ADF6CA12512244400F237B2 /* MapExt.swift in Sources */, - 7AC3554E29696C4500889457 /* DummyNewController.swift in Sources */, + 7AC44B822DB390B900ADC026 /* MainTabScreen.swift in Sources */, 7A7158122C444A6400852088 /* AdsViewModel.swift in Sources */, 7AF231952DA1C29300AE5EB3 /* AuthViewModel.swift in Sources */, 7AB4E4662D58A16C0006D052 /* GenericError.swift in Sources */, @@ -1470,12 +1455,10 @@ 7A2C96122C3B155B00AE46B5 /* NoteAlertModifier.swift in Sources */, 7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */, 7AF231972DA1C30000AE5EB3 /* AuthCoordinator.swift in Sources */, - 7A5911F22D63268400EC51BA /* SearchCoordinator.swift in Sources */, 7A7DADAC2D99738300F52F6C /* AudioRecordView.swift in Sources */, 7A1090EC24A4E3E100B4F0B2 /* CellProgressView.swift in Sources */, 7AB9FE2A2D08CF35005DE374 /* EventsScreenMode.swift in Sources */, 7AB490292D6B1217002F39C6 /* ACKeyboardView.swift in Sources */, - 7A11471623FDEB2A00B424AF /* MainSplitController.swift in Sources */, 7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */, 7A1022722C554A1300B84627 /* CustomHostingController.swift in Sources */, 7A1022792C557ED600B84627 /* LocationPickerViewModel.swift in Sources */, @@ -1498,14 +1481,12 @@ 7AC3555B296995B200889457 /* UIEdgeInsets.swift in Sources */, 7A06E0AC2C7065AC005731AC /* SettingsScreen.swift in Sources */, 7AF231992DA27C1B00AE5EB3 /* ACButtonView.swift in Sources */, - 7A131FD72D37B77E00DC7755 /* HistoryCoordinator.swift in Sources */, 7A7158002C43EA6900852088 /* OwnersScreen.swift in Sources */, 7A4955822D58CCF900912E66 /* HistoryFilter.swift in Sources */, 7A4322912CB2CC8A00085CF6 /* FiltersScreen.swift in Sources */, 7ABD1B472D044A3200B43213 /* GalleryScreen.swift in Sources */, 7A71580C2C44453200852088 /* AdsScreen.swift in Sources */, 7AADD4452DB2D4D60027FD7B /* MapInput.swift in Sources */, - 7A06E0B02C7065D8005731AC /* SettingsCoordinator.swift in Sources */, 7A91894F29A2BD8700519C74 /* GestureRecognizers.swift in Sources */, 7AFBE8CC2C3085C6003C491D /* ACProgressView.swift in Sources */, 7A131FD32D37B75500DC7755 /* HistoryScreen.swift in Sources */, @@ -1517,7 +1498,6 @@ 7A17CE4C2A2E850200626A6E /* UISegmentedControl.swift in Sources */, 7A9519802D80B6C100E69883 /* RecordsScreen.swift in Sources */, 7A131FD52D37B76A00DC7755 /* HistoryViewModel.swift in Sources */, - 7A123C742D9DC40A00781F24 /* RecordScreenOutput.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/AutoCat/Base.lproj/Main.storyboard b/AutoCat/Base.lproj/Main.storyboard index 3789fe4..d1c633e 100644 --- a/AutoCat/Base.lproj/Main.storyboard +++ b/AutoCat/Base.lproj/Main.storyboard @@ -3,34 +3,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/AutoCat/Controllers/DummyNewController.swift b/AutoCat/Controllers/DummyNewController.swift deleted file mode 100644 index bb78849..0000000 --- a/AutoCat/Controllers/DummyNewController.swift +++ /dev/null @@ -1,6 +0,0 @@ -import UIKit - -/// Dummy controller for detecting tap on "plus" tab -class DummyNewController: UIViewController { - -} diff --git a/AutoCat/Controllers/MainSplitController.swift b/AutoCat/Controllers/MainSplitController.swift deleted file mode 100644 index fb8c8ac..0000000 --- a/AutoCat/Controllers/MainSplitController.swift +++ /dev/null @@ -1,64 +0,0 @@ -import UIKit - -class MainSplitController: UISplitViewController, UISplitViewControllerDelegate { - - override func viewDidLoad() { - super.viewDidLoad() - self.preferredDisplayMode = .oneBesideSecondary - self.delegate = self - } - - func splitViewController(_ splitViewController: UISplitViewController, showDetail vc: UIViewController, sender: Any?) -> Bool { - if self.isCollapsed { - let tabController = self.viewControllers.first as? UITabBarController - let selectedNavController = tabController?.selectedViewController - - var vcToPush = vc - if let nav = vc as? UINavigationController { - vcToPush = nav.topViewController! - } - - vcToPush.hidesBottomBarWhenPushed = true - selectedNavController?.show(vcToPush, sender: self) - return true - } - - return false - } - - func splitViewController(_ splitViewController: UISplitViewController, separateSecondaryFrom primaryViewController: UIViewController) -> UIViewController? - { - let tabController = splitViewController.viewControllers.first as? UITabBarController - let selectedNavController = tabController?.selectedViewController as? UINavigationController - -// if selectedNavController?.viewControllers.count ?? 0 > 1 && selectedNavController?.viewControllers[1] is ReportController { -// if let controllers = selectedNavController?.popToRootViewController(animated: false) { -// let nav = UINavigationController() -// nav.setViewControllers(controllers, animated: true) -// return nav -// } -// } - - return nil - } - - func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool - { - guard let detailNav = secondaryViewController as? UINavigationController, - let detail = detailNav.viewControllers.first - else - { - return false - } - - if let tabController = primaryViewController as? UITabBarController { - let selectedNavController = tabController.selectedViewController as? UINavigationController - detail.hidesBottomBarWhenPushed = true - selectedNavController?.setNavigationBarHidden(false, animated: false) - selectedNavController?.pushViewController(detail, animated: false) - return true - } - - return false - } -} diff --git a/AutoCat/Controllers/MainTabController.swift b/AutoCat/Controllers/MainTabController.swift deleted file mode 100644 index 9885842..0000000 --- a/AutoCat/Controllers/MainTabController.swift +++ /dev/null @@ -1,123 +0,0 @@ -import UIKit -import SwiftEntryKit -import AutoCatCore - -class MainTabController: UITabBarController, UITabBarControllerDelegate { - - var settingsCoordinator: SettingsCoordinator? - var historyViewModel: HistoryViewModel? - - override func viewDidLoad() { - super.viewDidLoad() - self.delegate = self - - if #available(iOS 18, *) { - // Setting the horizontal size class will force the tab bar - // to be displayed at the bottom. - traitOverrides.horizontalSizeClass = .compact - } - - viewControllers = [] - addHistoryTab() - addRecordsTab() - -#if !targetEnvironment(macCatalyst) - addDummyTab() -#endif - addSearchTab() - addSettings() - } - - func addHistoryTab() { - - let coordinator = HistoryCoordinator() - let (controller, viewModel) = coordinator.start() - controller.tabBarItem = UITabBarItem(title: NSLocalizedString("History", comment: ""), - image: UIImage(systemName: "clock.arrow.circlepath"), tag: 0) - viewControllers = [controller] - historyViewModel = viewModel - } - - func addRecordsTab() { - - let coordinator = RecordsCoordinator() - let controller = coordinator.start(output: self) - controller.tabBarItem = UITabBarItem(title: NSLocalizedString("Records", comment: ""), - image: UIImage(named: "record"), tag: 0) - viewControllers?.append(controller) - } - - func addDummyTab() { - - let controller = DummyNewController() - controller.tabBarItem = UITabBarItem(title: "", image: UIImage(systemName: "plus"), tag: 0) - viewControllers?.append(controller) - } - - func addSearchTab() { - let coordinator = SearchCoordinator() - let controller = coordinator.start() - controller.tabBarItem = UITabBarItem(title: NSLocalizedString("Search", comment: ""), - image: UIImage(systemName: "magnifyingglass"), tag: 0) - viewControllers?.append(controller) - } - - func addSettings() { - - let coordinator = SettingsCoordinator(tabController: self) - settingsCoordinator = coordinator - let controller = coordinator.start() - controller.tabBarItem = UITabBarItem(title: NSLocalizedString("Settings", comment: ""), - image: UIImage(systemName: "gear"), tag: 0) - viewControllers?.append(controller) - } - - func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { - if viewController is DummyNewController { - showCheckPuller() - return false - } else { - return true - } - } - - func showCheckPuller() { - guard let historyViewModel else { - return - } - - var attributes = EKAttributes.bottomToast - attributes.displayDuration = .infinity - attributes.entryBackground = .color(color: .init(.secondarySystemBackground)) - attributes.screenBackground = .color(color: EKColor(UIColor(white: 0, alpha: 0.7))) - attributes.roundCorners = .top(radius: 24) - attributes.screenInteraction = .dismiss - attributes.scroll = .disabled - attributes.entryInteraction = .absorbTouches - attributes.entranceAnimation = .init(translate: .init(duration: 0.2)) - attributes.exitAnimation = .init(translate: .init(duration: 0.2)) - - let newNumberController = NewNumberController() - newNumberController.onCheck = { number in - SwiftEntryKit.dismiss { - self.selectedIndex = 0 - Task { await historyViewModel.checkNewNumber(number) } - } - } - - SwiftEntryKit.display(entry: newNumberController, using: attributes) - - // User probably just saw a vehicle and is about to start entering plate number - // Requesting current location ASAP while we still close to initial location - let locationService = ServiceContainer.shared.resolve(LocationServiceProtocol.self) - Task { try? await locationService.requestCurrentLocation() } - } -} - -extension MainTabController: RecordScreenOutput { - - func checkRecord(number: String, event: VehicleEventDto?) { - selectedIndex = 0 - Task { await historyViewModel?.checkRecord(number: number, event: event) } - } -} diff --git a/AutoCat/SceneDelegate.swift b/AutoCat/SceneDelegate.swift index b70a9db..9bb25ab 100644 --- a/AutoCat/SceneDelegate.swift +++ b/AutoCat/SceneDelegate.swift @@ -87,9 +87,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { if settingsService.user.token.isEmpty { let coordinator = AuthCoordinator(window: self.window) self.window?.rootViewController = coordinator.start() - //self.window?.rootViewController = storyboard.instantiateViewController(identifier: "AuthController") } else { - self.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController") + //self.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController") + + self.window?.rootViewController = UIHostingController(rootView: MainTabScreen()) + if let number { Task { await openReport(with: number) } } diff --git a/AutoCat/Screens/AuthScreen/AuthCoordinator.swift b/AutoCat/Screens/AuthScreen/AuthCoordinator.swift index 6ddc4d7..974ed7d 100644 --- a/AutoCat/Screens/AuthScreen/AuthCoordinator.swift +++ b/AutoCat/Screens/AuthScreen/AuthCoordinator.swift @@ -37,7 +37,6 @@ final class AuthCoordinator { func openMainScreen() { - let storyboard = UIStoryboard(name: "Main", bundle: nil) - window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController") + window?.rootViewController = UIHostingController(rootView: MainTabScreen()) } } diff --git a/AutoCat/Screens/FiltersScreen/FiltersScreen.swift b/AutoCat/Screens/FiltersScreen/FiltersScreen.swift index 77848c4..1618d95 100644 --- a/AutoCat/Screens/FiltersScreen/FiltersScreen.swift +++ b/AutoCat/Screens/FiltersScreen/FiltersScreen.swift @@ -124,5 +124,6 @@ struct FiltersScreen: View { .task { await viewModel.loadData() } + .toolbar(.hidden, for: .tabBar) } } diff --git a/AutoCat/Screens/HistoryScreen/HistoryCoordinator.swift b/AutoCat/Screens/HistoryScreen/HistoryCoordinator.swift deleted file mode 100644 index 266969a..0000000 --- a/AutoCat/Screens/HistoryScreen/HistoryCoordinator.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// HistoryCoordinator.swift -// AutoCat -// -// Created by Selim Mustafaev on 15.01.2025. -// Copyright © 2025 Selim Mustafaev. All rights reserved. -// - -import UIKit -import SwiftUI -import AutoCatCore - -@MainActor -final class HistoryCoordinator { - - func start() -> (UIViewController, HistoryViewModel) { - - let resolver = ServiceContainer.shared - let viewModel = HistoryViewModel( - apiService: resolver.resolve(ApiServiceProtocol.self), - storageService: resolver.resolve(StorageServiceProtocol.self), - vehicleService: resolver.resolve(VehicleServiceProtocol.self) - ) - - let view = HistoryScreen(viewModel: viewModel) - let controller = UIHostingController(rootView: view) - - return (controller, viewModel) - } -} diff --git a/AutoCat/Screens/HistoryScreen/HistoryScreen.swift b/AutoCat/Screens/HistoryScreen/HistoryScreen.swift index 828d632..1801467 100644 --- a/AutoCat/Screens/HistoryScreen/HistoryScreen.swift +++ b/AutoCat/Screens/HistoryScreen/HistoryScreen.swift @@ -15,6 +15,21 @@ struct HistoryScreen: View { @State var filterSheetPresented = false @State var exportSheetPresented = false + init() { + + let resolver = ServiceContainer.shared + self.viewModel = HistoryViewModel( + apiService: resolver.resolve(ApiServiceProtocol.self), + storageService: resolver.resolve(StorageServiceProtocol.self), + vehicleService: resolver.resolve(VehicleServiceProtocol.self) + ) + } + + init(viewModel: HistoryViewModel) { + + self.viewModel = viewModel + } + var body: some View { NavigationStack { List { diff --git a/AutoCat/Screens/HistoryScreen/HistoryViewModel.swift b/AutoCat/Screens/HistoryScreen/HistoryViewModel.swift index 1d13120..5cff5c5 100644 --- a/AutoCat/Screens/HistoryScreen/HistoryViewModel.swift +++ b/AutoCat/Screens/HistoryScreen/HistoryViewModel.swift @@ -129,7 +129,8 @@ final class HistoryViewModel: ACHudContainer { if errors.isEmpty { hud = nil if !vehicle.unrecognized { - vehicleToOpen = vehicle + // TODO: Fix programmatic navigation + //vehicleToOpen = vehicle } } else { showErrors(errors) diff --git a/AutoCat/Screens/MainTabScreen/MainTabScreen.swift b/AutoCat/Screens/MainTabScreen/MainTabScreen.swift new file mode 100644 index 0000000..e79942d --- /dev/null +++ b/AutoCat/Screens/MainTabScreen/MainTabScreen.swift @@ -0,0 +1,121 @@ +// +// MainTabScreen.swift +// AutoCat +// +// Created by Selim Mustafaev on 19.04.2025. +// Copyright © 2025 Selim Mustafaev. All rights reserved. +// + +import SwiftUI +import UIKit +import SwiftEntryKit +import AutoCatCore + +struct MainTabScreen: View { + + @State private var selection = 0 + + let historyViewModel: HistoryViewModel + let recordsViewModel: RecordsViewModel + + init() { + let resolver = ServiceContainer.shared + + historyViewModel = HistoryViewModel( + apiService: resolver.resolve(ApiServiceProtocol.self), + storageService: resolver.resolve(StorageServiceProtocol.self), + vehicleService: resolver.resolve(VehicleServiceProtocol.self) + ) + + recordsViewModel = RecordsViewModel( + recordService: resolver.resolve(VehicleRecordServiceProtocol.self), + storageService: resolver.resolve(StorageServiceProtocol.self), + recordPlayer: resolver.resolve(RecordPlayerServiceProtocol.self) + ) + + recordsViewModel.onCheckRecord = checkRecord + } + + var body: some View { + TabView(selection: $selection) { + HistoryScreen(viewModel: historyViewModel) + .tabItem { + Label("History", systemImage: "clock.arrow.circlepath") + } + .tag(0) + + RecordsScreen(viewModel: recordsViewModel) + .tabItem { + Label("Records", image: "record") + } + .tag(1) + +#if os(iOS) + Text("") + .tabItem { + Label("", systemImage: "plus") + } + .tag(2) +#endif + + SearchScreen() + .tabItem { + Label("Search", systemImage: "magnifyingglass") + } + .tag(3) + + SettingsScreen() + .tabItem { + Label("Settings", systemImage: "gear") + } + .tag(4) + } +#if os(iOS) + .onChange(of: selection) { oldValue, newValue in + if newValue == 2 { + self.selection = oldValue + showCheckPuller() + } + } +#endif + } + + func showCheckPuller() { + + var attributes = EKAttributes.bottomToast + attributes.displayDuration = .infinity + attributes.entryBackground = .color(color: .init(.secondarySystemBackground)) + attributes.screenBackground = .color(color: EKColor(UIColor(white: 0, alpha: 0.7))) + attributes.roundCorners = .top(radius: 24) + attributes.screenInteraction = .dismiss + attributes.scroll = .disabled + attributes.entryInteraction = .absorbTouches + attributes.entranceAnimation = .init(translate: .init(duration: 0.2)) + attributes.exitAnimation = .init(translate: .init(duration: 0.2)) + + let newNumberController = NewNumberController() + newNumberController.onCheck = { number in + SwiftEntryKit.dismiss { + selection = 0 + Task { await historyViewModel.checkNewNumber(number) } + } + } + + SwiftEntryKit.display(entry: newNumberController, using: attributes) + + // User probably just saw a vehicle and is about to start entering plate number + // Requesting current location ASAP while we still close to initial location + let locationService = ServiceContainer.shared.resolve(LocationServiceProtocol.self) + Task { try? await locationService.requestCurrentLocation() } + } + + func checkRecord(number: String, event: VehicleEventDto?) { + + selection = 0 + Task { await historyViewModel.checkRecord(number: number, event: event) } + } +} + +#Preview { + MainTabScreen() +} diff --git a/AutoCat/Screens/MapScreen/MapScreen.swift b/AutoCat/Screens/MapScreen/MapScreen.swift index a81003b..eea40df 100644 --- a/AutoCat/Screens/MapScreen/MapScreen.swift +++ b/AutoCat/Screens/MapScreen/MapScreen.swift @@ -48,5 +48,6 @@ struct MapScreen: View { await viewModel.reloadMarkers() } } + .toolbar(.hidden, for: .tabBar) } } diff --git a/AutoCat/Screens/RecordsScreen/RecordScreenOutput.swift b/AutoCat/Screens/RecordsScreen/RecordScreenOutput.swift deleted file mode 100644 index 1fb44d0..0000000 --- a/AutoCat/Screens/RecordsScreen/RecordScreenOutput.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// RecordScreenOutput.swift -// AutoCat -// -// Created by Selim Mustafaev on 02.04.2025. -// Copyright © 2025 Selim Mustafaev. All rights reserved. -// - -import AutoCatCore - -@MainActor -protocol RecordScreenOutput: AnyObject { - - func checkRecord(number: String, event: VehicleEventDto?) -} diff --git a/AutoCat/Screens/RecordsScreen/RecordsCoordinator.swift b/AutoCat/Screens/RecordsScreen/RecordsCoordinator.swift deleted file mode 100644 index 540b67a..0000000 --- a/AutoCat/Screens/RecordsScreen/RecordsCoordinator.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// RecordsCoordinator.swift -// AutoCat -// -// Created by Selim Mustafaev on 11.03.2025. -// Copyright © 2025 Selim Mustafaev. All rights reserved. -// - -import UIKit -import SwiftUI -import AutoCatCore - -@MainActor -final class RecordsCoordinator { - - func start(output: RecordScreenOutput?) -> UIViewController { - - let resolver = ServiceContainer.shared - let viewModel = RecordsViewModel( - recordService: resolver.resolve(VehicleRecordServiceProtocol.self), - storageService: resolver.resolve(StorageServiceProtocol.self), - recordPlayer: resolver.resolve(RecordPlayerServiceProtocol.self) - ) - - viewModel.output = output - - let view = RecordsScreen(viewModel: viewModel) - return UIHostingController(rootView: view) - } -} diff --git a/AutoCat/Screens/RecordsScreen/RecordsScreen.swift b/AutoCat/Screens/RecordsScreen/RecordsScreen.swift index b2aa035..8730797 100644 --- a/AutoCat/Screens/RecordsScreen/RecordsScreen.swift +++ b/AutoCat/Screens/RecordsScreen/RecordsScreen.swift @@ -17,6 +17,21 @@ struct RecordsScreen: View { @State var numberText = "" @State var selectedRecordId: String = "" + init() { + + let resolver = ServiceContainer.shared + self.viewModel = RecordsViewModel( + recordService: resolver.resolve(VehicleRecordServiceProtocol.self), + storageService: resolver.resolve(StorageServiceProtocol.self), + recordPlayer: resolver.resolve(RecordPlayerServiceProtocol.self) + ) + } + + init(viewModel: RecordsViewModel) { + + self.viewModel = viewModel + } + var body: some View { NavigationStack { List { diff --git a/AutoCat/Screens/RecordsScreen/RecordsViewModel.swift b/AutoCat/Screens/RecordsScreen/RecordsViewModel.swift index e9fb9ca..0404111 100644 --- a/AutoCat/Screens/RecordsScreen/RecordsViewModel.swift +++ b/AutoCat/Screens/RecordsScreen/RecordsViewModel.swift @@ -16,7 +16,8 @@ final class RecordsViewModel: ACHudContainer { let recordService: VehicleRecordServiceProtocol let storageService: StorageServiceProtocol let recordPlayer: RecordPlayerServiceProtocol - weak var output: RecordScreenOutput? + + var onCheckRecord: ((String, VehicleEventDto?) -> Void)? var hud: ACHud? var showRecordingAlert: Bool = false @@ -116,6 +117,6 @@ final class RecordsViewModel: ACHudContainer { return } - output?.checkRecord(number: number, event: record.event) + onCheckRecord?(number, record.event) } } diff --git a/AutoCat/Screens/ReportScreen/ReportScreen.swift b/AutoCat/Screens/ReportScreen/ReportScreen.swift index 450b902..729f6f6 100644 --- a/AutoCat/Screens/ReportScreen/ReportScreen.swift +++ b/AutoCat/Screens/ReportScreen/ReportScreen.swift @@ -146,6 +146,7 @@ struct ReportScreen: View { GalleryScreen(photos: viewModel.vehicle.photos) } } + .toolbar(.hidden, for: .tabBar) } @ViewBuilder diff --git a/AutoCat/Screens/SearchScreen/SearchCoordinator.swift b/AutoCat/Screens/SearchScreen/SearchCoordinator.swift deleted file mode 100644 index 72f8684..0000000 --- a/AutoCat/Screens/SearchScreen/SearchCoordinator.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// SearchCoordinator.swift -// AutoCat -// -// Created by Selim Mustafaev on 17.02.2025. -// Copyright © 2025 Selim Mustafaev. All rights reserved. -// - -import UIKit -import SwiftUI -import AutoCatCore - -@MainActor -final class SearchCoordinator { - - func start() -> UIViewController { - - let resolver = ServiceContainer.shared - let viewModel = SearchViewModel( - apiService: resolver.resolve(ApiServiceProtocol.self), - vehicleService: resolver.resolve(VehicleServiceProtocol.self) - ) - - let view = SearchScreen(viewModel: viewModel) - return UIHostingController(rootView: view) - } -} diff --git a/AutoCat/Screens/SearchScreen/SearchScreen.swift b/AutoCat/Screens/SearchScreen/SearchScreen.swift index 3b40d6f..dafcef5 100644 --- a/AutoCat/Screens/SearchScreen/SearchScreen.swift +++ b/AutoCat/Screens/SearchScreen/SearchScreen.swift @@ -20,6 +20,15 @@ struct SearchScreen: View { @State var viewModel: SearchViewModel + init() { + + let resolver = ServiceContainer.shared + self.viewModel = SearchViewModel( + apiService: resolver.resolve(ApiServiceProtocol.self), + vehicleService: resolver.resolve(VehicleServiceProtocol.self) + ) + } + var body: some View { NavigationStack { List { diff --git a/AutoCat/Screens/SettingsScreen/SettingsCoordinator.swift b/AutoCat/Screens/SettingsScreen/SettingsCoordinator.swift deleted file mode 100644 index afe1374..0000000 --- a/AutoCat/Screens/SettingsScreen/SettingsCoordinator.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// SettingsCoordinator.swift -// AutoCat -// -// Created by Selim Mustafaev on 17.08.2024. -// Copyright © 2024 Selim Mustafaev. All rights reserved. -// - -import UIKit -import SwiftUI -import AutoCatCore - -@MainActor -class SettingsCoordinator { - - weak var tabController: UITabBarController? - - init(tabController: UITabBarController) { - - self.tabController = tabController - } - - func start() -> UIViewController { - - let viewModel = SettingsViewModel(settingsService: ServiceContainer.shared.resolve(SettingsServiceProtocol.self)) - viewModel.coordinator = self - return UIHostingController(rootView: SettingsScreen(viewModel: viewModel)) - } - - func openAuthScreen() { - guard let window = tabController?.tabBar.window else { - return - } - - let coordinator = AuthCoordinator(window: window) - window.rootViewController = coordinator.start() - } -} diff --git a/AutoCat/Screens/SettingsScreen/SettingsScreen.swift b/AutoCat/Screens/SettingsScreen/SettingsScreen.swift index b07919e..6f45db8 100644 --- a/AutoCat/Screens/SettingsScreen/SettingsScreen.swift +++ b/AutoCat/Screens/SettingsScreen/SettingsScreen.swift @@ -14,6 +14,12 @@ struct SettingsScreen: View { @State var viewModel: SettingsViewModel @State var googleSheetOpened = false @State var googleLoginSheetOpened = false + + init() { + self.viewModel = SettingsViewModel( + settingsService: ServiceContainer.shared.resolve(SettingsServiceProtocol.self) + ) + } var body: some View { NavigationStack { diff --git a/AutoCat/Screens/SettingsScreen/SettingsViewModel.swift b/AutoCat/Screens/SettingsScreen/SettingsViewModel.swift index 348887f..9396da5 100644 --- a/AutoCat/Screens/SettingsScreen/SettingsViewModel.swift +++ b/AutoCat/Screens/SettingsScreen/SettingsViewModel.swift @@ -6,6 +6,7 @@ // Copyright © 2024 Selim Mustafaev. All rights reserved. // +import UIKit import SwiftUI import AutoCatCore @@ -13,7 +14,6 @@ import AutoCatCore @Observable class SettingsViewModel { - weak var coordinator: SettingsCoordinator? var settingService: SettingsServiceProtocol var autocatEmail: String { @@ -49,7 +49,19 @@ class SettingsViewModel { func signOut() { settingService.user.token = "" - coordinator?.openAuthScreen() + + let window = UIApplication.shared + .connectedScenes + .filter({$0.activationState == .foregroundActive}) + .map({$0 as? UIWindowScene}) + .compactMap({$0}) + .first?.windows + .filter({$0.isKeyWindow}).first + + if let window { + let coordinator = AuthCoordinator(window: window) + window.rootViewController = coordinator.start() + } } func googleSignout() { diff --git a/AutoCatCore/Services/SettingsService/SettingsService.swift b/AutoCatCore/Services/SettingsService/SettingsService.swift index f00f343..c606a98 100644 --- a/AutoCatCore/Services/SettingsService/SettingsService.swift +++ b/AutoCatCore/Services/SettingsService/SettingsService.swift @@ -55,7 +55,9 @@ public final class SettingsService: SettingsServiceProtocol { public var userData: Data? { didSet { - set(value: userData, for: .user) + if let userData { + set(value: userData, for: .user) + } } }