From 6df854d4fb22bcf50d4de1dea1edcd85660a67a3 Mon Sep 17 00:00:00 2001 From: ericKwon95 Date: Thu, 28 Nov 2024 23:15:44 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20=EC=9D=B8=EA=B8=B0=20=EC=87=BC?= =?UTF-8?q?=EC=B8=A0=20=EB=A6=AC=EB=93=80=EC=84=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WeeklyPopularShortsReducer.swift | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsReducer.swift diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsReducer.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsReducer.swift new file mode 100644 index 0000000..e5c2ac1 --- /dev/null +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsReducer.swift @@ -0,0 +1,57 @@ +// +// WeeklyPopularShortsReducer.swift +// Climeet-iOS +// +// Created by 권승용 on 11/26/24. +// + +import Foundation +import ComposableArchitecture + +struct PopularShorts: Equatable, Identifiable { + let id = UUID() + let thumbnailImageURL: String + + init(from dto: ShortsDTO.Shorts.Response) throws { + guard let thumbnailImageURL = dto.thumbnailImageURL else { + throw AppError.dataParsingError("dto property nil") + } + self.thumbnailImageURL = thumbnailImageURL + } +} + +@Reducer +struct WeeklyPopularShortsReducer { + @ObservableState + struct State: Equatable { + var shortsItems: IdentifiedArrayOf = [] + } + + enum Action { + case onFirstAppear + case popularShortsResponse([PopularShorts]) + } + + @Dependency(\.shortsClient) var shortsClient + + var body: some ReducerOf { + Reduce { state, action in + switch action { + case .onFirstAppear: + return .run { send in + let request = ShortsDTO.List.Request(page: 0, size: 10) + let response = try await shortsClient.popularShorts(request) + let result = try response.result.map { + try PopularShorts(from: $0) + } + await send(.popularShortsResponse(result)) + } + + case let .popularShortsResponse(response): + state.shortsItems = IdentifiedArray(uniqueElements: response) + print(state.shortsItems) + return .none + } + } + } +} From 503960a7ef1ec873da0a9812031d44775df85a28 Mon Sep 17 00:00:00 2001 From: ericKwon95 Date: Thu, 28 Nov 2024 23:16:16 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EC=9D=B8=EA=B8=B0=20=EC=87=BC?= =?UTF-8?q?=EC=B8=A0=20=ED=99=94=EB=A9=B4=20=EC=8A=A4=ED=86=A0=EC=96=B4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Home/HomeReducer.swift | 5 ++++ .../Presentation/Home/HomeView.swift | 2 +- .../WeeklyPopularShortsView.swift | 23 +++++++++++++++---- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/HomeReducer.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/HomeReducer.swift index 2de8571..302215a 100644 --- a/Climeet-iOS/Climeet-iOS/Presentation/Home/HomeReducer.swift +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/HomeReducer.swift @@ -15,12 +15,14 @@ struct HomeReducer { var banner = BannerReducer.State() var shortcut = HomeGymShortcutReducer.State() var bestClimber = HomeBestClimberReducer.State() + var popularShorts = WeeklyPopularShortsReducer.State() } enum Action { case banner(BannerReducer.Action) case shortcut(HomeGymShortcutReducer.Action) case bestClimber(HomeBestClimberReducer.Action) + case popularShorts(WeeklyPopularShortsReducer.Action) } var body: some ReducerOf { @@ -33,5 +35,8 @@ struct HomeReducer { Scope(state: \.bestClimber, action: \.bestClimber) { HomeBestClimberReducer() } + Scope(state: \.popularShorts, action: \.popularShorts) { + WeeklyPopularShortsReducer() + } } } diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/HomeView.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/HomeView.swift index 5b522be..fb96b57 100644 --- a/Climeet-iOS/Climeet-iOS/Presentation/Home/HomeView.swift +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/HomeView.swift @@ -26,7 +26,7 @@ struct HomeView: View { .padding(.bottom, 48) HomeBestClimberView(store: store.scope(state: \.bestClimber, action: \.bestClimber)) .padding(.bottom, 48) - WeeklyPopularShortsView() + WeeklyPopularShortsView(store: store.scope(state: \.popularShorts, action: \.popularShorts)) .padding(.bottom, 48) WeeklyPopularGymView() .padding(.bottom, 48) diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift index c5e26c5..29107c0 100644 --- a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift @@ -6,8 +6,12 @@ // import SwiftUI +import ComposableArchitecture +import Kingfisher struct WeeklyPopularShortsView: View { + @Bindable var store: StoreOf + var body: some View { VStack(spacing: 0) { header @@ -15,6 +19,9 @@ struct WeeklyPopularShortsView: View { .padding(.bottom, 20) shorts } + .onFirstAppear { + store.send(.onFirstAppear) + } } private var header: some View { @@ -29,11 +36,14 @@ struct WeeklyPopularShortsView: View { private var shorts: some View { ScrollView(.horizontal) { - HStack(spacing: 7.75) { - ForEach(0..<8, id: \.self) { _ in - RoundedRectangle(cornerRadius: 5) - .foregroundStyle(.gray) + HStack(spacing: 8) { + ForEach(store.shortsItems) { item in + KFImage(URL(string: item.thumbnailImageURL)) + .resizable() + .aspectRatio(contentMode: .fill) .frame(width: 96, height: 160) + .clipped() + .cornerRadius(5) } } } @@ -42,6 +52,9 @@ struct WeeklyPopularShortsView: View { } #Preview { - WeeklyPopularShortsView() + let store = Store(initialState: WeeklyPopularShortsReducer.State()) { + WeeklyPopularShortsReducer() + } + WeeklyPopularShortsView(store: store) .background(Color.climeetBackground) } From 830ad5042be9e22a9dcb88d9ceaa9879c6fa3b03 Mon Sep 17 00:00:00 2001 From: ericKwon95 Date: Thu, 28 Nov 2024 23:16:41 +0900 Subject: [PATCH 3/9] =?UTF-8?q?chore:=20print=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Climeet-iOS/Presentation/Home/Banner/BannerReducer.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/Banner/BannerReducer.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/Banner/BannerReducer.swift index bfc2d01..4182cd4 100644 --- a/Climeet-iOS/Climeet-iOS/Presentation/Home/Banner/BannerReducer.swift +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/Banner/BannerReducer.swift @@ -83,7 +83,6 @@ struct BannerReducer { case .timerTick: state.timerCount += 1 - print(state.timerCount) if state.timerCount == bannerChangeTime { state.timerCount = 0 // TODO: banner change From 1616d02f08825641ca6befdb46b287aa28a528f5 Mon Sep 17 00:00:00 2001 From: ericKwon95 Date: Sat, 30 Nov 2024 00:05:26 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20=EC=95=94=EC=9E=A5=20=EB=82=9C?= =?UTF-8?q?=EC=9D=B4=EB=8F=84=20=EC=A0=95=EB=B3=B4=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - structured concurrency 적용 --- .../Model/GymDifficulty.swift | 22 ++++++++++ .../Model/PopularShorts.swift | 25 +++++++++++ .../WeeklyPopularShortsReducer.swift | 44 +++++++++++++------ 3 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/Model/GymDifficulty.swift create mode 100644 Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/Model/PopularShorts.swift diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/Model/GymDifficulty.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/Model/GymDifficulty.swift new file mode 100644 index 0000000..7def054 --- /dev/null +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/Model/GymDifficulty.swift @@ -0,0 +1,22 @@ +// +// GymDifficulty.swift +// Climeet-iOS +// +// Created by 권승용 on 11/29/24. +// + +import Foundation + +struct GymDifficulty: Equatable { + let level: Int + let color: String + + init(from dto: DifficultyMappingDTO.GymDifficulty.ResponseElement) throws { + guard let level = dto.difficulty, + let color = dto.gymDifficultyColor else { + throw AppError.dataParsingError("dto property nil") + } + self.level = level + self.color = color + } +} diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/Model/PopularShorts.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/Model/PopularShorts.swift new file mode 100644 index 0000000..fd98e50 --- /dev/null +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/Model/PopularShorts.swift @@ -0,0 +1,25 @@ +// +// PopularShorts.swift +// Climeet-iOS +// +// Created by 권승용 on 11/29/24. +// + +import Foundation + +struct PopularShorts: Equatable, Identifiable { + let id = UUID() + let gymName: String + let thumbnailImageURL: String + let difficulty: GymDifficulty + + init(from dto: ShortsDTO.Shorts.Response, difficulty: GymDifficulty) throws { + guard let gymName = dto.gymName, + let thumbnailImageURL = dto.thumbnailImageURL else { + throw AppError.dataParsingError("dto property nil") + } + self.gymName = gymName + self.thumbnailImageURL = thumbnailImageURL + self.difficulty = difficulty + } +} diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsReducer.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsReducer.swift index e5c2ac1..39ec7e7 100644 --- a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsReducer.swift +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsReducer.swift @@ -8,18 +8,6 @@ import Foundation import ComposableArchitecture -struct PopularShorts: Equatable, Identifiable { - let id = UUID() - let thumbnailImageURL: String - - init(from dto: ShortsDTO.Shorts.Response) throws { - guard let thumbnailImageURL = dto.thumbnailImageURL else { - throw AppError.dataParsingError("dto property nil") - } - self.thumbnailImageURL = thumbnailImageURL - } -} - @Reducer struct WeeklyPopularShortsReducer { @ObservableState @@ -33,6 +21,7 @@ struct WeeklyPopularShortsReducer { } @Dependency(\.shortsClient) var shortsClient + @Dependency(\.difficultyMappingClient) var difficultyMappingClient var body: some ReducerOf { Reduce { state, action in @@ -41,9 +30,36 @@ struct WeeklyPopularShortsReducer { return .run { send in let request = ShortsDTO.List.Request(page: 0, size: 10) let response = try await shortsClient.popularShorts(request) - let result = try response.result.map { - try PopularShorts(from: $0) + + let result = try await withThrowingTaskGroup(of: PopularShorts?.self) { group in + for responseItem in response.result { + group.addTask { + guard let id = responseItem.shortsDetailInfo?.gymID else { + throw AppError.dataParsingError("gymID not found") + } + + let difficulty = try await difficultyMappingClient.gymDifficulty(id) + + guard !difficulty.isEmpty else { return nil } + + return try PopularShorts( + from: responseItem, + difficulty: try GymDifficulty(from: difficulty[0]) + ) + } + } + + var popularShorts: [PopularShorts] = [] + + for try await item in group { + if let item = item { + popularShorts.append(item) + } + } + + return popularShorts } + await send(.popularShortsResponse(result)) } From a0781ec67b948c28c743849ae27c1c562f951332 Mon Sep 17 00:00:00 2001 From: ericKwon95 Date: Sat, 30 Nov 2024 00:06:36 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20=EC=87=BC=EC=B8=A0=20=EC=9C=84=20?= =?UTF-8?q?=EB=A3=A8=ED=8A=B8=20=EB=82=9C=EC=9D=B4=EB=8F=84=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WeeklyPopularShortsView.swift | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift index 29107c0..3543ca0 100644 --- a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift @@ -37,13 +37,27 @@ struct WeeklyPopularShortsView: View { private var shorts: some View { ScrollView(.horizontal) { HStack(spacing: 8) { - ForEach(store.shortsItems) { item in - KFImage(URL(string: item.thumbnailImageURL)) - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: 96, height: 160) - .clipped() - .cornerRadius(5) + if store.shortsItems.isEmpty { + ForEach(0..<8, id: \.self) { _ in + RoundedRectangle(cornerRadius: 5) + .foregroundStyle(.gray) + .frame(width: 96, height: 160) + } + } else { + ForEach(store.shortsItems) { item in + ShortsThumbnailView(imageURL: item.thumbnailImageURL) + .overlay { + VStack { + Spacer() + HStack { + Spacer() + DifficultyMark(difficulty: item.difficulty) + } + .padding(.trailing, 5) + .padding(.bottom, 10) + } + } + } } } } @@ -51,6 +65,41 @@ struct WeeklyPopularShortsView: View { } } +fileprivate struct ShortsThumbnailView: View { + let imageURL: String + + var body: some View { + KFImage(URL(string: imageURL)) + .placeholder({ + Color.gray + }) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 96, height: 160) + .clipped() + .cornerRadius(5) + } +} + +fileprivate struct DifficultyMark: View { + let difficulty: GymDifficulty + + var body: some View { + Text("V\(difficulty.level)") + .foregroundStyle(Color(hex: difficulty.color) ?? .gray) + .font(.climeetFontParagraph5()) + .frame(width: 30, height: 30) + .overlay { + Circle() + .stroke( + Color(hex: difficulty.color) ?? .gray, + style: StrokeStyle(lineWidth: 1.5) + ) + .frame(width: 30, height: 30) + } + } +} + #Preview { let store = Store(initialState: WeeklyPopularShortsReducer.State()) { WeeklyPopularShortsReducer() From 8c00359dbf2aa8e213e526ec96e4b0aeb2b672ed Mon Sep 17 00:00:00 2001 From: ericKwon95 Date: Sat, 30 Nov 2024 00:07:09 +0900 Subject: [PATCH 6/9] =?UTF-8?q?chore:=20pbxproj=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - xcconfig 파일 경로 정리 --- .../Climeet-iOS.xcodeproj/project.pbxproj | 30 +++++++------------ .../xcschemes/Climeet-iOS.xcscheme | 2 +- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/Climeet-iOS/Climeet-iOS.xcodeproj/project.pbxproj b/Climeet-iOS/Climeet-iOS.xcodeproj/project.pbxproj index e914b17..72dc86c 100644 --- a/Climeet-iOS/Climeet-iOS.xcodeproj/project.pbxproj +++ b/Climeet-iOS/Climeet-iOS.xcodeproj/project.pbxproj @@ -36,20 +36,11 @@ /* Begin PBXFileReference section */ 0453294E2C5B8E3400BBE289 /* Climeet-iOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Climeet-iOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 0489EEF92C3BE58E00BFC55B /* Climeet-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Climeet-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 04ED90052CD3A519009B59A0 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; B94EC2222BD13CBB00DC3FDB /* Climeet-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Climeet-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; B94EC2412BD1473E00DC3FDB /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ - 041DA0422CF419B600CFDC31 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Debug.xcconfig, - Shared.xcconfig, - ); - target = B94EC2212BD13CBB00DC3FDB /* Climeet-iOS */; - }; 604B97A62CC394F2005EDD29 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( @@ -60,7 +51,7 @@ /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ - 604B958E2CC394EF005EDD29 /* XCConfig */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (041DA0422CF419B600CFDC31 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = XCConfig; sourceTree = ""; }; + 604B958E2CC394EF005EDD29 /* XCConfig */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = XCConfig; sourceTree = ""; }; 604B96BF2CC394F2005EDD29 /* Climeet-iOS */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (604B97A62CC394F2005EDD29 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = "Climeet-iOS"; sourceTree = ""; }; 604B97A82CC394F5005EDD29 /* Climeet-iOSTests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = "Climeet-iOSTests"; sourceTree = ""; }; 604B97AC2CC394F7005EDD29 /* Climeet-iOSUITests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = "Climeet-iOSUITests"; sourceTree = ""; }; @@ -208,7 +199,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1530; - LastUpgradeCheck = 1600; + LastUpgradeCheck = 1610; TargetAttributes = { 0453294D2C5B8E3400BBE289 = { CreatedOnToolsVersion = 15.3; @@ -336,8 +327,6 @@ /* Begin XCBuildConfiguration section */ 045329572C5B8E3400BBE289 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 604B958E2CC394EF005EDD29 /* XCConfig */; - baseConfigurationReferenceRelativePath = Debug.xcconfig; buildSettings = { CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; @@ -382,8 +371,6 @@ }; 0489EF002C3BE58E00BFC55B /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 604B958E2CC394EF005EDD29 /* XCConfig */; - baseConfigurationReferenceRelativePath = Debug.xcconfig; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -430,6 +417,8 @@ }; B94EC22E2BD13CBD00DC3FDB /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReferenceAnchor = 604B958E2CC394EF005EDD29 /* XCConfig */; + baseConfigurationReferenceRelativePath = Release.xcconfig; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -493,6 +482,8 @@ }; B94EC22F2BD13CBD00DC3FDB /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReferenceAnchor = 604B958E2CC394EF005EDD29 /* XCConfig */; + baseConfigurationReferenceRelativePath = Release.xcconfig; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -550,7 +541,7 @@ B94EC2312BD13CBD00DC3FDB /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReferenceAnchor = 604B958E2CC394EF005EDD29 /* XCConfig */; - baseConfigurationReferenceRelativePath = Debug.xcconfig; + baseConfigurationReferenceRelativePath = Release.xcconfig; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -558,7 +549,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"Climeet-iOS/Preview Content\""; - DEVELOPMENT_TEAM = 7MJ69FU8BU; + DEVELOPMENT_TEAM = MV89SHQKF4; ENABLE_PREVIEWS = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; @@ -586,7 +577,8 @@ }; B94EC2322BD13CBD00DC3FDB /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 04ED90052CD3A519009B59A0 /* Release.xcconfig */; + baseConfigurationReferenceAnchor = 604B958E2CC394EF005EDD29 /* XCConfig */; + baseConfigurationReferenceRelativePath = Release.xcconfig; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -594,7 +586,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"Climeet-iOS/Preview Content\""; - DEVELOPMENT_TEAM = 7MJ69FU8BU; + DEVELOPMENT_TEAM = MV89SHQKF4; ENABLE_PREVIEWS = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; diff --git a/Climeet-iOS/Climeet-iOS.xcodeproj/xcshareddata/xcschemes/Climeet-iOS.xcscheme b/Climeet-iOS/Climeet-iOS.xcodeproj/xcshareddata/xcschemes/Climeet-iOS.xcscheme index b40aad4..b647777 100644 --- a/Climeet-iOS/Climeet-iOS.xcodeproj/xcshareddata/xcschemes/Climeet-iOS.xcscheme +++ b/Climeet-iOS/Climeet-iOS.xcodeproj/xcshareddata/xcschemes/Climeet-iOS.xcscheme @@ -1,6 +1,6 @@ Date: Sat, 30 Nov 2024 00:31:45 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20opaque=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20=ED=95=A8=EC=88=98=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=97=AC=EB=9F=AC=20=ED=83=80=EC=9E=85=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ViewBuilder 적용 --- .../Shorts/ShortsDeckView/ShortsDeckView.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Shorts/ShortsDeckView/ShortsDeckView.swift b/Climeet-iOS/Climeet-iOS/Presentation/Shorts/ShortsDeckView/ShortsDeckView.swift index 7c5c6f1..4e1c6fd 100644 --- a/Climeet-iOS/Climeet-iOS/Presentation/Shorts/ShortsDeckView/ShortsDeckView.swift +++ b/Climeet-iOS/Climeet-iOS/Presentation/Shorts/ShortsDeckView/ShortsDeckView.swift @@ -95,14 +95,13 @@ struct ShortsDeckView: View { } } + @ViewBuilder private func GymInfoView(gymName: String?, gymDifficultyColor: String?) -> some View { - if let gymName = gymName, let difficultyColor = gymDifficultyColor { let gymDifficultyColor = convertHexadecimal(difficultyColor) - - return HStack(spacing: 4) { + HStack(spacing: 4) { Text(gymName) .font(.system(size: 12, weight: .light)) .foregroundColor(.white) @@ -119,17 +118,18 @@ struct ShortsDeckView: View { .padding(.horizontal, 7) .padding(.vertical, 10) } else { - return Rectangle() + Rectangle() .foregroundStyle(.clear) } } - + + @ViewBuilder private func DifficultyView(colorHexadecimal: String?, difficulty: String?) -> some View { if let colorHexadecimal = colorHexadecimal, let difficulty = difficulty { let hexadecimal = convertHexadecimal(colorHexadecimal) - return ZStack { + ZStack { Circle() .stroke(hexadecimal, lineWidth: 1.5) .frame(width: 30, height: 30) @@ -139,7 +139,7 @@ struct ShortsDeckView: View { .lineLimit(1) } } else { - return Rectangle() + Rectangle() .foregroundStyle(.clear) } } From 3c344b27a615b32bc7b9f9001d29d97d8ae77649 Mon Sep 17 00:00:00 2001 From: ericKwon95 Date: Sat, 30 Nov 2024 00:55:04 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=20=ED=8F=B0=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/DesignSystem/Util/Font+.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/DesignSystem/Sources/DesignSystem/Util/Font+.swift b/DesignSystem/Sources/DesignSystem/Util/Font+.swift index 7838fcd..de9aba7 100644 --- a/DesignSystem/Sources/DesignSystem/Util/Font+.swift +++ b/DesignSystem/Sources/DesignSystem/Util/Font+.swift @@ -61,5 +61,20 @@ extension Font { public static func climeetFontCaptionText3() -> Self { Self.custom("Pretendard-Regular", size: 12) } + + public static func climeetFontCustom(size: CGFloat, weight: Font.Weight) -> Self { + switch weight { + case .bold: + Self.custom("Pretendard-Bold", size: size) + case .semibold: + Self.custom("Pretendard-SemiBold", size: size) + case .medium: + Self.custom("Pretendard-Medium", size: size) + case .regular: + Self.custom("Pretendard-Regular", size: size) + default: + Font.system(size: size, weight: weight) + } + } } #endif From f6f1c7824b42344044f690cc2ad48d70aaea108c Mon Sep 17 00:00:00 2001 From: ericKwon95 Date: Sat, 30 Nov 2024 00:55:36 +0900 Subject: [PATCH 9/9] =?UTF-8?q?feat:=20=EC=87=BC=EC=B8=A0=20=EC=83=81?= =?UTF-8?q?=EB=8B=A8=20=EC=95=94=EC=9E=A5=20=EC=A0=95=EB=B3=B4=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EB=B7=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WeeklyPopularShortsView.swift | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift index 3543ca0..5c1226b 100644 --- a/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift +++ b/Climeet-iOS/Climeet-iOS/Presentation/Home/WeeklyPopularShorts/WeeklyPopularShortsView.swift @@ -8,6 +8,7 @@ import SwiftUI import ComposableArchitecture import Kingfisher +import DesignSystem struct WeeklyPopularShortsView: View { @Bindable var store: StoreOf @@ -48,6 +49,12 @@ struct WeeklyPopularShortsView: View { ShortsThumbnailView(imageURL: item.thumbnailImageURL) .overlay { VStack { + HStack { + RouteInfo(gymTitle: item.gymName, holdColor: .red) + Spacer() + } + .padding(.top, 4) + .padding(.leading, 4) Spacer() HStack { Spacer() @@ -100,6 +107,28 @@ fileprivate struct DifficultyMark: View { } } +fileprivate struct RouteInfo: View { + let gymTitle: String + let holdColor: Color + + var body: some View { + HStack(alignment: .center, spacing: 2) { + Text(gymTitle) + .font(.climeetFontCustom(size: 8, weight: .regular)) + .foregroundStyle(.white) + Circle() + .foregroundStyle(holdColor) + .frame(width: 8, height: 8) + } + .padding(.horizontal, 5) + .padding(.vertical, 2) + .background { + Capsule() + .foregroundStyle(Color(hex: "#000000")?.opacity(0.5) ?? Color.red) + } + } +} + #Preview { let store = Store(initialState: WeeklyPopularShortsReducer.State()) { WeeklyPopularShortsReducer()