From a34cf3058f4a16e91c89ae39cd237379ef1c8daa Mon Sep 17 00:00:00 2001 From: Arifin Firdaus Date: Wed, 4 Sep 2024 19:09:39 +1200 Subject: [PATCH] T17120620: CC-6770 When OS text size is 135% the segment control component between All videos and Playlists is gone. --- .../Sources/Video/Views/TabBarView.swift | 118 ++++++++++++ .../Video/Views/TabContainerView.swift | 176 +++++------------- .../Preview_FilesSearchUseCase.swift | 2 +- 3 files changed, 163 insertions(+), 133 deletions(-) create mode 100644 Modules/Presentation/Features/Video/Sources/Video/Views/TabBarView.swift diff --git a/Modules/Presentation/Features/Video/Sources/Video/Views/TabBarView.swift b/Modules/Presentation/Features/Video/Sources/Video/Views/TabBarView.swift new file mode 100644 index 0000000000..4863c90a96 --- /dev/null +++ b/Modules/Presentation/Features/Video/Sources/Video/Views/TabBarView.swift @@ -0,0 +1,118 @@ +import SwiftUI + +struct TabBarView: View { + @Binding var currentTab: VideosTab + @Namespace var namespace + let videoConfig: VideoConfig + + static let defaultHeight: CGFloat = 44 + + @State private var orientation = UIDeviceOrientation.unknown + + var body: some View { + HStack { + if interfaceOrientation.isLandscape { + Spacer() + } + ForEach(VideosTab.allCases, id: \.self) { tab in + TabBarItem( + currentTab: self.$currentTab, + namespace: namespace.self, + tabBarItemName: tab.title, + tab: tab, + videoConfig: videoConfig + ) + .frame(maxWidth: orientation.isPortrait ? .infinity : 195) + } + if interfaceOrientation.isLandscape { + Spacer() + } + } + .frame(maxWidth: interfaceOrientation.isPortrait ? .infinity : nil) + .edgesIgnoringSafeArea(.all) + .background(videoConfig.colorAssets.navigationBgColor) + .onRotate { newOrientation in + orientation = newOrientation + } + } + + private var interfaceOrientation: UIInterfaceOrientation { + guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { + return .unknown + } + return windowScene.interfaceOrientation + } +} + +struct TabBarItem: View { + @Binding var currentTab: VideosTab + let namespace: Namespace.ID + + var tabBarItemName: String + var tab: VideosTab + + let videoConfig: VideoConfig + + var body: some View { + Button( + action: { currentTab = tab }, + label: buttonContent + ) + } + + private func buttonContent() -> some View { + ZStack(alignment: .bottom) { + Text(tabBarItemName) + .multilineTextAlignment(.center) + .font(isTabActive ? .system(.subheadline).bold() : .subheadline) + .foregroundStyle( + isTabActive + ? videoConfig.colorAssets.tabActiveIndicatorColor + : videoConfig.colorAssets.tabInactiveTextColor + ) + .frame(maxHeight: .infinity, alignment: .center) + + Group { + if isTabActive { + videoConfig.colorAssets.tabActiveIndicatorColor + .frame(height: 1) + .matchedGeometryEffect(id: "underline", in: namespace, properties: .frame) + } else { + videoConfig.colorAssets.tabInactiveIndicatorColor + .frame(height: 1) + } + } + } + .animation(.spring(), value: self.currentTab) + .frame(height: TabBarView.defaultHeight) + } + + private var isTabActive: Bool { + currentTab == tab + } +} + +struct Preview_TabBarView: View { + @State private var currentTab: VideosTab = .all + + var body: some View { + TabBarView( + currentTab: $currentTab, + videoConfig: .preview + ) + } +} + +#Preview { + Preview_TabBarView() +} + +#Preview { + Preview_TabBarView() + .preferredColorScheme(.dark) +} + +#Preview { + Preview_TabBarView() + .dynamicTypeSize(.xxxLarge) +} diff --git a/Modules/Presentation/Features/Video/Sources/Video/Views/TabContainerView.swift b/Modules/Presentation/Features/Video/Sources/Video/Views/TabContainerView.swift index b342ff7f15..5e4922b712 100644 --- a/Modules/Presentation/Features/Video/Sources/Video/Views/TabContainerView.swift +++ b/Modules/Presentation/Features/Video/Sources/Video/Views/TabContainerView.swift @@ -31,7 +31,7 @@ struct TabContainerView: View { var body: some View { VStack(spacing: 0) { TabBarView(currentTab: self.$currentTab, videoConfig: videoConfig) - .frame(height: syncModel.showsTabView ? 44 : 0) + .frame(height: syncModel.showsTabView ? TabBarView.defaultHeight : 0) .opacity(syncModel.showsTabView ? 1 : 0) .animation(.easeInOut(duration: 0.1), value: syncModel.showsTabView) @@ -61,140 +61,52 @@ struct TabContainerView: View { } } -struct TabBarView: View { - @Binding var currentTab: VideosTab - @Namespace var namespace - let videoConfig: VideoConfig - - @State private var orientation = UIDeviceOrientation.unknown - - var body: some View { - HStack { - if interfaceOrientation.isLandscape { - Spacer() - } - ForEach(VideosTab.allCases, id: \.self) { tab in - TabBarItem( - currentTab: self.$currentTab, - namespace: namespace.self, - tabBarItemName: tab.title, - tab: tab, - videoConfig: videoConfig - ) - .frame(maxWidth: orientation.isPortrait ? .infinity : 195) - } - if interfaceOrientation.isLandscape { - Spacer() - } - } - .frame(maxWidth: interfaceOrientation.isPortrait ? .infinity : nil) - .edgesIgnoringSafeArea(.all) - .background(videoConfig.colorAssets.navigationBgColor) - .onRotate { newOrientation in - orientation = newOrientation - } - } - - private var interfaceOrientation: UIInterfaceOrientation { - guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { - return .unknown - } - return windowScene.interfaceOrientation - } +#Preview { + TabContainerView( + videoListViewModel: makeNullViewModel(), + videoPlaylistViewModel: makeVideoPlaylistsViewModel(), + syncModel: VideoRevampSyncModel(), + videoConfig: .preview, + router: Preview_VideoRevampRouter(), + didChangeCurrentTab: { _ in } + ) } -struct TabBarItem: View { - @Binding var currentTab: VideosTab - let namespace: Namespace.ID - - var tabBarItemName: String - var tab: VideosTab - - let videoConfig: VideoConfig - - var body: some View { - Button( - action: { currentTab = tab }, - label: buttonContent - ) - } - - private func buttonContent() -> some View { - VStack { - Spacer() - - Text(tabBarItemName) - .multilineTextAlignment(.center) - .font(isTabActive ? .system(.subheadline).bold() : .subheadline) - .foregroundColor( - isTabActive - ? videoConfig.colorAssets.tabActiveIndicatorColor - : videoConfig.colorAssets.tabInactiveTextColor - ) - Group { - if isTabActive { - videoConfig.colorAssets.tabActiveIndicatorColor - .frame(height: 2) - .matchedGeometryEffect(id: "underline", in: namespace, properties: .frame) - } else { - videoConfig.colorAssets.tabInactiveIndicatorColor - .frame(height: 2) - } - } - } - .animation(.spring(), value: self.currentTab) - } - - private var isTabActive: Bool { - currentTab == tab - } +#Preview { + TabContainerView( + videoListViewModel: makeNullViewModel(), + videoPlaylistViewModel: makeVideoPlaylistsViewModel(), + syncModel: VideoRevampSyncModel(), + videoConfig: .preview, + router: Preview_VideoRevampRouter(), + didChangeCurrentTab: { _ in } + ) + .preferredColorScheme(.dark) } -#Preview { - func makeNullViewModel() -> VideoListViewModel { - VideoListViewModel( - syncModel: VideoRevampSyncModel(), - contentProvider: VideoListViewModelContentProvider(photoLibraryUseCase: Preview_PhotoLibraryUseCase()), - selection: VideoSelection(), - fileSearchUseCase: Preview_FilesSearchUseCase(), - thumbnailLoader: Preview_ThumbnailLoader(), - sensitiveNodeUseCase: Preview_SensitiveNodeUseCase() - ) - } +private func makeNullViewModel() -> VideoListViewModel { + VideoListViewModel( + syncModel: VideoRevampSyncModel(), + contentProvider: VideoListViewModelContentProvider(photoLibraryUseCase: Preview_PhotoLibraryUseCase()), + selection: VideoSelection(), + fileSearchUseCase: Preview_FilesSearchUseCase(), + thumbnailLoader: Preview_ThumbnailLoader(), + sensitiveNodeUseCase: Preview_SensitiveNodeUseCase() + ) +} - func makeVideoPlaylistsViewModel() -> VideoPlaylistsViewModel { - VideoPlaylistsViewModel( - videoPlaylistsUseCase: Preview_VideoPlaylistUseCase(), - videoPlaylistContentUseCase: Preview_VideoPlaylistContentUseCase(), - videoPlaylistModificationUseCase: Preview_VideoPlaylistModificationUseCase(), - sortOrderPreferenceUseCase: Preview_SortOrderPreferenceUseCase(), - syncModel: VideoRevampSyncModel(), - alertViewModel: .preview, - renameVideoPlaylistAlertViewModel: .preview, - thumbnailLoader: Preview_ThumbnailLoader(), - featureFlagProvider: Preview_FeatureFlagProvider(isFeatureFlagEnabled: false), - contentProvider: VideoPlaylistsViewModelContentProvider( - videoPlaylistsUseCase: Preview_VideoPlaylistUseCase()) - ) - } - - return Group { - TabContainerView( - videoListViewModel: makeNullViewModel(), - videoPlaylistViewModel: makeVideoPlaylistsViewModel(), - syncModel: VideoRevampSyncModel(), - videoConfig: .preview, - router: Preview_VideoRevampRouter(), - didChangeCurrentTab: { _ in } - ) - TabContainerView( - videoListViewModel: makeNullViewModel(), - videoPlaylistViewModel: makeVideoPlaylistsViewModel(), - syncModel: VideoRevampSyncModel(), - videoConfig: .preview, - router: Preview_VideoRevampRouter(), - didChangeCurrentTab: { _ in } - ) - .preferredColorScheme(.dark) - } +private func makeVideoPlaylistsViewModel() -> VideoPlaylistsViewModel { + VideoPlaylistsViewModel( + videoPlaylistsUseCase: Preview_VideoPlaylistUseCase(), + videoPlaylistContentUseCase: Preview_VideoPlaylistContentUseCase(), + videoPlaylistModificationUseCase: Preview_VideoPlaylistModificationUseCase(), + sortOrderPreferenceUseCase: Preview_SortOrderPreferenceUseCase(), + syncModel: VideoRevampSyncModel(), + alertViewModel: .preview, + renameVideoPlaylistAlertViewModel: .preview, + thumbnailLoader: Preview_ThumbnailLoader(), + featureFlagProvider: Preview_FeatureFlagProvider(isFeatureFlagEnabled: false), + contentProvider: VideoPlaylistsViewModelContentProvider( + videoPlaylistsUseCase: Preview_VideoPlaylistUseCase()) + ) } diff --git a/Modules/Presentation/Features/Video/Sources/Video/Views/Videos/PreviewSupport/Preview_FilesSearchUseCase.swift b/Modules/Presentation/Features/Video/Sources/Video/Views/Videos/PreviewSupport/Preview_FilesSearchUseCase.swift index 1ba7cd0336..0d218583f4 100644 --- a/Modules/Presentation/Features/Video/Sources/Video/Views/Videos/PreviewSupport/Preview_FilesSearchUseCase.swift +++ b/Modules/Presentation/Features/Video/Sources/Video/Views/Videos/PreviewSupport/Preview_FilesSearchUseCase.swift @@ -51,6 +51,6 @@ struct Preview_PhotoLibraryUseCase: PhotoLibraryUseCaseProtocol { } func media(for filterOptions: PhotosFilterOptionsEntity, excludeSensitive: Bool?, searchText: String?, sortOrder: SortOrderEntity) async throws -> [NodeEntity] { - [] + [ .preview ] } }