콘텐츠 메인, 라이브 메인, 오디션 메인, 마이페이지

- 로그인 하지 않고 페이지 조회가 되도록 수정
This commit is contained in:
Yu Sung 2025-03-24 18:32:27 +09:00
parent fa94c5447f
commit 80cb19a1c7
32 changed files with 874 additions and 595 deletions

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_logo_circle_gray.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -12,6 +12,8 @@ enum AppStep {
case main case main
case login
case signUp case signUp
case findPassword case findPassword

View File

@ -89,6 +89,12 @@ extension AuditionApi: TargetType {
} }
var headers: [String : String]? { var headers: [String : String]? {
switch self {
case .getAuditionList:
return nil
default:
return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"] return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"]
} }
} }
}

View File

@ -11,16 +11,19 @@ struct AuditionView: View {
@StateObject var viewModel = AuditionViewModel() @StateObject var viewModel = AuditionViewModel()
@AppStorage("isAuditionNotification") private var isAuditionNotification: Bool = UserDefaults.bool(forKey: .isAuditionNotification) @AppStorage("isAuditionNotification") private var isAuditionNotification: Bool = UserDefaults.bool(forKey: .isAuditionNotification)
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
BaseView(isLoading: $viewModel.isLoading) { BaseView(isLoading: $viewModel.isLoading) {
VStack(spacing: 0) { VStack(spacing: 0) {
HomeNavigationBar(title: "오디션") { HomeNavigationBar(title: "오디션") {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
Image(isAuditionNotification ? "btn_audition_notification_selected" : "btn_audition_notification_normal") Image(isAuditionNotification ? "btn_audition_notification_selected" : "btn_audition_notification_normal")
.onTapGesture { .onTapGesture {
viewModel.updateNotificationSettings() viewModel.updateNotificationSettings()
} }
} }
}
HStack(spacing: 0) { HStack(spacing: 0) {
Text("보이스온 오디션 이용방법") Text("보이스온 오디션 이용방법")
@ -70,12 +73,17 @@ struct AuditionView: View {
AuditionItemView(item: item) AuditionItemView(item: item)
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
if !item.isOff { if !item.isOff {
AppState.shared AppState.shared
.setAppStep( .setAppStep(
step: .auditionDetail(auditionId: item.id) step: .auditionDetail(auditionId: item.id)
) )
} }
} else {
AppState.shared
.setAppStep(step: .login)
}
} }
} }
} else if $0 == viewModel.firstIsOffIndex { } else if $0 == viewModel.firstIsOffIndex {
@ -104,24 +112,21 @@ struct AuditionView: View {
AuditionItemView(item: item) AuditionItemView(item: item)
.padding(.top, 25) .padding(.top, 25)
.onTapGesture {
if !item.isOff {
AppState.shared
.setAppStep(
step: .auditionDetail(auditionId: item.id)
)
}
}
} }
} else { } else {
AuditionItemView(item: item) AuditionItemView(item: item)
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
if !item.isOff { if !item.isOff {
AppState.shared AppState.shared
.setAppStep( .setAppStep(
step: .auditionDetail(auditionId: item.id) step: .auditionDetail(auditionId: item.id)
) )
} }
} else {
AppState.shared
.setAppStep(step: .login)
}
} }
} }

View File

@ -41,6 +41,7 @@ enum ContentApi {
case getContentMainHome(isAdultContentVisible: Bool, contentType: ContentType) case getContentMainHome(isAdultContentVisible: Bool, contentType: ContentType)
case getPopularContentByCreator(creatorId: Int, isAdultContentVisible: Bool, contentType: ContentType) case getPopularContentByCreator(creatorId: Int, isAdultContentVisible: Bool, contentType: ContentType)
case getContentMainHomeContentRanking(isAdultContentVisible: Bool, contentType: ContentType, sortType: String)
case getContentMainSeries(isAdultContentVisible: Bool, contentType: ContentType) case getContentMainSeries(isAdultContentVisible: Bool, contentType: ContentType)
case getRecommendSeriesListByGenre(genreId: Int, isAdultContentVisible: Bool, contentType: ContentType) case getRecommendSeriesListByGenre(genreId: Int, isAdultContentVisible: Bool, contentType: ContentType)
@ -168,6 +169,9 @@ extension ContentApi: TargetType {
case .getPopularContentByCreator: case .getPopularContentByCreator:
return "/v2/audio-content/main/home/popular-content-by-creator" return "/v2/audio-content/main/home/popular-content-by-creator"
case .getContentMainHomeContentRanking:
return "/v2/audio-content/main/home/content/ranking"
case .getContentMainSeries: case .getContentMainSeries:
return "/v2/audio-content/main/series" return "/v2/audio-content/main/series"
@ -238,7 +242,7 @@ extension ContentApi: TargetType {
case .getMainBannerList, .getMainOrderList, .getNewContentUploadCreatorList, .getCurationList, .getAudioContentByTheme: case .getMainBannerList, .getMainOrderList, .getNewContentUploadCreatorList, .getCurationList, .getAudioContentByTheme:
return .get return .get
case .getContentMainHome, .getPopularContentByCreator, .getContentMainSeries, .getRecommendSeriesListByGenre, .getRecommendSeriesByCreator, .getContentMainContent, case .getContentMainHome, .getPopularContentByCreator, .getContentMainHomeContentRanking, .getContentMainSeries, .getRecommendSeriesListByGenre, .getRecommendSeriesByCreator, .getContentMainContent,
.getContentMainNewContentOfTheme, .getDailyContentRanking, .getRecommendContentByTag, .getContentMainAlarm, .getContentMainAlarmAll, .getContentMainNewContentOfTheme, .getDailyContentRanking, .getRecommendContentByTag, .getContentMainAlarm, .getContentMainAlarmAll,
.getContentMainAsmr, .getPopularAsmrContentByCreator, .getContentMainReplay, .getPopularReplayContentByCreator, .getContentMainAsmr, .getPopularAsmrContentByCreator, .getContentMainReplay, .getPopularReplayContentByCreator,
.getContentMainFree, .getIntroduceCreatorList, .getNewFreeContentOfTheme, .getPopularFreeContentByCreator, .getCompletedSeries, .getContentMainContentPopularContentByCreator: .getContentMainFree, .getIntroduceCreatorList, .getNewFreeContentOfTheme, .getPopularFreeContentByCreator, .getCompletedSeries, .getContentMainContentPopularContentByCreator:
@ -439,6 +443,15 @@ extension ContentApi: TargetType {
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
case .getContentMainHomeContentRanking(let isAdultContentVisible, let contentType, let sortType):
let parameters = [
"sort-type": sortType,
"isAdultContentVisible": isAdultContentVisible,
"contentType": contentType
] as [String : Any]
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
case .getRecommendSeriesByCreator(let creatorId, let isAdultContentVisible, let contentType): case .getRecommendSeriesByCreator(let creatorId, let isAdultContentVisible, let contentType):
let parameters = [ let parameters = [
"creatorId": creatorId, "creatorId": creatorId,

View File

@ -11,6 +11,8 @@ import Kingfisher
struct ContentMainTabRankContentView: View { struct ContentMainTabRankContentView: View {
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
let rows = [ let rows = [
GridItem(.fixed(60), alignment: .leading), GridItem(.fixed(60), alignment: .leading),
GridItem(.fixed(60), alignment: .leading), GridItem(.fixed(60), alignment: .leading),
@ -92,9 +94,13 @@ struct ContentMainTabRankContentView: View {
.frame(width: screenSize().width * 0.66, alignment: .leading) .frame(width: screenSize().width * 0.66, alignment: .leading)
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture { .onTapGesture {
AppState if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
.shared AppState.shared
.setAppStep(step: .contentDetail(contentId: content.contentId)) .setAppStep(step: .contentDetail(contentId: content.contentId))
} else {
AppState.shared
.setAppStep(step: .login)
}
} }
} }
} }

View File

@ -10,6 +10,8 @@ import Kingfisher
struct ContentByChannelView: View { struct ContentByChannelView: View {
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
let title: String let title: String
let creatorList: [ContentCreatorResponse] let creatorList: [ContentCreatorResponse]
let contentList: [GetAudioContentRankingItem] let contentList: [GetAudioContentRankingItem]
@ -111,15 +113,23 @@ struct ContentByChannelView: View {
.foregroundColor(.gray77) .foregroundColor(.gray77)
} }
.onTapGesture { .onTapGesture {
AppState if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
.shared AppState.shared
.setAppStep(step: .creatorDetail(userId: content.creatorId)) .setAppStep(step: .creatorDetail(userId: content.creatorId))
} else {
AppState.shared
.setAppStep(step: .login)
}
} }
} }
.onTapGesture { .onTapGesture {
AppState if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
.shared AppState.shared
.setAppStep(step: .contentDetail(contentId: content.contentId)) .setAppStep(step: .contentDetail(contentId: content.contentId))
} else {
AppState.shared
.setAppStep(step: .login)
}
} }
} }
} }

View File

@ -31,4 +31,14 @@ class ContentMainTabHomeRepository {
) )
) )
} }
func getContentRanking(sortType: String = "매출") -> AnyPublisher<Response, MoyaError> {
return api.requestPublisher(
.getContentMainHomeContentRanking(
isAdultContentVisible: UserDefaults.isAdultContentVisible(),
contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL,
sortType: sortType
)
)
}
} }

View File

@ -10,6 +10,7 @@ import SwiftUI
struct ContentMainTabHomeView: View { struct ContentMainTabHomeView: View {
@StateObject var viewModel = ContentMainTabHomeViewModel() @StateObject var viewModel = ContentMainTabHomeViewModel()
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
BaseView(isLoading: $viewModel.isLoading) { BaseView(isLoading: $viewModel.isLoading) {
@ -29,11 +30,13 @@ struct ContentMainTabHomeView: View {
Spacer() Spacer()
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
Image("ic_content_keep") Image("ic_content_keep")
.onTapGesture { .onTapGesture {
AppState.shared.setAppStep(step: .myBox(currentTab: .orderlist)) AppState.shared.setAppStep(step: .myBox(currentTab: .orderlist))
} }
} }
}
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
if let notice = viewModel.noticeItem { if let notice = viewModel.noticeItem {
@ -45,12 +48,14 @@ struct ContentMainTabHomeView: View {
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
} }
if viewModel.bannerList.count > 0 { if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty &&
viewModel.bannerList.count > 0 {
ContentMainBannerViewV2(bannerList: viewModel.bannerList) ContentMainBannerViewV2(bannerList: viewModel.bannerList)
.padding(.top, 30) .padding(.top, 30)
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
} }
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
HStack(spacing: 0) { HStack(spacing: 0) {
Image("ic_title_search_black") Image("ic_title_search_black")
@ -192,6 +197,7 @@ struct ContentMainTabHomeView: View {
.cornerRadius(5.3) .cornerRadius(5.3)
.padding(.top, 30) .padding(.top, 30)
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
}
if let response = viewModel.rankCreatorResponse { if let response = viewModel.rankCreatorResponse {
ContentMainTabHomeRankCreatorView(response: response) ContentMainTabHomeRankCreatorView(response: response)
@ -210,7 +216,11 @@ struct ContentMainTabHomeView: View {
title: "인기 단편", title: "인기 단편",
isMore: true, isMore: true,
onClickMore: { onClickMore: {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep(step: .contentRankingAll) AppState.shared.setAppStep(step: .contentRankingAll)
} else {
AppState.shared.setAppStep(step: .login)
}
}, },
sortList: !viewModel.rankSortTypeList.isEmpty ? sortList: !viewModel.rankSortTypeList.isEmpty ?
viewModel.rankSortTypeList : viewModel.rankSortTypeList :
@ -221,7 +231,8 @@ struct ContentMainTabHomeView: View {
.padding(.top, 30) .padding(.top, 30)
} }
if viewModel.eventBannerList.count > 0 { if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty &&
viewModel.eventBannerList.count > 0 {
SectionEventBannerView(items: viewModel.eventBannerList) SectionEventBannerView(items: viewModel.eventBannerList)
.padding(.top, 30) .padding(.top, 30)
} }

View File

@ -11,7 +11,6 @@ import Combine
final class ContentMainTabHomeViewModel: ObservableObject { final class ContentMainTabHomeViewModel: ObservableObject {
private let repository = ContentMainTabHomeRepository() private let repository = ContentMainTabHomeRepository()
private let contentRepository = ContentRepository()
private var subscription = Set<AnyCancellable>() private var subscription = Set<AnyCancellable>()
@Published var errorMessage = "" @Published var errorMessage = ""
@ -77,7 +76,7 @@ final class ContentMainTabHomeViewModel: ObservableObject {
func getContentRanking(sort: String = "매출") { func getContentRanking(sort: String = "매출") {
isLoading = true isLoading = true
contentRepository.getContentRanking(page: 1, size: 12, sortType: sort) repository.getContentRanking(sortType: sort)
.sink { result in .sink { result in
switch result { switch result {
case .finished: case .finished:
@ -90,10 +89,10 @@ final class ContentMainTabHomeViewModel: ObservableObject {
do { do {
let jsonDecoder = JSONDecoder() let jsonDecoder = JSONDecoder()
let decoded = try jsonDecoder.decode(ApiResponse<GetAudioContentRanking>.self, from: responseData) let decoded = try jsonDecoder.decode(ApiResponse<[GetAudioContentRankingItem]>.self, from: responseData)
if let data = decoded.data, decoded.success { if let data = decoded.data, decoded.success {
self.rankContentList = data.items self.rankContentList = data
} else { } else {
if let message = decoded.message { if let message = decoded.message {
self.errorMessage = message self.errorMessage = message

View File

@ -10,6 +10,8 @@ import Kingfisher
struct ContentMainTabHomeRankCreatorView: View { struct ContentMainTabHomeRankCreatorView: View {
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
let response: GetExplorerSectionResponse let response: GetExplorerSectionResponse
let rankingCrawns = ["ic_crown_1", "ic_crown_2", "ic_crown_3"] let rankingCrawns = ["ic_crown_1", "ic_crown_2", "ic_crown_3"]
@ -121,8 +123,13 @@ struct ContentMainTabHomeRankCreatorView: View {
} }
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared AppState.shared
.setAppStep(step: .creatorDetail(userId: creator.id)) .setAppStep(step: .creatorDetail(userId: creator.id))
} else {
AppState.shared
.setAppStep(step: .login)
}
} }
} }
} }

View File

@ -17,13 +17,16 @@ struct ContentView: View {
if appState.isChangeAdultContentVisible { if appState.isChangeAdultContentVisible {
EmptyView() EmptyView()
} else { } else {
MainView() HomeView()
} }
switch appState.appStep { switch appState.appStep {
case .splash: case .splash:
SplashView() SplashView()
case .login:
LoginView()
case .signUp: case .signUp:
SignUpView() SignUpView()

View File

@ -12,6 +12,7 @@ struct SectionEventBannerView: View {
@State private var currentIndex = 0 @State private var currentIndex = 0
@State private var timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect() @State private var timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
let items: [EventItem] let items: [EventItem]
@ -38,11 +39,15 @@ struct SectionEventBannerView: View {
) )
.tag(index) .tag(index)
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
if let _ = item.detailImageUrl { if let _ = item.detailImageUrl {
AppState.shared.setAppStep(step: .eventDetail(event: item)) AppState.shared.setAppStep(step: .eventDetail(event: item))
} else if let link = item.link, link.trimmingCharacters(in: .whitespaces).count > 0, let url = URL(string: link), UIApplication.shared.canOpenURL(url) { } else if let link = item.link, link.trimmingCharacters(in: .whitespaces).count > 0, let url = URL(string: link), UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url) UIApplication.shared.open(url)
} }
} else {
AppState.shared.setAppStep(step: .login)
}
} }
} else { } else {
KFImage(URL(string: item.thumbnailImageUrl)) KFImage(URL(string: item.thumbnailImageUrl))
@ -62,11 +67,15 @@ struct SectionEventBannerView: View {
) )
.tag(index) .tag(index)
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
if let _ = item.detailImageUrl { if let _ = item.detailImageUrl {
AppState.shared.setAppStep(step: .eventDetail(event: item)) AppState.shared.setAppStep(step: .eventDetail(event: item))
} else if let link = item.link, link.trimmingCharacters(in: .whitespaces).count > 0, let url = URL(string: link), UIApplication.shared.canOpenURL(url) { } else if let link = item.link, link.trimmingCharacters(in: .whitespaces).count > 0, let url = URL(string: link), UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url) UIApplication.shared.open(url)
} }
} else {
AppState.shared.setAppStep(step: .login)
}
} }
} }
} }

View File

@ -12,6 +12,7 @@ struct LiveView: View {
@StateObject var viewModel = LiveViewModel() @StateObject var viewModel = LiveViewModel()
@StateObject var appState = AppState.shared @StateObject var appState = AppState.shared
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
ZStack { ZStack {
@ -44,9 +45,13 @@ struct LiveView: View {
} }
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep( AppState.shared.setAppStep(
step: .contentAllByTheme(themeId: 7) step: .contentAllByTheme(themeId: 7)
) )
} else {
AppState.shared.setAppStep(step: .login)
}
} }
if viewModel.recommendChannelItems.count > 0 { if viewModel.recommendChannelItems.count > 0 {
@ -61,10 +66,18 @@ struct LiveView: View {
SectionLiveNowView( SectionLiveNowView(
items: viewModel.liveNowItems, items: viewModel.liveNowItems,
onClickParticipant: { onClickParticipant: {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
viewModel.enterLiveRoom(roomId: $0) viewModel.enterLiveRoom(roomId: $0)
} else {
AppState.shared.setAppStep(step: .login)
}
}, },
onTapCreateLive: { onTapCreateLive: {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep(step: .createLive(timeSettingMode: .NOW, onSuccess: onCreateSuccess)) AppState.shared.setAppStep(step: .createLive(timeSettingMode: .NOW, onSuccess: onCreateSuccess))
} else {
AppState.shared.setAppStep(step: .login)
}
}, },
onClickRefresh: { onClickRefresh: {
viewModel.getSummary() viewModel.getSummary()
@ -82,12 +95,26 @@ struct LiveView: View {
SectionLiveReservationView( SectionLiveReservationView(
items: viewModel.liveReservationItems, items: viewModel.liveReservationItems,
onClickCancel: { viewModel.getSummary() }, onClickCancel: { viewModel.getSummary() },
onClickStart: { roomId in processStart(roomId: roomId) }, onClickStart: { roomId in
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
processStart(roomId: roomId)
} else {
AppState.shared.setAppStep(step: .login)
}
},
onClickReservation: { roomId in onClickReservation: { roomId in
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
viewModel.reservationLiveRoom(roomId: roomId) viewModel.reservationLiveRoom(roomId: roomId)
} else {
AppState.shared.setAppStep(step: .login)
}
}, },
onTapCreateLive: { onTapCreateLive: {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep(step: .createLive(timeSettingMode: .RESERVATION, onSuccess: onCreateSuccess)) AppState.shared.setAppStep(step: .createLive(timeSettingMode: .RESERVATION, onSuccess: onCreateSuccess))
} else {
AppState.shared.setAppStep(step: .login)
}
} }
) )
} }
@ -102,7 +129,11 @@ struct LiveView: View {
.padding(.trailing, 16) .padding(.trailing, 16)
.padding(.bottom, 16) .padding(.bottom, 16)
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep(step: .createLive(timeSettingMode: .NOW, onSuccess: onCreateSuccess)) AppState.shared.setAppStep(step: .createLive(timeSettingMode: .NOW, onSuccess: onCreateSuccess))
} else {
AppState.shared.setAppStep(step: .login)
}
} }
} }
} }

View File

@ -84,10 +84,17 @@ final class LiveViewModel: ObservableObject {
} }
func getSummary() { func getSummary() {
if !UserDefaults.string(forKey: UserDefaultsKey.token).trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
getFollowedChannelList() getFollowedChannelList()
}
getRecommendChannelList() getRecommendChannelList()
getRecommendLive() getRecommendLive()
if !UserDefaults.string(forKey: UserDefaultsKey.token).trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
getLatestPostListFromCreatorsYouFollow() getLatestPostListFromCreatorsYouFollow()
}
isLoading = true isLoading = true
eventBannerItems.removeAll() eventBannerItems.removeAll()

View File

@ -15,6 +15,8 @@ struct SectionLiveNowView: View {
let onTapCreateLive: () -> Void let onTapCreateLive: () -> Void
let onClickRefresh: () -> Void let onClickRefresh: () -> Void
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
LazyVStack(spacing: 13.3) { LazyVStack(spacing: 13.3) {
HStack(spacing: 0) { HStack(spacing: 0) {
@ -45,6 +47,7 @@ struct SectionLiveNowView: View {
LiveNowItemView(item: item) LiveNowItemView(item: item)
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep( AppState.shared.setAppStep(
step: .liveDetail( step: .liveDetail(
roomId: item.roomId, roomId: item.roomId,
@ -59,6 +62,9 @@ struct SectionLiveNowView: View {
} }
) )
) )
} else {
AppState.shared.setAppStep(step: .login)
}
} }
} }
} }

View File

@ -13,6 +13,7 @@ struct SectionRecommendLiveView: View {
let items: [GetRecommendLiveResponse] let items: [GetRecommendLiveResponse]
@State private var currentIndex = 0 @State private var currentIndex = 0
@State private var timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect() @State private var timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
@ -27,11 +28,13 @@ struct SectionRecommendLiveView: View {
Spacer() Spacer()
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
Image("ic_message") Image("ic_message")
.onTapGesture { .onTapGesture {
AppState.shared.setAppStep(step: .message) AppState.shared.setAppStep(step: .message)
} }
} }
}
.frame(width: screenSize().width - 26.7, alignment: .leading) .frame(width: screenSize().width - 26.7, alignment: .leading)
TabView(selection: $currentIndex) { TabView(selection: $currentIndex) {
@ -53,7 +56,11 @@ struct SectionRecommendLiveView: View {
height: (screenSize().width - 26.7) * 0.53 height: (screenSize().width - 26.7) * 0.53
) )
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep(step: .creatorDetail(userId: item.creatorId)) AppState.shared.setAppStep(step: .creatorDetail(userId: item.creatorId))
} else {
AppState.shared.setAppStep(step: .login)
}
} }
.cornerRadius(4.7) .cornerRadius(4.7)
} else { } else {
@ -72,7 +79,11 @@ struct SectionRecommendLiveView: View {
height: (screenSize().width - 26.7) * 0.53 height: (screenSize().width - 26.7) * 0.53
) )
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep(step: .creatorDetail(userId: item.creatorId)) AppState.shared.setAppStep(step: .creatorDetail(userId: item.creatorId))
} else {
AppState.shared.setAppStep(step: .login)
}
} }
.cornerRadius(4.7) .cornerRadius(4.7)
} }

View File

@ -13,6 +13,7 @@ struct SectionRecommendChannelView: View {
let items: [GetRecommendChannelResponse] let items: [GetRecommendChannelResponse]
@Binding var isFollowingList: Bool @Binding var isFollowingList: Bool
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
VStack(spacing: 21.3) { VStack(spacing: 21.3) {
@ -20,22 +21,23 @@ struct SectionRecommendChannelView: View {
if isFollowingList { if isFollowingList {
Text("팔로잉 ") Text("팔로잉 ")
.font(.custom(Font.bold.rawValue, size: 18.3)) .font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(Color(hex: "eeeeee")) .foregroundColor(.grayee)
} else { } else {
Text("추천 ") Text("추천 ")
.font(.custom(Font.bold.rawValue, size: 18.3)) .font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(Color(hex: "eeeeee")) .foregroundColor(.grayee)
} }
Text("채널") Text("채널")
.font(.custom(Font.bold.rawValue, size: 18.3)) .font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(Color(hex: "3bb9f1")) .foregroundColor(.button)
Spacer() Spacer()
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
Text("팔로잉 채널") Text("팔로잉 채널")
.font(.custom(Font.medium.rawValue, size: 13.3)) .font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(Color(hex: "777777")) .foregroundColor(.gray77)
Image(isFollowingList ? "btn_toggle_on_big" : "btn_toggle_off_big") Image(isFollowingList ? "btn_toggle_on_big" : "btn_toggle_off_big")
.resizable() .resizable()
@ -45,6 +47,7 @@ struct SectionRecommendChannelView: View {
isFollowingList.toggle() isFollowingList.toggle()
} }
} }
}
.frame(width: screenSize().width - 26.7, alignment: .leading) .frame(width: screenSize().width - 26.7, alignment: .leading)
ScrollView(.horizontal, showsIndicators: false) { ScrollView(.horizontal, showsIndicators: false) {
@ -70,7 +73,7 @@ struct SectionRecommendChannelView: View {
Circle() Circle()
.strokeBorder(lineWidth: 3) .strokeBorder(lineWidth: 3)
.foregroundColor( .foregroundColor(
Color(hex: "3bb9f1") .button
.opacity(item.isOnAir ? 1 : 0) .opacity(item.isOnAir ? 1 : 0)
) )
) )
@ -81,21 +84,25 @@ struct SectionRecommendChannelView: View {
.foregroundColor(.white) .foregroundColor(.white)
.padding(.vertical, 2.7) .padding(.vertical, 2.7)
.padding(.horizontal, 5.7) .padding(.horizontal, 5.7)
.background(Color(hex: "3bb9f1")) .background(Color.button)
.cornerRadius(6.7) .cornerRadius(6.7)
} }
} }
Text(item.nickname) Text(item.nickname)
.font(.custom(Font.medium.rawValue, size: 11.3)) .font(.custom(Font.medium.rawValue, size: 11.3))
.foregroundColor(Color(hex: "bbbbbb")) .foregroundColor(Color.graybb)
.frame(width: screenSize().width * 0.18) .frame(width: screenSize().width * 0.18)
.lineLimit(1) .lineLimit(1)
} }
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep( AppState.shared.setAppStep(
step: .creatorDetail(userId: item.creatorId) step: .creatorDetail(userId: item.creatorId)
) )
} else {
AppState.shared.setAppStep(step: .login)
}
} }
} }
@ -112,11 +119,16 @@ struct SectionRecommendChannelView: View {
.lineLimit(1) .lineLimit(1)
} }
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep(step: .followingList) AppState.shared.setAppStep(step: .followingList)
} else {
AppState.shared.setAppStep(step: .login)
} }
} }
} }
} }
.padding(.horizontal, 13.3)
}
} }
} }
} }

View File

@ -15,6 +15,7 @@ struct SectionLiveReservationView: View {
let onClickStart: (Int) -> Void let onClickStart: (Int) -> Void
let onClickReservation: (Int) -> Void let onClickReservation: (Int) -> Void
let onTapCreateLive: () -> Void let onTapCreateLive: () -> Void
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
VStack(spacing: 13.3) { VStack(spacing: 13.3) {
@ -34,6 +35,7 @@ struct SectionLiveReservationView: View {
.font(.custom(Font.light.rawValue, size: 11.3)) .font(.custom(Font.light.rawValue, size: 11.3))
.foregroundColor(Color(hex: "bbbbbb")) .foregroundColor(Color(hex: "bbbbbb"))
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep( AppState.shared.setAppStep(
step: .liveReservationAll( step: .liveReservationAll(
onClickReservation: onClickReservation, onClickReservation: onClickReservation,
@ -42,6 +44,9 @@ struct SectionLiveReservationView: View {
onTapCreateLive: onTapCreateLive onTapCreateLive: onTapCreateLive
) )
) )
} else {
AppState.shared.setAppStep(step: .login)
}
} }
} }
} }
@ -57,6 +62,7 @@ struct SectionLiveReservationView: View {
MyLiveReservationItemView(item: item, index: index) MyLiveReservationItemView(item: item, index: index)
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep( AppState.shared.setAppStep(
step: .liveDetail( step: .liveDetail(
roomId: item.roomId, roomId: item.roomId,
@ -66,11 +72,15 @@ struct SectionLiveReservationView: View {
onClickCancel: onClickCancel onClickCancel: onClickCancel
) )
) )
} else {
AppState.shared.setAppStep(step: .login)
}
} }
} else { } else {
LiveReservationItemView(item: item) LiveReservationItemView(item: item)
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared.setAppStep( AppState.shared.setAppStep(
step: .liveDetail( step: .liveDetail(
roomId: item.roomId, roomId: item.roomId,
@ -80,6 +90,9 @@ struct SectionLiveReservationView: View {
onClickCancel: onClickCancel onClickCancel: onClickCancel
) )
) )
} else {
AppState.shared.setAppStep(step: .login)
}
} }
} }
} }

View File

@ -25,6 +25,7 @@ struct HomeView: View {
private let contentView = ContentMainTabHomeView() private let contentView = ContentMainTabHomeView()
@State private var isShowPlayer = false @State private var isShowPlayer = false
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
GeometryReader { proxy in GeometryReader { proxy in
@ -168,11 +169,13 @@ struct HomeView: View {
} }
} }
.onAppear { .onAppear {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
pushTokenUpdate() pushTokenUpdate()
viewModel.getMemberInfo() viewModel.getMemberInfo()
viewModel.getEventPopup() viewModel.getEventPopup()
viewModel.addAllPlaybackTracking() viewModel.addAllPlaybackTracking()
} }
}
if appState.isShowPlayer { if appState.isShowPlayer {
LiveRoomViewV2() LiveRoomViewV2()

View File

@ -1,27 +0,0 @@
//
// MainView.swift
// SodaLive
//
// Created by klaus on 2023/08/09.
//
import SwiftUI
struct MainView: View {
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View {
if token.count > 0 {
HomeView()
} else {
LoginView()
}
}
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}

View File

@ -17,10 +17,12 @@ struct MyPageView: View {
@StateObject var viewModel = MyPageViewModel() @StateObject var viewModel = MyPageViewModel()
@State private var payload = Payload() @State private var payload = Payload()
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
var body: some View { var body: some View {
BaseView(isLoading: $viewModel.isLoading) { BaseView(isLoading: $viewModel.isLoading) {
if viewModel.isShowAuthView { if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty &&
viewModel.isShowAuthView {
BootpayUI(payload: payload, requestType: BootpayRequest.TYPE_AUTHENTICATION) BootpayUI(payload: payload, requestType: BootpayRequest.TYPE_AUTHENTICATION)
.onConfirm { .onConfirm {
DEBUG_LOG("onConfirm: \($0)") DEBUG_LOG("onConfirm: \($0)")
@ -47,6 +49,7 @@ struct MyPageView: View {
GeometryReader { geo in GeometryReader { geo in
VStack { VStack {
HomeNavigationBar(title: "마이 페이지") { HomeNavigationBar(title: "마이 페이지") {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
Image("ic_settings") Image("ic_settings")
.resizable() .resizable()
.frame(width: 20, height: 20) .frame(width: 20, height: 20)
@ -54,6 +57,8 @@ struct MyPageView: View {
AppState.shared.setAppStep(step: .settings) AppState.shared.setAppStep(step: .settings)
} }
} }
}
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
RefreshableScrollView( RefreshableScrollView(
refreshing: $viewModel.isLoading, refreshing: $viewModel.isLoading,
action: { action: {
@ -206,14 +211,106 @@ struct MyPageView: View {
} }
} }
} }
} else {
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 24) {
HStack(spacing: 6.7) {
Image("ic_logo_circle_gray")
Text("Login")
.font(.custom(Font.medium.rawValue, size: 32))
.foregroundColor(.gray90)
}
.padding(20)
.frame(maxWidth: .infinity)
.background(Color.bg)
.cornerRadius(6.7)
.contentShape(Rectangle())
.padding(.horizontal, 13.3)
.padding(.top, 24)
.onTapGesture {
AppState.shared
.setAppStep(step: .login)
}
HStack(spacing: 0) {
HStack(spacing: 6.7) {
Text("0")
.font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(.grayee)
Image("ic_can")
.resizable()
.frame(width: 20, height: 20)
Image("ic_forward")
.resizable()
.frame(width: 20, height: 20)
}
.onTapGesture {
AppState.shared
.setAppStep(step: .login)
}
Spacer()
HStack(spacing: 7) {
Image("ic_coin_w")
.resizable()
.frame(width: 26.7, height: 26.7)
Text("충전")
.font(.custom(Font.bold.rawValue, size: 12))
.foregroundColor(Color(hex: "b38fff"))
}
.padding(.horizontal, 11.3)
.padding(.vertical, 7)
.overlay(
RoundedRectangle(cornerRadius: CGFloat(16.7))
.stroke(lineWidth: 1)
.foregroundColor(Color(hex: "b38fff"))
)
.cornerRadius(16.7)
.onTapGesture {
AppState.shared
.setAppStep(step: .login)
}
}
.frame(maxWidth: .infinity)
.padding(.horizontal, 13.3)
.padding(.vertical, 10)
.background(Color.gray22)
.cornerRadius(6.7)
.padding(.horizontal, 13.3)
ServiceCenterButtonView()
.padding(.horizontal, 13.3)
if let url = URL(string: "https://blog.naver.com/sodalive_official"),
UIApplication.shared.canOpenURL(url) {
Image("img_how_to_use")
.resizable()
.frame(
width: screenSize().width,
height: (200 * screenSize().width) / 1080
)
.onTapGesture {
UIApplication.shared.open(url)
}
}
}
}
}
} }
.frame(width: geo.size.width, height: geo.size.height) .frame(width: geo.size.width, height: geo.size.height)
} }
.onAppear { .onAppear {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
viewModel.getMypage() viewModel.getMypage()
} }
} }
} }
}
.popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) { .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) {
GeometryReader { geo in GeometryReader { geo in
HStack { HStack {

View File

@ -43,6 +43,6 @@ extension FaqApi: TargetType {
} }
var headers: [String : String]? { var headers: [String : String]? {
return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"] return nil
} }
} }

View File

@ -25,8 +25,9 @@ struct ServiceCenterButtonView: View {
.frame(width: 20, height: 20) .frame(width: 20, height: 20)
} }
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
.frame(width: screenSize().width - 26.7, height: 66.7) .frame(height: 66.7)
.background(Color(hex: "13181b")) .frame(maxWidth: .infinity)
.background(Color.bg)
.cornerRadius(6.7) .cornerRadius(6.7)
.onTapGesture { .onTapGesture {
AppState.shared.setAppStep(step: .serviceCenter) AppState.shared.setAppStep(step: .serviceCenter)

View File

@ -25,7 +25,7 @@ struct ServiceCenterView: View {
Text("고객센터") Text("고객센터")
.font(.custom(Font.bold.rawValue, size: 20)) .font(.custom(Font.bold.rawValue, size: 20))
.foregroundColor(Color(hex: "eeeeee")) .foregroundColor(.grayee)
HStack(spacing: 13.3) { HStack(spacing: 13.3) {
Image("ic_service_center_kakao") Image("ic_service_center_kakao")
@ -48,13 +48,14 @@ struct ServiceCenterView: View {
Rectangle() Rectangle()
.frame(width: screenSize().width, height: 6.7) .frame(width: screenSize().width, height: 6.7)
.foregroundColor(Color(hex: "232323")) .foregroundColor(.gray23)
.padding(.vertical, 20) .padding(.vertical, 20)
Text("자주 묻는 질문") Text("자주 묻는 질문")
.font(.custom(Font.bold.rawValue, size: 18.3)) .font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(Color(hex: "eeeeee")) .foregroundColor(.grayee)
.frame(width: screenSize().width - 26.7, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 13.3)
ServiceCenterCategoryView( ServiceCenterCategoryView(
categories: viewModel.categories, categories: viewModel.categories,

View File

@ -20,6 +20,9 @@ struct SettingsView: View {
GeometryReader { geo in GeometryReader { geo in
VStack(spacing: 0) { VStack(spacing: 0) {
DetailNavigationBar(title: "설정") DetailNavigationBar(title: "설정")
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 0) {
VStack(spacing: 0) { VStack(spacing: 0) {
HStack(spacing: 0) { HStack(spacing: 0) {
Text("공지사항") Text("공지사항")
@ -198,8 +201,6 @@ struct SettingsView: View {
.frame(width: cardWidth, alignment: .leading) .frame(width: cardWidth, alignment: .leading)
.padding(.top, 13.3) .padding(.top, 13.3)
Spacer()
Text("로그아웃") Text("로그아웃")
.font(.custom(Font.bold.rawValue, size: 14.7)) .font(.custom(Font.bold.rawValue, size: 14.7))
.foregroundColor(Color.grayee) .foregroundColor(Color.grayee)
@ -209,6 +210,7 @@ struct SettingsView: View {
.onTapGesture { .onTapGesture {
isShowLogoutDialog = true isShowLogoutDialog = true
} }
.padding(.top, 46.7)
Text("모든 기기에서 로그아웃") Text("모든 기기에서 로그아웃")
.font(.custom(Font.medium.rawValue, size: 14.7)) .font(.custom(Font.medium.rawValue, size: 14.7))
@ -228,6 +230,8 @@ struct SettingsView: View {
} }
} }
} }
}
}
if isShowLogoutDialog { if isShowLogoutDialog {
SodaDialog( SodaDialog(
@ -239,8 +243,9 @@ struct SettingsView: View {
ContentPlayerPlayManager.shared.resetPlayer() ContentPlayerPlayManager.shared.resetPlayer()
viewModel.logout { viewModel.logout {
self.isShowLogoutDialog = false self.isShowLogoutDialog = false
AppState.shared.setAppStep(step: .main)
UserDefaults.reset() UserDefaults.reset()
AppState.shared.isChangeAdultContentVisible = true
AppState.shared.setAppStep(step: .splash)
} }
}, },
cancelButtonTitle: "취소", cancelButtonTitle: "취소",
@ -260,8 +265,9 @@ struct SettingsView: View {
ContentPlayerPlayManager.shared.resetPlayer() ContentPlayerPlayManager.shared.resetPlayer()
viewModel.logoutAllDevice { viewModel.logoutAllDevice {
self.isShowLogoutAllDeviceDialog = false self.isShowLogoutAllDeviceDialog = false
AppState.shared.setAppStep(step: .main)
UserDefaults.reset() UserDefaults.reset()
AppState.shared.isChangeAdultContentVisible = true
AppState.shared.setAppStep(step: .splash)
} }
}, },
cancelButtonTitle: "취소", cancelButtonTitle: "취소",

View File

@ -56,6 +56,7 @@ final class SignOutViewModel: ObservableObject {
if decoded.success { if decoded.success {
UserDefaults.reset() UserDefaults.reset()
AppState.shared.isChangeAdultContentVisible = true
AppState.shared.setAppStep(step: .splash) AppState.shared.setAppStep(step: .splash)
} else { } else {
if let message = decoded.message { if let message = decoded.message {

View File

@ -11,6 +11,8 @@ import Kingfisher
struct SeriesListBigItemView: View { struct SeriesListBigItemView: View {
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
let item: SeriesListItem let item: SeriesListItem
let isVisibleCreator: Bool let isVisibleCreator: Bool
@ -26,8 +28,13 @@ struct SeriesListBigItemView: View {
.cornerRadius(5) .cornerRadius(5)
.clipped() .clipped()
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared AppState.shared
.setAppStep(step: .seriesDetail(seriesId: item.seriesId)) .setAppStep(step: .seriesDetail(seriesId: item.seriesId))
} else {
AppState.shared
.setAppStep(step: .login)
}
} }
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
@ -80,8 +87,13 @@ struct SeriesListBigItemView: View {
.lineLimit(1) .lineLimit(1)
} }
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
AppState.shared AppState.shared
.setAppStep(step: .creatorDetail(userId: item.creator.creatorId)) .setAppStep(step: .creatorDetail(userId: item.creator.creatorId))
} else {
AppState.shared
.setAppStep(step: .login)
}
} }
} }

View File

@ -17,7 +17,7 @@ struct LoginView: View {
var body: some View { var body: some View {
BaseView(isLoading: $viewModel.isLoading) { BaseView(isLoading: $viewModel.isLoading) {
VStack(spacing: 0) { VStack(spacing: 0) {
HomeNavigationBar(title: "로그인") {} DetailNavigationBar(title: "로그인")
Spacer() Spacer()

View File

@ -55,6 +55,8 @@ final class LoginViewModel: ObservableObject {
UserDefaults.set(data.userId, forKey: .userId) UserDefaults.set(data.userId, forKey: .userId)
UserDefaults.set(data.email, forKey: .email) UserDefaults.set(data.email, forKey: .email)
UserDefaults.set(data.token, forKey: .token) UserDefaults.set(data.token, forKey: .token)
AppState.shared.isChangeAdultContentVisible = true
AppState.shared.setAppStep(step: .splash)
} else { } else {
if let message = decoded.message { if let message = decoded.message {
self.errorMessage = message self.errorMessage = message

View File

@ -58,7 +58,8 @@ final class SignUpViewModel: ObservableObject {
UserDefaults.set(data.userId, forKey: .userId) UserDefaults.set(data.userId, forKey: .userId)
UserDefaults.set(data.email, forKey: .email) UserDefaults.set(data.email, forKey: .email)
UserDefaults.set(data.token, forKey: .token) UserDefaults.set(data.token, forKey: .token)
AppState.shared.back() AppState.shared.isChangeAdultContentVisible = true
AppState.shared.setAppStep(step: .splash)
} else { } else {
if let message = decoded.message { if let message = decoded.message {
self.errorMessage = message self.errorMessage = message