From 842cbba23b34594c4c162f27d0680ad18337948f Mon Sep 17 00:00:00 2001 From: chansooo <89574881+chansooo@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:02:53 +0900 Subject: [PATCH] =?UTF-8?q?Feature/=EB=B0=88=EC=83=81=EC=84=B8=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EA=B5=AC=ED=98=84=20#23=20(#26)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: memeDetail 모듈 추가 * feat: kingfisher 추가 * design: ㅋ, 개웃겨 리소스 추가 * feat: MemeDetail 모델 구현 * feat: MemeDetail UI 구현 * chore: 코드리뷰 봇 무시 * refactor: 재사용 가능한 뷰 분리 --- .github/workflows/codeReview.yml | 46 ++++++------ Projects/Core/PPACModels/Sources/Dummy.swift | 1 - .../PPACModels/Sources/Meme/MemeDetail.swift | 49 ++++++++++++ Projects/Features/MemeDetail/Project.swift | 30 ++++++++ .../Features/MemeDetail/Resources/dummy.swift | 1 + .../MemeDetail/Sources/HashTagView.swift | 40 ++++++++++ .../MemeDetail/Sources/LikeButton.swift | 23 ++++++ .../Sources/MemeDetailCardView.swift | 71 ++++++++++++++++++ .../MemeDetail/Sources/MemeDetailView.swift | 32 ++++++++ .../MemeDetail/Sources/MemeImageView.swift | 36 +++++++++ .../\343\205\213.imageset/Contents.json" | 23 ++++++ .../\343\205\213.imageset/\343\205\213.svg" | 6 ++ .../\343\205\213@2x.png" | Bin 0 -> 1336 bytes .../\343\205\213@3x.png" | Bin 0 -> 1856 bytes .../Contents.json" | 23 ++++++ .../\352\260\234\354\233\203\352\262\250.png" | Bin 0 -> 1705 bytes ...\260\234\354\233\203\352\262\250@2x 1.png" | Bin 0 -> 3253 bytes ...\260\234\354\233\203\352\262\250@3x 1.png" | Bin 0 -> 4772 bytes Tuist/Package.resolved | 9 +++ Tuist/Package.swift | 3 + .../TargetDependency+.swift | 1 + 21 files changed, 370 insertions(+), 24 deletions(-) delete mode 100644 Projects/Core/PPACModels/Sources/Dummy.swift create mode 100644 Projects/Core/PPACModels/Sources/Meme/MemeDetail.swift create mode 100644 Projects/Features/MemeDetail/Project.swift create mode 100644 Projects/Features/MemeDetail/Resources/dummy.swift create mode 100644 Projects/Features/MemeDetail/Sources/HashTagView.swift create mode 100644 Projects/Features/MemeDetail/Sources/LikeButton.swift create mode 100644 Projects/Features/MemeDetail/Sources/MemeDetailCardView.swift create mode 100644 Projects/Features/MemeDetail/Sources/MemeDetailView.swift create mode 100644 Projects/Features/MemeDetail/Sources/MemeImageView.swift create mode 100644 "Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/Contents.json" create mode 100644 "Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/\343\205\213.svg" create mode 100644 "Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/\343\205\213@2x.png" create mode 100644 "Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/\343\205\213@3x.png" create mode 100644 "Projects/ResourceKit/Resources/Icon.xcassets/\352\260\234\354\233\203\352\262\250.imageset/Contents.json" create mode 100644 "Projects/ResourceKit/Resources/Icon.xcassets/\352\260\234\354\233\203\352\262\250.imageset/\352\260\234\354\233\203\352\262\250.png" create mode 100644 "Projects/ResourceKit/Resources/Icon.xcassets/\352\260\234\354\233\203\352\262\250.imageset/\352\260\234\354\233\203\352\262\250@2x 1.png" create mode 100644 "Projects/ResourceKit/Resources/Icon.xcassets/\352\260\234\354\233\203\352\262\250.imageset/\352\260\234\354\233\203\352\262\250@3x 1.png" diff --git a/.github/workflows/codeReview.yml b/.github/workflows/codeReview.yml index 70b02a1..c3e107c 100644 --- a/.github/workflows/codeReview.yml +++ b/.github/workflows/codeReview.yml @@ -1,27 +1,27 @@ -name: Code Review +# name: Code Review -permissions: - contents: read - pull-requests: write +# permissions: +# contents: read +# pull-requests: write -on: - pull_request: - types: [opened, reopened, synchronize] +# on: +# pull_request: +# types: [opened, reopened, synchronize] -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: anc95/ChatGPT-CodeReview@main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - LANGUAGE: Korean - OPENAI_API_ENDPOINT: https://api.openai.com/v1 - MODEL: gpt-4o - # PROMPT: # example: Please check if there are any confusions or irregularities in the following code diff: - top_p: 1 - temperature: 1 - max_tokens: 4096 - MAX_PATCH_LENGTH: 10000 +# jobs: +# test: +# runs-on: ubuntu-latest +# steps: +# - uses: anc95/ChatGPT-CodeReview@main +# env: +# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +# OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} +# LANGUAGE: Korean +# OPENAI_API_ENDPOINT: https://api.openai.com/v1 +# MODEL: gpt-4o +# # PROMPT: # example: Please check if there are any confusions or irregularities in the following code diff: +# top_p: 1 +# temperature: 1 +# max_tokens: 4096 +# MAX_PATCH_LENGTH: 10000 diff --git a/Projects/Core/PPACModels/Sources/Dummy.swift b/Projects/Core/PPACModels/Sources/Dummy.swift deleted file mode 100644 index 8af4b57..0000000 --- a/Projects/Core/PPACModels/Sources/Dummy.swift +++ /dev/null @@ -1 +0,0 @@ -// dummy임니다 diff --git a/Projects/Core/PPACModels/Sources/Meme/MemeDetail.swift b/Projects/Core/PPACModels/Sources/Meme/MemeDetail.swift new file mode 100644 index 0000000..d33e88b --- /dev/null +++ b/Projects/Core/PPACModels/Sources/Meme/MemeDetail.swift @@ -0,0 +1,49 @@ +// +// MemeDetail.swift +// PPACModels +// +// Created by kimchansoo on 6/28/24. +// + +import Foundation + +public struct MemeDetail { + + // MARK: - Properties + + public let title: String + public let keywords: [String] + public let imageUrlString: String + public let source: String + public let isTodayMeme: Bool + public let reaction: Int + + // MARK: - Initializers + + public init( + title: String, + keywords: [String], + imageUrlString: String, + source: String, + isTodayMeme: Bool, + reaction: Int + ) { + self.title = title + self.keywords = keywords + self.imageUrlString = imageUrlString + self.source = source + self.isTodayMeme = isTodayMeme + self.reaction = reaction + } +} + +public extension MemeDetail { + static let mock = MemeDetail( + title: "나는 공부를 찢어", + keywords: ["공부", "학생", "시험기간"], + imageUrlString: "https://avatars.githubusercontent.com/u/26344479?s=64&v=4", + source: "깃허브", + isTodayMeme: true, + reaction: 4 + ) +} diff --git a/Projects/Features/MemeDetail/Project.swift b/Projects/Features/MemeDetail/Project.swift new file mode 100644 index 0000000..fb6ae79 --- /dev/null +++ b/Projects/Features/MemeDetail/Project.swift @@ -0,0 +1,30 @@ +// +// Project.swift +// MemeDetail +// +// Created by kimchansoo on 2024/06/28 +// + +import ProjectDescription +import ProjectDescriptionHelpers + +let project = Project( + name: "MemeDetail", + targets: [ + .configure( + name: "MemeDetail", + product: .framework, + infoPlist: .default, + sources: "Sources/**", + resources: "Resources/**", + dependencies: [ + .ThirdParty.Dependency, + .ThirdParty.Kingfisher, + .ResourceKit, + .Core.DesignSystem, + .Core.PPACModels, + ] + ) + ] +) + diff --git a/Projects/Features/MemeDetail/Resources/dummy.swift b/Projects/Features/MemeDetail/Resources/dummy.swift new file mode 100644 index 0000000..1f7ee25 --- /dev/null +++ b/Projects/Features/MemeDetail/Resources/dummy.swift @@ -0,0 +1 @@ +//더미임미다 diff --git a/Projects/Features/MemeDetail/Sources/HashTagView.swift b/Projects/Features/MemeDetail/Sources/HashTagView.swift new file mode 100644 index 0000000..4b4795b --- /dev/null +++ b/Projects/Features/MemeDetail/Sources/HashTagView.swift @@ -0,0 +1,40 @@ +// +// HashTagView.swift +// MemeDetail +// +// Created by kimchansoo on 6/29/24. +// + +import SwiftUI + +public struct HashTagView: View { + + // MARK: - Properties + + private let keywords: [String] + + // MARK: - Initializers + + public init(keywords: [String]) { + self.keywords = keywords + } + + // MARK: - UI + + var body: some View { + HStack(alignment: .center, spacing: 6) { + ForEach(keywords, id: \.self) { title in + hashTag(title: title) + } + } + .frame(maxWidth: .infinity, alignment: .center) + .cornerRadius(40) + } + + func hashTag(title: String) -> some View { + Text("#\(title)") + .font(Font.Body.large) + .foregroundColor(Color.Text.tertiary) + } + +} diff --git a/Projects/Features/MemeDetail/Sources/LikeButton.swift b/Projects/Features/MemeDetail/Sources/LikeButton.swift new file mode 100644 index 0000000..aa2bb75 --- /dev/null +++ b/Projects/Features/MemeDetail/Sources/LikeButton.swift @@ -0,0 +1,23 @@ +// +// LikeButton.swift +// MemeDetail +// +// Created by kimchansoo on 6/29/24. +// + +import SwiftUI + +import ResourceKit + +public struct LikeButton: View { + var body: some View { + HStack(alignment: .center, spacing: 6) { + ResourceKitAsset.Icon.ㅋ.swiftUIImage + ResourceKitAsset.Icon.개웃겨.swiftUIImage + } + .frame(maxWidth: .infinity) + .frame(height: 46, alignment: .center) + .background(Color.Skeleton.primary) + .cornerRadius(10) + } +} diff --git a/Projects/Features/MemeDetail/Sources/MemeDetailCardView.swift b/Projects/Features/MemeDetail/Sources/MemeDetailCardView.swift new file mode 100644 index 0000000..0be0224 --- /dev/null +++ b/Projects/Features/MemeDetail/Sources/MemeDetailCardView.swift @@ -0,0 +1,71 @@ +// +// MemeDetailCardView.swift +// MemeDetail +// +// Created by kimchansoo on 6/29/24. +// + +import SwiftUI + +import PPACModels +import Kingfisher +import ResourceKit + +struct MemeDetailCardView: View { + + // MARK: - Properties + + let meme: MemeDetail + + // MARK: - UI + + var body: some View { + VStack(alignment: .center, spacing: 0) { + + MemeImageView(imageUrlString: meme.imageUrlString) + .padding(.bottom, 25) + + titleLabel + .padding(.bottom, 5) + + HashTagView(keywords: meme.keywords) + .padding(.bottom, 11) + + subtitleLabel + .padding(.bottom, 20) + + LikeButton() + .padding(.bottom, 20) + } + .padding(10) + .background(.white) + .cornerRadius(20) + .overlay( + RoundedRectangle(cornerRadius: 20) + .inset(by: 1) + .stroke(.black, lineWidth: 2) + ) + .padding(.horizontal, 24) + } + + // MARK: - Methods + + var titleLabel: some View { + Text(meme.title) + .font(Font.Heading.large.weight(.semibold)) + .multilineTextAlignment(.center) + .foregroundColor(Color.Text.primary) + .frame(maxWidth: .infinity, alignment: .center) + } + + var subtitleLabel: some View { + Text("출처: \(self.meme.source)") + .font(Font.Body.xsmall) + .multilineTextAlignment(.center) + .foregroundColor(Color.Icon.assistive) + } +} + +#Preview { + MemeDetailCardView(meme: .mock) +} diff --git a/Projects/Features/MemeDetail/Sources/MemeDetailView.swift b/Projects/Features/MemeDetail/Sources/MemeDetailView.swift new file mode 100644 index 0000000..ba2a1c3 --- /dev/null +++ b/Projects/Features/MemeDetail/Sources/MemeDetailView.swift @@ -0,0 +1,32 @@ +// +// MemeDetailView.swift +// MemeDetail +// +// Created by kimchansoo on 6/28/24. +// + +import SwiftUI + +import PPACModels + +struct MemeDetailView: View { + + // MARK: - Properties + private let meme: MemeDetail + + // MARK: - Initializers + + init(meme: MemeDetail) { + self.meme = meme + } + + // MARK: - UI + + var body: some View { + MemeDetailCardView(meme: meme) + } +} + +#Preview { + MemeDetailView(meme: .mock) +} diff --git a/Projects/Features/MemeDetail/Sources/MemeImageView.swift b/Projects/Features/MemeDetail/Sources/MemeImageView.swift new file mode 100644 index 0000000..4538f00 --- /dev/null +++ b/Projects/Features/MemeDetail/Sources/MemeImageView.swift @@ -0,0 +1,36 @@ +// +// MemeImageView.swift +// MemeDetail +// +// Created by kimchansoo on 6/29/24. +// + +import SwiftUI + +import Kingfisher + +struct MemeImageView: View { + + // MARK: - Properties + + private let imageUrlString: String + + // MARK: - Initializers + + init(imageUrlString: String) { + self.imageUrlString = imageUrlString + } + + // MARK: - UI + + var body: some View { + KFImage(URL(string: imageUrlString)) + .resizable() + .loadDiskFileSynchronously() + .cacheMemoryOnly() + .fade(duration: 0.25) + .frame(maxWidth: .infinity) + .aspectRatio(0.9375, contentMode: .fit) + .cornerRadius(10) + } +} diff --git "a/Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/Contents.json" "b/Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/Contents.json" new file mode 100644 index 0000000..5c48c84 --- /dev/null +++ "b/Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "ㅋ.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "ㅋ@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "ㅋ@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/\343\205\213.svg" "b/Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/\343\205\213.svg" new file mode 100644 index 0000000..8506d44 --- /dev/null +++ "b/Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/\343\205\213.svg" @@ -0,0 +1,6 @@ + + + + + + diff --git "a/Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/\343\205\213@2x.png" "b/Projects/ResourceKit/Resources/Icon.xcassets/\343\205\213.imageset/\343\205\213@2x.png" new file mode 100644 index 0000000000000000000000000000000000000000..ddac985a2905c0fda9a93c20577aff1abdbb7427 GIT binary patch literal 1336 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 literal 0 HcmV?d00001 diff --git "a/Projects/ResourceKit/Resources/Icon.xcassets/\352\260\234\354\233\203\352\262\250.imageset/\352\260\234\354\233\203\352\262\250@2x 1.png" "b/Projects/ResourceKit/Resources/Icon.xcassets/\352\260\234\354\233\203\352\262\250.imageset/\352\260\234\354\233\203\352\262\250@2x 1.png" new file mode 100644 index 0000000000000000000000000000000000000000..a51e7027b934f2b5d9468f2f7c5cbd9965780186 GIT binary patch literal 3253 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 literal 0 HcmV?d00001 diff --git "a/Projects/ResourceKit/Resources/Icon.xcassets/\352\260\234\354\233\203\352\262\250.imageset/\352\260\234\354\233\203\352\262\250@3x 1.png" "b/Projects/ResourceKit/Resources/Icon.xcassets/\352\260\234\354\233\203\352\262\250.imageset/\352\260\234\354\233\203\352\262\250@3x 1.png" new file mode 100644 index 0000000000000000000000000000000000000000..67107bfc96209293e748581ee081eed8789a0b35 GIT binary patch literal 4772 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