From 187db6917c80b62daef6c41aa9ba07e8d9f6e08c Mon Sep 17 00:00:00 2001 From: mandos1995 Date: Sat, 10 Aug 2024 16:22:29 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EC=A2=8B=EC=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=9E=91=ED=92=88=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EC=97=B0=EB=8F=99=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/Show/Sources/Client/ShowClient.swift | 8 +++++++- Projects/Show/Sources/Feature/ShowFeature.swift | 12 ++++++++++++ .../FetchFavoriteShowListResponseDTO.swift | 17 +++++++++++++++++ Projects/Show/Sources/Service/ShowService.swift | 14 +++++++++++++- 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift diff --git a/Projects/Show/Sources/Client/ShowClient.swift b/Projects/Show/Sources/Client/ShowClient.swift index 97586a22..26104fee 100644 --- a/Projects/Show/Sources/Client/ShowClient.swift +++ b/Projects/Show/Sources/Client/ShowClient.swift @@ -14,6 +14,7 @@ public struct ShowClient { public var fetchShowList: (Int, ShowFeature.ShowType, ShowSortFeature.CategoryType) async throws -> FetchShowResponseDTO var fetchShowSearchList: (String) async throws -> FetchShowResponseDTO var fetchShowDetail: (String) async throws -> ShowDetailResponseContent + var fetchFavoriteShowList: ([String]) async throws -> FetchFavoriteShowListResponseDTO } extension ShowClient: DependencyKey { @@ -21,7 +22,8 @@ extension ShowClient: DependencyKey { Self( fetchShowList: fetchShowList, fetchShowSearchList: fetchShowSearchList(keyword:), - fetchShowDetail: fetchShowDetail(id:) + fetchShowDetail: fetchShowDetail(id:), + fetchFavoriteShowList: fetchFavoriteShowList(ids:) ) }() @@ -35,6 +37,10 @@ extension ShowClient: DependencyKey { public static func fetchShowDetail(id: String) async throws -> ShowDetailResponseContent { return try await MoyaProvider().request(.fetchShowDetail(id: id)) } + + public static func fetchFavoriteShowList(ids: [String]) async throws -> FetchFavoriteShowListResponseDTO { + return try await MoyaProvider().request(.fetchFavoriteShow(ids: ids)) + } } extension DependencyValues { diff --git a/Projects/Show/Sources/Feature/ShowFeature.swift b/Projects/Show/Sources/Feature/ShowFeature.swift index 81dcb6d9..23a3fa07 100644 --- a/Projects/Show/Sources/Feature/ShowFeature.swift +++ b/Projects/Show/Sources/Feature/ShowFeature.swift @@ -56,6 +56,8 @@ public struct ShowFeature { case path(StackAction) case didTappedSearch case didTappedShow(showId: String) + case showFavoriteListResponse(FetchFavoriteShowListResponseDTO) + case fetchFavoriteShowList(ids: [String]) } @Dependency (\.showClient) var showClient @@ -97,6 +99,16 @@ public struct ShowFeature { return .none case .showListResponse(let response): state.showList.append(contentsOf: response) + return .run { send in + let ids = response.map { $0.id } + await send(.fetchFavoriteShowList(ids: ids)) + } + case .fetchFavoriteShowList(let ids): + return .run { send in + try await send(.showFavoriteListResponse(showClient.fetchFavoriteShowList(ids))) + } + case .showFavoriteListResponse(let response): + print("######", response) return .none case .didScrollToLastItem: return .run { [page = state.page] send in diff --git a/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift b/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift new file mode 100644 index 00000000..dac0ac6b --- /dev/null +++ b/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift @@ -0,0 +1,17 @@ +// +// FetchFavoriteShowListResponseDTO.swift +// Show +// +// Created by 김민석 on 8/10/24. +// + +import Foundation + +public struct FetchFavoriteShowListResponseDTO: Decodable { + public let content: [FetchFavoriteShowListContent] +} + +public struct FetchFavoriteShowListContent: Decodable { + public let showId: String + public let favorite: Bool +} diff --git a/Projects/Show/Sources/Service/ShowService.swift b/Projects/Show/Sources/Service/ShowService.swift index 0de26545..85a234bb 100644 --- a/Projects/Show/Sources/Service/ShowService.swift +++ b/Projects/Show/Sources/Service/ShowService.swift @@ -15,6 +15,7 @@ enum ShowAPI { case fetchShowList(page: Int, genre: ShowFeature.ShowType, sort: ShowSortFeature.CategoryType) case fetchShowSearchList(keyword: String) case fetchShowDetail(id: String) + case fetchFavoriteShow(ids: [String]) } extension ShowAPI: TargetType { @@ -24,6 +25,7 @@ extension ShowAPI: TargetType { case .fetchShowList: return "/shows" case .fetchShowSearchList: return "/search/shows" case .fetchShowDetail(let id): return "/shows/\(id)" + case .fetchFavoriteShow: return "/member/favorite" } } var method: Moya.Method { .get } @@ -41,8 +43,18 @@ extension ShowAPI: TargetType { return .requestParameters(parameters: param, encoding: URLEncoding.default) case .fetchShowDetail: return .requestPlain + case .fetchFavoriteShow(let ids): + for id in ids { + param.updateValue(id, forKey: "showIds") + } + return .requestParameters(parameters: param, encoding: URLEncoding.default) } } - var headers: [String : String]? { nil } + var headers: [String : String]? { + switch self { + case .fetchFavoriteShow: return Utils.authHeader + default: return nil + } + } } From 4fc677f909d83513e6a22d4ce61c2412d583b336 Mon Sep 17 00:00:00 2001 From: mandos1995 Date: Sat, 24 Aug 2024 15:39:35 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EC=A2=8B=EC=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=9E=91=ED=92=88=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/Show/Sources/Feature/ShowFeature.swift | 11 +++++++++-- Projects/Show/Sources/Service/ShowService.swift | 8 +++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Projects/Show/Sources/Feature/ShowFeature.swift b/Projects/Show/Sources/Feature/ShowFeature.swift index 23a3fa07..77784cb6 100644 --- a/Projects/Show/Sources/Feature/ShowFeature.swift +++ b/Projects/Show/Sources/Feature/ShowFeature.swift @@ -58,6 +58,7 @@ public struct ShowFeature { case didTappedShow(showId: String) case showFavoriteListResponse(FetchFavoriteShowListResponseDTO) case fetchFavoriteShowList(ids: [String]) + case failedToFavoriteList(Error) } @Dependency (\.showClient) var showClient @@ -105,10 +106,16 @@ public struct ShowFeature { } case .fetchFavoriteShowList(let ids): return .run { send in - try await send(.showFavoriteListResponse(showClient.fetchFavoriteShowList(ids))) + do { + try await send(.showFavoriteListResponse(showClient.fetchFavoriteShowList(ids))) + } catch { + await send(.failedToFavoriteList(error)) + } } case .showFavoriteListResponse(let response): - print("######", response) + return .none + case .failedToFavoriteList(let error): + print(error.localizedDescription) return .none case .didScrollToLastItem: return .run { [page = state.page] send in diff --git a/Projects/Show/Sources/Service/ShowService.swift b/Projects/Show/Sources/Service/ShowService.swift index 85a234bb..e7314eda 100644 --- a/Projects/Show/Sources/Service/ShowService.swift +++ b/Projects/Show/Sources/Service/ShowService.swift @@ -19,7 +19,7 @@ enum ShowAPI { } extension ShowAPI: TargetType { - var baseURL: URL { URL(string: "\(Secret.BASE_URL)")! } + var baseURL: URL { URL(string: "\(Secret.BASE_URL)")!.absoluteURL } var path: String { switch self { case .fetchShowList: return "/shows" @@ -44,10 +44,8 @@ extension ShowAPI: TargetType { case .fetchShowDetail: return .requestPlain case .fetchFavoriteShow(let ids): - for id in ids { - param.updateValue(id, forKey: "showIds") - } - return .requestParameters(parameters: param, encoding: URLEncoding.default) + param.updateValue(ids, forKey: "showIds") + return .requestParameters(parameters: param, encoding: URLEncoding(arrayEncoding: .noBrackets)) } } From 308eeb25faa156de4ff7f56caa17dc0ba4b91110 Mon Sep 17 00:00:00 2001 From: mandos1995 Date: Sat, 24 Aug 2024 15:55:13 +0900 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20=EC=A2=8B=EC=95=84=ED=95=98=EB=8A=94?= =?UTF-8?q?=20=EC=9E=91=ED=92=88=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20API=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Enums/UserDefaultKeys.swift | 1 + Projects/Show/Sources/Client/ShowClient.swift | 8 +++---- .../Show/Sources/Feature/ShowFeature.swift | 13 ++++++------ .../FetchFavoriteShowListResponseDTO.swift | 21 ++++++++++++++++--- .../Show/Sources/Service/ShowService.swift | 11 +++++----- Projects/Show/Sources/Views/ShowView.swift | 3 ++- 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/Projects/Common/Sources/Enums/UserDefaultKeys.swift b/Projects/Common/Sources/Enums/UserDefaultKeys.swift index 0c1ecd0e..3a9a743d 100644 --- a/Projects/Common/Sources/Enums/UserDefaultKeys.swift +++ b/Projects/Common/Sources/Enums/UserDefaultKeys.swift @@ -14,4 +14,5 @@ public enum UserDefaultKeys: String, CaseIterable { case refreshTokenExpiresAt case isShowPopluarTooltip case showRecentSearches + case favoriteShow } diff --git a/Projects/Show/Sources/Client/ShowClient.swift b/Projects/Show/Sources/Client/ShowClient.swift index 26104fee..8416a0a0 100644 --- a/Projects/Show/Sources/Client/ShowClient.swift +++ b/Projects/Show/Sources/Client/ShowClient.swift @@ -14,7 +14,7 @@ public struct ShowClient { public var fetchShowList: (Int, ShowFeature.ShowType, ShowSortFeature.CategoryType) async throws -> FetchShowResponseDTO var fetchShowSearchList: (String) async throws -> FetchShowResponseDTO var fetchShowDetail: (String) async throws -> ShowDetailResponseContent - var fetchFavoriteShowList: ([String]) async throws -> FetchFavoriteShowListResponseDTO + var fetchFavoriteShowList: () async throws -> FetchFavoriteShowListResponseDTO } extension ShowClient: DependencyKey { @@ -23,7 +23,7 @@ extension ShowClient: DependencyKey { fetchShowList: fetchShowList, fetchShowSearchList: fetchShowSearchList(keyword:), fetchShowDetail: fetchShowDetail(id:), - fetchFavoriteShowList: fetchFavoriteShowList(ids:) + fetchFavoriteShowList: fetchFavoriteShowList ) }() @@ -38,8 +38,8 @@ extension ShowClient: DependencyKey { return try await MoyaProvider().request(.fetchShowDetail(id: id)) } - public static func fetchFavoriteShowList(ids: [String]) async throws -> FetchFavoriteShowListResponseDTO { - return try await MoyaProvider().request(.fetchFavoriteShow(ids: ids)) + public static func fetchFavoriteShowList() async throws -> FetchFavoriteShowListResponseDTO { + return try await MoyaProvider().request(.fetchFavoriteShow) } } diff --git a/Projects/Show/Sources/Feature/ShowFeature.swift b/Projects/Show/Sources/Feature/ShowFeature.swift index 77784cb6..f33a1c87 100644 --- a/Projects/Show/Sources/Feature/ShowFeature.swift +++ b/Projects/Show/Sources/Feature/ShowFeature.swift @@ -42,6 +42,7 @@ public struct ShowFeature { var page: Int = 0 @Presents var bottomSheet: ShowSortFeature.State? var isShowTooltip = !UserDefaults.standard.bool(forKey: UserDefaultKeys.isShowPopluarTooltip.rawValue) + var favoriteShowList: Set = [] var path = StackState() } @@ -57,7 +58,7 @@ public struct ShowFeature { case didTappedSearch case didTappedShow(showId: String) case showFavoriteListResponse(FetchFavoriteShowListResponseDTO) - case fetchFavoriteShowList(ids: [String]) + case fetchFavoriteShowList case failedToFavoriteList(Error) } @@ -100,19 +101,17 @@ public struct ShowFeature { return .none case .showListResponse(let response): state.showList.append(contentsOf: response) - return .run { send in - let ids = response.map { $0.id } - await send(.fetchFavoriteShowList(ids: ids)) - } - case .fetchFavoriteShowList(let ids): + return .none + case .fetchFavoriteShowList: return .run { send in do { - try await send(.showFavoriteListResponse(showClient.fetchFavoriteShowList(ids))) + try await send(.showFavoriteListResponse(showClient.fetchFavoriteShowList())) } catch { await send(.failedToFavoriteList(error)) } } case .showFavoriteListResponse(let response): + state.favoriteShowList = Set(response.content.map { $0.id }) return .none case .failedToFavoriteList(let error): print(error.localizedDescription) diff --git a/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift b/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift index dac0ac6b..d01dbca7 100644 --- a/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift +++ b/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift @@ -7,11 +7,26 @@ import Foundation +import Common + public struct FetchFavoriteShowListResponseDTO: Decodable { public let content: [FetchFavoriteShowListContent] } -public struct FetchFavoriteShowListContent: Decodable { - public let showId: String - public let favorite: Bool +public struct FetchFavoriteShowListContent: Hashable, Equatable, Decodable { + public static func == (lhs: FetchFavoriteShowListContent, rhs: FetchFavoriteShowListContent) -> Bool { + lhs.id == rhs.id + } + + public let id: String + public let name: String + public let startDate: String + public let endDate: String + public let facilityName: String + public let poster: String + public let genre: Genre + public let showTimes: [ShowTime] + public let runtime: String + public let reviewCount: Int + public let reviewGradeSum: Int } diff --git a/Projects/Show/Sources/Service/ShowService.swift b/Projects/Show/Sources/Service/ShowService.swift index e7314eda..7b6ad844 100644 --- a/Projects/Show/Sources/Service/ShowService.swift +++ b/Projects/Show/Sources/Service/ShowService.swift @@ -15,7 +15,7 @@ enum ShowAPI { case fetchShowList(page: Int, genre: ShowFeature.ShowType, sort: ShowSortFeature.CategoryType) case fetchShowSearchList(keyword: String) case fetchShowDetail(id: String) - case fetchFavoriteShow(ids: [String]) + case fetchFavoriteShow } extension ShowAPI: TargetType { @@ -25,7 +25,9 @@ extension ShowAPI: TargetType { case .fetchShowList: return "/shows" case .fetchShowSearchList: return "/search/shows" case .fetchShowDetail(let id): return "/shows/\(id)" - case .fetchFavoriteShow: return "/member/favorite" + case .fetchFavoriteShow: + let memberId = UserDefaults.standard.integer(forKey: UserDefaultKeys.userId.rawValue) + return "/members/\(memberId)/favorite" } } var method: Moya.Method { .get } @@ -43,9 +45,8 @@ extension ShowAPI: TargetType { return .requestParameters(parameters: param, encoding: URLEncoding.default) case .fetchShowDetail: return .requestPlain - case .fetchFavoriteShow(let ids): - param.updateValue(ids, forKey: "showIds") - return .requestParameters(parameters: param, encoding: URLEncoding(arrayEncoding: .noBrackets)) + case .fetchFavoriteShow: + return .requestPlain } } diff --git a/Projects/Show/Sources/Views/ShowView.swift b/Projects/Show/Sources/Views/ShowView.swift index c121be43..faad8864 100644 --- a/Projects/Show/Sources/Views/ShowView.swift +++ b/Projects/Show/Sources/Views/ShowView.swift @@ -74,7 +74,7 @@ public struct ShowView: View { HStack { Spacer() - Image(asset: CommonAsset.showFavoriteUnfill) + Image(asset: store.favoriteShowList.contains(show.id) ? CommonAsset.showFavoriteFill : CommonAsset.showFavoriteUnfill) .frame(width: 28, height: 28) } .padding([.bottom, .trailing], 10) @@ -92,6 +92,7 @@ public struct ShowView: View { } .onAppear { store.send(.fetchShowList(page: 0)) + store.send(.fetchFavoriteShowList) } .sheet(item: $store.scope(state: \.bottomSheet, action: \.bottomSheet)) { store in ShowSortBottomSheet(store: store) From 7d5d2da2e31880e885d9f451506297348fa95cf9 Mon Sep 17 00:00:00 2001 From: mandos1995 Date: Sun, 3 Nov 2024 22:55:28 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EC=9E=91=ED=92=88=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/App/Support/Info.plist | 6 ++-- Projects/Show/Sources/Client/ShowClient.swift | 14 +++++++- .../Show/Sources/Feature/ShowFeature.swift | 34 +++++++++++++++++++ .../FetchFavoriteShowListResponseDTO.swift | 4 +-- .../Show/Sources/Service/ShowService.swift | 22 +++++++++--- Projects/Show/Sources/Views/ShowView.swift | 3 ++ 6 files changed, 73 insertions(+), 10 deletions(-) diff --git a/Projects/App/Support/Info.plist b/Projects/App/Support/Info.plist index 7daaef77..91e04b1e 100644 --- a/Projects/App/Support/Info.plist +++ b/Projects/App/Support/Info.plist @@ -38,7 +38,9 @@ CFBundleVersion - 2 + 3 + ITSAppUsesNonExemptEncryption + KAKAO_NATIVE_APP_KEY $(KAKAO_NATIVE_APP_KEY) LSApplicationQueriesSchemes @@ -68,7 +70,7 @@ UIApplicationSupportsIndirectInputEvents UILaunchStoryboardName - Launch Screen.storyboard + Launch Screen UIRequiredDeviceCapabilities armv7 diff --git a/Projects/Show/Sources/Client/ShowClient.swift b/Projects/Show/Sources/Client/ShowClient.swift index 8416a0a0..51ca4363 100644 --- a/Projects/Show/Sources/Client/ShowClient.swift +++ b/Projects/Show/Sources/Client/ShowClient.swift @@ -15,6 +15,8 @@ public struct ShowClient { var fetchShowSearchList: (String) async throws -> FetchShowResponseDTO var fetchShowDetail: (String) async throws -> ShowDetailResponseContent var fetchFavoriteShowList: () async throws -> FetchFavoriteShowListResponseDTO + var putFavoriteShow: (String) async throws -> Bool + var deleteFavoriteShow: (String) async throws -> Bool } extension ShowClient: DependencyKey { @@ -23,7 +25,9 @@ extension ShowClient: DependencyKey { fetchShowList: fetchShowList, fetchShowSearchList: fetchShowSearchList(keyword:), fetchShowDetail: fetchShowDetail(id:), - fetchFavoriteShowList: fetchFavoriteShowList + fetchFavoriteShowList: fetchFavoriteShowList, + putFavoriteShow: putFavoriteShow(id:), + deleteFavoriteShow: deleteFavoriteShow(id:) ) }() @@ -41,6 +45,14 @@ extension ShowClient: DependencyKey { public static func fetchFavoriteShowList() async throws -> FetchFavoriteShowListResponseDTO { return try await MoyaProvider().request(.fetchFavoriteShow) } + + public static func putFavoriteShow(id: String) async throws -> Bool { + return try await MoyaProvider().request(.putFavoriteShow(id: id)) + } + + public static func deleteFavoriteShow(id: String) async throws -> Bool { + return try await MoyaProvider().request(.deleteFavoriteShow(id: id)) + } } extension DependencyValues { diff --git a/Projects/Show/Sources/Feature/ShowFeature.swift b/Projects/Show/Sources/Feature/ShowFeature.swift index f33a1c87..bf58cabd 100644 --- a/Projects/Show/Sources/Feature/ShowFeature.swift +++ b/Projects/Show/Sources/Feature/ShowFeature.swift @@ -60,6 +60,11 @@ public struct ShowFeature { case showFavoriteListResponse(FetchFavoriteShowListResponseDTO) case fetchFavoriteShowList case failedToFavoriteList(Error) + case didTappedFavorite(id: String) + case selectedFavorite(id: String) + case deselectedFavorite(id: String) + case isSucessSelectedFavorite(Bool) + case isSucessDeselectedFavorite(Bool) } @Dependency (\.showClient) var showClient @@ -127,6 +132,35 @@ public struct ShowFeature { case .didTappedSearch: state.path.append(.showSearch()) return .none + case .didTappedFavorite(let id): + let isCancle = state.favoriteShowList.contains(id) + return .run { send in + isCancle ? await send(.deselectedFavorite(id: id)) : await send(.selectedFavorite(id: id)) + } + case .selectedFavorite(let id): + return .run { send in + do { + try await send(.isSucessSelectedFavorite(showClient.putFavoriteShow(id))) + } catch { + await send(.isSucessSelectedFavorite(false)) + } + } + case .deselectedFavorite(let id): + return .run { send in + do { + try await send(.isSucessDeselectedFavorite(showClient.deleteFavoriteShow(id))) + } catch { + await send(.isSucessDeselectedFavorite(false)) + } + } + case .isSucessSelectedFavorite: + return .run { send in + await send(.fetchFavoriteShowList) + } + case .isSucessDeselectedFavorite: + return .run { send in + await send(.fetchFavoriteShowList) + } case .path(.element(id: _, action: .showSearch(.didTappedCancelButton))): state.path.removeAll() return .none diff --git a/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift b/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift index d01dbca7..bad8922c 100644 --- a/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift +++ b/Projects/Show/Sources/Model/FetchFavoriteShowListResponseDTO.swift @@ -27,6 +27,6 @@ public struct FetchFavoriteShowListContent: Hashable, Equatable, Decodable { public let genre: Genre public let showTimes: [ShowTime] public let runtime: String - public let reviewCount: Int - public let reviewGradeSum: Int + public let reviewCount: Int? + public let reviewGradeSum: Int? } diff --git a/Projects/Show/Sources/Service/ShowService.swift b/Projects/Show/Sources/Service/ShowService.swift index 7b6ad844..bad315ff 100644 --- a/Projects/Show/Sources/Service/ShowService.swift +++ b/Projects/Show/Sources/Service/ShowService.swift @@ -16,6 +16,8 @@ enum ShowAPI { case fetchShowSearchList(keyword: String) case fetchShowDetail(id: String) case fetchFavoriteShow + case putFavoriteShow(id: String) + case deleteFavoriteShow(id: String) } extension ShowAPI: TargetType { @@ -28,9 +30,17 @@ extension ShowAPI: TargetType { case .fetchFavoriteShow: let memberId = UserDefaults.standard.integer(forKey: UserDefaultKeys.userId.rawValue) return "/members/\(memberId)/favorite" + case .putFavoriteShow(let id): return "/shows/\(id)/favorite" + case .deleteFavoriteShow(let id): return "/shows/\(id)/favorite" + } + } + var method: Moya.Method { + switch self { + case .putFavoriteShow: return .put + case .deleteFavoriteShow: return .delete + default: return .get } } - var method: Moya.Method { .get } var task: Moya.Task { var param: [String: Any] = [:] @@ -43,16 +53,18 @@ extension ShowAPI: TargetType { case .fetchShowSearchList(let keyword): param.updateValue(keyword, forKey: "keyword") return .requestParameters(parameters: param, encoding: URLEncoding.default) - case .fetchShowDetail: - return .requestPlain - case .fetchFavoriteShow: - return .requestPlain + case .fetchShowDetail: return .requestPlain + case .fetchFavoriteShow: return .requestPlain + case .putFavoriteShow: return .requestPlain + case .deleteFavoriteShow: return .requestPlain } } var headers: [String : String]? { switch self { case .fetchFavoriteShow: return Utils.authHeader + case .putFavoriteShow: return Utils.authHeader + case .deleteFavoriteShow: return Utils.authHeader default: return nil } } diff --git a/Projects/Show/Sources/Views/ShowView.swift b/Projects/Show/Sources/Views/ShowView.swift index faad8864..e2fd4313 100644 --- a/Projects/Show/Sources/Views/ShowView.swift +++ b/Projects/Show/Sources/Views/ShowView.swift @@ -76,6 +76,9 @@ public struct ShowView: View { Spacer() Image(asset: store.favoriteShowList.contains(show.id) ? CommonAsset.showFavoriteFill : CommonAsset.showFavoriteUnfill) .frame(width: 28, height: 28) + .onTapGestureRectangle { + store.send(.didTappedFavorite(id: show.id)) + } } .padding([.bottom, .trailing], 10) } From 38fd1b9eeeb0d68a4dd41a9b89ff7cd5a774a151 Mon Sep 17 00:00:00 2001 From: mandos1995 Date: Sun, 24 Nov 2024 00:32:22 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=EC=9E=91=ED=92=88=20id=20=EA=B0=92?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A6=90=EA=B2=A8=EC=B0=BE=EA=B8=B0=20?= =?UTF-8?q?=ED=95=9C=20=EC=9E=91=ED=92=88=20=EC=97=AC=EB=B6=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/Show/Sources/Client/ShowClient.swift | 8 +++++++- .../Sources/Feature/ShowDetailFeature.swift | 18 ++++++++++++++++++ .../Model/FetchIsFavoriteShowResponseDTO.swift | 17 +++++++++++++++++ .../Show/Sources/Service/ShowService.swift | 7 +++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 Projects/Show/Sources/Model/FetchIsFavoriteShowResponseDTO.swift diff --git a/Projects/Show/Sources/Client/ShowClient.swift b/Projects/Show/Sources/Client/ShowClient.swift index 51ca4363..47d21cc1 100644 --- a/Projects/Show/Sources/Client/ShowClient.swift +++ b/Projects/Show/Sources/Client/ShowClient.swift @@ -17,6 +17,7 @@ public struct ShowClient { var fetchFavoriteShowList: () async throws -> FetchFavoriteShowListResponseDTO var putFavoriteShow: (String) async throws -> Bool var deleteFavoriteShow: (String) async throws -> Bool + var fetchIsFavoriteShow: (String) async throws -> FetchIsFavoriteShowResponseDTO } extension ShowClient: DependencyKey { @@ -27,7 +28,8 @@ extension ShowClient: DependencyKey { fetchShowDetail: fetchShowDetail(id:), fetchFavoriteShowList: fetchFavoriteShowList, putFavoriteShow: putFavoriteShow(id:), - deleteFavoriteShow: deleteFavoriteShow(id:) + deleteFavoriteShow: deleteFavoriteShow(id:), + fetchIsFavoriteShow: fetchIsFavoriteShow(id:) ) }() @@ -53,6 +55,10 @@ extension ShowClient: DependencyKey { public static func deleteFavoriteShow(id: String) async throws -> Bool { return try await MoyaProvider().request(.deleteFavoriteShow(id: id)) } + + static func fetchIsFavoriteShow(id: String) async throws -> FetchIsFavoriteShowResponseDTO { + return try await MoyaProvider().request(.fetchIsFavoriteShow(id: id)) + } } extension DependencyValues { diff --git a/Projects/Show/Sources/Feature/ShowDetailFeature.swift b/Projects/Show/Sources/Feature/ShowDetailFeature.swift index 2f286531..10eccecf 100644 --- a/Projects/Show/Sources/Feature/ShowDetailFeature.swift +++ b/Projects/Show/Sources/Feature/ShowDetailFeature.swift @@ -31,6 +31,7 @@ public struct ShowDetailFeature { var currentSelectedCategory: ShowDetailCategoryType = .detail var facilityInfo: FetchFacilityResponseDTO? var detailImageHeight: CGFloat = 300 + var isLikeShow: Bool = false var review: ReviewFeature.State? } @@ -41,7 +42,10 @@ public struct ShowDetailFeature { case fetchFacilityDetail(id: String) case facilityDetailResponse(FetchFacilityResponseDTO) case didTappedMoreDetailImage + case fetchIsFavoriteShow case review(ReviewFeature.Action) + case isFavoriteShowResponse(Bool) + case failedToFetchIsList(Error) } @Dependency (\.showClient) var showClient @@ -91,6 +95,20 @@ public struct ShowDetailFeature { case .didTappedMoreDetailImage: state.detailImageHeight = state.detailImageHeight == 300 ? .infinity: 300 return .none + case .fetchIsFavoriteShow: + return .run { [id = state.showId] send in + do { + try await send(.isFavoriteShowResponse(showClient.fetchIsFavoriteShow(id).content.first?.favorite ?? false)) + } catch { + await send(.failedToFetchIsList(error)) + } + } + case .isFavoriteShowResponse(let isFavorite): + state.isLikeShow = isFavorite + return .none + case .failedToFetchIsList(let error): + print(error.localizedDescription) + return .none case .review: return .none } diff --git a/Projects/Show/Sources/Model/FetchIsFavoriteShowResponseDTO.swift b/Projects/Show/Sources/Model/FetchIsFavoriteShowResponseDTO.swift new file mode 100644 index 00000000..e598739d --- /dev/null +++ b/Projects/Show/Sources/Model/FetchIsFavoriteShowResponseDTO.swift @@ -0,0 +1,17 @@ +// +// FetchIsFavoriteShowResponseDTO.swift +// Show +// +// Created by 김민석 on 11/23/24. +// + +import Foundation + +struct FetchIsFavoriteShowResponseDTO: Decodable { + let content: [FetchIsFavoriteShowContent] +} + +struct FetchIsFavoriteShowContent: Decodable { + let showId: String + let favorite: Bool +} diff --git a/Projects/Show/Sources/Service/ShowService.swift b/Projects/Show/Sources/Service/ShowService.swift index bad315ff..bea03a36 100644 --- a/Projects/Show/Sources/Service/ShowService.swift +++ b/Projects/Show/Sources/Service/ShowService.swift @@ -18,6 +18,7 @@ enum ShowAPI { case fetchFavoriteShow case putFavoriteShow(id: String) case deleteFavoriteShow(id: String) + case fetchIsFavoriteShow(id: String) } extension ShowAPI: TargetType { @@ -32,6 +33,8 @@ extension ShowAPI: TargetType { return "/members/\(memberId)/favorite" case .putFavoriteShow(let id): return "/shows/\(id)/favorite" case .deleteFavoriteShow(let id): return "/shows/\(id)/favorite" + case .fetchIsFavoriteShow: + return "/member/favorite" } } var method: Moya.Method { @@ -57,6 +60,9 @@ extension ShowAPI: TargetType { case .fetchFavoriteShow: return .requestPlain case .putFavoriteShow: return .requestPlain case .deleteFavoriteShow: return .requestPlain + case .fetchIsFavoriteShow(let id): + param.updateValue(id, forKey: "showId") + return .requestParameters(parameters: param, encoding: URLEncoding.default) } } @@ -65,6 +71,7 @@ extension ShowAPI: TargetType { case .fetchFavoriteShow: return Utils.authHeader case .putFavoriteShow: return Utils.authHeader case .deleteFavoriteShow: return Utils.authHeader + case .fetchIsFavoriteShow: return Utils.authHeader default: return nil } } From 745eb4d0b0a210045916798889dd9270e4553d5f Mon Sep 17 00:00:00 2001 From: mandos1995 Date: Sun, 1 Dec 2024 16:31:46 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=EC=9E=91=ED=92=88=EC=83=81?= =?UTF-8?q?=EC=84=B8=EC=97=90=EC=84=9C=20=EC=A6=90=EA=B2=A8=EC=B0=BE?= =?UTF-8?q?=EA=B8=B0=20=ED=95=9C=20=EC=9E=91=ED=92=88=20UI=20=EB=8C=80?= =?UTF-8?q?=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/Show/Sources/Feature/ShowDetailFeature.swift | 7 ++++--- Projects/Show/Sources/Service/ShowService.swift | 2 +- Projects/Show/Sources/Views/ShowDetailView.swift | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Projects/Show/Sources/Feature/ShowDetailFeature.swift b/Projects/Show/Sources/Feature/ShowDetailFeature.swift index 10eccecf..5c904ad4 100644 --- a/Projects/Show/Sources/Feature/ShowDetailFeature.swift +++ b/Projects/Show/Sources/Feature/ShowDetailFeature.swift @@ -45,7 +45,7 @@ public struct ShowDetailFeature { case fetchIsFavoriteShow case review(ReviewFeature.Action) case isFavoriteShowResponse(Bool) - case failedToFetchIsList(Error) + case failedToFetchIsLike(Error) } @Dependency (\.showClient) var showClient @@ -58,6 +58,7 @@ public struct ShowDetailFeature { return .run { [id = state.showId] send in do { try await send(.showDetailResponse(showClient.fetchShowDetail(id))) + try await send(.fetchIsFavoriteShow) } catch { print(error.localizedDescription) } @@ -100,13 +101,13 @@ public struct ShowDetailFeature { do { try await send(.isFavoriteShowResponse(showClient.fetchIsFavoriteShow(id).content.first?.favorite ?? false)) } catch { - await send(.failedToFetchIsList(error)) + await send(.failedToFetchIsLike(error)) } } case .isFavoriteShowResponse(let isFavorite): state.isLikeShow = isFavorite return .none - case .failedToFetchIsList(let error): + case .failedToFetchIsLike(let error): print(error.localizedDescription) return .none case .review: diff --git a/Projects/Show/Sources/Service/ShowService.swift b/Projects/Show/Sources/Service/ShowService.swift index bea03a36..fc870e1a 100644 --- a/Projects/Show/Sources/Service/ShowService.swift +++ b/Projects/Show/Sources/Service/ShowService.swift @@ -61,7 +61,7 @@ extension ShowAPI: TargetType { case .putFavoriteShow: return .requestPlain case .deleteFavoriteShow: return .requestPlain case .fetchIsFavoriteShow(let id): - param.updateValue(id, forKey: "showId") + param.updateValue(id, forKey: "showIds") return .requestParameters(parameters: param, encoding: URLEncoding.default) } } diff --git a/Projects/Show/Sources/Views/ShowDetailView.swift b/Projects/Show/Sources/Views/ShowDetailView.swift index adcddbc6..1a8c4390 100644 --- a/Projects/Show/Sources/Views/ShowDetailView.swift +++ b/Projects/Show/Sources/Views/ShowDetailView.swift @@ -30,7 +30,7 @@ public struct ShowDetailView: View { VStack(spacing: 0) { HStack { Spacer() - Image(asset: CommonAsset.showDetailFavoriteHeartUnfill) + Image(asset: store.isLikeShow ? CommonAsset.showDetailFavoriteHeartFill : CommonAsset.showDetailFavoriteHeartUnfill) } .padding([.top, .trailing], 18) From 81bf4ef69e330fa397c3f64753fd8b5365555164 Mon Sep 17 00:00:00 2001 From: mandos1995 Date: Mon, 2 Dec 2024 22:57:19 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=EC=9E=91=ED=92=88=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=EC=97=90=EC=84=9C=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=EB=A0=89=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Feature/ShowDetailFeature.swift | 39 +++++++++++++++++++ .../Show/Sources/Views/ShowDetailView.swift | 3 ++ 2 files changed, 42 insertions(+) diff --git a/Projects/Show/Sources/Feature/ShowDetailFeature.swift b/Projects/Show/Sources/Feature/ShowDetailFeature.swift index 5c904ad4..96eac380 100644 --- a/Projects/Show/Sources/Feature/ShowDetailFeature.swift +++ b/Projects/Show/Sources/Feature/ShowDetailFeature.swift @@ -46,6 +46,11 @@ public struct ShowDetailFeature { case review(ReviewFeature.Action) case isFavoriteShowResponse(Bool) case failedToFetchIsLike(Error) + case didTappedFaovorite + case selectedFavorite + case deselectedFavorite + case isSucessSelectedFavorite(Bool) + case isSucessDeselectedFavorite(Bool) } @Dependency (\.showClient) var showClient @@ -112,6 +117,40 @@ public struct ShowDetailFeature { return .none case .review: return .none + case .didTappedFaovorite: + return .run { [isFavorite = state.isLikeShow ] send in + if isFavorite { + await send(.deselectedFavorite) + } else { + await send(.selectedFavorite) + } + } + case .selectedFavorite: + return .run { [showId = state.showId] send in + do { + try await send(.isSucessSelectedFavorite(showClient.putFavoriteShow(showId))) + } catch { + await send(.isSucessSelectedFavorite(false)) + } + } + case .deselectedFavorite: + return .run { [showId = state.showId] send in + do { + try await send(.isSucessDeselectedFavorite(showClient.deleteFavoriteShow(showId))) + } catch { + await send(.isSucessDeselectedFavorite(false)) + } + } + case .isSucessSelectedFavorite(let isSuccess): + guard isSuccess else { return .none } + return .run { send in + await send(.fetchDetailResponse) + } + case .isSucessDeselectedFavorite(let isSuccess): + guard isSuccess else { return .none } + return .run { send in + await send(.fetchDetailResponse) + } } } .ifLet(\.review, action: \.review) { diff --git a/Projects/Show/Sources/Views/ShowDetailView.swift b/Projects/Show/Sources/Views/ShowDetailView.swift index 1a8c4390..77ffe255 100644 --- a/Projects/Show/Sources/Views/ShowDetailView.swift +++ b/Projects/Show/Sources/Views/ShowDetailView.swift @@ -31,6 +31,9 @@ public struct ShowDetailView: View { HStack { Spacer() Image(asset: store.isLikeShow ? CommonAsset.showDetailFavoriteHeartFill : CommonAsset.showDetailFavoriteHeartUnfill) + .onTapGestureRectangle { + store.send(.didTappedFaovorite) + } } .padding([.top, .trailing], 18)