Skip to content

Commit

Permalink
fix: 검색 화면 QA 이슈 해결 (#72)
Browse files Browse the repository at this point in the history
* fix: 설정화면 QA 이슈 해결

* chore: 사용하지 않는 코드 삭제
  • Loading branch information
lina-wev authored Aug 22, 2024
1 parent 32e507e commit 9d94baf
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 49 deletions.
94 changes: 67 additions & 27 deletions Projects/Features/Search/Sources/View/Result/SearchResultView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,28 @@ public struct SearchResultView: View {
}

public var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 0) {
Text("\(viewModel.state.memeList.count)개의 밈을 찾았어요")
.font(Font.Body.Medium.medium)
.foregroundColor(Color.Text.primary)
.padding(.all, 20)

MemeListView(
memeDetailList: $viewModel.state.memeList,
memeClickHandler: { meme in
viewModel.dispatch(type: .memeDetailTapped(meme: meme))
},
memeCopyHandler: { meme in
viewModel.dispatch(type: .memeCopyTapped(meme: meme))
VStack(spacing: 0) {
Rectangle()
.fill(Color.Background.assistive)
.frame(maxWidth: .infinity)
.frame(height: 1)
.padding(.top, 51)

ScrollView {
VStack(alignment: .leading, spacing: 0) {
if viewModel.state.memeList.count > 0 {
memeListView
} else if viewModel.state.isLoading == false {
emptyMemeView
}
)
.padding(.horizontal, 20)

HStack(alignment: .center) {
Text("카페인 빨리 충전하고\n재밌는 밈 더 찾아둘게요!")
.font(Font.Body.Large.medium)
.foregroundColor(Color.Text.assistive)
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity)
.frame(height: 236)
}

}
.padding(.top, 51)
.plainNavigationBar(
backHandler: { viewModel.dispatch(type: .naviBackButtonTapped) },
rightActionHandler: nil,
hasConfigureButton: false,
title: "키워드"
title: viewModel.state.keyword
)
.onAppear {
viewModel.dispatch(type: .viewWillAppear)
Expand All @@ -66,4 +53,57 @@ public struct SearchResultView: View {
text: "이미지를 클립보드에 복사했어요"
)
}

private var memeListView: some View {
VStack(alignment: .leading, spacing: 0) {
Text("\(viewModel.state.memeList.count)개의 밈을 찾았어요")
.font(Font.Body.Medium.medium)
.foregroundColor(Color.Text.primary)
.padding(.all, 20)

MemeListView(
memeDetailList: $viewModel.state.memeList,
memeClickHandler: { meme in
viewModel.dispatch(type: .memeDetailTapped(meme: meme))
},
memeCopyHandler: { meme in
viewModel.dispatch(type: .memeCopyTapped(meme: meme))
}
)
.padding(.horizontal, 20)

HStack(alignment: .center) {
Text("카페인 빨리 충전하고\n재밌는 밈 더 찾아둘게요!")
.font(Font.Body.Large.medium)
.foregroundColor(Color.Text.assistive)
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity)
.frame(height: 236)
}
}

private var emptyMemeView: some View {
VStack(alignment: .center, spacing: 20) {
ResourceKitAsset.Icon.emptyMeme.swiftUIImage
.resizable()
.frame(width: 80, height: 80)
.padding(.top, 160)

VStack(spacing: 8) {
Text("밈이 없어요")
.font(Font.Heading.Small.bold)
.foregroundColor(Color.Text.primary)

HStack(alignment: .center) {
Text("카페인 빨리 충전하고\n재밌는 밈 더 찾아둘게요!")
.font(Font.Body.Large.medium)
.foregroundColor(Color.Text.assistive)
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity)
}
}
.frame(maxWidth: .infinity)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public final class SearchResultViewModel: ViewModelType, ObservableObject {
var keyword: String
var memeList: [MemeDetail]
var isActiveCopyPopup: Bool = false
var isLoading: Bool = true
}

// MARK: - Properties
Expand Down Expand Up @@ -80,7 +81,9 @@ public final class SearchResultViewModel: ViewModelType, ObservableObject {
@MainActor
private func fetchData() async {
do {
state.isLoading = true
state.memeList = try await searchKeywordUseCase.execute(keyword: state.keyword)
state.isLoading = false
} catch(let error) {
debugPrint("error = \(error)")
}
Expand Down
124 changes: 103 additions & 21 deletions Projects/Features/Search/Sources/View/SearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,48 @@ import PPACUtil
import DesignSystem
import ResourceKit

import SkeletonUI

public struct SearchView: View {
@Environment(\.screenSize) var screenSize
@ObservedObject var viewModel: SearchViewModel

public init(viewModel: SearchViewModel) {
self.viewModel = viewModel
}

public var body: some View {
VStack(spacing: 0) {
fakeSearchBar

ScrollView {
VStack(spacing: 0) {
currentHotKeywords
memeCategoriesViews
ZStack {
VStack(spacing: 0) {
fakeSearchBar

ScrollView {
VStack(spacing: 0) {
currentHotKeywords
memeCategoriesViews
}
}
.scrollIndicators(.hidden)
}
.scrollIndicators(.hidden)
}
.padding(.bottom, 40)
.onAppear {
viewModel.dispatch(type: .viewWillAppear)
}
.basicModal(
isPresented: $viewModel.state.isPresenting,
opacity: 0.5,
content: {
SearchPreparingAlert {
viewModel.dispatch(type: .dismissSearchBarAlert)
.padding(.bottom, 64 + 50) // 탭바 높이 추가
.onAppear {
viewModel.dispatch(type: .viewWillAppear)
}
.basicModal(
isPresented: $viewModel.state.isPresenting,
opacity: 0.5,
content: {
SearchPreparingAlert {
viewModel.dispatch(type: .dismissSearchBarAlert)
}
}
)

if viewModel.state.isLoading {
skeletonView
}
)
}
.animation(.easeInOut, value: viewModel.state.isLoading)
}

private var fakeSearchBar: some View {
Expand Down Expand Up @@ -107,7 +117,79 @@ public struct SearchView: View {
}
}
}

private var skeletonView: some View {
VStack(alignment: .leading, spacing: 0) {
EmptyView()
searchSkeleton(
size: .init(width: screenSize.width - 40, height: 44),
shape: .rounded(.radius(10))
)
.padding(.vertical, 16)

searchSkeleton(
size: .init(width: 200, height: 20),
shape: .rounded(.radius(4))
)
.padding(.vertical, 18)

ScrollView(.horizontal) {
HStack(spacing: 10) {
ForEach(0..<5) { _ in
searchSkeleton(
size: .init(width: 90, height: 92),
shape: .rounded(.radius(12))
)
}
Spacer()
}
}
.padding(.bottom, 40)

searchSkeleton(
size: .init(width: 200, height: 20),
shape: .rounded(.radius(4))
)
.padding(.vertical, 18)

searchSkeleton(
size: .init(width: 60, height: 16),
shape: .rounded(.radius(4))
)
.padding(.top, 4)
.padding(.bottom, 16)

HStack {
ForEach(0..<3) { _ in
searchSkeleton(
size: .init(width: 60, height: 36),
shape: .rounded(.radius(18))
)
.padding(.top, 4)
}
}

Spacer()
}
.padding(.leading, 20)
.background(.white)
}

private func searchSkeleton(size: CGSize? = .none, shape: ShapeType = .capsule) -> some View {
EmptyView()
.skeleton(
with: viewModel.state.isLoading,
size: size,
animation: .linear(duration: 2, delay: 0, speed: 1),
appearance: .gradient(
.linear,
color: Color.Skeleton.secondary,
background: Color.Skeleton.primary,
radius: 1
),
shape: shape
)
}
}

extension HotKeyword: HorizontalMemeItemProtocol {}

4 changes: 3 additions & 1 deletion Projects/Features/Search/Sources/View/SearchViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public final class SearchViewModel: ViewModelType, ObservableObject {
var hotKeywords: [HotKeyword]
var memeCategories: [MemeCategory]
var isPresenting: Bool = false
var isLoading: Bool = true
}

// MARK: - Properties
Expand Down Expand Up @@ -80,10 +81,11 @@ public final class SearchViewModel: ViewModelType, ObservableObject {
@MainActor
func fetchData() async {
guard state.hotKeywords == [] || state.memeCategories == [] else { return }

state.isLoading = true
do {
state.hotKeywords = try await hotKeywordsUseCase.execute()
state.memeCategories = try await memeCategorysUseCase.execute()
state.isLoading = false
} catch(let error) {
debugPrint("error = \(error)")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "empty_meme.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

0 comments on commit 9d94baf

Please sign in to comment.