From 2c8485a1cde43530760f00149bfae5753251290f Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Thu, 24 Aug 2023 14:30:09 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A7=88=EC=9D=B4=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=20-=20=EA=B5=AC=EB=A7=A4=EB=AA=A9=EB=A1=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ic_heart_777.imageset/Contents.json | 21 ++++ .../ic_heart_777.imageset/ic_heart_777.png | Bin 0 -> 830 bytes .../Contents.json | 21 ++++ .../ic_message_square_777.png | Bin 0 -> 471 bytes SodaLive/Sources/App/AppStep.swift | 2 + SodaLive/Sources/ContentView.swift | 3 + SodaLive/Sources/MyPage/CanCardView.swift | 6 +- SodaLive/Sources/MyPage/MyInfoCardView.swift | 6 +- SodaLive/Sources/MyPage/MyPageResponse.swift | 1 + SodaLive/Sources/MyPage/MyPageView.swift | 5 + .../GetAudioContentOrderListResponse.swift | 25 +++++ .../MyPage/OrderList/OrderListAllView.swift | 82 ++++++++++++++ .../OrderList/OrderListAllViewModel.swift | 77 +++++++++++++ .../MyPage/OrderList/OrderListItemView.swift | 101 ++++++++++++++++++ .../MyPage/OrderList/OrderListView.swift | 46 ++++++++ .../MyPage/ReservationStatusView.swift | 6 +- 16 files changed, 399 insertions(+), 3 deletions(-) create mode 100644 SodaLive/Resources/Assets.xcassets/ic_heart_777.imageset/Contents.json create mode 100644 SodaLive/Resources/Assets.xcassets/ic_heart_777.imageset/ic_heart_777.png create mode 100644 SodaLive/Resources/Assets.xcassets/ic_message_square_777 1.imageset/Contents.json create mode 100644 SodaLive/Resources/Assets.xcassets/ic_message_square_777 1.imageset/ic_message_square_777.png create mode 100644 SodaLive/Sources/MyPage/OrderList/GetAudioContentOrderListResponse.swift create mode 100644 SodaLive/Sources/MyPage/OrderList/OrderListAllView.swift create mode 100644 SodaLive/Sources/MyPage/OrderList/OrderListAllViewModel.swift create mode 100644 SodaLive/Sources/MyPage/OrderList/OrderListItemView.swift create mode 100644 SodaLive/Sources/MyPage/OrderList/OrderListView.swift diff --git a/SodaLive/Resources/Assets.xcassets/ic_heart_777.imageset/Contents.json b/SodaLive/Resources/Assets.xcassets/ic_heart_777.imageset/Contents.json new file mode 100644 index 0000000..c0f9fff --- /dev/null +++ b/SodaLive/Resources/Assets.xcassets/ic_heart_777.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "ic_heart_777.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SodaLive/Resources/Assets.xcassets/ic_heart_777.imageset/ic_heart_777.png b/SodaLive/Resources/Assets.xcassets/ic_heart_777.imageset/ic_heart_777.png new file mode 100644 index 0000000000000000000000000000000000000000..7a37c1dc83c5a7dfef732c76ddb5388cdaa2b746 GIT binary patch literal 830 zcmV-E1Ht@>P)wUU$2K2PvVX}M&oFQ1H}5^q7!$qdA6LSpQ@vidQRHzIWZPn~_>oK|oo=`5 z1ld}f1&<8kw^?MhD%WZYqeSf15|LE+tba(M9p5W_vrtjTCEna zh+Ev+v|kUnS~^fIAUtNFc*13oxm;WqauSSjgW@iPJ&A?3Xdj?hHN*M6HpS(L(xO$k zxB4LT7qDlzD-FN|5t*0h~!l$xy@L(7_lS5u1DujG_IsSS-Fm z%GjdG!gzzE(r4{GaN%YCfOyQ@@@U>0x_-BD|ykIuub+7Ur{c zWF5OfAt``1whNQIIhNqHXQi6g0{%ssdVp}HtG0^A{wxAZUa77Ck=Pp{<>aLENj+Vj zJwQ!zexx&qPbN|}>vTH(wBBamwSm&tMrWf<`cUFmGI4B5x$SoQ>l#q(L9VQ$bAw+T z=tRn7GM`ED9-`RvO4%U7e685z_^sv?ka#E=PCaHPolfU*1CS-&SX!rq6mVBclZ)$8 zR#JWg-(^b07*qo IM6N<$g3c~;rT_o{ literal 0 HcmV?d00001 diff --git a/SodaLive/Resources/Assets.xcassets/ic_message_square_777 1.imageset/Contents.json b/SodaLive/Resources/Assets.xcassets/ic_message_square_777 1.imageset/Contents.json new file mode 100644 index 0000000..94a4c86 --- /dev/null +++ b/SodaLive/Resources/Assets.xcassets/ic_message_square_777 1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "ic_message_square_777.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SodaLive/Resources/Assets.xcassets/ic_message_square_777 1.imageset/ic_message_square_777.png b/SodaLive/Resources/Assets.xcassets/ic_message_square_777 1.imageset/ic_message_square_777.png new file mode 100644 index 0000000000000000000000000000000000000000..b4a2ed2ae1e56c696be9e08d087ea3a47345ec23 GIT binary patch literal 471 zcmV;|0Vw{7P)@QG1^T}T)h8tc$pNF* zPqK*rC-}+O$R9xS$1%<&f*^44@(kniRaI3QMbT?l@|PfrE%CC!=D@UM*dD_$%z03B z+_;75<%kv36VswKgTC*(hGA@3=zy(r>aT=-6kD>`8fP(WItzX`$~ml?7e#TOB*_6r z#PdAcG|e5A=W+`e2p!EW%W~n$;A#2}Sdk`#NO^vc;IVFa$A_(8Ty{9d z2M=5nY~-M>zQ$x@?XogI#hNmZIw^s=bCj!P5;f zxg0U{GowU~7$T@lj<_VKRE}r~;!ffs%H@dGCPASW+_^u$Rm*Aq1>ao-gNI+T%$)!L N002ovPDHLkV1fW?$ov2R literal 0 HcmV?d00001 diff --git a/SodaLive/Sources/App/AppStep.swift b/SodaLive/Sources/App/AppStep.swift index 6cd0155..37ca6d5 100644 --- a/SodaLive/Sources/App/AppStep.swift +++ b/SodaLive/Sources/App/AppStep.swift @@ -105,4 +105,6 @@ enum AppStep { case profileUpdate(refresh: () -> Void) case followingList + + case orderListAll } diff --git a/SodaLive/Sources/ContentView.swift b/SodaLive/Sources/ContentView.swift index a98af20..2f24eed 100644 --- a/SodaLive/Sources/ContentView.swift +++ b/SodaLive/Sources/ContentView.swift @@ -148,6 +148,9 @@ struct ContentView: View { case .followingList: FollowCreatorView() + case .orderListAll: + OrderListAllView() + default: EmptyView() .frame(width: 0, height: 0, alignment: .topLeading) diff --git a/SodaLive/Sources/MyPage/CanCardView.swift b/SodaLive/Sources/MyPage/CanCardView.swift index 36026f5..e97511e 100644 --- a/SodaLive/Sources/MyPage/CanCardView.swift +++ b/SodaLive/Sources/MyPage/CanCardView.swift @@ -71,7 +71,11 @@ struct CanCardView_Previews: PreviewProvider { websiteUrl: "", blogUrl: "", liveReservationCount: 0, - isAuth: false + isAuth: false, + orderList: GetAudioContentOrderListResponse( + totalCount: 0, + items: [] + ) ), refresh: {} ) diff --git a/SodaLive/Sources/MyPage/MyInfoCardView.swift b/SodaLive/Sources/MyPage/MyInfoCardView.swift index 3287d31..2de3075 100644 --- a/SodaLive/Sources/MyPage/MyInfoCardView.swift +++ b/SodaLive/Sources/MyPage/MyInfoCardView.swift @@ -88,7 +88,11 @@ struct MyInfoCardView_Previews: PreviewProvider { websiteUrl: "", blogUrl: "", liveReservationCount: 0, - isAuth: false + isAuth: false, + orderList: GetAudioContentOrderListResponse( + totalCount: 0, + items: [] + ) ), refresh: {} ) diff --git a/SodaLive/Sources/MyPage/MyPageResponse.swift b/SodaLive/Sources/MyPage/MyPageResponse.swift index 1635cf1..802608e 100644 --- a/SodaLive/Sources/MyPage/MyPageResponse.swift +++ b/SodaLive/Sources/MyPage/MyPageResponse.swift @@ -18,5 +18,6 @@ struct MyPageResponse: Decodable { let blogUrl: String? let liveReservationCount: Int let isAuth: Bool + let orderList: GetAudioContentOrderListResponse } diff --git a/SodaLive/Sources/MyPage/MyPageView.swift b/SodaLive/Sources/MyPage/MyPageView.swift index b470276..50a32a0 100644 --- a/SodaLive/Sources/MyPage/MyPageView.swift +++ b/SodaLive/Sources/MyPage/MyPageView.swift @@ -94,6 +94,11 @@ struct MyPageView: View { ReservationStatusView(data: data) .padding(.top, 33.3) + if data.orderList.totalCount > 0 { + OrderListView(items: data.orderList.items) + .padding(.top, 40) + } + ServiceCenterButtonView() .padding(.top, 40) diff --git a/SodaLive/Sources/MyPage/OrderList/GetAudioContentOrderListResponse.swift b/SodaLive/Sources/MyPage/OrderList/GetAudioContentOrderListResponse.swift new file mode 100644 index 0000000..dbd6e47 --- /dev/null +++ b/SodaLive/Sources/MyPage/OrderList/GetAudioContentOrderListResponse.swift @@ -0,0 +1,25 @@ +// +// GetAudioContentOrderListResponse.swift +// SodaLive +// +// Created by klaus on 2023/08/24. +// + +import Foundation + +struct GetAudioContentOrderListResponse: Decodable { + let totalCount: Int + let items: [GetAudioContentOrderListItem] +} + +struct GetAudioContentOrderListItem: Decodable { + let contentId: Int + let coverImageUrl: String + let title: String + let themeStr: String + let duration: String? + let isAdult: Bool + let orderType: OrderType + let likeCount: Int + let commentCount: Int +} diff --git a/SodaLive/Sources/MyPage/OrderList/OrderListAllView.swift b/SodaLive/Sources/MyPage/OrderList/OrderListAllView.swift new file mode 100644 index 0000000..1b4ba01 --- /dev/null +++ b/SodaLive/Sources/MyPage/OrderList/OrderListAllView.swift @@ -0,0 +1,82 @@ +// +// OrderListAllView.swift +// SodaLive +// +// Created by klaus on 2023/08/24. +// + +import SwiftUI + +struct OrderListAllView: View { + + @StateObject var viewModel = OrderListAllViewModel() + + var body: some View { + BaseView(isLoading: $viewModel.isLoading) { + VStack(spacing: 0) { + HStack(spacing: 0) { + Button { + AppState.shared.back() + } label: { + Image("ic_back") + .resizable() + .frame(width: 20, height: 20) + + Text("구매목록") + .font(.custom(Font.bold.rawValue, size: 18.3)) + .foregroundColor(Color(hex: "eeeeee")) + } + + Spacer() + } + .padding(.horizontal, 13.3) + .frame(height: 50) + .background(Color.black) + + ScrollViewReader { reader in + ScrollView(.vertical, showsIndicators: false) { + LazyVStack(spacing: 10.7) { + ScrollerToTop(reader: reader, scrollOnChange: $viewModel.scrollToTop) + + ForEach(0..() + + @Published var errorMessage = "" + @Published var isShowPopup = false + @Published var isLoading = false + + @Published var orderList = [GetAudioContentOrderListItem]() + @Published var scrollToTop = false + + var page = 1 + var isLast = false + private let pageSize = 10 + + func getOrderList() { + if (!isLast && !isLoading) { + isLoading = true + + repository.getOrderList(page: page, size: pageSize) + .sink { result in + switch result { + case .finished: + DEBUG_LOG("finish") + case .failure(let error): + ERROR_LOG(error.localizedDescription) + } + } receiveValue: { [unowned self] response in + let responseData = response.data + + do { + let jsonDecoder = JSONDecoder() + let decoded = try jsonDecoder.decode(ApiResponse.self, from: responseData) + + if let data = decoded.data, decoded.success { + if page == 1 { + self.orderList.removeAll() + self.scrollToTop.toggle() + } + + if !data.items.isEmpty { + page += 1 + self.orderList.append(contentsOf: data.items) + } else { + isLast = true + } + } else { + if let message = decoded.message { + self.errorMessage = message + } else { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + } + + self.isShowPopup = true + } + } catch { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + self.isShowPopup = true + } + + self.isLoading = false + } + .store(in: &subscription) + } + } +} diff --git a/SodaLive/Sources/MyPage/OrderList/OrderListItemView.swift b/SodaLive/Sources/MyPage/OrderList/OrderListItemView.swift new file mode 100644 index 0000000..107e48c --- /dev/null +++ b/SodaLive/Sources/MyPage/OrderList/OrderListItemView.swift @@ -0,0 +1,101 @@ +// +// OrderListItemView.swift +// SodaLive +// +// Created by klaus on 2023/08/24. +// + +import SwiftUI +import Kingfisher + +struct OrderListItemView: View { + + let item: GetAudioContentOrderListItem + + var body: some View { + VStack(spacing: 12) { + HStack(spacing: 10) { + ZStack(alignment: .topLeading) { + KFImage(URL(string: item.coverImageUrl)) + .resizable() + .frame(width: 66.7, height: 66.7, alignment: .center) + .clipped() + .cornerRadius(5.3) + + if item.isAdult { + Text("19") + .font(.custom(Font.bold.rawValue, size: 11.3)) + .foregroundColor(Color.white) + .padding(4) + .background(Color(hex: "e53621")) + .clipShape(Circle()) + .padding(.top, 4.3) + .padding(.leading, 4.3) + } + } + + VStack(alignment: .leading, spacing: 0) { + HStack(spacing: 8) { + Text(item.themeStr) + .font(.custom(Font.medium.rawValue, size: 8)) + .foregroundColor(Color(hex: "3bac6a")) + .padding(2.6) + .background(Color(hex: "28312b")) + .cornerRadius(2.6) + + Text(item.duration!) + .font(.custom(Font.medium.rawValue, size: 8)) + .foregroundColor(Color(hex: "777777")) + .padding(2.6) + .background(Color(hex: "222222")) + .cornerRadius(2.6) + } + + Text(item.title) + .font(.custom(Font.medium.rawValue, size: 12)) + .foregroundColor(Color(hex: "d2d2d2")) + .fixedSize(horizontal: false, vertical: true) + .padding(.top, 2.6) + .padding(.bottom, 6.7) + + HStack(spacing: 13.3) { + HStack(spacing: 6) { + Image("ic_heart_777") + .resizable() + .frame(width: 13.3, height: 13.3) + + Text("\(item.likeCount)") + .font(.custom(Font.medium.rawValue, size: 10)) + .foregroundColor(Color(hex: "777777")) + } + + HStack(spacing: 6) { + Image("ic_message_square_777") + .resizable() + .frame(width: 13.3, height: 13.3) + + Text("\(item.commentCount)") + .font(.custom(Font.medium.rawValue, size: 10)) + .foregroundColor(Color(hex: "777777")) + } + } + } + + Spacer() + + Text(item.orderType == .RENTAL ? "대여중" : "소장중") + .font(.custom(Font.medium.rawValue, size: 10.3)) + .foregroundColor(item.orderType == .RENTAL ? .white : .black) + .padding(.horizontal, 5.3) + .padding(.vertical, 2.7) + .background(Color(hex: item.orderType == .RENTAL ? "660fd4" : "b1ef2c")) + .cornerRadius(2.6) + } + + Rectangle() + .foregroundColor(Color(hex: "595959")) + .frame(maxWidth: .infinity) + .frame(height: 0.5) + } + } +} diff --git a/SodaLive/Sources/MyPage/OrderList/OrderListView.swift b/SodaLive/Sources/MyPage/OrderList/OrderListView.swift new file mode 100644 index 0000000..06d6690 --- /dev/null +++ b/SodaLive/Sources/MyPage/OrderList/OrderListView.swift @@ -0,0 +1,46 @@ +// +// OrderListView.swift +// SodaLive +// +// Created by klaus on 2023/08/24. +// + +import SwiftUI + +struct OrderListView: View { + let items: [GetAudioContentOrderListItem] + + var body: some View { + VStack(spacing: 0) { + HStack(spacing: 0) { + Text("구매목록") + .font(.custom(Font.bold.rawValue, size: 18)) + .foregroundColor(Color(hex: "eeeeee")) + + Spacer() + + Text("전체보기") + .font(.custom(Font.medium.rawValue, size: 11)) + .foregroundColor(Color(hex: "bbbbbb")) + .onTapGesture { + AppState.shared.setAppStep(step: .orderListAll) + } + } + + VStack(spacing: 13.3) { + ForEach(0..