Skip to content

Commit

Permalink
Merge pull request #140 from YAPP-Github/refactor/#129-ContentListFea…
Browse files Browse the repository at this point in the history
…ture

refactor: ContentListFeature 액션 컨벤션 수정
  • Loading branch information
ShapeKim98 authored Oct 15, 2024
2 parents 38658ba + b8eaaec commit fb90c81
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,40 +66,40 @@ public struct ContentListFeature {
public enum View: Equatable, BindableAction {
/// - Binding
case binding(BindingAction<State>)

case pagenation
/// - Button Tapped
case linkCardTapped(content: BaseContentItem)
case kebabButtonTapped(content: BaseContentItem)
case bottomSheetButtonTapped(
case bottomSheet(
delegate: PokitBottomSheet.Delegate,
content: BaseContentItem
)
case deleteAlertConfirmTapped(content: BaseContentItem)
case sortTextLinkTapped
case backButtonTapped
case 컨텐츠_항목_눌렀을때(content: BaseContentItem)
case 컨텐츠_항목_케밥_버튼_눌렀을때(content: BaseContentItem)
case 컨텐츠_삭제_눌렀을때(content: BaseContentItem)
case 정렬_버튼_눌렀을때
case dismiss
/// - On Appeared
case contentListViewOnAppeared
case pagenation
case 뷰가_나타났을때

case 링크_공유_완료
case 링크_공유시트_해제
case 경고시트_해제
}

public enum InnerAction: Equatable {
case dismissBottomSheet
case 컨텐츠_목록_조회(BaseContentListInquiry)
case 컨텐츠_삭제_반영(id: Int)
case pagenation_네트워크_결과(BaseContentListInquiry)
case pagenation_초기화
case 컨텐츠_목록_갱신(BaseContentListInquiry)
case 컨텐츠_개수_갱신(Int)
case 바텀시트_해제
case 컨텐츠_목록_조회_API_반영(BaseContentListInquiry)
case 컨텐츠_삭제_API_반영(id: Int)
case 컨텐츠_목록_조회_페이징_API_반영(BaseContentListInquiry)
case 페이징_초기화
case 컨텐츠_개수_업데이트(Int)
}

public enum AsyncAction: Equatable {
case 읽지않음_컨텐츠_조회
case 즐겨찾기_링크모음_조회
case 컨텐츠_삭제(id: Int)
case pagenation_네트워크
case 페이징_재조회
case 컨텐츠_개수_조회
case 컨텐츠_삭제_API(id: Int)
case 컨텐츠_목록_조회_페이징_API
case 컨텐츠_목록_조회_API
case 컨텐츠_개수_조회_API
case 클립보드_감지
}

public enum ScopeAction: Equatable {
Expand Down Expand Up @@ -148,94 +148,79 @@ public struct ContentListFeature {
/// - Reducer body
public var body: some ReducerOf<Self> {
Reduce(self.core)
._printChanges()
}
}
//MARK: - FeatureAction Effect
private extension ContentListFeature {
/// - View Effect
func handleViewAction(_ action: Action.View, state: inout State) -> Effect<Action> {
switch action {
case .kebabButtonTapped(let content):
case .컨텐츠_항목_케밥_버튼_눌렀을때(let content):
state.bottomSheetItem = content
return .none
case .linkCardTapped(let content):
case .컨텐츠_항목_눌렀을때(let content):
return .send(.delegate(.링크상세(content: content)))
case .bottomSheetButtonTapped(let delegate, let content):
return .run { send in
await send(.inner(.dismissBottomSheet))
await send(.scope(.bottomSheet(delegate: delegate, content: content)))
}
case .deleteAlertConfirmTapped:
case .bottomSheet(let delegate, let content):
return .concatenate(
.send(.inner(.바텀시트_해제)),
.send(.scope(.bottomSheet(delegate: delegate, content: content)))
)
case .컨텐츠_삭제_눌렀을때:
guard let id = state.alertItem?.id else { return .none }
return .run { [id] send in
await send(.async(.컨텐츠_삭제(id: id)))
}
return .send(.async(.컨텐츠_삭제_API(id: id)))
case .binding:
return .none
case .sortTextLinkTapped:
case .정렬_버튼_눌렀을때:
state.isListDescending.toggle()
state.domain.pageable.sort = [
state.isListDescending ? "createdAt,desc" : "createdAt,asc"
]
return .send(.inner(.pagenation_초기화), animation: .pokitDissolve)
case .backButtonTapped:
return .send(.inner(.페이징_초기화), animation: .pokitDissolve)
case .dismiss:
return .run { _ in await dismiss() }
case .contentListViewOnAppeared:
return .run { [type = state.contentType] send in
switch type {
case .unread:
await send(.async(.읽지않음_컨텐츠_조회), animation: .pokitDissolve)
case .favorite:
await send(.async(.즐겨찾기_링크모음_조회), animation: .pokitDissolve)
}

for await _ in self.pasteBoard.changes() {
let url = try await pasteBoard.probableWebURL()
await send(.delegate(.linkCopyDetected(url)), animation: .pokitSpring)
}
}

case .뷰가_나타났을때:
return .merge(
.send(.async(.컨텐츠_개수_조회_API)),
.send(.async(.컨텐츠_목록_조회_API)),
.send(.async(.클립보드_감지))
)
case .pagenation:
return .send(.async(.pagenation_네트워크))
case .링크_공유_완료:
return .send(.async(.컨텐츠_목록_조회_페이징_API))
case .링크_공유시트_해제:
state.shareSheetItem = nil
return .none
case .경고시트_해제:
state.alertItem = nil
return .none
}
}

/// - Inner Effect
func handleInnerAction(_ action: Action.InnerAction, state: inout State) -> Effect<Action> {
switch action {
case .dismissBottomSheet:
case .바텀시트_해제:
state.bottomSheetItem = nil
return .none
case .컨텐츠_목록_조회(let contentList):
case .컨텐츠_목록_조회_페이징_API_반영(let contentList):
let list = state.domain.contentList.data ?? []
guard let newList = contentList.data else { return .none }

state.domain.contentList = contentList
state.domain.contentList.data = list + newList
return .none
case .컨텐츠_삭제_반영(id: let id):
case .컨텐츠_삭제_API_반영(id: let id):
state.alertItem = nil
state.domain.contentList.data?.removeAll { $0.id == id }
return .none
case .pagenation_네트워크_결과(let contentList):
case .컨텐츠_목록_조회_API_반영(let contentList):
state.domain.contentList = contentList
return .none
case .pagenation_초기화:
case .페이징_초기화:
state.domain.pageable.page = 0
state.domain.contentList.data = nil
switch state.contentType {
case .unread:
return .send(.async(.읽지않음_컨텐츠_조회), animation: .pokitDissolve)
case .favorite:
return .send(.async(.즐겨찾기_링크모음_조회), animation: .pokitDissolve)
}
case let .컨텐츠_목록_갱신(contentList):
state.domain.contentList = contentList
return .none
case let .컨텐츠_개수_갱신(count):
return .send(.async(.컨텐츠_목록_조회_API), animation: .pokitDissolve)
case let .컨텐츠_개수_업데이트(count):
state.domain.contentCount = count
return .none
}
Expand All @@ -244,105 +229,58 @@ private extension ContentListFeature {
/// - Async Effect
func handleAsyncAction(_ action: Action.AsyncAction, state: inout State) -> Effect<Action> {
switch action {
case .읽지않음_컨텐츠_조회:
return .run { [pageable = state.domain.pageable] send in
await send(.async(.컨텐츠_개수_조회))
let contentList = try await remindClient.읽지않음_컨텐츠_조회(
BasePageableRequest(
page: pageable.page,
size: pageable.size,
sort: pageable.sort
)
).toDomain()
await send(
.inner(.컨텐츠_목록_조회(contentList)),
animation: pageable.page == 0 ? .pokitDissolve : nil
)
}
case .즐겨찾기_링크모음_조회:
return .run { [pageable = state.domain.pageable] send in
await send(.async(.컨텐츠_개수_조회))
let contentList = try await remindClient.즐겨찾기_링크모음_조회(
BasePageableRequest(
page: pageable.page,
size: pageable.size,
sort: pageable.sort
)
).toDomain()
await send(
.inner(.컨텐츠_목록_조회(contentList)),
animation: pageable.page == 0 ? .pokitDissolve : nil
)
}
case .컨텐츠_삭제(id: let id):
return .run { [count = state.domain.contentCount] send in
let newCount = count - 1
await send(.inner(.컨텐츠_개수_갱신(newCount)), animation: .pokitSpring)
let _ = try await contentClient.컨텐츠_삭제("\(id)")
await send(.inner(.컨텐츠_삭제_반영(id: id)), animation: .pokitSpring)
}
case .컨텐츠_삭제_API(id: let id):
let count = state.domain.contentCount
let newCount = count - 1

return .merge(
.send(.inner(.컨텐츠_개수_업데이트(newCount))),
contentDelete(contentId: id)
)

case .pagenation_네트워크:
case .컨텐츠_목록_조회_페이징_API:
state.domain.pageable.page += 1
return .run { [type = state.contentType] send in
return .run { [
type = state.contentType,
pageableRequest = BasePageableRequest(
page: state.domain.pageable.page,
size: state.domain.pageable.size,
sort: state.domain.pageable.sort
)
] send in
let contentList: BaseContentListInquiry
switch type {
case .unread:
await send(.async(.읽지않음_컨텐츠_조회))
break
contentList = try await remindClient.읽지않음_컨텐츠_조회(
pageableRequest
).toDomain()
case .favorite:
await send(.async(.즐겨찾기_링크모음_조회))
break
contentList = try await remindClient.즐겨찾기_링크모음_조회(
pageableRequest
).toDomain()
}

await send(.inner(.컨텐츠_목록_조회_페이징_API_반영(contentList)))
}
case .페이징_재조회:
return .run { [
pageable = state.domain.pageable,
contentType = state.contentType
] send in
await send(.async(.컨텐츠_개수_조회))
let stream = AsyncThrowingStream<BaseContentListInquiry, Error> { continuation in
Task {
for page in 0...pageable.page {
let paeagableRequest = BasePageableRequest(
page: page,
size: pageable.size,
sort: pageable.sort
)
switch contentType {
case .favorite:
let contentList = try await remindClient.즐겨찾기_링크모음_조회(
paeagableRequest
).toDomain()
continuation.yield(contentList)
case .unread:
let contentList = try await remindClient.읽지않음_컨텐츠_조회(
paeagableRequest
).toDomain()
continuation.yield(contentList)
}
}
continuation.finish()
}
}
var contentItems: BaseContentListInquiry? = nil
for try await contentList in stream {
let items = contentItems?.data ?? []
let newItems = contentList.data ?? []
contentItems = contentList
contentItems?.data = items + newItems
}
guard let contentItems else { return }
await send(.inner(.컨텐츠_목록_갱신(contentItems)), animation: .pokitSpring)
}
case .컨텐츠_개수_조회:
case .컨텐츠_목록_조회_API:
return contentListFetch(state: &state)
case .컨텐츠_개수_조회_API:
return .run { [ contentType = state.contentType ] send in
let count: Int
switch contentType {
case .favorite:
let count = try await remindClient.즐겨찾기_컨텐츠_개수_조회().count
await send(.inner(.컨텐츠_개수_갱신(count)), animation: .pokitSpring)
count = try await remindClient.즐겨찾기_컨텐츠_개수_조회().count
case .unread:
let count = try await remindClient.읽지않음_컨텐츠_개수_조회().count
await send(.inner(.컨텐츠_개수_갱신(count)), animation: .pokitSpring)
count = try await remindClient.읽지않음_컨텐츠_개수_조회().count
}

await send(.inner(.컨텐츠_개수_업데이트(count)), animation: .pokitSpring)
}
case .클립보드_감지:
return .run { send in
for await _ in self.pasteBoard.changes() {
let url = try await pasteBoard.probableWebURL()
await send(.delegate(.linkCopyDetected(url)), animation: .pokitSpring)
}
}
}
Expand Down Expand Up @@ -372,11 +310,59 @@ private extension ContentListFeature {
func handleDelegateAction(_ action: Action.DelegateAction, state: inout State) -> Effect<Action> {
switch action {
case .컨텐츠_목록_조회:
return .send(.async(.페이징_재조회))
return .send(.async(.컨텐츠_목록_조회_API))
default:
return .none
}
}

func contentListFetch(state: inout State) -> Effect<Action> {
return .run { [
pageable = state.domain.pageable,
contentType = state.contentType
] send in
let stream = AsyncThrowingStream<BaseContentListInquiry, Error> { continuation in
Task {
for page in 0...pageable.page {
let paeagableRequest = BasePageableRequest(
page: page,
size: pageable.size,
sort: pageable.sort
)
switch contentType {
case .favorite:
let contentList = try await remindClient.즐겨찾기_링크모음_조회(
paeagableRequest
).toDomain()
continuation.yield(contentList)
case .unread:
let contentList = try await remindClient.읽지않음_컨텐츠_조회(
paeagableRequest
).toDomain()
continuation.yield(contentList)
}
}
continuation.finish()
}
}
var contentItems: BaseContentListInquiry? = nil
for try await contentList in stream {
let items = contentItems?.data ?? []
let newItems = contentList.data ?? []
contentItems = contentList
contentItems?.data = items + newItems
}
guard let contentItems else { return }
await send(.inner(.컨텐츠_목록_조회_API_반영(contentItems)))
}
}

func contentDelete(contentId: Int) -> Effect<Action> {
return .run { send in
let _ = try await contentClient.컨텐츠_삭제("\(contentId)")
await send(.inner(.컨텐츠_삭제_API_반영(id: contentId)), animation: .pokitSpring)
}
}
}

public extension ContentListFeature {
Expand Down
Loading

0 comments on commit fb90c81

Please sign in to comment.