diff --git a/SodaLive/Sources/Live/Now/All/LiveNowAllItemView.swift b/SodaLive/Sources/Live/Now/All/LiveNowAllItemView.swift index 28e69dc..8ffbb48 100644 --- a/SodaLive/Sources/Live/Now/All/LiveNowAllItemView.swift +++ b/SodaLive/Sources/Live/Now/All/LiveNowAllItemView.swift @@ -11,33 +11,39 @@ import Kingfisher struct LiveNowAllItemView: View { let item: GetRoomListResponse + let itemWidth: CGFloat var body: some View { - VStack(spacing: 13.3) { - HStack(spacing: 20) { - ZStack(alignment: .topLeading) { - KFImage(URL(string: item.coverImageUrl)) - .resizable() - .scaledToFill() - .frame(width: 80, height: 116.7, alignment: .top) - .cornerRadius(4.7) - .clipped() - } + VStack(alignment: .leading, spacing: 8) { + ZStack { + KFImage(URL(string: item.coverImageUrl)) + .resizable() + .scaledToFill() + .frame(width: itemWidth, height: itemWidth * 144 / 102, alignment: .center) + .cornerRadius(4.7) + .clipped() - VStack(alignment: .leading, spacing: 0) { - HStack(alignment: .top, spacing: 0) { - VStack(alignment: .leading, spacing: 0) { - Text(item.creatorNickname) - .font(.custom(Font.medium.rawValue, size: 11.3)) - .foregroundColor(Color(hex: "bbbbbb")) + LinearGradient( + colors: [Color.black.opacity(0.1), Color.black.opacity(0.8)], + startPoint: .top, + endPoint: .bottom + ) + + VStack(alignment: .trailing, spacing: 0) { + HStack(spacing: 0) { + HStack(spacing: 1) { + if item.price > 0 { + Image("ic_can_white") + } - Text(item.title) - .font(.custom(Font.medium.rawValue, size: 15.3)) - .foregroundColor(Color(hex: "e2e2e2")) - .lineLimit(2) - .padding(.top, 4.3) - .padding(.trailing, 20) + Text(item.price > 0 ? "\(item.price)" : "무료") + .font(.custom(Font.medium.rawValue, size: 12)) + .foregroundColor(Color.white) } + .padding(.horizontal, 7.3) + .padding(.vertical, 4) + .background(item.price > 0 ? Color.mainRed3 : Color.gray11) + .cornerRadius(13.3) Spacer() @@ -45,48 +51,92 @@ struct LiveNowAllItemView: View { Image("ic_lock") .resizable() .frame(width: 20, height: 20) + .padding(2.7) + .background(Color.gray33.opacity(0.7)) + .clipShape(Circle()) } } - .padding(.top, 13.3) + .padding(.horizontal, 3.3) + .padding(.top, 3.3) Spacer() - HStack(spacing: 0) { - Text(item.numberOfPeople > item.numberOfParticipate ? "참여가능" : "Sold out") - .font(.custom(Font.medium.rawValue, size: 13.3)) - .foregroundColor( - Color( - hex: item.numberOfPeople > item.numberOfParticipate ? - "3bb9f1" : - "ffd300" - ) - ) - - Spacer() - - if item.price > 0 { - Text("\(item.price)") - .font(.custom(Font.bold.rawValue, size: 15.3)) - .foregroundColor(Color(hex: "eeeeee")) + if item.numberOfPeople - item.numberOfParticipate < 3 { + HStack(spacing: 0) { + Spacer() - Image("ic_can") - .resizable() - .frame(width: 20, height: 20) - .padding(.leading, 6.7) - } else { - Text("무료") - .font(.custom(Font.bold.rawValue, size: 15.3)) - .foregroundColor(Color(hex: "eeeeee")) + HStack(spacing: 2) { + Text("잔여") + .font(.custom(Font.medium.rawValue, size: 12)) + .foregroundColor(Color.grayee) + + Text("\(item.numberOfPeople - item.numberOfParticipate)") + .font(.custom(Font.medium.rawValue, size: 12)) + .foregroundColor(Color.button) + } + .padding(.horizontal, 4) + .padding(.vertical, 3) + .background(Color.gray33.opacity(0.7)) + .cornerRadius(13.3) } + .padding(.horizontal, 3.3) + .padding(.bottom, 3.3) } - .padding(.bottom, 3.3) } } + .frame(width: itemWidth, height: itemWidth * 144 / 102) - Rectangle() - .foregroundColor(Color(hex: "909090").opacity(0.5)) - .frame(width: screenSize().width - 26.7, height: 1) + Text("\(item.title)") + .font(.custom(Font.medium.rawValue, size: 12)) + .foregroundColor(Color(hex: "eeeeee")) + .lineLimit(2) + .fixedSize(horizontal: false, vertical: true) + + if item.tags.count > 0 { + Text("\(item.tags.map { "#\($0)" }.joined(separator: " "))") + .font(.custom(Font.medium.rawValue, size: 11)) + .foregroundColor(Color.button) + } + + HStack(spacing: 5.3) { + KFImage(URL(string: item.creatorProfileImage)) + .resizable() + .scaledToFill() + .frame(width: 21.3, height: 21.3, alignment: .center) + .clipShape(Circle()) + + Text("\(item.creatorNickname)") + .font(.custom(Font.medium.rawValue, size: 10)) + .foregroundColor(Color.gray77) + } } - .frame(width: screenSize().width - 26.7, height: 130, alignment: .center) + .frame(width: itemWidth) } } + +struct LiveNowAllItemView_Previews: PreviewProvider { + static var previews: some View { + LiveNowAllItemView( + item: GetRoomListResponse( + roomId: 99, + title: "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttest", + content: "testtest", + beginDateTime: "2022.05.23 Mon 03:00 PM", + numberOfParticipate: 3, + numberOfPeople: 5, + coverImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png", + isAdult: true, + price: 20, + tags: ["팬미팅", "힐링"], + channelName: nil, + creatorProfileImage: "https://test-cf.sodalive.net/profile/default-profile.png", + creatorNickname: "user8", + creatorId: 19, + isReservation: false, + isPrivateRoom: true + ), + itemWidth: 102 + ) + } +} + diff --git a/SodaLive/Sources/Live/Now/All/LiveNowAllView.swift b/SodaLive/Sources/Live/Now/All/LiveNowAllView.swift index 37baba9..f150d78 100644 --- a/SodaLive/Sources/Live/Now/All/LiveNowAllView.swift +++ b/SodaLive/Sources/Live/Now/All/LiveNowAllView.swift @@ -13,6 +13,14 @@ struct LiveNowAllView: View { @StateObject var viewModel = LiveViewModel() @StateObject var liveAllViewModel = LiveAllViewModel() + let columns = [ + GridItem(.flexible(), alignment: .top), + GridItem(.flexible(), alignment: .top), + GridItem(.flexible(), alignment: .top) + ] + + let spacing: CGFloat = 13.3 + let onClickParticipant: (Int) -> Void var body: some View { @@ -29,11 +37,11 @@ struct LiveNowAllView: View { viewModel.getLiveNowList() }, content: { - VStack(spacing: 13.3) { + LazyVGrid(columns: columns, spacing: spacing) { ForEach(0..