Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
26f0a20
[feat] #180 FeatureRecommend 타겟 생성
ShapeKim98 Jan 29, 2025
0044fbf
[feat] #180 추천 컨텐츠 api 추가
ShapeKim98 Jan 29, 2025
1fa81a0
[feat] #180 Recommend 도메인 일부 작성
ShapeKim98 Jan 29, 2025
98d024c
[feat] #180 키워드 프로퍼티 추가
ShapeKim98 Jan 29, 2025
0eb87a8
[design] #180 추천 리스트 화면 일부 작성
ShapeKim98 Jan 29, 2025
10680fd
[design] #180 opacity 포킷 버튼 추가
ShapeKim98 Jan 29, 2025
7fdef9e
[design] #180 추천 콘텐츠 카드 버튼 추가
ShapeKim98 Jan 29, 2025
447ea60
[feat] #180 유저 관심사 목록 조회 api 작성
ShapeKim98 Jan 30, 2025
1e165ab
[fix] #180 추천 컨텐츠 조회 api 파라미터 누락 수정
ShapeKim98 Jan 30, 2025
ec6e019
[feat] #180 관심사 필터링 기능 구현
ShapeKim98 Jan 30, 2025
bea65b5
[feat] #180 링크 추가하기 delegate 작성
ShapeKim98 Jan 30, 2025
9c7a17c
[feat] #180 링크 공유하기 기능 구현
ShapeKim98 Jan 30, 2025
bc9fb13
[design] #180 관심사 편집 버튼 추가
ShapeKim98 Jan 30, 2025
b6bd4e0
[fix] #180 PokitFlowLayout 잘못된 레이아웃 수정
ShapeKim98 Jan 30, 2025
64408ae
[chore] #180 컨텐츠 목업 데이터 변경
ShapeKim98 Jan 30, 2025
9c02398
[fix] #180 잘못된 ui 수정
ShapeKim98 Jan 30, 2025
502675a
[feat] #180 리마인드 -> 추천으로 플로우 교체
ShapeKim98 Jan 30, 2025
84b61f8
[design] #180 링크 추천 헤더 디자인 변경
ShapeKim98 Jan 30, 2025
80fec61
[feat] #180 링크 url 이동 구현
ShapeKim98 Jan 30, 2025
6330343
[design] #180 관심사 필터 선택 ui/ux 개선
ShapeKim98 Jan 30, 2025
dbf931b
[remove] #180 FeatureRemind 제거
ShapeKim98 Jan 30, 2025
4a8d553
[chore] #180 그래프 업데이트
ShapeKim98 Jan 30, 2025
a2ce3f0
[fix] #180 피드백 반영
ShapeKim98 Feb 2, 2025
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
4 changes: 2 additions & 2 deletions Projects/App/Sources/MainTab/MainTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import DSKit

public enum MainTab: String, CaseIterable {
case pokit = "포킷"
case remind = "리마인드"
case recommend = "링크추천"

var title: String { return self.rawValue }

var icon: PokitImage {
switch self {
case .pokit: return .icon(.folderFill)
case .remind: return .icon(.remind)
case .recommend: return .icon(.remind)
}
}
}
41 changes: 36 additions & 5 deletions Projects/App/Sources/MainTab/MainTabFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SwiftUI

import ComposableArchitecture
import FeaturePokit
import FeatureRemind
import FeatureRecommend
import FeatureContentDetail
import Domain
import DSKit
Expand Down Expand Up @@ -37,7 +37,7 @@ public struct MainTabFeature {

var path: StackState<MainTabPath.State> = .init()
var pokit: PokitRootFeature.State
var remind: RemindFeature.State = .init()
var recommend: RecommendFeature.State = .init()
@Presents var contentDetail: ContentDetailFeature.State?
@Shared(.inMemory("SelectCategory")) var categoryId: Int?
@Shared(.inMemory("PushTapped")) var isPushTapped: Bool = false
Expand All @@ -59,7 +59,7 @@ public struct MainTabFeature {
/// Todo: scope로 이동
case path(StackAction<MainTabPath.State, MainTabPath.Action>)
case pokit(PokitRootFeature.Action)
case remind(RemindFeature.Action)
case recommend(RecommendFeature.Action)
case contentDetail(PresentationAction<ContentDetailFeature.Action>)

@CasePathable
Expand All @@ -70,6 +70,8 @@ public struct MainTabFeature {
case onAppear
case onOpenURL(url: URL)
case 경고_확인버튼_클릭
case 검색_버튼_눌렀을때
case 알림_버튼_눌렀을때
}
public enum InnerAction: Equatable {
case 링크추가및수정이동(contentId: Int)
Expand Down Expand Up @@ -129,7 +131,7 @@ public struct MainTabFeature {
return .none
case .pokit:
return .none
case .remind:
case .recommend:
return .none
case .contentDetail:
return .none
Expand All @@ -138,7 +140,14 @@ public struct MainTabFeature {
/// - Reducer body
public var body: some ReducerOf<Self> {
Scope(state: \.pokit, action: \.pokit) { PokitRootFeature() }
Scope(state: \.remind, action: \.remind) { RemindFeature() }
Scope(state: \.recommend, action: \.recommend) {
withDependencies {
$0[UserClient.self] = .testValue
$0[ContentClient.self] = .testValue
} operation: {
RecommendFeature()
}
}
Comment on lines +143 to +150
Copy link
Member

Choose a reason for hiding this comment

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

오우 이방법 되게 영리하네요 빨리 api나와야하는데


BindingReducer()
navigationReducer
Expand Down Expand Up @@ -198,6 +207,28 @@ private extension MainTabFeature {
case .경고_확인버튼_클릭:
state.error = nil
return .run { send in await send(.inner(.errorSheetPresented(false))) }
case .검색_버튼_눌렀을때:
switch state.selectedTab {
case .pokit: return .none
case .recommend:
return RecommendFeature()
.reduce(
into: &state.recommend,
action: .view(.검색_버튼_눌렀을때)
)
.map(Action.recommend)
}
case .알림_버튼_눌렀을때:
switch state.selectedTab {
case .pokit: return .none
case .recommend:
return RecommendFeature()
.reduce(
into: &state.recommend,
action: .view(.알림_버튼_눌렀을때)
)
.map(Action.recommend)
}
}
}
/// - Inner Effect
Expand Down
18 changes: 9 additions & 9 deletions Projects/App/Sources/MainTab/MainTabFeatureView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import SwiftUI
import ComposableArchitecture
import DSKit
import FeaturePokit
import FeatureRemind
import FeatureRecommend
import FeatureSetting
import FeatureCategorySetting
import FeatureContentDetail
Expand Down Expand Up @@ -135,8 +135,8 @@ private extension MainTabView {
.pokitNavigationBar { pokitNavigationBar }
.toolbarBackground(.hidden, for: .tabBar)

case .remind:
RemindView(store: store.scope(state: \.remind, action: \.remind))
case .recommend:
RecommendView(store: store.scope(state: \.recommend, action: \.recommend))
.pokitNavigationBar { remindNavigationBar }
.toolbarBackground(.hidden, for: .tabBar)
}
Expand Down Expand Up @@ -173,19 +173,19 @@ private extension MainTabView {
var remindNavigationBar: some View {
PokitHeader {
PokitHeaderItems(placement: .leading) {
Text("Remind")
.font(.system(size: 32, weight: .heavy))
.foregroundStyle(.pokit(.text(.brand)))
Text("링크추천")
.pokitFont(.title2)
.foregroundStyle(.pokit(.text(.primary)))
}

PokitHeaderItems(placement: .trailing) {
PokitToolbarButton(
.icon(.search),
action: { store.send(.remind(.view(.검색_버튼_눌렀을때))) }
action: { send(.검색_버튼_눌렀을때) }
)
PokitToolbarButton(
.icon(.bell),
action: { store.send(.remind(.view(.알림_버튼_눌렀을때))) }
action: { send(.알림_버튼_눌렀을때) }
)
}
}
Expand All @@ -198,7 +198,7 @@ private extension MainTabView {

Spacer()

bottomTabBarItem(.remind)
bottomTabBarItem(.recommend)
}
.padding(.horizontal, 48)
.padding(.top, 12)
Expand Down
19 changes: 5 additions & 14 deletions Projects/App/Sources/MainTab/MainTabPath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ public extension MainTabFeature {
switch action {
/// - 네비게이션 바 `알림`버튼 눌렀을 때
case .pokit(.delegate(.alertButtonTapped)),
.remind(.delegate(.alertButtonTapped)),
.recommend(.delegate(.알림_버튼_눌렀을때)),
.delegate(.알림함이동):
state.isPushTapped = false
state.path.append(.알림함(PokitAlertBoxFeature.State()))
return .none

/// - 네비게이션 바 `검색`버튼 눌렀을 때
case .pokit(.delegate(.searchButtonTapped)),
.remind(.delegate(.searchButtonTapped)):
.recommend(.delegate(.검색_버튼_눌렀을때)):
state.path.append(.검색(PokitSearchFeature.State()))
return .none

Expand Down Expand Up @@ -120,7 +120,6 @@ public extension MainTabFeature {
/// - 링크 상세
case let .path(.element(_, action: .카테고리상세(.delegate(.contentItemTapped(content))))),
let .pokit(.delegate(.contentDetailTapped(content))),
let .remind(.delegate(.링크상세(content))),
let .path(.element(_, action: .링크목록(.delegate(.링크상세(content: content))))),
let .path(.element(_, action: .검색(.delegate(.linkCardTapped(content: content))))):

Expand All @@ -130,7 +129,7 @@ public extension MainTabFeature {
/// - 링크상세 바텀시트에서 링크수정으로 이동
case let .contentDetail(.presented(.delegate(.editButtonTapped(id)))),
let .pokit(.delegate(.링크수정하기(id))),
let .remind(.delegate(.링크수정(id))),
let .recommend(.delegate(.추가하기_버튼_눌렀을때(id))),
let .path(.element(_, action: .카테고리상세(.delegate(.링크수정(id))))),
let .path(.element(_, action: .링크목록(.delegate(.링크수정(id))))),
let .path(.element(_, action: .검색(.delegate(.링크수정(id))))),
Expand All @@ -148,8 +147,8 @@ public extension MainTabFeature {
switch state.selectedTab {
case .pokit:
return .send(.pokit(.delegate(.미분류_카테고리_컨텐츠_조회)))
case .remind:
return .send(.remind(.delegate(.컨텐츠_상세보기_delegate_위임)))
case .recommend:
return .none
}
}
switch lastPath {
Expand Down Expand Up @@ -200,14 +199,6 @@ public extension MainTabFeature {
case let .pokit(.delegate(.linkPopup(text))):
state.linkPopup = .text(title: text)
return .none
/// 링크목록 `안읽음`
case .remind(.delegate(.링크목록_안읽음)):
state.path.append(.링크목록(ContentListFeature.State(contentType: .unread)))
return .none
/// 링크목록 `즐겨찾기`
case .remind(.delegate(.링크목록_즐겨찾기)):
state.path.append(.링크목록(ContentListFeature.State(contentType: .favorite)))
return .none

case .path(.element(_, action: .설정(.delegate(.로그아웃)))):
return .send(.delegate(.로그아웃))
Expand Down
16 changes: 9 additions & 7 deletions Projects/CoreKit/Sources/Data/DTO/Base/ContentBaseResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,26 @@ public struct ContentBaseResponse: Decodable {
public let createdAt: String
public let isRead: Bool?
public let isFavorite: Bool?
public let keyword: String?
}

extension ContentBaseResponse {
public static func mock(id: Int) -> Self {
Self(
contentId: id,
category: .init(
categoryId: 992,
categoryName: "미분류"
categoryId: 567,
categoryName: "신서유기"
),
data: "https://www.youtube.com/watch?v=wtSwdGJzQCQ",
data: "https://youtu.be/CIzKDrN7IpU?si=B0-7X7I_54VHAfkk",
domain: "youtube",
title: "신서유기",
title: "[#샷추가] 거리 두기 철저하게 지키게 만드는 인물 퀴즈ㅋㅋㅋ어떤 음식을 뺄지 고민하지 마요..어차피 다 못 먹으니까요🤣 | #신서유기5 #Diggle",
memo: nil,
thumbNail: "https://i.ytimg.com/vi/NnOC4_kH0ok/hqdefault.jpg?sqp=-oaymwEjCNACELwBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLDN6u6mTjbaVmRZ4biJS_aDq4uvAQ",
createdAt: "2024.08.08",
thumbNail: "https://i.ytimg.com/vi/CIzKDrN7IpU/maxresdefault.jpg",
createdAt: "2024.12.03",
isRead: false,
isFavorite: true
isFavorite: true,
keyword: "예능"
)
}
}
Expand Down
10 changes: 9 additions & 1 deletion Projects/CoreKit/Sources/Data/DTO/User/InterestResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ extension InterestResponse {
Self(code: "code2", description: "산책"),
Self(code: "code3", description: "프로그래밍"),
Self(code: "code4", description: "여행"),
Self(code: "code5", description: "요리")
Self(code: "code5", description: "요리"),
Self(code: "code6", description: "스포츠/레저"),
Self(code: "code7", description: "기획/마케팅"),
Self(code: "code8", description: "쇼핑"),
Self(code: "code9", description: "경제/시사"),
Self(code: "code10", description: "영화/드라마"),
Self(code: "code11", description: "장소"),
Self(code: "code12", description: "인테리어"),
Self(code: "code13", description: "IT"),
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ extension ContentClient: DependencyKey {
},
미분류_링크_삭제: { model in
try await provider.requestNoBody(.미분류_링크_삭제(model: model))
},
추천_컨텐츠_조회: { pageable, keyword in
try await provider.request(.추천_컨텐츠_조회(pageable: pageable, keyword: keyword))
}
)
}()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ extension ContentClient: TestDependencyKey {
컨텐츠_검색: { _, _ in .mock },
썸네일_수정: { _, _ in },
미분류_링크_포킷_이동: { _ in },
미분류_링크_삭제: { _ in }
미분류_링크_삭제: { _ in },
추천_컨텐츠_조회: { _, _ in .mock }
)
}()
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,9 @@ public struct ContentClient {
public var 미분류_링크_삭제: @Sendable (
_ model: ContentDeleteRequest
) async throws -> Void
public var 추천_컨텐츠_조회: @Sendable (
_ pageable: BasePageableRequest,
_ keyword: String?
) async throws -> ContentListInquiryResponse
}

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public enum ContentEndpoint {
case 썸네일_수정(contentId: String, model: ThumbnailRequest)
case 미분류_링크_포킷_이동(model: ContentMoveRequest)
case 미분류_링크_삭제(model: ContentDeleteRequest)
case 추천_컨텐츠_조회(
pageable: BasePageableRequest,
keyword: String?
)
}

extension ContentEndpoint: TargetType {
Expand Down Expand Up @@ -63,6 +67,8 @@ extension ContentEndpoint: TargetType {
return ""
case .미분류_링크_삭제:
return "/uncategorized"
case .추천_컨텐츠_조회:
return "/recommended"
}
}

Expand All @@ -85,7 +91,8 @@ extension ContentEndpoint: TargetType {

case .카태고리_내_컨텐츠_목록_조회,
.미분류_카테고리_컨텐츠_조회,
.컨텐츠_검색:
.컨텐츠_검색,
.추천_컨텐츠_조회:
return .get
}
}
Expand Down Expand Up @@ -126,6 +133,19 @@ extension ContentEndpoint: TargetType {
],
encoding: URLEncoding.default
)
case let .추천_컨텐츠_조회(pageable, keyword):
var parameters: [String: Any] = [
"page": pageable.page,
"size": pageable.size,
"sort": pageable.sort.map { String($0) }.joined(separator: ",")
]
if let keyword {
parameters["keyword"] = keyword
}
return .requestParameters(
parameters: parameters,
encoding: URLEncoding.default
)
case let .컨텐츠_검색(pageable, condition):
return .requestParameters(
parameters: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ extension UserClient: DependencyKey {
},
fcm_토큰_저장: { model in
try await provider.request(.fcm_토큰_저장(model: model))
},
유저_관심사_목록_조회: {
try await provider.request(.유저_관심사_목록_조회)
}
)
}()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ extension UserClient: TestDependencyKey {
닉네임_중복_체크: { _ in .mock },
관심사_목록_조회: { InterestResponse.mock },
닉네임_조회: { .mock },
fcm_토큰_저장: { _ in .mock }
fcm_토큰_저장: { _ in .mock },
유저_관심사_목록_조회: { InterestResponse.mock }
)
}()
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ public struct UserClient {
public var 관심사_목록_조회: @Sendable () async throws -> [InterestResponse]
public var 닉네임_조회: @Sendable () async throws -> BaseUserResponse
public var fcm_토큰_저장: @Sendable (_ model: FCMRequest) async throws -> FCMResponse
public var 유저_관심사_목록_조회: @Sendable () async throws -> [InterestResponse]
}
Loading