콘텐츠 보기 설정
- UI 설정
This commit is contained in:
		
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 509 B After Width: | Height: | Size: 1.5 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 668 B After Width: | Height: | Size: 2.0 KiB | 
| @@ -40,6 +40,8 @@ class AppState: ObservableObject { | |||||||
|     @Published var purchasedContentId = 0 |     @Published var purchasedContentId = 0 | ||||||
|     @Published var purchasedContentOrderType = OrderType.KEEP |     @Published var purchasedContentOrderType = OrderType.KEEP | ||||||
|      |      | ||||||
|  |     @Published var isChangeAdultContentVisible = false | ||||||
|  |      | ||||||
|     func setAppStep(step: AppStep) { |     func setAppStep(step: AppStep) { | ||||||
|         switch step { |         switch step { | ||||||
|         case .splash, .main: |         case .splash, .main: | ||||||
|   | |||||||
| @@ -38,6 +38,8 @@ enum AppStep { | |||||||
|      |      | ||||||
|     case notificationSettings |     case notificationSettings | ||||||
|      |      | ||||||
|  |     case contentViewSettings | ||||||
|  |      | ||||||
|     case signOut |     case signOut | ||||||
|      |      | ||||||
|     case canStatus(refresh: () -> Void) |     case canStatus(refresh: () -> Void) | ||||||
|   | |||||||
| @@ -14,7 +14,11 @@ struct ContentView: View { | |||||||
|         ZStack { |         ZStack { | ||||||
|             Color.black.ignoresSafeArea() |             Color.black.ignoresSafeArea() | ||||||
|              |              | ||||||
|             MainView() |             if appState.isChangeAdultContentVisible { | ||||||
|  |                 EmptyView() | ||||||
|  |             } else { | ||||||
|  |                 MainView() | ||||||
|  |             } | ||||||
|              |              | ||||||
|             switch appState.appStep { |             switch appState.appStep { | ||||||
|             case .splash: |             case .splash: | ||||||
| @@ -59,6 +63,9 @@ struct ContentView: View { | |||||||
|             case .notificationSettings: |             case .notificationSettings: | ||||||
|                 NotificationSettingsView() |                 NotificationSettingsView() | ||||||
|                  |                  | ||||||
|  |             case .contentViewSettings: | ||||||
|  |                 ContentSettingsView() | ||||||
|  |                  | ||||||
|             case .signOut: |             case .signOut: | ||||||
|                 SignOutView() |                 SignOutView() | ||||||
|                  |                  | ||||||
|   | |||||||
| @@ -23,6 +23,8 @@ enum UserDefaultsKey: String, CaseIterable { | |||||||
|     case isFollowedChannel |     case isFollowedChannel | ||||||
|     case isViewedOnboardingView |     case isViewedOnboardingView | ||||||
|     case notShowingEventPopupId |     case notShowingEventPopupId | ||||||
|  |     case isAdultContentVisible | ||||||
|  |     case contentPreference | ||||||
| } | } | ||||||
|  |  | ||||||
| extension UserDefaults { | extension UserDefaults { | ||||||
|   | |||||||
							
								
								
									
										127
									
								
								SodaLive/Sources/Settings/Content/ContentSettingsView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								SodaLive/Sources/Settings/Content/ContentSettingsView.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | |||||||
|  | // | ||||||
|  | //  ContentSettingsView.swift | ||||||
|  | //  SodaLive | ||||||
|  | // | ||||||
|  | //  Created by klaus on 10/10/24. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | import SwiftUI | ||||||
|  |  | ||||||
|  | struct ContentSettingsView: View { | ||||||
|  |      | ||||||
|  |     @StateObject var viewModel = ContentSettingsViewModel() | ||||||
|  |      | ||||||
|  |     var body: some View { | ||||||
|  |         ZStack { | ||||||
|  |             Color.black.ignoresSafeArea() | ||||||
|  |              | ||||||
|  |             VStack(spacing: 0) { | ||||||
|  |                 DetailNavigationBar(title: "콘텐츠 보기 설정") { | ||||||
|  |                     if AppState.shared.isChangeAdultContentVisible { | ||||||
|  |                         AppState.shared.setAppStep(step: .splash) | ||||||
|  |                     } else { | ||||||
|  |                         AppState.shared.back() | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                  | ||||||
|  |                 ScrollView(.vertical) { | ||||||
|  |                     VStack(spacing: 0) { | ||||||
|  |                         HStack(spacing: 0) { | ||||||
|  |                             Text("민감한 콘텐츠 보기") | ||||||
|  |                                 .font(.custom(Font.bold.rawValue, size: 15)) | ||||||
|  |                                 .foregroundColor(Color(hex: "eeeeee")) | ||||||
|  |                              | ||||||
|  |                             Spacer() | ||||||
|  |                              | ||||||
|  |                             Image(viewModel.isAdultContentVisible ? "btn_toggle_on_big" : "btn_toggle_off_big") | ||||||
|  |                                 .resizable() | ||||||
|  |                                 .frame(width: 44, height: 27) | ||||||
|  |                                 .onTapGesture { | ||||||
|  |                                     viewModel.isAdultContentVisible.toggle() | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                         .frame(height: 50) | ||||||
|  |                          | ||||||
|  |                         if viewModel.isAdultContentVisible { | ||||||
|  |                             Rectangle() | ||||||
|  |                                 .frame(height: 1) | ||||||
|  |                                 .foregroundColor(Color.gray90.opacity(0.3)) | ||||||
|  |                              | ||||||
|  |                             HStack(spacing: 0) { | ||||||
|  |                                 HStack(spacing: 13.3) { | ||||||
|  |                                     Image( | ||||||
|  |                                         viewModel.adultContentPreference == .ALL ? | ||||||
|  |                                         "btn_radio_select_selected" : | ||||||
|  |                                             "btn_radio_select_normal" | ||||||
|  |                                     ) | ||||||
|  |                                     .resizable() | ||||||
|  |                                     .frame(width: 20, height: 20) | ||||||
|  |                                      | ||||||
|  |                                     Text("전체") | ||||||
|  |                                         .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||||
|  |                                         .foregroundColor(Color.grayee) | ||||||
|  |                                 } | ||||||
|  |                                 .contentShape(Rectangle()) | ||||||
|  |                                 .onTapGesture { | ||||||
|  |                                     viewModel.adultContentPreference = .ALL | ||||||
|  |                                 } | ||||||
|  |                                  | ||||||
|  |                                 Spacer() | ||||||
|  |                                  | ||||||
|  |                                 HStack(spacing: 13.3) { | ||||||
|  |                                     Image( | ||||||
|  |                                         viewModel.adultContentPreference == .MALE ? | ||||||
|  |                                         "btn_radio_select_selected" : | ||||||
|  |                                             "btn_radio_select_normal" | ||||||
|  |                                     ) | ||||||
|  |                                     .resizable() | ||||||
|  |                                     .frame(width: 20, height: 20) | ||||||
|  |                                      | ||||||
|  |                                     Text("남성향") | ||||||
|  |                                         .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||||
|  |                                         .foregroundColor(Color.grayee) | ||||||
|  |                                 } | ||||||
|  |                                 .contentShape(Rectangle()) | ||||||
|  |                                 .onTapGesture { | ||||||
|  |                                     viewModel.adultContentPreference = .MALE | ||||||
|  |                                 } | ||||||
|  |                                  | ||||||
|  |                                 Spacer() | ||||||
|  |                                  | ||||||
|  |                                 HStack(spacing: 13.3) { | ||||||
|  |                                     Image( | ||||||
|  |                                         viewModel.adultContentPreference == .FEMALE ? | ||||||
|  |                                         "btn_radio_select_selected" : | ||||||
|  |                                             "btn_radio_select_normal" | ||||||
|  |                                     ) | ||||||
|  |                                     .resizable() | ||||||
|  |                                     .frame(width: 20, height: 20) | ||||||
|  |                                      | ||||||
|  |                                     Text("여성향") | ||||||
|  |                                         .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||||
|  |                                         .foregroundColor(Color.grayee) | ||||||
|  |                                 } | ||||||
|  |                                 .contentShape(Rectangle()) | ||||||
|  |                                 .onTapGesture { | ||||||
|  |                                     viewModel.adultContentPreference = .FEMALE | ||||||
|  |                                 } | ||||||
|  |                                 Spacer() | ||||||
|  |                             } | ||||||
|  |                             .frame(height: 50) | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     .padding(.vertical, 6.7) | ||||||
|  |                     .padding(.horizontal, 13.3) | ||||||
|  |                     .background(Color.gray22) | ||||||
|  |                     .cornerRadius(10) | ||||||
|  |                     .padding(.top, 13.3) | ||||||
|  |                     .padding(.horizontal, 13.3) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #Preview { | ||||||
|  |     ContentSettingsView() | ||||||
|  | } | ||||||
| @@ -0,0 +1,33 @@ | |||||||
|  | // | ||||||
|  | //  ContentSettingsViewModel.swift | ||||||
|  | //  SodaLive | ||||||
|  | // | ||||||
|  | //  Created by klaus on 10/10/24. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | import Foundation | ||||||
|  |  | ||||||
|  | final class ContentSettingsViewModel: ObservableObject { | ||||||
|  |     @Published var isAdultContentVisible = UserDefaults.bool(forKey: .isAdultContentVisible) { | ||||||
|  |         didSet { | ||||||
|  |             if oldValue != isAdultContentVisible { | ||||||
|  |                 UserDefaults.set(isAdultContentVisible, forKey: .isAdultContentVisible) | ||||||
|  |                 AppState.shared.isChangeAdultContentVisible = true | ||||||
|  |                  | ||||||
|  |                 if !isAdultContentVisible { | ||||||
|  |                     adultContentPreference = .ALL | ||||||
|  |                     UserDefaults.set(ContentType.ALL.rawValue, forKey: .contentPreference) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Published var adultContentPreference = ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL { | ||||||
|  |         didSet { | ||||||
|  |             if oldValue != adultContentPreference { | ||||||
|  |                 UserDefaults.set(adultContentPreference.rawValue, forKey: .contentPreference) | ||||||
|  |                 AppState.shared.isChangeAdultContentVisible = true | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								SodaLive/Sources/Settings/Content/ContentType.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								SodaLive/Sources/Settings/Content/ContentType.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | // | ||||||
|  | //  ContentType.swift | ||||||
|  | //  SodaLive | ||||||
|  | // | ||||||
|  | //  Created by klaus on 10/10/24. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | enum ContentType: String, Codable { | ||||||
|  |     // 전체 | ||||||
|  |     case ALL | ||||||
|  |      | ||||||
|  |     // 남성향 | ||||||
|  |     case MALE | ||||||
|  |      | ||||||
|  |     // 여성향 | ||||||
|  |     case FEMALE | ||||||
|  | } | ||||||
| @@ -89,6 +89,29 @@ struct SettingsView: View { | |||||||
|                     .cornerRadius(6.7) |                     .cornerRadius(6.7) | ||||||
|                     .padding(.top, 26.7) |                     .padding(.top, 26.7) | ||||||
|                      |                      | ||||||
|  |                     if UserDefaults.bool(forKey: .auth) { | ||||||
|  |                         HStack(spacing: 0) { | ||||||
|  |                             Text("콘텐츠 보기 설정") | ||||||
|  |                                 .font(.custom(Font.bold.rawValue, size: 14.7)) | ||||||
|  |                                 .foregroundColor(Color.grayee) | ||||||
|  |                              | ||||||
|  |                             Spacer() | ||||||
|  |                              | ||||||
|  |                             Image("ic_forward") | ||||||
|  |                                 .resizable() | ||||||
|  |                                 .frame(width: 20, height: 20) | ||||||
|  |                         } | ||||||
|  |                         .padding(.horizontal, 16.7) | ||||||
|  |                         .frame(width: cardWidth, height: 50) | ||||||
|  |                         .background(Color.gray22) | ||||||
|  |                         .cornerRadius(6.7) | ||||||
|  |                         .contentShape(Rectangle()) | ||||||
|  |                         .padding(.top, 13.3) | ||||||
|  |                         .onTapGesture { | ||||||
|  |                             AppState.shared.setAppStep(step: .contentViewSettings) | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                      | ||||||
|                     VStack(spacing: 0) { |                     VStack(spacing: 0) { | ||||||
|                         HStack(spacing: 0) { |                         HStack(spacing: 0) { | ||||||
|                             Text("이용약관") |                             Text("이용약관") | ||||||
|   | |||||||
| @@ -58,6 +58,9 @@ struct SplashView: View { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         .onAppear { |         .onAppear { | ||||||
|  |             DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { | ||||||
|  |                 AppState.shared.isChangeAdultContentVisible = false | ||||||
|  |             } | ||||||
|             fetchLastestVersion() |             fetchLastestVersion() | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung