-
Notifications
You must be signed in to change notification settings - Fork 0
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] 태그 관리 기능 구현 #482
[Feat] 태그 관리 기능 구현 #482
Changes from 5 commits
b0ebd57
3b64c6b
9688f0b
a738e81
18498c5
ce27f42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ protocol PaperDataRepository: Sendable { | |
|
||
// 문서에 태그를 추가합니다 | ||
@discardableResult | ||
func addTag(to id: UUID, with tag: String) -> Result<VoidResponse, Error> | ||
func addTag(to id: UUID, with tag: String) -> Result<Tag, Error> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이하 동일 |
||
|
||
// 문서의 태그를 삭제합니다 : 전체 태그 리스트에서는 유지 | ||
@discardableResult | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,7 +103,7 @@ extension DefaultHomeSearchUseCase { | |
private func fetchPapersByTagName(_ tagName: String) -> [PaperInfo] { | ||
let response = tagDataRepository.fetchAllTags() | ||
if case let .success(tags) = response { | ||
let result = tags.filter { $0.name == tagName } | ||
let result = tags.filter { $0.name.localizedCaseInsensitiveContains(tagName) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이름이 정확해야지 검색이 되는 기존 로직에서 같은 스펠이 들어가 있으면 검색 결과에 포함이 되도록 수정했습니다! |
||
|
||
if result.isEmpty { | ||
return [] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// | ||
// TagControlUseCase.swift | ||
// Reazy | ||
// | ||
// Created by 문인범 on 3/6/25. | ||
// | ||
|
||
import Foundation | ||
|
||
|
||
/** | ||
태그 관리 유즈케이스 (태그 생성, 추가, 삭제 등) | ||
*/ | ||
protocol TagControlUseCase { | ||
@discardableResult | ||
func addTagToPaper(to paperId: UUID, with tag: String) -> Result<Tag, Error> | ||
|
||
@discardableResult | ||
func removeTagFromPaper(to paperId: UUID, with tagId: UUID) -> Result<VoidResponse, Error> | ||
|
||
@discardableResult | ||
func createTag(_ name: String) -> Result<Tag, Error> | ||
|
||
func searchTags(_ name: String) throws -> [Tag] | ||
} | ||
|
||
|
||
final class DefaultTagControlUseCase: TagControlUseCase { | ||
private let paperDataRepository: PaperDataRepository | ||
private let tagRepository: TagDataRepository | ||
|
||
init(paperDataRepository: PaperDataRepository, tagRepository: TagDataRepository) { | ||
self.paperDataRepository = paperDataRepository | ||
self.tagRepository = tagRepository | ||
} | ||
|
||
func addTagToPaper(to paperId: UUID, with tag: String) -> Result<Tag, Error> { | ||
paperDataRepository.addTag(to: paperId, with: tag) | ||
} | ||
|
||
func removeTagFromPaper(to paperId: UUID, with tagId: UUID) -> Result<VoidResponse, Error> { | ||
paperDataRepository.removeTag(from: paperId, tagID: tagId) | ||
} | ||
|
||
func createTag(_ name: String) -> Result<Tag, Error> { | ||
tagRepository.addTag(name: name) | ||
} | ||
|
||
func searchTags(_ name: String) throws -> [Tag] { | ||
let tags = tagRepository.fetchAllTags() | ||
|
||
switch tags { | ||
case let .success(tags): | ||
let filteredResult = tags.filter { $0.name.localizedCaseInsensitiveContains(name) } | ||
return filteredResult | ||
case .failure: | ||
throw NSError() | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ struct HomePDFCell: View { | |
let starAction: () -> Void | ||
let tagAction: (UUID) -> Void | ||
let editAction: () -> Void | ||
let setTagAction: () -> Void | ||
let copyAction: () -> Void | ||
let deleteAction: () -> Void | ||
|
||
|
@@ -48,6 +49,9 @@ struct HomePDFCell: View { | |
EllipsisButtonView { | ||
editAction() | ||
popover.toggle() | ||
} setTagAction: { | ||
setTagAction() | ||
popover.toggle() | ||
Comment on lines
+52
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PaperInfo 셀의 ellipsis 액션에 태그 관리 액션을 추가했습니다 |
||
} copyPaperAction: { | ||
copyAction() | ||
popover.toggle() | ||
|
@@ -148,6 +152,7 @@ private struct EllipsisView: View { | |
// MARK: - Epllipsis 버튼 뷰 | ||
private struct EllipsisButtonView: View { | ||
let editTitleAction: () -> Void | ||
let setTagAction: () -> Void | ||
let copyPaperAction: () -> Void | ||
let deletePaperAction: () -> Void | ||
|
||
|
@@ -174,6 +179,7 @@ private struct EllipsisButtonView: View { | |
|
||
Button { | ||
// TODO: 추후 연결 필요 | ||
setTagAction() | ||
} label: { | ||
HStack { | ||
Text("태그 관리") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ final class HomeSearchViewModel: ObservableObject, Sendable { | |
enum SearchViewStatus: Hashable { | ||
case normal | ||
case search(PaperInfo) | ||
case setTag(PaperInfo) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 태그 관리 뷰의 트리거를 위해 케이스를 추가 했습니다(이름 수정 뷰의 트리거와 동일하게 돌아감) |
||
} | ||
} | ||
|
||
|
@@ -134,6 +135,15 @@ extension HomeSearchViewModel { | |
} | ||
} | ||
|
||
// MARK: - TagControl 메소드 | ||
extension HomeSearchViewModel { | ||
public func setTagButtonTapped(_ paperInfo: PaperInfo) { | ||
withAnimation(.easeInOut) { | ||
viewStatus = .setTag(paperInfo) | ||
} | ||
} | ||
} | ||
|
||
|
||
// MARK: - Internal Method | ||
extension HomeSearchViewModel { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -221,6 +221,20 @@ struct HomeView: View { | |
} completeAction: { text in | ||
homeSearchViewModel.completeButtonTappedInEditingTitle(title: text) | ||
} | ||
.onDisappear { | ||
homeSearchViewModel.searchPapers() | ||
} | ||
Comment on lines
+235
to
+237
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 수정 결과가 이전 뷰에 반영이 될 수 있게 해당 뷰를 나가면 데이터를 다시 fetch 하도록 바꾸었습니다! |
||
} | ||
// 태그 관리 | ||
if case let .setTag(paperInfo) = homeSearchViewModel.viewStatus { | ||
TagControlView(paperInfo: paperInfo) { | ||
homeSearchViewModel.viewStatus = .normal | ||
} completeAction: { | ||
homeSearchViewModel.viewStatus = .normal | ||
} | ||
.onDisappear { | ||
homeSearchViewModel.searchPapers() | ||
} | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// | ||
// TagControlCell.swift | ||
// Reazy | ||
// | ||
// Created by 문인범 on 3/7/25. | ||
// | ||
|
||
import SwiftUI | ||
|
||
|
||
struct TagControlCell: View { | ||
let tag: Tag? | ||
let name: String | ||
|
||
let action: () -> Void | ||
|
||
init(name: String) { | ||
self.tag = nil | ||
self.name = name | ||
self.action = {} | ||
} | ||
|
||
init(tag: Tag, action: @escaping () -> Void) { | ||
self.tag = tag | ||
self.name = tag.name | ||
self.action = action | ||
} | ||
Comment on lines
+17
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 버튼으로 사용하는 경우와 단순히 보여주기 위한 셀로 쓰이는 경우가 나뉘어져 있어
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 초기화를 이런 식으로 사용할 수도 있군요,, 굳굳!!! |
||
|
||
var body: some View { | ||
Button { | ||
action() | ||
} label: { | ||
Text(tag?.name ?? name) | ||
.reazyFont(.body3) | ||
.foregroundStyle(.gray800) | ||
.frame(height: 28) | ||
.padding(.horizontal, 9) | ||
.background { | ||
RoundedRectangle(cornerRadius: 5) | ||
.foregroundStyle(.primary3) | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UI반영을 위해(추가된 태그 표시) 추가된 태그를 반환하도록 변경했습니다!