feat: 메인 라이브
- 최근 종료한 라이브 UI 추가
This commit is contained in:
		
							
								
								
									
										51
									
								
								SodaLive/Sources/Live/LatestFinishedLiveItemView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								SodaLive/Sources/Live/LatestFinishedLiveItemView.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					//  LatestFinishedLiveItemView.swift
 | 
				
			||||||
 | 
					//  SodaLive
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//  Created by klaus on 7/22/25.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import SwiftUI
 | 
				
			||||||
 | 
					import Kingfisher
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct LatestFinishedLiveItemView: View {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    let item: GetLatestFinishedLiveResponse
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    var body: some View {
 | 
				
			||||||
 | 
					        VStack(spacing: 0) {
 | 
				
			||||||
 | 
					            KFImage(URL(string: item.profileImageUrl))
 | 
				
			||||||
 | 
					                .cancelOnDisappear(true)
 | 
				
			||||||
 | 
					                .resizable()
 | 
				
			||||||
 | 
					                .scaledToFill()
 | 
				
			||||||
 | 
					                .frame(width: 84, height: 84, alignment: .top)
 | 
				
			||||||
 | 
					                .clipShape(Circle())
 | 
				
			||||||
 | 
					                           
 | 
				
			||||||
 | 
					            Text(item.nickname)
 | 
				
			||||||
 | 
					                .font(.custom(Font.preRegular.rawValue, size: 16))
 | 
				
			||||||
 | 
					                .foregroundColor(.white)
 | 
				
			||||||
 | 
					                .padding(.top, 20)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            Spacer()
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            Text(item.timeAgo)
 | 
				
			||||||
 | 
					                .font(.custom(Font.preRegular.rawValue, size: 16))
 | 
				
			||||||
 | 
					                .foregroundColor(Color(hex: "78909C"))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .padding(16)
 | 
				
			||||||
 | 
					        .frame(width: 144, height: 204)
 | 
				
			||||||
 | 
					        .background(Color(hex: "263238"))
 | 
				
			||||||
 | 
					        .cornerRadius(16)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Preview {
 | 
				
			||||||
 | 
					    LatestFinishedLiveItemView(
 | 
				
			||||||
 | 
					        item: GetLatestFinishedLiveResponse(
 | 
				
			||||||
 | 
					            memberId: 1,
 | 
				
			||||||
 | 
					            nickname: "크리에이터 1",
 | 
				
			||||||
 | 
					            profileImageUrl: "https://cf.sodalive.net/profile/34638/34638-profile-5bfc2bac-3278-48f8-b60c-1294b615f629-8832-1751707083877",
 | 
				
			||||||
 | 
					            timeAgo: "5분전"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -85,6 +85,10 @@ struct LiveView: View {
 | 
				
			|||||||
                                SectionRecommendLiveView(items: viewModel.recommendLiveItems)
 | 
					                                SectionRecommendLiveView(items: viewModel.recommendLiveItems)
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            
 | 
					                            
 | 
				
			||||||
 | 
					                            if viewModel.latestFinishedLiveItems.count > 0 {
 | 
				
			||||||
 | 
					                                SectionLatestFinishedLiveView(items: viewModel.latestFinishedLiveItems)
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            
 | 
				
			||||||
                            if viewModel.replayLiveItems.count > 0 {
 | 
					                            if viewModel.replayLiveItems.count > 0 {
 | 
				
			||||||
                                LiveReplayListView(contentList: viewModel.replayLiveItems)
 | 
					                                LiveReplayListView(contentList: viewModel.replayLiveItems)
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										68
									
								
								SodaLive/Sources/Live/SectionLatestFinishedLiveView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								SodaLive/Sources/Live/SectionLatestFinishedLiveView.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					//  SectionLatestFinishedLiveView.swift
 | 
				
			||||||
 | 
					//  SodaLive
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//  Created by klaus on 7/22/25.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import SwiftUI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SectionLatestFinishedLiveView: View {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    let items: [GetLatestFinishedLiveResponse]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    @AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    var body: some View {
 | 
				
			||||||
 | 
					        VStack(alignment: .leading, spacing: 16) {
 | 
				
			||||||
 | 
					            HStack(spacing: 0) {
 | 
				
			||||||
 | 
					                Text("최근")
 | 
				
			||||||
 | 
					                    .font(.custom(Font.preBold.rawValue, size: 24))
 | 
				
			||||||
 | 
					                    .foregroundColor(.button)
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                Text(" 종료한 라이브")
 | 
				
			||||||
 | 
					                    .font(.custom(Font.preBold.rawValue, size: 24))
 | 
				
			||||||
 | 
					                    .foregroundColor(.white)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            .padding(.horizontal, 24)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            ScrollView(.horizontal, showsIndicators: false) {
 | 
				
			||||||
 | 
					                HStack(spacing: 16) {
 | 
				
			||||||
 | 
					                    ForEach(0..<items.count, id: \.self) {
 | 
				
			||||||
 | 
					                        let item = items[$0]
 | 
				
			||||||
 | 
					                        LatestFinishedLiveItemView(item: item)
 | 
				
			||||||
 | 
					                            .onTapGesture {
 | 
				
			||||||
 | 
					                                if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
 | 
				
			||||||
 | 
					                                    AppState.shared
 | 
				
			||||||
 | 
					                                        .setAppStep(step: .creatorDetail(userId: item.memberId))
 | 
				
			||||||
 | 
					                                } else {
 | 
				
			||||||
 | 
					                                    AppState.shared
 | 
				
			||||||
 | 
					                                        .setAppStep(step: .login)
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                .padding(.horizontal, 24)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Preview {
 | 
				
			||||||
 | 
					    SectionLatestFinishedLiveView(
 | 
				
			||||||
 | 
					        items: [
 | 
				
			||||||
 | 
					            GetLatestFinishedLiveResponse(
 | 
				
			||||||
 | 
					                memberId: 1,
 | 
				
			||||||
 | 
					                nickname: "크리에이터 1",
 | 
				
			||||||
 | 
					                profileImageUrl: "https://cf.sodalive.net/profile/34638/34638-profile-5bfc2bac-3278-48f8-b60c-1294b615f629-8832-1751707083877",
 | 
				
			||||||
 | 
					                timeAgo: "5분전"
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            GetLatestFinishedLiveResponse(
 | 
				
			||||||
 | 
					                memberId: 2,
 | 
				
			||||||
 | 
					                nickname: "크리에이터 2",
 | 
				
			||||||
 | 
					                profileImageUrl: "https://cf.sodalive.net/profile/34638/34638-profile-5bfc2bac-3278-48f8-b60c-1294b615f629-8832-1751707083877",
 | 
				
			||||||
 | 
					                timeAgo: "1시간전"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user