Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 검색 화면 정리 및 검색 상세 화면 구현 #46

Merged
merged 5 commits into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Projects/Core/DesignSystem/Sources/HorizontalMimScrollView.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// HorizontalMimScrollView.swift
// HorizontalMememScrollView.swift
// DesignSystem
//
// Created by 리나 on 2024/06/29.
Expand All @@ -8,14 +8,14 @@
import SwiftUI
import ResourceKit

public protocol HorizontalMimItemProtocol: Hashable { }
public protocol HorizontalMemeItemProtocol: Hashable { }

public protocol HorizontalMimItemViewProtocol: View {
associatedtype Item: HorizontalMimItemProtocol
public protocol HorizontalMemeItemViewProtocol: View {
associatedtype Item: HorizontalMemeItemProtocol
init(item: Item)
}

public struct HorizontalMimScrollView<Item: HorizontalMimItemProtocol, ItemView: HorizontalMimItemViewProtocol>: View where ItemView.Item == Item {
public struct HorizontalMemeScrollView<Item: HorizontalMemeItemProtocol, ItemView: HorizontalMemeItemViewProtocol>: View where ItemView.Item == Item {
@Binding public var items: [Item]
private var itemClickHandler: ((Item) -> ())?
public init(items: Binding<[Item]>, itemClickHandler: ((Item) -> ())? = nil) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// CategoryTagView.swift
// KeywordsTagView.swift
// DesignSystem
//
// Created by 리나 on 2024/06/29.
Expand All @@ -9,33 +9,39 @@ import SwiftUI
import ResourceKit

// thanks to NamS
public struct CategoryTagView: View {
@State public var categories: [String]
public struct KeywordsTagView: View {
@State public var keywords: [String]
var onTapHandler: ((String) -> ())?

public init(categories: [String]) {
self.categories = categories
public init(keywords: [String], onTapHandler: ((String) -> ())?) {
self.keywords = keywords
self.onTapHandler = onTapHandler
}

public var body: some View {
ScrollView {
CategoryTagLayout(verticalSpacing: 8, horizontalSpacing: 8) {
ForEach(categories, id: \.self) { category in
Text(category)
ForEach(keywords, id: \.self) { keyword in
Text(keyword)
.font(Font.Body.Medium.medium)
.foregroundColor(Color.Text.primary)
.padding(.horizontal, 16)
.padding(.vertical, 9.5)
.background(
Capsule().foregroundStyle(Color.Background.assistive)
)
.onTapGesture {
onTapHandler?(keyword)
}
}
}
}
.onAppear {
// tagView 사이즈를 잰 후 다시 그리기 위함
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
let cacheValue = categories
categories = []
categories = cacheValue
let cacheValue = keywords
keywords = []
keywords = cacheValue
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// MimCategoryView.swift
// MemeCategoryView.swift
// DesignSystem
//
// Created by 리나 on 2024/06/30.
Expand All @@ -8,19 +8,25 @@
import SwiftUI
import ResourceKit

public struct MimCategoryView: View {
public let title: String
public let categories: [String]
public struct MemeCategoryView: View {
public let category: String
public let keywords: [String]
public let onTapHandler: ((String) -> ())?

public init(title: String, categories: [String]) {
self.title = title
self.categories = categories
public init(
category: String,
keywords: [String],
onTapHandler: ((String) -> ())?
) {
self.category = category
self.keywords = keywords
self.onTapHandler = onTapHandler
}

public var body: some View {
VStack(spacing: 0) {
HStack {
Text(title)
Text(category)
.font(Font.Body.Small.semiBold)
.foregroundColor(Color.Text.tertiary)

Expand All @@ -30,7 +36,7 @@ public struct MimCategoryView: View {
.padding(.bottom, 16)
.padding(.horizontal, 20)

CategoryTagView(categories: categories)
KeywordsTagView(keywords: keywords, onTapHandler: onTapHandler)
.padding(.horizontal, 20)
.padding(.bottom, 20)
}
Expand Down
21 changes: 12 additions & 9 deletions Projects/Core/DesignSystem/Sources/View/Meme/MemeListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ import SwiftUI
import PPACModels

public struct MemeListView: View {
private let memeDetailList: [MemeDetail]
private let columns = Array(repeating: GridItem(.flexible(),
spacing: 12,
alignment: .center),count: 2)
@Binding var memeDetailList: [MemeDetail]
private let columns = Array(
repeating: GridItem(
.flexible(),
spacing: 12,
alignment: .center
), count: 2
)
Comment on lines +12 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 gridItem으로 하고 grid 사용하면 두 column 사이에 공백이 생길텐데 그 부분은 추후에 처리하실 예정이실까요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hryeong66 확인 부탁드려횹🙏

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hryeong66 확인 부탁드려횹🙏

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앟 요거 grid로 하면 한 row 의 높이가 높은 쪽에 맞춰져서 디자인 요구사항을 맞출 수 없어
LazyVStack 두개를 HStack으로 넣는걸로 수정했습니다!
그래서 요 column 안쓰는데 삭제가 안되었네여.. 다음 PR 때 같이 삭제해서 올릴게요~!
image

private let memeClickHandler: ((MemeDetail) -> ())?
private let memeCopyHandler: ((MemeDetail) -> ())?
private let onAppearLastMemeHandler: (() -> ())?
Expand All @@ -22,12 +26,12 @@ public struct MemeListView: View {
}

public init(
memeDetailList: [MemeDetail],
memeDetailList: Binding<[MemeDetail]>,
memeClickHandler: ((MemeDetail) -> ())? = nil,
memeCopyHandler: ((MemeDetail) -> ())? = nil,
onAppearLastMemeHandler: (() -> ())? = nil
) {
self.memeDetailList = memeDetailList
self._memeDetailList = memeDetailList
self.memeClickHandler = memeClickHandler
self.memeCopyHandler = memeCopyHandler
self.onAppearLastMemeHandler = onAppearLastMemeHandler
Expand All @@ -45,7 +49,6 @@ public struct MemeListView: View {
}
}


public var body: some View {
ScrollView {
HStack(alignment: .top) {
Expand Down Expand Up @@ -96,11 +99,11 @@ public struct MemeListView: View {

"https://images.unsplash.com/photo-1507146426996-ef05306b995a?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" ]

let memeDetailList = (0..<20)
@State var memeDetailList = (0..<20)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20개로 한정된 이유가 있나요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hryeong66 요거 그냥 테스트용으로 두신거죠?_?
크게 이유 없어보입니당~

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 요거는 테스트로 추가한거라 개수는 임의로 넣었습니답!

lina0322 marked this conversation as resolved.
Show resolved Hide resolved
.map { MemeDetail(id: "\($0)", title: MemeDetail.mock.title,
keywords: MemeDetail.mock.keywords,
imageUrlString: mockImageList[$0 % 4],
source: MemeDetail.mock.source,
isTodayMeme: true, reaction: $0 % 4, isFarmemed: true) }
return MemeListView(memeDetailList: memeDetailList)
return MemeListView(memeDetailList: $memeDetailList)
}
20 changes: 11 additions & 9 deletions Projects/Core/PPACData/Sources/Endpoint/MemeEndpoint.swift
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
////
//// MemeEndpoint.swift
//// PPACData
////
//// Created by kimchansoo on 7/6/24.
////
//
//import Foundation
// MemeEndpoint.swift
// PPACData
//
//import PPACNetwork
// Created by kimchansoo on 7/6/24.
//

import Foundation

import PPACNetwork
import PPACUtil

public enum MemeEndpoint: Requestable {

case recommendMeme(size: Int)
case getSearchKeywordMemeList(keyword: String)
case meme(memeId: String)
case bookmark(memeId: String)
case share(memeId: String)
Expand All @@ -31,6 +27,8 @@ public enum MemeEndpoint: Requestable {
switch self {
case .recommendMeme:
return .get
case .getSearchKeywordMemeList:
return .get
case .meme:
return .get
case .bookmark:
Expand All @@ -52,6 +50,8 @@ public enum MemeEndpoint: Requestable {
switch self {
case .recommendMeme:
return "/meme/recommend-memes"
case let .getSearchKeywordMemeList(keyword):
return "/meme/search/\(keyword)"
case .meme(let memeId):
return "/meme/\(memeId)"
case .bookmark(let memeId):
Expand All @@ -69,6 +69,8 @@ public enum MemeEndpoint: Requestable {
switch self {
case .recommendMeme(let size):
return .query(["size": String(size)])
case .getSearchKeywordMemeList:
return nil
case .bookmark:
return nil
case .share:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ public final class KeywordRepositoryImpl: KeywordRepository {
// MARK: - Methods

public func getHotKeywords() async throws -> [HotKeyword] {
let result = await self.networkService
.request(KeywordEndPoint.getTopKeywords,
dataType: BaseDTO<[TopKeywordResponseDTO]>.self)
let endPoint = KeywordEndPoint.getTopKeywords
let result = await self.networkService.request(endPoint, dataType: BaseDTO<[TopKeywordResponseDTO]>.self)
switch result {
case .success(let data):
guard let hotKeywordData = data.data else { throw NetworkError.dataDecodingError }
Expand All @@ -37,16 +36,15 @@ public final class KeywordRepositoryImpl: KeywordRepository {
}
}

public func getMimCategorys() async throws -> [MimCategory] {
let result = await self.networkService
.request(KeywordEndPoint.getRecommendKeywords,
dataType: BaseDTO<[RecommendKeywordResponseDTO]>.self)
public func getMemeCategorys() async throws -> [MemeCategory] {
let endPoint = KeywordEndPoint.getRecommendKeywords
let result = await self.networkService.request(endPoint, dataType: BaseDTO<[RecommendKeywordResponseDTO]>.self)
switch result {
case .success(let data):
guard let mimCategoryData = data.data else { throw NetworkError.dataDecodingError }
let mimCategorys = mimCategoryData
.compactMap { MimCategory(title: $0.category, categories: $0.keywords.map {$0.name }) }
return mimCategorys
guard let memeCategoryData = data.data else { throw NetworkError.dataDecodingError }
let memeCategorys = memeCategoryData
.compactMap { MemeCategory(category: $0.category, keywords: $0.keywords.map { $0.name }) }
return memeCategorys
case .failure(let error):
throw error
}
Expand Down
12 changes: 12 additions & 0 deletions Projects/Core/PPACData/Sources/Repository/MemeRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ public class MemeRepositoryImpl: MemeRepository {
}
}

public func getSearchKeywordMemeList(keyword: String) async throws -> [MemeDetail] {
let endpoint = MemeEndpoint.getSearchKeywordMemeList(keyword: keyword)
let result = await networkservice.request(endpoint, dataType: BaseDTO<MemeWithPaginationResponseDTO>.self)
switch result {
case .success(let data):
guard let memeResponseDTOList = data.data?.memeList else { throw NetworkError.dataDecodingError }
return memeResponseDTOList.map { $0.toModel() }
case .failure(let error):
throw error
}
}

public func getMemeDetail(memeId: String) async throws -> MemeDetail {
let endpoint = MemeEndpoint.meme(memeId: memeId)
let result = await networkservice.request(endpoint, dataType: BaseDTO<MemeResponseDTO>.self)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ import PPACModels

public protocol KeywordRepository {
func getHotKeywords() async throws -> [HotKeyword]
func getMimCategorys() async throws -> [MimCategory]
func getMemeCategorys() async throws -> [MemeCategory]
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import PPACModels
public protocol MemeRepository {

func getRecommendMemes(size: Int) async throws -> [MemeDetail]
func getSearchKeywordMemeList(keyword: String) async throws -> [MemeDetail]
func getMemeDetail(memeId: String) async throws -> MemeDetail
func bookmarkMeme(memeId: String) async throws
func shareMeme(memeId: String) async throws
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// SearchKeywordUseCase.swift
// PPACDomain
//
// Created by 리나 on 7/18/24.
//

import Foundation

import PPACModels

public protocol SearchKeywordUseCase {
func execute(keyword: String) async throws -> [MemeDetail]
}

public class SearchKeywordUseCaseImpl: SearchKeywordUseCase {
private let repository: MemeRepository

public init(repository: MemeRepository) {
self.repository = repository
}

public func execute(keyword: String) async throws -> [MemeDetail] {
try await repository.getSearchKeywordMemeList(keyword: keyword)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// HotKeywordsUseCase.swift
// PPACDomain
//
// Created by 리나 on 7/18/24.
//

import Foundation

import PPACModels

public protocol HotKeywordsUseCase {
func execute() async throws -> [HotKeyword]
}

public class HotKeywordsUseCaseImpl: HotKeywordsUseCase {
private let repository: KeywordRepository

public init(repository: KeywordRepository) {
self.repository = repository
}

public func execute() async throws -> [HotKeyword] {
try await repository.getHotKeywords()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// MemeCategorysUseCase.swift
// PPACDomain
//
// Created by 리나 on 7/18/24.
//

import Foundation

import PPACModels

public protocol MemeCategorysUseCase {
func execute() async throws -> [MemeCategory]
}

public class MemeCategorysUseCaseImpl: MemeCategorysUseCase {
private let repository: KeywordRepository

public init(repository: KeywordRepository) {
self.repository = repository
}

public func execute() async throws -> [MemeCategory] {
try await repository.getMemeCategorys()
}
}
Loading
Loading