diff --git a/Qapple/Qapple.xcodeproj/project.pbxproj b/Qapple/Qapple.xcodeproj/project.pbxproj index e18952ee..a9d72c93 100644 --- a/Qapple/Qapple.xcodeproj/project.pbxproj +++ b/Qapple/Qapple.xcodeproj/project.pbxproj @@ -402,9 +402,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Qapple/QappleBox/Qapple.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 2503091219; + CURRENT_PROJECT_VERSION = 2505142036; DEVELOPMENT_ASSET_PATHS = "\"Qapple/Resource/Preview Content\""; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = G9WTRLK7PY; @@ -425,11 +425,11 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.1.0; + MARKETING_VERSION = 2.1.3; PRODUCT_BUNDLE_IDENTIFIER = "com.qapple.Apple-Developer-Academy-POSTECH"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Qapple+Development"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Qapple+Distribution"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; @@ -449,9 +449,9 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Qapple/QappleBox/Qapple.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 2503091219; + CURRENT_PROJECT_VERSION = 2505142036; DEVELOPMENT_ASSET_PATHS = "\"Qapple/Resource/Preview Content\""; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = G9WTRLK7PY; @@ -472,11 +472,11 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.1.0; + MARKETING_VERSION = 2.1.3; PRODUCT_BUNDLE_IDENTIFIER = "com.qapple.Apple-Developer-Academy-POSTECH"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Qapple+Development"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Qapple+Distribution"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; diff --git a/Qapple/Qapple/SourceCode/App/AppDelegate.swift b/Qapple/Qapple/SourceCode/App/AppDelegate.swift index 2d0f5575..14034138 100644 --- a/Qapple/Qapple/SourceCode/App/AppDelegate.swift +++ b/Qapple/Qapple/SourceCode/App/AppDelegate.swift @@ -29,7 +29,7 @@ extension AppDelegate { didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil ) -> Bool { #if DEBUG - RepositoryService.shared.configureServer(to: .test) + RepositoryService.shared.configureServer(to: .production) #else RepositoryService.shared.configureServer(to: .production) #endif diff --git a/Qapple/Qapple/SourceCode/Data/Repository/AnswerRepository.swift b/Qapple/Qapple/SourceCode/Data/Repository/AnswerRepository.swift index a558044c..7381a6ee 100644 --- a/Qapple/Qapple/SourceCode/Data/Repository/AnswerRepository.swift +++ b/Qapple/Qapple/SourceCode/Data/Repository/AnswerRepository.swift @@ -12,7 +12,7 @@ import Foundation struct AnswerRepository { var fetchAnswerListOfProfile: (_ threshold: Int?) async throws -> ([Answer], QappleAPI.PaginationInfo) var fetchAnswerPreviewList: (_ questionId: Int) async throws -> [Answer] - var fetchAnswerListOfQuestion: (_ questionId: Int, _ threshold: String?) async throws -> ( + var fetchAnswerListOfQuestion: (_ questionId: Int, _ threshold: Int?) async throws -> ( [Answer], QappleAPI.TotalCount, QappleAPI.PaginationInfo diff --git a/Qapple/Qapple/SourceCode/Entity/AcademyEventFor4th.swift b/Qapple/Qapple/SourceCode/Entity/AcademyEventFor4th.swift index 5b0f4ac7..08a2da1f 100644 --- a/Qapple/Qapple/SourceCode/Entity/AcademyEventFor4th.swift +++ b/Qapple/Qapple/SourceCode/Entity/AcademyEventFor4th.swift @@ -99,6 +99,11 @@ enum AcademyEventFor4th: CaseIterable { let (startDate, endDate) = period return daysBetween(startDate, endDate) + 1 } + + /// 현재 이벤트의 남은 일수를 반환합니다. + var leftDays: Int { + daysBetween(.now, self.period.1) + 1 + } } // MARK: - Helper diff --git a/Qapple/Qapple/SourceCode/Feature/1.MainFlow/MainFlowFeature.swift b/Qapple/Qapple/SourceCode/Feature/1.MainFlow/MainFlowFeature.swift index fb8c0271..22314066 100644 --- a/Qapple/Qapple/SourceCode/Feature/1.MainFlow/MainFlowFeature.swift +++ b/Qapple/Qapple/SourceCode/Feature/1.MainFlow/MainFlowFeature.swift @@ -238,7 +238,7 @@ extension MainFlowFeature { case bulletinBoard(BulletinBoardFeature) case bulletinBoardSearch(BulletinBoardSearchFeature) case bulletinBoardPost(BulletinBoardPostFeature) - case comment(CommentFeature) + case comment(BoardCommentFeature) case profileEdit(ProfileEditFeature) case myAnswerList(MyAnswerListFeature) case peopleWhoMadeQapple diff --git a/Qapple/Qapple/SourceCode/Feature/1.MainFlow/MainFlowView.swift b/Qapple/Qapple/SourceCode/Feature/1.MainFlow/MainFlowView.swift index 47d449c7..c89e6d20 100644 --- a/Qapple/Qapple/SourceCode/Feature/1.MainFlow/MainFlowView.swift +++ b/Qapple/Qapple/SourceCode/Feature/1.MainFlow/MainFlowView.swift @@ -52,7 +52,7 @@ struct MainFlowView: View { case let .bulletinBoard(store): BulletinBoardView(store: store) case let .bulletinBoardSearch(store): BulletinBoardSearchView(store: store) case let .bulletinBoardPost(store): BulletinBoardPostView(store: store) - case let .comment(store): CommentView(store: store) + case let .comment(store): BoardCommentView(store: store) case let .profileEdit(store): ProfileEditView(store: store) case let .myAnswerList(store): MyAnswerListView(store: store) case .peopleWhoMadeQapple: PeopleWhoMadeQappleView() diff --git a/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-2.TodayQuestion/TodayQuestionFeature.swift b/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-2.TodayQuestion/TodayQuestionFeature.swift index 28b1f2d9..0480c398 100644 --- a/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-2.TodayQuestion/TodayQuestionFeature.swift +++ b/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-2.TodayQuestion/TodayQuestionFeature.swift @@ -28,6 +28,7 @@ struct TodayQuestionFeature { enum Action { case onAppear case onDisappear + case active case refresh case mainQuestionResponse(Question) case answerListResponse([Answer]) @@ -58,7 +59,7 @@ struct TodayQuestionFeature { var body: some ReducerOf { Reduce { state, action in switch action { - case .onAppear, .refresh: + case .onAppear, .active, .refresh: return .run { [isFirstLaunch = state.isFirstLaunch] send in if isFirstLaunch { await send(.toggleLoading(true), animation: .bouncy) } do { diff --git a/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-2.TodayQuestion/TodayQuestionView.swift b/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-2.TodayQuestion/TodayQuestionView.swift index bc334f7c..411f7727 100644 --- a/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-2.TodayQuestion/TodayQuestionView.swift +++ b/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-2.TodayQuestion/TodayQuestionView.swift @@ -10,6 +10,8 @@ import SwiftUI struct TodayQuestionView: View { + @Environment(\.scenePhase) private var scenePhase + @Bindable var store: StoreOf var body: some View { @@ -26,6 +28,11 @@ struct TodayQuestionView: View { } .background(.second) .scrollIndicators(.hidden) + .onChange(of: scenePhase) { _, newPhase in + if newPhase == .active { + store.send(.active) + } + } .onAppear { store.send(.onAppear) } diff --git a/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-6.AnswerList/AnswerListFeature.swift b/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-6.AnswerList/AnswerListFeature.swift index a6cfea27..3cb009cf 100644 --- a/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-6.AnswerList/AnswerListFeature.swift +++ b/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-6.AnswerList/AnswerListFeature.swift @@ -79,7 +79,7 @@ struct AnswerListFeature { do { let response = try await answerRepository.fetchAnswerListOfQuestion( state.question.id, - state.paginationInfo.threshold + Int(state.paginationInfo.threshold) ) await send(.paginagionResponse(response.0, response.2)) } catch { diff --git a/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-7.AnswerCommentList/AnswerCommentView.swift b/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-7.AnswerCommentList/AnswerCommentView.swift index 32d51eca..1b3385a5 100644 --- a/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-7.AnswerCommentList/AnswerCommentView.swift +++ b/Qapple/Qapple/SourceCode/Feature/2.QuestionTab/2-7.AnswerCommentList/AnswerCommentView.swift @@ -85,51 +85,63 @@ private struct CommentListView: View { var body: some View { ZStack { - ScrollView { - LazyVStack(spacing: 0) { - seperator - // TODO: 4/14 데이터 연결 필요 -// ForEach(Array(self.store.commentList.enumerated()), id: \.offset) { index, comment in -// AnswerCommentCell( -// comment: comment, -// like: { -// store.send(.likeCommentButtonTapped(comment)) -// }, -// delete: { -// store.send(.deleteCommentButtonTapped(comment)) -// }, -// report: { -// store.send(.reportButtonTapped(comment)) -// } -// ) -// .configurePagination( -// store.commentList, -// currentIndex: index, -// hasNext: store.paginationInfo.hasNext, -// pagination: { -// store.send(.pagination) -// } -// ) -// .disabled(store.isLoading) -// -// seperator -// } - - ForEach(AnswerCommentFeature.sampleComment) { comment in - AnswerCommentCell( - comment: comment, - like: { - store.send(.likeCommentButtonTapped(comment)) - }, - delete: { - store.send(.deleteCommentButtonTapped(comment)) - }, - report: { - store.send(.reportButtonTapped(comment)) - } - ) + VStack { + seperator + + HStack { + Text("댓글") + .pretendard(.medium, 14) + .foregroundStyle(.sub3) + Spacer() + } + .padding(.top, 12) + .padding(.horizontal, 20) + + ScrollView { + LazyVStack(spacing: 0) { + // TODO: 4/14 데이터 연결 필요 + // ForEach(Array(self.store.commentList.enumerated()), id: \.offset) { index, comment in + // AnswerCommentCell( + // comment: comment, + // like: { + // store.send(.likeCommentButtonTapped(comment)) + // }, + // delete: { + // store.send(.deleteCommentButtonTapped(comment)) + // }, + // report: { + // store.send(.reportButtonTapped(comment)) + // } + // ) + // .configurePagination( + // store.commentList, + // currentIndex: index, + // hasNext: store.paginationInfo.hasNext, + // pagination: { + // store.send(.pagination) + // } + // ) + // .disabled(store.isLoading) + // + // seperator + // } - seperator + ForEach(AnswerCommentFeature.sampleComment) { comment in + AnswerCommentCell( + comment: comment, + like: { + store.send(.likeCommentButtonTapped(comment)) + }, + delete: { + store.send(.deleteCommentButtonTapped(comment)) + }, + report: { + store.send(.reportButtonTapped(comment)) + } + ) + + seperator + } } } } diff --git a/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardCell.swift b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardCell.swift index 142f4afd..8fac5022 100644 --- a/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardCell.swift +++ b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardCell.swift @@ -60,10 +60,11 @@ private struct NormalBoardCell: View { board: board, like: like ) + .padding(.top, 16) .padding(.horizontal, 16) Divider() - .padding(.top, 16) + .padding(.top, 24) } .background(Background.first) } @@ -158,7 +159,7 @@ private struct ContentView: View { board: board, like: like ) - .padding(.top, 12) + .padding(.top, 16) .disabled(board.isReported) } } diff --git a/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardFeature.swift b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardFeature.swift index 7a68c4da..333b9916 100644 --- a/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardFeature.swift +++ b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardFeature.swift @@ -16,6 +16,7 @@ struct BulletinBoardFeature { @Presents var alert: AlertState? var bulletinBoardList: [BulletinBoard] = [] var todayQuestion: Question = .initialState + var event: AcademyEventFor4th = .fourthStart var paginationInfo = QappleAPI.PaginationInfo(threshold: "", hasNext: false) var isLoading: Bool = false var isFirstLaunch = true @@ -23,6 +24,7 @@ struct BulletinBoardFeature { enum Action { case onAppear + case active case refresh case pagination case bulletinBoardListResponse(Question, [BulletinBoard], QappleAPI.PaginationInfo) @@ -61,9 +63,12 @@ struct BulletinBoardFeature { @Dependency(\.bulletinBoardRepository) var bulletinBoardRepository var body: some ReducerOf { - Reduce { state,action in + Reduce { state, action in switch action { - case .onAppear, .refresh: + case .onAppear, .active, .refresh: + if let currentEvent = AcademyEventFor4th.currentEvent { + state.event = currentEvent + } return .run { [isFirstLaunch = state.isFirstLaunch] send in if isFirstLaunch { await send(.toggleLoading(true), animation: .bouncy) } do { diff --git a/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardView.swift b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardView.swift index 7c57d84d..48939ec2 100644 --- a/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardView.swift +++ b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-1.BulletinBoard/BulletinBoardView.swift @@ -12,6 +12,8 @@ import ComposableArchitecture struct BulletinBoardView: View { + @Environment(\.scenePhase) private var scenePhase + @Bindable var store: StoreOf var body: some View { @@ -22,7 +24,11 @@ struct BulletinBoardView: View { .padding(.bottom, 20) } .background(.first) - + .onChange(of: scenePhase) { _, newPhase in + if newPhase == .active { + store.send(.active) + } + } .onAppear{ store.send(.onAppear) } @@ -67,7 +73,7 @@ private struct BulletinBoardContentView: View { Button { store.send(.academyDayCounterTapped) } label: { - QPAcademyDayCounter() + QPAcademyDayCounter(event: store.event) .padding(.top, 8) .padding(.horizontal, 16) } @@ -114,7 +120,7 @@ private struct QuestionNotificationView: View { } } else { Button { - store.send(.popularAnswerTapped(store.todayQuestion)) + // store.send(.popularAnswerTapped(store.todayQuestion)) } label: { HStack(spacing: 0) { VStack(spacing: 0) { @@ -130,13 +136,15 @@ private struct QuestionNotificationView: View { VStack(alignment: .leading, spacing: 0) { - Text("오늘의 인기 답변") - .font(.pretendard(.regular, size: 12)) - .foregroundStyle(TextLabel.sub4) - - Spacer() +// Text("오늘의 인기 답변") +// .font(.pretendard(.regular, size: 12)) +// .foregroundStyle(TextLabel.sub4) +// +// Spacer() - Text("프라이데이는 여자친구가 가지고 싶어요") // TODO: 인기 답변으로 + Text("이전에 개발자의 실수로 이상한(?) 정보가 표시됐었답니다.") // TODO: 인기 답변으로 + .lineLimit(2) + .multilineTextAlignment(.leading) .font(.pretendard(.regular, size: 15)) .foregroundStyle(.white) } diff --git a/Qapple/Qapple/SourceCode/Feature/4.Comment/CommentCell.swift b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentCell.swift similarity index 99% rename from Qapple/Qapple/SourceCode/Feature/4.Comment/CommentCell.swift rename to Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentCell.swift index 22babc82..fee573b4 100644 --- a/Qapple/Qapple/SourceCode/Feature/4.Comment/CommentCell.swift +++ b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentCell.swift @@ -1,5 +1,5 @@ // -// CommentCell.swift +// BoardCommentCell.swift // Qapple // // Created by 문인범 on 1/21/25. @@ -7,7 +7,7 @@ import SwiftUI -struct CommentCell: View { +struct BoardCommentCell: View { let comment: BoardComment let like: () -> Void let delete: () -> Void @@ -272,7 +272,7 @@ private struct CommentReportButton: View { anonymityId: 2 ) - CommentCell( + BoardCommentCell( comment: comment, like: {}, delete: {}, diff --git a/Qapple/Qapple/SourceCode/Feature/4.Comment/CommentFeature.swift b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentFeature.swift similarity index 98% rename from Qapple/Qapple/SourceCode/Feature/4.Comment/CommentFeature.swift rename to Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentFeature.swift index 46d62baa..b2c3dce1 100644 --- a/Qapple/Qapple/SourceCode/Feature/4.Comment/CommentFeature.swift +++ b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentFeature.swift @@ -1,5 +1,5 @@ // -// CommentFeature.swift +// BoardCommentFeature.swift // Qapple // // Created by 문인범 on 1/21/25. @@ -9,7 +9,7 @@ import Foundation import ComposableArchitecture @Reducer -struct CommentFeature { +struct BoardCommentFeature { @ObservableState struct State: Equatable { var board: BulletinBoard @@ -273,7 +273,7 @@ struct CommentFeature { // MARK: - BulletinBoardSheet -extension CommentFeature { +extension BoardCommentFeature { @Reducer(state: .equatable) enum Sheet { case seeMore(SeeMoreSheetFeature) @@ -282,7 +282,7 @@ extension CommentFeature { // MARK: - CommentAlert -extension AlertState where Action == CommentFeature.Action.Alert { +extension AlertState where Action == BoardCommentFeature.Action.Alert { static func confirmDeletion(_ boardCommentId: Int) -> Self { return Self { TextState("정말로 댓글을 삭제하시겠습니까?") @@ -305,7 +305,7 @@ extension AlertState where Action == CommentFeature.Action.Alert { } } -extension CommentFeature { +extension BoardCommentFeature { // 이름을 익명화 해주는 method private func anonymizeCommentList(_ BoardWriterId: Int, _ commentList: [BoardComment]) -> [BoardComment] { var anonymousArray: [Int: Int] = [:] diff --git a/Qapple/Qapple/SourceCode/Feature/4.Comment/CommentView.swift b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentView.swift similarity index 68% rename from Qapple/Qapple/SourceCode/Feature/4.Comment/CommentView.swift rename to Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentView.swift index 07a6aecb..04b5ecef 100644 --- a/Qapple/Qapple/SourceCode/Feature/4.Comment/CommentView.swift +++ b/Qapple/Qapple/SourceCode/Feature/3.BulletinBoard/3-4.BoardComment/BoardCommentView.swift @@ -1,5 +1,5 @@ // -// CommentView.swift +// BoardCommentView.swift // Qapple // // Created by 문인범 on 1/21/25. @@ -8,8 +8,8 @@ import SwiftUI import ComposableArchitecture -struct CommentView: View { - @Bindable var store: StoreOf +struct BoardCommentView: View { + @Bindable var store: StoreOf private let screenWidth: CGFloat = UIScreen.main.bounds.width @@ -44,7 +44,7 @@ struct CommentView: View { AddCommentView(store: store) .frame(width: screenWidth) .padding(.bottom, 8) - + } .background(Color.bk) .onTapGesture { @@ -78,38 +78,49 @@ struct CommentView: View { // MARK: - CommentListView private struct CommentListView: View { - let store: StoreOf + let store: StoreOf var body: some View { ZStack { - ScrollView { - LazyVStack(spacing: 0) { - seperator - - ForEach(Array(self.store.commentList.enumerated()), id: \.offset) { index, comment in - CommentCell( - comment: comment, - like: { - store.send(.likeCommentButtonTapped(comment)) - }, - delete: { - store.send(.deleteCommentButtonTapped(comment)) - }, - report: { - store.send(.reportButtonTapped(comment)) - } - ) - .configurePagination( - store.commentList, - currentIndex: index, - hasNext: store.paginationInfo.hasNext, - pagination: { - store.send(.pagination) - } - ) - .disabled(store.isLoading) - - seperator + VStack { + seperator + + HStack { + Text("댓글") + .pretendard(.medium, 14) + .foregroundStyle(.sub3) + Spacer() + } + .padding(.top, 12) + .padding(.horizontal, 20) + + ScrollView { + LazyVStack(spacing: 0) { + ForEach(Array(self.store.commentList.enumerated()), id: \.offset) { index, comment in + BoardCommentCell( + comment: comment, + like: { + store.send(.likeCommentButtonTapped(comment)) + }, + delete: { + store.send(.deleteCommentButtonTapped(comment)) + }, + report: { + store.send(.reportButtonTapped(comment)) + } + ) + .configurePagination( + store.commentList, + currentIndex: index, + hasNext: store.paginationInfo.hasNext, + pagination: { + store.send(.pagination) + } + ) + .disabled(store.isLoading) + + seperator + } } } } @@ -140,7 +151,7 @@ private struct CommentListView: View { // MARK: - AddCommentView private struct AddCommentView: View { - @Bindable var store: StoreOf + @Bindable var store: StoreOf var body: some View { HStack(alignment: .bottom) { @@ -173,9 +184,9 @@ private struct AddCommentView: View { // MARK: - Preview #Preview { - CommentView( + BoardCommentView( store: Store( - initialState: CommentFeature.State( + initialState: BoardCommentFeature.State( board: BulletinBoard( id: 1, writerId: 1, @@ -191,6 +202,6 @@ private struct AddCommentView: View { ) ) ){ - CommentFeature() - }) + BoardCommentFeature() + }) } diff --git a/Qapple/Qapple/SourceCode/UIComponent/QPAcademyDayCounter.swift b/Qapple/Qapple/SourceCode/UIComponent/QPAcademyDayCounter.swift index f7794f5b..744b1415 100644 --- a/Qapple/Qapple/SourceCode/UIComponent/QPAcademyDayCounter.swift +++ b/Qapple/Qapple/SourceCode/UIComponent/QPAcademyDayCounter.swift @@ -9,67 +9,7 @@ import SwiftUI struct QPAcademyDayCounter: View { - var body: some View { - Group { - if let currentEvent = AcademyEventFor4th.currentEvent { - ContentView( - event: currentEvent, - dayLeft: currentEvent.period.1.dayLeft - ) - } else { - if let nextEvent = AcademyEventFor4th.nextEvent { - Header( - event: nextEvent, - dayLeft: nextEvent.period.0.dayLeft, - isCurrentEvent: false - ) - } - } - } - .padding(.vertical, 14) - .padding(.horizontal, 20) - .background(.second) - .clipShape(RoundedRectangle(cornerRadius: 12)) - } -} - -// MARK: - ContentView - -private struct ContentView: View { - - let event: AcademyEventFor4th - let dayLeft: Int - - var body: some View { - VStack(spacing: 0) { - Header(event: event, dayLeft: dayLeft, isCurrentEvent: true) - -// HStack { -// Text(event.period.0.formatting(.mdKorean)) -// Spacer() -// Text(event.period.1.formatting(.mdKorean)) -// } -// .padding(.top, 16) -// .padding(.horizontal, 2) -// .foregroundStyle(.main).opacity(0.6) -// .pretendard(.semiBold, 14) - -// ProgressBar( -// event: event, -// dayLeft: dayLeft -// ) -// .padding(.top, 8) - } - } -} - -// MARK: - Header - -private struct Header: View { - let event: AcademyEventFor4th - let dayLeft: Int - let isCurrentEvent: Bool var body: some View { HStack(spacing: 8) { @@ -88,52 +28,23 @@ private struct Header: View { .foregroundStyle(.main).opacity(0.8) .pretendard(.semiBold, 17) } + .padding(.vertical, 14) + .padding(.horizontal, 20) + .background(.second) + .clipShape(RoundedRectangle(cornerRadius: 12)) } private var dayLeftText: String { - if dayLeft == 0 { + if event.leftDays == 0 { "마지막 날" } else { - "\(dayLeft)\(isCurrentEvent ? "일 남음" : "일 후 시작")" + "\(event.leftDays)일 남음" } } } -// MARK: - ProgressBar - -private struct ProgressBar: View { - - let event: AcademyEventFor4th - let dayLeft: Int - - var body: some View { - GeometryReader { proxy in - ZStack(alignment: .leading) { - RoundedRectangle(cornerRadius: 10) - .foregroundStyle(TextLabel.ph) - .frame(width: proxy.size.width) - .clipShape(RoundedRectangle(cornerRadius: 10)) - - RoundedRectangle(cornerRadius: 10) - .foregroundStyle(.button) - .frame(width: proxy.size.width * progress) - } - } - .frame(height: 16) - } - - /// Progress 값을 반환합니다. - private var progress: Double { - let (startDate, endDate) = event.period - let total = Calendar.utc - .dateComponents([.day], from: startDate, to: endDate) - .day ?? 0 - return Double(total - dayLeft) / Double(total) - } -} - // MARK: - Preview #Preview { - QPAcademyDayCounter() + QPAcademyDayCounter(event: .currentEvent!) } diff --git a/Qapple/Qapple/SourceCode/UIComponent/QPAnswerCell.swift b/Qapple/Qapple/SourceCode/UIComponent/QPAnswerCell.swift index ac1ae10a..53281cda 100644 --- a/Qapple/Qapple/SourceCode/UIComponent/QPAnswerCell.swift +++ b/Qapple/Qapple/SourceCode/UIComponent/QPAnswerCell.swift @@ -84,11 +84,12 @@ private struct NormalCell: View { Content() .padding(.top, 8) .padding(.horizontal, 16) - - Footer() - .padding(.top, 6) .padding(.bottom, 20) - .padding(.horizontal, 16) + +// Footer() +// .padding(.top, 6) +// .padding(.bottom, 20) +// .padding(.horizontal, 16) } .background(.first) }