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: 폴더 구독 기능 구현 #206

Open
wants to merge 15 commits into
base: refactor
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion Tidify/Targets/Tidify/Config/Debug.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
// https://help.apple.com/xcode/#/dev745c5c974

KAKAO_NATIVE_APP_KEY = 2f2bda6aa215b8ede225cc7247fa120c
BASE_URL = 118.67.134.190:8080
BASE_URL = tdf-lb-316240643.ap-northeast-2.elb.amazonaws.com:8080
USER_AGENT = Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1
2 changes: 1 addition & 1 deletion Tidify/Targets/Tidify/Config/Release.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
// https://help.apple.com/xcode/#/dev745c5c974

KAKAO_NATIVE_APP_KEY = 2f2bda6aa215b8ede225cc7247fa120c
BASE_URL = 118.67.134.190:8080
BASE_URL = tdf-lb-316240643.ap-northeast-2.elb.amazonaws.com:8080
USER_AGENT = Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,37 @@ final class DefaultFolderDetailRepository: FolderDetailRepository {
}

// MARK: - Methods
func fetchBookmarkListInFolder(id: Int) async throws -> FetchBookmarkResponse {
let response = try await networkProvider.request(endpoint: FolderEndpoint.fetchBookmarkListInFolder(id: id), type: BookmarkListResponse.self)
func fetchBookmarkListInFolder(id: Int, subscribe: Bool) async throws -> FetchBookmarkResponse {
let response = try await networkProvider.request(endpoint: FolderEndpoint.fetchBookmarkListInFolder(id: id, subscribe: subscribe), type: BookmarkListResponse.self)

return FetchBookmarkResponse(
bookmarks: response.toDomain(),
currentPage: response.bookmarkListDTO.currentPage,
isLastPage: response.bookmarkListDTO.isLastPage
)
}

func subscribeFolder(id: Int) async throws {
let response = try await networkProvider.request(endpoint: FolderEndpoint.subscribeFolder(id: id), type: APIResponse.self)

if !response.isSuccess {
throw FolderSubscriptionError.failSubscribe
}
}

func stopSubscription(id: Int) async throws {
let response = try await networkProvider.request(endpoint: FolderEndpoint.stopSubscription(id: id), type: APIResponse.self)

if !response.isSuccess {
throw FolderSubscriptionError.failStopSubscription
}
}

func stopSharingFolder(id: Int) async throws {
let response = try await networkProvider.request(endpoint: FolderEndpoint.stopSharingFolder(id: id), type: APIResponse.self)

if !response.isSuccess {
throw FolderSubscriptionError.failStopSharing
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ enum BookmarkEndpoint: EndpointType {
}

extension BookmarkEndpoint {
var baseRouthPath: String {
var baseRoutePath: String {
return "/app/bookmarks"
}

var fullPath: String {
switch self {
case .fetchBoomarkList(let request, let category):
if request.keyword.isNotNil {
return AppProperties.baseURL + baseRouthPath + "/search"
return AppProperties.baseURL + baseRoutePath + "/search"
}
return AppProperties.baseURL + (category == .normal ? baseRouthPath : baseRouthPath + "/star")
return AppProperties.baseURL + (category == .normal ? baseRoutePath : baseRoutePath + "/star")
case .createBookmark:
return AppProperties.baseURL + baseRouthPath
return AppProperties.baseURL + baseRoutePath
case .deleteBookmark(let id), .updateBookmark(let id, _):
return AppProperties.baseURL + baseRouthPath + "/\(id)"
return AppProperties.baseURL + baseRoutePath + "/\(id)"
case .favoriteBookmark(let id):
return AppProperties.baseURL + baseRouthPath + "/star/\(id)"
return AppProperties.baseURL + baseRoutePath + "/star/\(id)"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
import TidifyCore

protocol EndpointType {
var baseRouthPath: String { get }
var baseRoutePath: String { get }
var fullPath: String { get }
var method: HTTPMethod { get }
var parameters: [String: String]? { get }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,51 @@ import TidifyDomain
enum FolderEndpoint: EndpointType {
case createFolder(request: FolderRequestDTO)
case fetchFolderList(start: Int, count: Int, category: FolderCategory)
case fetchBookmarkListInFolder(id: Int)
case fetchBookmarkListInFolder(id: Int, subscribe: Bool)
case updateFolder(id: Int, request: FolderRequestDTO)
case deleteFolder(id: Int)
case subscribeFolder(id: Int)
case stopSubscription(id: Int)
case stopSharingFolder(id: Int)
}

extension FolderEndpoint {
var baseRouthPath: String {
return "/app/folders"
var baseRoutePath: String {
return AppProperties.baseURL + "/app/folders"
}

var fullPath: String {
switch self {
case .createFolder:
return AppProperties.baseURL + baseRouthPath
return baseRoutePath
case .fetchFolderList(_, _, let category):
let path: String = AppProperties.baseURL + baseRouthPath
let path: String = baseRoutePath

switch category {
case .normal: return path
case .subscribe: return path + "/subscribed"
case .share: return path + "/subscribing"
}
case .fetchBookmarkListInFolder(let id):
return AppProperties.baseURL + baseRouthPath + "/\(id)/bookmarks"
case .fetchBookmarkListInFolder(let id, let subscribe):
var finalPath = baseRoutePath + "/\(id)/bookmarks"
if subscribe {
finalPath += "/shared"
}
return finalPath
case .deleteFolder(let id), .updateFolder(let id, _):
return AppProperties.baseURL + baseRouthPath + "/\(id)"
return baseRoutePath + "/\(id)"
case .subscribeFolder(let id):
return baseRoutePath + "/subscribed/\(id)"
case .stopSubscription(let id):
return baseRoutePath + "/un-subscribed/\(id)"
case .stopSharingFolder(let id):
return baseRoutePath + "/\(id)/share-suspending"
}
}

var method: HTTPMethod {
switch self {
case .createFolder:
case .createFolder, .subscribeFolder, .stopSubscription, .stopSharingFolder:
return .post
case .fetchFolderList, .fetchBookmarkListInFolder:
return .get
Expand Down Expand Up @@ -71,8 +84,7 @@ extension FolderEndpoint {
"label": request.color
]

case .deleteFolder, .fetchBookmarkListInFolder:
return nil
default: return nil
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ enum UserEndpoint: EndpointType {
}

extension UserEndpoint {
var baseRouthPath: String {
var baseRoutePath: String {
return "/oauth2"
}

var fullPath: String {
switch self {
case .signIn:
return AppProperties.baseURL + baseRouthPath + "/login"
return AppProperties.baseURL + baseRoutePath + "/login"
case .signOut:
return AppProperties.baseURL + baseRouthPath + "/withdrawal"
return AppProperties.baseURL + baseRoutePath + "/withdrawal"
}
}

Expand Down
3 changes: 2 additions & 1 deletion Tidify/Targets/TidifyDomain/Sources/DomainAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public struct DomainAssembly: Assemblable {
container.register(type: FolderDetailUseCase.self) { container in
return DefaultFolderDetailUseCase(
folderDetailRepository: container.resolve(type: FolderDetailRepository.self)!,
bookmarkRepository: container.resolve(type: BookmarkRepository.self)!
bookmarkRepository: container.resolve(type: BookmarkRepository.self)!,
folderRepository: container.resolve(type: FolderRepository.self)!
)
}
}
Expand Down
4 changes: 4 additions & 0 deletions Tidify/Targets/TidifyDomain/Sources/Entities/Folder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ public struct Folder: Equatable {
self.color = color
self.count = count
}

public static func ==(lhs: Folder, rhs: Folder) -> Bool {
lhs.id == rhs.id && lhs.title == rhs.title && lhs.color == rhs.color
}
}

public extension Folder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,14 @@
public protocol FolderDetailRepository: AnyObject {

/// 특정 폴더 ID에 포함된 북마크 리스트를 반환합니다.
func fetchBookmarkListInFolder(id: Int) async throws -> FetchBookmarkResponse
func fetchBookmarkListInFolder(id: Int, subscribe: Bool) async throws -> FetchBookmarkResponse

/// 특정 폴더를 구독합니다.
func subscribeFolder(id: Int) async throws

/// 특정 폴더의 구독을 취소합니다.
func stopSubscription(id: Int) async throws

/// 공유하고 있는 폴더의 공유를 중단합니다.
func stopSharingFolder(id: Int) async throws
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,54 @@
// Copyright © 2023 Tidify. All rights reserved.
//

public protocol FolderDetailUseCase: BookmarkListUseCase {
public protocol FolderDetailUseCase: BookmarkListUseCase & FetchFolderUseCase {
var bookmarkRepository: BookmarkRepository { get }

func fetchBookmarkListInFolder(id: Int) async throws -> FetchBookmarkResponse
func fetchBookmarkListInFolder(id: Int, subscribe: Bool) async throws -> FetchBookmarkResponse
func subscribeFolder(id: Int) async throws
func stopSubscription(id: Int) async throws
func stopSharingFolder(id: Int) async throws
}

public enum FolderSubscriptionError: Error {
case failStopSharing
case failStopSubscription
case failSharing
case failSubscribe
}

final class DefaultFolderDetailUseCase: FolderDetailUseCase {

// MARK: - Properties
private let folderDetailRepository: FolderDetailRepository
let bookmarkRepository: BookmarkRepository
let folderRepository: FolderRepository

// MARK: - Initializer
init(folderDetailRepository: FolderDetailRepository, bookmarkRepository: BookmarkRepository) {
init(
folderDetailRepository: FolderDetailRepository,
bookmarkRepository: BookmarkRepository,
folderRepository: FolderRepository
) {
self.folderDetailRepository = folderDetailRepository
self.bookmarkRepository = bookmarkRepository
self.folderRepository = folderRepository
}

// MARK: - Methods
func fetchBookmarkListInFolder(id: Int) async throws -> FetchBookmarkResponse {
try await folderDetailRepository.fetchBookmarkListInFolder(id: id)
func fetchBookmarkListInFolder(id: Int, subscribe: Bool) async throws -> FetchBookmarkResponse {
try await folderDetailRepository.fetchBookmarkListInFolder(id: id, subscribe: subscribe)
}

func subscribeFolder(id: Int) async throws {
try await folderDetailRepository.subscribeFolder(id: id)
}

func stopSubscription(id: Int) async throws {
try await folderDetailRepository.stopSubscription(id: id)
}

func stopSharingFolder(id: Int) async throws {
try await folderDetailRepository.stopSharingFolder(id: id)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,17 @@ public extension UIColor {

static func toColor(_ colorString: String) -> UIColor {
switch colorString {
case LabelColors.ASHBLUE.colorString: return .t_ashBlue()
case LabelColors.ASHBLUE.colorString, "BLACK": return .t_ashBlue()
case LabelColors.BLUE.colorString: return .t_blue()
case LabelColors.PURPLE.colorString: return .t_purple()
case LabelColors.GREEN.colorString: return .t_green()
case LabelColors.YELLOW.colorString: return .t_yellow()
case LabelColors.ORANGE.colorString: return .t_orange()
case LabelColors.RED.colorString: return .t_red()
case LabelColors.MINT.colorString: return .t_mint()
case LabelColors.MINT.colorString, "SKYBLUE": return .t_mint()
case LabelColors.INDIGO.colorString: return t_indigo()
case LabelColors.PINK.colorString: return .t_pink()
default: return .init()
default: return .t_ashBlue()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ fileprivate extension UIView {
override init(target: Any?, action: Selector?) {
super.init(target: target, action: action)
addTarget(self, action: #selector(tap))
cancelsTouchesInView = false
}

@objc private func tap(sender: UITapGestureRecognizer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ internal enum AlertType: CaseIterable {
case folderFetchError
case bookmarkCreationError
case bookmarkFetchError
case bookmarkFavoriteError
case bookmarkDeleteError
case stopFolderSharingError
case stopFolderSubscriptionError
case subscribeFolderError

var title: String {
switch self {
Expand All @@ -35,6 +40,11 @@ internal enum AlertType: CaseIterable {
case .folderFetchError: return "폴더를 불러올 수 없습니다"
case .bookmarkCreationError: return "저장에 실패했습니다"
case .bookmarkFetchError: return "북마크를 불러올 수 없습니다"
case .bookmarkDeleteError: return "북마크를 삭제할 수 없습니다"
case .bookmarkFavoriteError: return "북마크 즐겨찾기를 할 수 없습니다"
case .stopFolderSharingError: return "공유 중단에 실패했습니다."
case .stopFolderSubscriptionError: return "구독 취소에 실패했습니다"
case .subscribeFolderError: return "구독에 실패했습니다"
}
}

Expand All @@ -49,7 +59,9 @@ internal enum AlertType: CaseIterable {
case .loginError: return "네트워크 연결상태 혹은 선택한 플랫폼을 확인해주세요"
case .folderCreationError: return "네트워크 연결상태 혹은 폴더 제목을 확인해주세요"
case .folderFetchError, .bookmarkFetchError: return "네트워크 연결상태를 확인 후 다시 접속해주세요"
case .bookmarkFavoriteError, .bookmarkDeleteError: return "네트워크 연결상태 혹은 북마크 상태를 확인해주세요"
case .bookmarkCreationError: return "네트워크 연결상태 혹은 URL을 확인해주세요"
case .stopFolderSharingError, .stopFolderSubscriptionError, .subscribeFolderError: return "네트워크 연결상태 혹은 폴더 상태를 확인해주세요"
}
}

Expand Down
Loading