Skip to content
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 Projects/App/Resources/Pokit-info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.0.2</string>
<string>2.1.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand Down
2 changes: 1 addition & 1 deletion Projects/App/ShareExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<key>CFBundleName</key>
<string>Pokit</string>
<key>CFBundleShortVersionString</key>
<string>2.0.1</string>
<string>2.1.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand Down
40 changes: 32 additions & 8 deletions Projects/App/Sources/MainTab/MainTabFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ComposableArchitecture
import FeaturePokit
import FeatureRecommend
import FeatureContentDetail
import FeatureCategoryDetail
import Domain
import DSKit
import Util
Expand Down Expand Up @@ -79,14 +80,14 @@ public struct MainTabFeature {
public enum InnerAction: Equatable {
case 링크추가및수정이동(contentId: Int)
case linkCopySuccess(URL?)
case 공유포킷_이동(sharedCategory: CategorySharing.SharedCategory)
case 공유받은_카테고리_이동(category: BaseCategoryItem, type: CategoryType)
case 경고_띄움(BaseError)
case errorSheetPresented(Bool)
case 링크팝업_활성화(PokitLinkPopup.PopupType)
case 카테고리상세_이동(category: BaseCategoryItem)
}
public enum AsyncAction: Equatable {
case 공유받은_카테고리_조회(categoryId: Int)
case 공유받은_카테고리_조회(categoryId: Int, shareType: String?)
}
public enum ScopeAction: Equatable { case doNothing }
public enum DelegateAction: Equatable {
Expand Down Expand Up @@ -208,15 +209,17 @@ private extension MainTabFeature {
let categoryIdString = queryItems.first(where: { $0.name == "categoryId" })?.value,
let categoryId = Int(categoryIdString)
else { return .none }


let shareType = queryItems.first(where: { $0.name == "shareType" })?.value

switch state.selectedTab {
case .pokit:
amplitudeTrack(.view_home_pokit(entryPoint: "deeplink"))
case .recommend:
amplitudeTrack(.view_home_recommend(entryPoint: "deeplink"))
}

return .send(.async(.공유받은_카테고리_조회(categoryId: categoryId)))
return .send(.async(.공유받은_카테고리_조회(categoryId: categoryId, shareType: shareType)))
case .경고_확인버튼_클릭:
state.error = nil
return .run { send in await send(.inner(.errorSheetPresented(false))) }
Expand Down Expand Up @@ -275,18 +278,39 @@ private extension MainTabFeature {
}
state.path.append(.카테고리상세(.init(category: category)))
return .none

case let .공유받은_카테고리_이동(category, type):
state.path.append(.카테고리상세(.init(type: type, category: category)))
return .none

default: return .none
}
}
/// - Async Effect
func handleAsyncAction(_ action: Action.AsyncAction, state: inout State) -> Effect<Action> {
switch action {
case let .공유받은_카테고리_조회(categoryId: categoryId):
case let .공유받은_카테고리_조회(categoryId: categoryId, shareType: shareType):
return .run { send in
do {
let request = BasePageableRequest(page: 0, size: 10, sort: ["createdAt", "desc"])
let sharedCategory = try await categoryClient.공유받은_카테고리_조회("\(categoryId)", request).toDomain()
await send(.inner(.공유포킷_이동(sharedCategory: sharedCategory)), animation: .smooth)
let request = BasePageableRequest(page: 0, size: 10, sort: ["createdAt,desc"])
let response = try await categoryClient.공유받은_카테고리_조회("\(categoryId)", request)
let category = BaseCategoryItem(
id: response.category.categoryId,
userId: 0,
categoryName: response.category.categoryName,
categoryImage: BaseCategoryImage(
imageId: response.category.categoryImageId,
imageURL: response.category.categoryImageUrl
),
contentCount: response.category.contentCount,
createdAt: "",
openType: .공개,
keywordType: .default,
userCount: 0,
isFavorite: false
)
let type: CategoryType = shareType == "invite" ? .초대 : .공유
await send(.inner(.공유받은_카테고리_이동(category: category, type: type)), animation: .smooth)
} catch {
guard let errorResponse = error as? ErrorResponse else { return }
let errorDomain = BaseError(response: errorResponse)
Expand Down
5 changes: 0 additions & 5 deletions Projects/App/Sources/MainTab/MainTabFeatureView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import FeatureContentDetail
import FeatureContentSetting
import FeatureCategoryDetail
import FeatureContentList
import FeatureCategorySharing

@ViewAction(for: MainTabFeature.self)
public struct MainTabView: View {
Expand Down Expand Up @@ -67,10 +66,6 @@ public extension MainTabView {
if let store = store.scope(state: \.링크목록, action: \.링크목록) {
ContentListView(store: store)
}
case .링크공유:
if let store = store.scope(state: \.링크공유, action: \.링크공유) {
CategorySharingView(store: store)
}
}

if self.store.linkPopup != nil {
Expand Down
81 changes: 22 additions & 59 deletions Projects/App/Sources/MainTab/MainTabPath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import FeatureCategorySetting
import FeatureContentDetail
import FeatureContentSetting
import FeatureContentList
import FeatureCategorySharing
import Domain
import Util

Expand All @@ -29,7 +28,6 @@ public struct MainTabPath {
case 링크추가및수정(ContentSettingFeature.State)
case 카테고리상세(CategoryDetailFeature.State)
case 링크목록(ContentListFeature.State)
case 링크공유(CategorySharingFeature.State)
}

public enum Action {
Expand All @@ -40,7 +38,6 @@ public struct MainTabPath {
case 링크추가및수정(ContentSettingFeature.Action)
case 카테고리상세(CategoryDetailFeature.Action)
case 링크목록(ContentListFeature.Action)
case 링크공유(CategorySharingFeature.Action)
}

public var body: some Reducer<State, Action> {
Expand All @@ -51,7 +48,6 @@ public struct MainTabPath {
Scope(state: \.링크추가및수정, action: \.링크추가및수정) { ContentSettingFeature() }
Scope(state: \.카테고리상세, action: \.카테고리상세) { CategoryDetailFeature() }
Scope(state: \.링크목록, action: \.링크목록) { ContentListFeature() }
Scope(state: \.링크공유, action: \.링크공유) { CategorySharingFeature() }
}
}

Expand Down Expand Up @@ -101,18 +97,10 @@ public extension MainTabFeature {
/// - 포킷 `추가` or `수정`이 성공적으로 `완료`되었을 때
case .path(.element(_, action: .포킷추가및수정(.delegate(.settingSuccess)))):
state.path.removeLast()
guard let lastPath = state.path.last else {
switch state.selectedTab {
case .pokit: return .none
case .recommend:
return .send(.recommend(.delegate(.포킷_추가하기_완료)))
}
}
switch lastPath {
case .링크공유:
state.path.removeLast()
return .none
default: return .none
switch state.selectedTab {
case .pokit: return .none
case .recommend:
return .send(.recommend(.delegate(.포킷_추가하기_완료)))
}

/// - 포킷 카테고리 아이템 눌렀을 때
Expand Down Expand Up @@ -218,51 +206,26 @@ public extension MainTabFeature {
return .send(.delegate(.로그아웃))
case .path(.element(_, action: .설정(.delegate(.회원탈퇴)))):
return .send(.delegate(.회원탈퇴))
case let .inner(.공유포킷_이동(sharedCategory: sharedCategory)):
state.path.append(.링크공유(CategorySharingFeature.State(sharedCategory: sharedCategory)))
return .none

/// 링크 공유에서 컨텐츠 상세보기
case let .path(.element(_, action: .링크공유(.delegate(.컨텐츠_아이템_클릭(categoryId: categoryId, content: content))))):
state.contentDetail = ContentDetailFeature.State(content: BaseContentDetail(
id: content.id,
category: BaseCategoryInfo(
categoryId: categoryId,
categoryName: content.categoryName
),
title: content.title,
data: content.data,
memo: content.memo ?? "",
createdAt: content.createdAt,
favorites: nil,
alertYn: .no
))
return .none

case let .path(.element(_, action: .링크공유(.delegate(.공유받은_카테고리_추가(sharedCategory))))):
let category = BaseCategoryItem(
id: sharedCategory.categoryId,
userId: 0,
categoryName: sharedCategory.categoryName,
categoryImage: BaseCategoryImage(
imageId: sharedCategory.categoryImageId,
imageURL: sharedCategory.categoryImageUrl
),
contentCount: sharedCategory.contentCount,
createdAt: "",
openType: .공개,
keywordType: .default,
userCount: 0,
isFavorite: false
)
state.path.append(.포킷추가및수정(PokitCategorySettingFeature.State(
type: .공유추가,
category: category
)))
return .none

case .path(.element(_, action: .알림함(.delegate(.alertBoxDismiss)))):
state.path.popLast()
let _ = state.path.popLast()
return .none

/// - 초대 수락 완료
case .path(.element(_, action: .카테고리상세(.delegate(.초대_수락_완료)))):
state.path.removeLast()
return .send(.inner(.링크팝업_활성화(.success(title: "초대를 수락했습니다", until: 2))), animation: .pokitSpring)

/// - 공유 포킷 저장 완료
case .path(.element(_, action: .카테고리상세(.delegate(.저장_완료)))):
state.path.removeLast()
return .send(.inner(.링크팝업_활성화(.success(title: "포킷을 저장했습니다", until: 2))), animation: .pokitSpring)

/// - 포킷 나가기 완료
case .path(.element(_, action: .카테고리상세(.delegate(.포킷나가기)))):
state.path.removeLast()
return .send(.inner(.링크팝업_활성화(.success(title: "포킷에서 나갔습니다", until: 2))), animation: .pokitSpring)

default: return .none
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,23 @@
import Foundation

public struct CategoryKaKaoShareModel {
public enum ShareType: String {
case 공유 = "share"
case 초대 = "invite"
}

let shareType: ShareType
let categoryName: String
let categoryId: Int
let imageURL: String

public init(
shareType: ShareType,
categoryName: String,
categoryId: Int,
imageURL: String
) {
self.shareType = shareType
self.categoryName = categoryName
self.categoryId = categoryId
self.imageURL = imageURL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ extension KakaoShareClient: DependencyKey {
/// 딥링크
let appLink = Link(
androidExecutionParams: [
"shareType": model.shareType.rawValue,
"categoryId": "\(model.categoryId)"
], iosExecutionParams: [
"shareType": model.shareType.rawValue,
"categoryId": "\(model.categoryId)"
]
)
Expand All @@ -32,12 +34,24 @@ extension KakaoShareClient: DependencyKey {
)

/// 카카오톡 메세지 내용
let content = Content(
title: "\(model.categoryName) 포킷을 공유받았어요!",
imageUrl: URL(string: model.imageURL),
description: "소중한 링크들이 담긴 포킷을 Pokit 앱에서 지금 바로 확인해보세요!",
link: appLink
)
let content = {
switch model.shareType {
case .공유:
Content(
title: "\(model.categoryName) 포킷을 공유받았어요!",
imageUrl: URL(string: model.imageURL),
description: "소중한 링크들이 담긴 포킷을 Pokit 앱에서 지금 바로 확인해보세요!",
link: appLink
)
case .초대:
Content(
title: "\(model.categoryName) 포킷 초대장이 왔어요!",
imageUrl: URL(string: model.imageURL),
description: "소중한 링크들이 담긴 포킷을 Pokit 앱에서 지금 바로 침여해보세요!",
link: appLink
)
}
}()

/// 피드 템플릿
let template = FeedTemplate(
Expand All @@ -60,7 +74,9 @@ extension KakaoShareClient: DependencyKey {
return
}

let serverCallbackArgs = ["categoryId": "\(model.categoryId)"]
let serverCallbackArgs = [
"categoryId": "\(model.categoryId)"
]

ShareApi.shared.shareDefault(
templateObject: templateJsonObject,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// InvitedUserResponse.swift
// CoreKit
//
// Created by 김도형 on 12/25/25.
//

import Foundation

public struct InvitedUserResponse: Decodable {
public let userId: Int
public let nickname: String
public let profileImage: BaseProfileImageResponse?
}

extension InvitedUserResponse {
public static var mock: Self = Self(
userId: 1,
nickname: "PokitUser",
profileImage: .mock
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ extension CategoryClient: DependencyKey {
},
공유받은_카테고리_저장: { model in
try await provider.requestNoBody(.공유받은_카테고리_저장(model: model))
},
포킷_초대된_유저_목록_조회: { id in
try await provider.request(.포킷_초대된_유저_목록_조회(categoryId: id))
},
포킷_내보내기: { categoryId, resignUserId in
try await provider.requestNoBody(
.포킷_내보내기(categoryId: categoryId, resignUserId: resignUserId)
)
},
포킷_나가기: { categoryId in
try await provider.requestNoBody(.포킷_나가기(categoryId: categoryId))
},
포킷_초대_수락: { categoryId in
try await provider.requestNoBody(.포킷_초대_수락(categoryId: categoryId))
}
)
}()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ extension CategoryClient: TestDependencyKey {
유저_카테고리_개수_조회: { .mock },
카테고리_상세_조회: { _ in .mock },
공유받은_카테고리_조회: { _, _ in .mock },
공유받은_카테고리_저장: { _ in }
공유받은_카테고리_저장: { _ in },
포킷_초대된_유저_목록_조회: { _ in [.mock] },
포킷_내보내기: { _, _ in },
포킷_나가기: { _ in },
포킷_초대_수락: { _ in }
)
}()
}
Loading
Loading