diff --git a/Projects/App/Sources/MainTab/MainTabFeature.swift b/Projects/App/Sources/MainTab/MainTabFeature.swift index 2e100816..3eaeed96 100644 --- a/Projects/App/Sources/MainTab/MainTabFeature.swift +++ b/Projects/App/Sources/MainTab/MainTabFeature.swift @@ -205,7 +205,7 @@ private extension MainTabFeature { case let .linkCopySuccess(url): guard let url else { return .none } state.linkPopup = .link( - title: "복사한 링크 저장하기", + title: Constants.복사한_링크_저장하기_문구, url: url.absoluteString ) state.link = url.absoluteString diff --git a/Projects/App/Sources/MainTab/MainTabPath.swift b/Projects/App/Sources/MainTab/MainTabPath.swift index aa3008c1..bfca29dc 100644 --- a/Projects/App/Sources/MainTab/MainTabPath.swift +++ b/Projects/App/Sources/MainTab/MainTabPath.swift @@ -16,6 +16,7 @@ import FeatureContentSetting import FeatureContentList import FeatureCategorySharing import Domain +import Util @Reducer public struct MainTabPath { @@ -180,10 +181,10 @@ public extension MainTabFeature { case .검색: return .merge( .send(.path(.element(id: stackElementId, action: .검색(.delegate(.컨텐츠_검색))))), - .send(.inner(.링크팝업_활성화(.success(title: "링크 저장 완료"))), animation: .pokitSpring) + .send(.inner(.링크팝업_활성화(.success(title: Constants.링크_저장_완료_문구))), animation: .pokitSpring) ) default: - return .send(.inner(.링크팝업_활성화(.success(title: "링크 저장 완료"))), animation: .pokitSpring) + return .send(.inner(.링크팝업_활성화(.success(title: Constants.링크_저장_완료_문구))), animation: .pokitSpring) } /// - 각 화면에서 링크 복사 감지했을 때 (링크 추가 및 수정 화면 제외) case let .path(.element(_, action: .알림함(.delegate(.linkCopyDetected(url))))), diff --git a/Projects/CoreKit/Sources/Data/DTO/Category/CategoryEditResponse.swift b/Projects/CoreKit/Sources/Data/DTO/Category/CategoryEditResponse.swift index e7de613a..a1681c90 100644 --- a/Projects/CoreKit/Sources/Data/DTO/Category/CategoryEditResponse.swift +++ b/Projects/CoreKit/Sources/Data/DTO/Category/CategoryEditResponse.swift @@ -35,7 +35,7 @@ extension CategoryImageResponse { public static var mock: [Self] = [ Self( imageId: 2312, - imageUrl: "https://pokit-storage.s3.ap-northeast-2.amazonaws.com/logo/pokit.png" + imageUrl: Constants.기본_썸네일_주소.absoluteString ), Self( imageId: 23122, diff --git a/Projects/DSKit/Sources/Components/PokitLinkPopup.swift b/Projects/DSKit/Sources/Components/PokitLinkPopup.swift index ff96df5e..b4d9de71 100644 --- a/Projects/DSKit/Sources/Components/PokitLinkPopup.swift +++ b/Projects/DSKit/Sources/Components/PokitLinkPopup.swift @@ -40,7 +40,7 @@ public struct PokitLinkPopup: View { .frame(width: 335, height: 60) .transition(.move(edge: .bottom).combined(with: .opacity)) .onReceive(timer) { _ in - guard second < 2 && type != nil else { + guard second < 2 else { closedPopup() return } @@ -99,8 +99,8 @@ public struct PokitLinkPopup: View { private func closedPopup() { withAnimation(.pokitSpring) { - second = 0 type = nil + second = 0 } } diff --git a/Projects/Feature/FeatureContentDetail/Sources/ContentDetail/ContentDetailFeature.swift b/Projects/Feature/FeatureContentDetail/Sources/ContentDetail/ContentDetailFeature.swift index 780853ec..a9047819 100644 --- a/Projects/Feature/FeatureContentDetail/Sources/ContentDetail/ContentDetailFeature.swift +++ b/Projects/Feature/FeatureContentDetail/Sources/ContentDetail/ContentDetailFeature.swift @@ -141,15 +141,14 @@ private extension ContentDetailFeature { case .뷰가_나타났을때: /// - 나중에 공유 받은 컨텐츠인지 확인해야함 state.memoTextAreaState = .memo(isReadOnly: false) - if let id = state.domain.contentId { return .send(.async(.컨텐츠_상세_조회_API(id: id))) - } else if let content = state.domain.content { + } + if let content = state.domain.content { state.memo = content.memo return .none - } else { - return .none } + return .none case .공유_버튼_눌렀을때: state.showShareSheet = true return .none @@ -255,7 +254,7 @@ private extension ContentDetailFeature { model: request ) await send( - .inner(.링크팝업_활성화(.success(title: "메모 수정 완료"))), + .inner(.링크팝업_활성화(.success(title: Constants.메모_수정_완료_문구))), animation: .pokitSpring ) } catch: { error, send in diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index 37113f66..a4783ab6 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -100,7 +100,7 @@ public struct ContentSettingFeature { case 뒤로가기_버튼_눌렀을때 } - public enum InnerAction: Equatable { + public enum InnerAction { case linkPopup(URL?) case linkPreview case 메타데이터_조회_수행(url: URL) @@ -112,6 +112,7 @@ public struct ContentSettingFeature { case 카테고리_목록_조회_API_반영(categoryList: BaseCategoryListInquiry) case 선택한_포킷_인메모리_삭제 case 링크팝업_활성화(PokitLinkPopup.PopupType) + case error(Error) } public enum AsyncAction: Equatable { @@ -198,7 +199,7 @@ private extension ContentSettingFeature { return .merge(mergeEffect) case .저장_버튼_눌렀을때: let isEdit = state.domain.categoryId != nil - if state.domain.title == "제목을 입력해주세요" { + if state.domain.title == Constants.제목을_입력해주세요_문구 { state.domain.title = state.title } state.saveIsLoading = true @@ -209,7 +210,7 @@ private extension ContentSettingFeature { case .포킷추가_버튼_눌렀을때: guard state.domain.categoryTotalCount < 30 else { /// 🚨 Error Case [1]: 포킷 갯수가 30개 이상일 경우 - state.linkPopup = .text(title: "최대 30개의 포킷을 생성할 수 있습니다.\n포킷을 삭제한 뒤에 추가해주세요.") + state.linkPopup = .text(title: Constants.포킷_최대_갯수_문구) return .none } @@ -237,7 +238,7 @@ private extension ContentSettingFeature { guard let url else { return .none } state.link = url.absoluteString state.linkPopup = .link( - title: "복사한 링크 저장하기", + title: Constants.복사한_링크_저장하기_문구, url: url.absoluteString ) return .none @@ -254,9 +255,11 @@ private extension ContentSettingFeature { ) } case let .메타데이텨_조회_반영(title: title, imageURL: imageURL): - let contentTitle = state.title.isEmpty ? "제목을 입력해주세요" : state.title + let contentTitle = state.title.isEmpty + ? Constants.제목을_입력해주세요_문구 + : state.title state.linkTitle = title ?? contentTitle - state.linkImageURL = imageURL ?? "https://pokit-storage.s3.ap-northeast-2.amazonaws.com/logo/pokit.png" + state.linkImageURL = imageURL ?? Constants.기본_썸네일_주소.absoluteString if let title, state.domain.title.isEmpty { state.domain.title = title } @@ -332,6 +335,12 @@ private extension ContentSettingFeature { state.linkPopup = type state.saveIsLoading = false return .none + case let .error(error): + guard let errorResponse = error as? ErrorResponse else { return .none } + return .send( + .inner(.링크팝업_활성화(.error(title: errorResponse.message))), + animation: .pokitSpring + ) } } @@ -387,11 +396,7 @@ private extension ContentSettingFeature { await send(.inner(.선택한_포킷_인메모리_삭제)) await send(.delegate(.저장하기_완료(contentId: contentId))) } catch: { error, send in - guard let errorResponse = error as? ErrorResponse else { return } - await send( - .inner(.링크팝업_활성화(.error(title: errorResponse.message))), - animation: .pokitSpring - ) + await send(.inner(.error(error))) } case .컨텐츠_추가_API: guard let categoryId = state.selectedPokit?.id else { @@ -410,11 +415,7 @@ private extension ContentSettingFeature { await send(.inner(.선택한_포킷_인메모리_삭제)) await send(.delegate(.저장하기_완료(contentId: content.contentId))) } catch: { error, send in - guard let errorResponse = error as? ErrorResponse else { return } - await send( - .inner(.링크팝업_활성화(.error(title: errorResponse.message))), - animation: .pokitSpring - ) + await send(.inner(.error(error))) } case .클립보드_감지: return .run { send in @@ -425,7 +426,7 @@ private extension ContentSettingFeature { } } } - + /// - Scope Effect func handleScopeAction(_ action: Action.ScopeAction, state: inout State) -> Effect { return .none @@ -436,21 +437,6 @@ private extension ContentSettingFeature { return .none } - func contentEdit(request: ContentBaseRequest, contentId: Int) -> Effect { - return .run { _ in - let _ = try await contentClient.컨텐츠_수정( - "\(contentId)", - request - ) - } catch: { error, send in - guard let errorResponse = error as? ErrorResponse else { return } - await send( - .inner(.링크팝업_활성화(.error(title: errorResponse.message))), - animation: .pokitSpring - ) - } - } - func categoryListFetch(request: BasePageableRequest) -> Effect { return .run { send in let categoryList = try await categoryClient.카테고리_목록_조회(request, false).toDomain() diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift index 047bc2ea..158c8bb4 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift @@ -8,6 +8,7 @@ import SwiftUI import ComposableArchitecture import DSKit +import Util @ViewAction(for: ContentSettingFeature.self) public struct ContentSettingView: View { @@ -97,8 +98,8 @@ private extension ContentSettingView { let isParsed = store.linkTitle != nil || store.linkImageURL != nil PokitLinkPreview( - title: store.linkTitle == "제목을 입력해주세요" - ? store.title.isEmpty ? "제목을 입력해주세요" : store.title + title: store.linkTitle == Constants.제목을_입력해주세요_문구 + ? store.title.isEmpty ? Constants.제목을_입력해주세요_문구 : store.title : store.linkTitle, url: isParsed ? store.urlText : nil, imageURL: store.linkImageURL diff --git a/Projects/Feature/FeatureLogin/Sources/RegisterNickname/RegisterNicknameView.swift b/Projects/Feature/FeatureLogin/Sources/RegisterNickname/RegisterNicknameView.swift index cc8f3cc3..6ce0890f 100644 --- a/Projects/Feature/FeatureLogin/Sources/RegisterNickname/RegisterNicknameView.swift +++ b/Projects/Feature/FeatureLogin/Sources/RegisterNickname/RegisterNicknameView.swift @@ -7,6 +7,7 @@ import ComposableArchitecture import SwiftUI import DSKit +import Util @ViewAction(for: RegisterNicknameFeature.self) public struct RegisterNicknameView: View { @@ -74,7 +75,7 @@ extension RegisterNicknameView { text: $store.nicknameText, shape: .rectangle, state: $store.textfieldState, - info: "한글, 영어, 숫자로만 입력이 가능합니다.", + info: Constants.한글_영어_숫자_입력_문구, maxLetter: 10, focusState: $isFocused, equals: true diff --git a/Projects/Feature/FeatureRemind/Sources/Remind/RemindFeature.swift b/Projects/Feature/FeatureRemind/Sources/Remind/RemindFeature.swift index 64bd7235..50b8f1ba 100644 --- a/Projects/Feature/FeatureRemind/Sources/Remind/RemindFeature.swift +++ b/Projects/Feature/FeatureRemind/Sources/Remind/RemindFeature.swift @@ -155,9 +155,7 @@ private extension RemindFeature { case .컨텐츠_항목_케밥_버튼_눌렀을때(let content): return .send(.delegate(.링크상세(content: content))) case .컨텐츠_항목_눌렀을때(let content): - guard let url = URL(string: content.data) else { - return .none - } + guard let url = URL(string: content.data) else { return .none } return .run { _ in await openURL(url) } case .뷰가_나타났을때: return allContentFetch(animation: .pokitDissolve) @@ -290,7 +288,6 @@ private extension RemindFeature { } /// - Scope Effect func handleScopeAction(_ action: Action.ScopeAction, state: inout State) -> Effect { - /// - 링크에 대한 `공유` / `수정` / `삭제` delegate return .none } /// - Delegate Effect diff --git a/Projects/Feature/FeatureSetting/Sources/Setting/NickNameSetting/NickNameSettingView.swift b/Projects/Feature/FeatureSetting/Sources/Setting/NickNameSetting/NickNameSettingView.swift index 36c81b0c..e4b7c249 100644 --- a/Projects/Feature/FeatureSetting/Sources/Setting/NickNameSetting/NickNameSettingView.swift +++ b/Projects/Feature/FeatureSetting/Sources/Setting/NickNameSetting/NickNameSettingView.swift @@ -8,6 +8,7 @@ import SwiftUI import ComposableArchitecture import DSKit +import Util @ViewAction(for: NickNameSettingFeature.self) public struct NickNameSettingView: View { @@ -37,7 +38,7 @@ public extension NickNameSettingView { ), shape: .rectangle, state: $store.textfieldState, - info: "한글, 영어, 숫자로만 입력이 가능합니다.", + info: Constants.한글_영어_숫자_입력_문구, maxLetter: 10, focusState: $isFocused, equals: true diff --git a/Projects/Util/Sources/Constants.swift b/Projects/Util/Sources/Constants.swift index 5b0a0e1d..b9da10f5 100644 --- a/Projects/Util/Sources/Constants.swift +++ b/Projects/Util/Sources/Constants.swift @@ -22,7 +22,14 @@ public enum Constants { public static let 개인정보_처리방침_주소: URL = URL(string: "https://www.notion.so/de3468b3be1744538c22a333ae1d0ec8")! public static let 마케팅_정보_수신_주소: URL = URL(string: "https://www.notion.so/bb6d0d6569204d5e9a7b67e5825f9d10")! public static let 고객문의_주소: URL = URL(string: "https://www.instagram.com/pokit.official/")! + public static let 기본_썸네일_주소: URL = URL(string: "https://pokit-storage.s3.ap-northeast-2.amazonaws.com/logo/pokit.png")! + public static let 포킷_최대_갯수_문구: String = "최대 30개의 포킷을 생성할 수 있습니다.\n포킷을 삭제한 뒤에 추가해주세요." + public static let 복사한_링크_저장하기_문구: String = "복사한 링크 저장하기" + public static let 제목을_입력해주세요_문구: String = "제목을 입력해주세요" + public static let 링크_저장_완료_문구: String = "링크 저장 완료" + public static let 메모_수정_완료_문구: String = "메모 수정 완료" + public static let 한글_영어_숫자_입력_문구: String = "한글, 영어, 숫자로만 입력이 가능합니다." public static var mockImageUrl: String { "https://picsum.photos/\(Int.random(in: 150...250))" } }