From a2b8a105fe3a0c523bf8687f127672ec91b39a7e Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Fri, 11 Oct 2024 12:03:17 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20=EC=84=A4=EC=A0=95=20-=20UI=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../btn_radio_select_normal.png | Bin 509 -> 1493 bytes .../btn_radio_select_selected.png | Bin 668 -> 2086 bytes SodaLive/Sources/App/AppState.swift | 2 + SodaLive/Sources/App/AppStep.swift | 2 + SodaLive/Sources/ContentView.swift | 9 +- .../Extensions/UserDefaultsExtension.swift | 2 + .../Content/ContentSettingsView.swift | 127 ++++++++++++++++++ .../Content/ContentSettingsViewModel.swift | 33 +++++ .../Settings/Content/ContentType.swift | 17 +++ SodaLive/Sources/Settings/SettingsView.swift | 23 ++++ SodaLive/Sources/Splash/SplashView.swift | 3 + 11 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 SodaLive/Sources/Settings/Content/ContentSettingsView.swift create mode 100644 SodaLive/Sources/Settings/Content/ContentSettingsViewModel.swift create mode 100644 SodaLive/Sources/Settings/Content/ContentType.swift diff --git a/SodaLive/Resources/Assets.xcassets/btn_radio_select_normal.imageset/btn_radio_select_normal.png b/SodaLive/Resources/Assets.xcassets/btn_radio_select_normal.imageset/btn_radio_select_normal.png index 40f508ac966062c49d4154dd31575a7b3d1d66f6..c27ca436a52c5fd934b8a0fb25e3debaab7cdd96 100644 GIT binary patch delta 1486 zcmV;<1u^>l1Jw(V8Gi-<0027t*>V5?010qNS#tmY3ljhU3ljkVnw%H_0004VQb$4n zuFf3k00004XF*Lt006O%3;baP000GQNklAAgr&iPbU(IQ&j=gsWJ-4+uPgUWjAhGDGKFgEXoc0D)5J@OezcT+S*!N zHdD%hyt=wlM}J30x*Z=M>vnm0sZLH#vi`QUwN-VStysu>!unWzaBxuXBLV+QTz#e(SAQ|^`hWU5eRNs^OiLv}a|viH4mj54 zI^?szU-BIV1Dk+^`zATw-Q895^YgC)>Izs3Zj_R~{YRmHUl6c?-H_cFfYNu>*4CDK zOZD~jDFM~}U6hugY^)F$e-@bjdUtoX!T3ppotvA}0jU~k@V#$Sfb}V z0=~JqA*txt-rj!mp{E#e&EyE87LyHTDGOM#sDDoq>3+egvaf1YOG``Ewc{q=&nRkP z0+qtLwdBfCaqXnLMp*$Y1I(SULr^VS*UHK7v#jh|SlWG0Iq31Dj|TXP@U; zU*uZZCLNp4XZulf; zs((qlbs+8>9fWEA=k$eeMUgKBxkt%NL_^yAJzGOPC-92^`dU&RzL zl79RiU>&ZRGxk;1!mNG(+`)lQ!%pKT+ZEea|S$|^+>%WqG1ZfU@24CqlfIcspSkmC?)X4%G81w&Dfm`uzxA~ z^2W-x%!%yEEoh5AJa}Q{NZ-w>@W}#ptvo(Hu4+}*x)iXDjEpS0zkBp}DATsT$>x-B zj-_i&bVsahCvvB1DH*XvYe>?_X&aec<(vQz*G`E$e8IIRCMIg) zS=p8^5qreCU-FeC=AH479D7CcI{(QzEuiHKsur5~5`j(R>bI^6DlT1KUhWWUFUW3;6$+{Z-nznvXiR`IeKvh@ zagi7s8+-OWi5JyN3usEdoO)@!cnO#fjq7ba8Aee^_HKx5aaSqL2jXx&E3?4j2ImNFMQAP*vjFEfsr>2La7erG>}(xnAQT!C_8~1}H7^@Di$O zc#S72T)m;8;iCi+s)FLGG)INfzMY?+rwR>7g{Z8+t`-&+TAG`iW0X`-Wx(1juAk>s oJYK^~n>q4-&d$!lazeWL4|}2&Q=Oqa(_)6&w?*4Eb3)6>(_)9&u> z($do9<>lMk+t}#@jQ{`u4s=pZQvjgp6>(e$L&f^08MApt?SEA60003?NklBO8Qt+;vWG+DzAAc8Ts=KNxrNQ8*(;+<)>VPx4pmVXJ4 zLlf%fgRD$u{~P7Yw7kHt0uP4r>OZh&4=LcpmSSp3pU%Y?yJ7lg) zb=K`ttYZ%xQ@odccu8k5^uQsVOzwx-P+z>>5fcL7jc1JX!-Bz(YzT%@1r-TYp3uR7 zjwI9!ur>rWK&bU%O&_{$u!|15VzJ8|8Y{4Y1{i_@% diff --git a/SodaLive/Resources/Assets.xcassets/btn_radio_select_selected.imageset/btn_radio_select_selected.png b/SodaLive/Resources/Assets.xcassets/btn_radio_select_selected.imageset/btn_radio_select_selected.png index 57f23d15227225e1b3e3ca753b4b007263233a8d..6f39bbcd952d53c8d61056e47f6e2b00cc91711d 100644 GIT binary patch delta 2084 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 phjrdFf%iaRK8=`D%PDHLkV1f)~LJa@_ diff --git a/SodaLive/Sources/App/AppState.swift b/SodaLive/Sources/App/AppState.swift index 5321177..b10c654 100644 --- a/SodaLive/Sources/App/AppState.swift +++ b/SodaLive/Sources/App/AppState.swift @@ -40,6 +40,8 @@ class AppState: ObservableObject { @Published var purchasedContentId = 0 @Published var purchasedContentOrderType = OrderType.KEEP + @Published var isChangeAdultContentVisible = false + func setAppStep(step: AppStep) { switch step { case .splash, .main: diff --git a/SodaLive/Sources/App/AppStep.swift b/SodaLive/Sources/App/AppStep.swift index 984b40c..352fc08 100644 --- a/SodaLive/Sources/App/AppStep.swift +++ b/SodaLive/Sources/App/AppStep.swift @@ -38,6 +38,8 @@ enum AppStep { case notificationSettings + case contentViewSettings + case signOut case canStatus(refresh: () -> Void) diff --git a/SodaLive/Sources/ContentView.swift b/SodaLive/Sources/ContentView.swift index f2b1e9a..a72f775 100644 --- a/SodaLive/Sources/ContentView.swift +++ b/SodaLive/Sources/ContentView.swift @@ -14,7 +14,11 @@ struct ContentView: View { ZStack { Color.black.ignoresSafeArea() - MainView() + if appState.isChangeAdultContentVisible { + EmptyView() + } else { + MainView() + } switch appState.appStep { case .splash: @@ -59,6 +63,9 @@ struct ContentView: View { case .notificationSettings: NotificationSettingsView() + case .contentViewSettings: + ContentSettingsView() + case .signOut: SignOutView() diff --git a/SodaLive/Sources/Extensions/UserDefaultsExtension.swift b/SodaLive/Sources/Extensions/UserDefaultsExtension.swift index 3570579..6545e6e 100644 --- a/SodaLive/Sources/Extensions/UserDefaultsExtension.swift +++ b/SodaLive/Sources/Extensions/UserDefaultsExtension.swift @@ -23,6 +23,8 @@ enum UserDefaultsKey: String, CaseIterable { case isFollowedChannel case isViewedOnboardingView case notShowingEventPopupId + case isAdultContentVisible + case contentPreference } extension UserDefaults { diff --git a/SodaLive/Sources/Settings/Content/ContentSettingsView.swift b/SodaLive/Sources/Settings/Content/ContentSettingsView.swift new file mode 100644 index 0000000..9ea9e7d --- /dev/null +++ b/SodaLive/Sources/Settings/Content/ContentSettingsView.swift @@ -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() +} diff --git a/SodaLive/Sources/Settings/Content/ContentSettingsViewModel.swift b/SodaLive/Sources/Settings/Content/ContentSettingsViewModel.swift new file mode 100644 index 0000000..38888c4 --- /dev/null +++ b/SodaLive/Sources/Settings/Content/ContentSettingsViewModel.swift @@ -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 + } + } + } +} diff --git a/SodaLive/Sources/Settings/Content/ContentType.swift b/SodaLive/Sources/Settings/Content/ContentType.swift new file mode 100644 index 0000000..7873d5a --- /dev/null +++ b/SodaLive/Sources/Settings/Content/ContentType.swift @@ -0,0 +1,17 @@ +// +// ContentType.swift +// SodaLive +// +// Created by klaus on 10/10/24. +// + +enum ContentType: String, Codable { + // 전체 + case ALL + + // 남성향 + case MALE + + // 여성향 + case FEMALE +} diff --git a/SodaLive/Sources/Settings/SettingsView.swift b/SodaLive/Sources/Settings/SettingsView.swift index 8d336f0..0d52d49 100644 --- a/SodaLive/Sources/Settings/SettingsView.swift +++ b/SodaLive/Sources/Settings/SettingsView.swift @@ -89,6 +89,29 @@ struct SettingsView: View { .cornerRadius(6.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) { HStack(spacing: 0) { Text("이용약관") diff --git a/SodaLive/Sources/Splash/SplashView.swift b/SodaLive/Sources/Splash/SplashView.swift index a8796d3..e6456d7 100644 --- a/SodaLive/Sources/Splash/SplashView.swift +++ b/SodaLive/Sources/Splash/SplashView.swift @@ -58,6 +58,9 @@ struct SplashView: View { } } .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { + AppState.shared.isChangeAdultContentVisible = false + } fetchLastestVersion() } }