diff --git a/Projects/App/Resources/Pokit-info.plist b/Projects/App/Resources/Pokit-info.plist
index 98d454b2..ff684a8a 100644
--- a/Projects/App/Resources/Pokit-info.plist
+++ b/Projects/App/Resources/Pokit-info.plist
@@ -21,7 +21,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 2.0.0
+ 2.0.1
CFBundleURLTypes
diff --git a/Projects/App/ShareExtension/Info.plist b/Projects/App/ShareExtension/Info.plist
index 8a334c06..c2ade449 100644
--- a/Projects/App/ShareExtension/Info.plist
+++ b/Projects/App/ShareExtension/Info.plist
@@ -13,7 +13,7 @@
CFBundleName
Pokit
CFBundleShortVersionString
- 1.0.9
+ 2.0.1
CFBundleURLTypes
diff --git a/Projects/App/Sources/MainTab/MainTabFeatureView.swift b/Projects/App/Sources/MainTab/MainTabFeatureView.swift
index 0fbfd373..4dcee06a 100644
--- a/Projects/App/Sources/MainTab/MainTabFeatureView.swift
+++ b/Projects/App/Sources/MainTab/MainTabFeatureView.swift
@@ -74,10 +74,8 @@ public extension MainTabView {
}
if self.store.linkPopup != nil {
- PokitLinkPopup(
- type: $store.linkPopup,
- action: { send(.링크팝업_버튼_눌렀을때, animation: .pokitSpring) }
- )
+ PokitLinkPopup(type: $store.linkPopup)
+ .onAction { send(.링크팝업_버튼_눌렀을때, animation: .pokitSpring) }
}
}
}
@@ -93,11 +91,9 @@ private extension MainTabView {
.overlay(alignment: .bottom) {
VStack(spacing: 0) {
if store.linkPopup != nil {
- PokitLinkPopup(
- type: $store.linkPopup,
- action: { send(.링크팝업_버튼_눌렀을때, animation: .pokitSpring) }
- )
- .padding(.bottom, 20)
+ PokitLinkPopup(type: $store.linkPopup)
+ .onAction { send(.링크팝업_버튼_눌렀을때, animation: .pokitSpring) }
+ .padding(.bottom, 20)
}
bottomTabBar
diff --git a/Projects/App/Sources/MainTab/MainTabPath.swift b/Projects/App/Sources/MainTab/MainTabPath.swift
index 68d1e33c..fbd1782d 100644
--- a/Projects/App/Sources/MainTab/MainTabPath.swift
+++ b/Projects/App/Sources/MainTab/MainTabPath.swift
@@ -194,13 +194,13 @@ public extension MainTabFeature {
case .검색:
return .merge(
.send(.path(.element(id: stackElementId, action: .검색(.delegate(.컨텐츠_검색))))),
- .send(.inner(.링크팝업_활성화(.success(title: Constants.링크_저장_완료_문구))), animation: .pokitSpring)
+ .send(.inner(.링크팝업_활성화(.success(title: Constants.링크_저장_완료_문구, until: 4))), animation: .pokitSpring)
)
default:
- return .send(.inner(.링크팝업_활성화(.success(title: Constants.링크_저장_완료_문구))), animation: .pokitSpring)
+ return .send(.inner(.링크팝업_활성화(.success(title: Constants.링크_저장_완료_문구, until: 4))), animation: .pokitSpring)
}
case .recommend(.delegate(.저장하기_완료)):
- return .send(.inner(.링크팝업_활성화(.success(title: Constants.링크_저장_완료_문구))), animation: .pokitSpring)
+ return .send(.inner(.링크팝업_활성화(.success(title: Constants.링크_저장_완료_문구, until: 4))), animation: .pokitSpring)
/// - 각 화면에서 링크 복사 감지했을 때 (링크 추가 및 수정 화면 제외)
case let .path(.element(_, action: .알림함(.delegate(.linkCopyDetected(url))))),
let .path(.element(_, action: .검색(.delegate(.linkCopyDetected(url))))),
diff --git a/Projects/DSKit/Sources/Components/PokitCaution.swift b/Projects/DSKit/Sources/Components/PokitCaution.swift
index e2ced148..82baabdd 100644
--- a/Projects/DSKit/Sources/Components/PokitCaution.swift
+++ b/Projects/DSKit/Sources/Components/PokitCaution.swift
@@ -84,9 +84,14 @@ public struct PokitCaution: View {
private let type: CautionType
private let action: (() -> Void)?
- public init(
+ public init(type: CautionType) {
+ self.type = type
+ self.action = nil
+ }
+
+ private init(
type: CautionType,
- action: (() -> Void)? = nil
+ action: (() -> Void)?
) {
self.type = type
self.action = action
@@ -132,11 +137,15 @@ public struct PokitCaution: View {
.frame(maxHeight: .infinity)
.padding(.bottom, 92)
}
+
+ public func onAction(_ action: @escaping () -> Void) -> Self {
+ PokitCaution(type: self.type, action: action)
+ }
}
#Preview {
- PokitCaution(
- type: .미분류_링크없음,
- action: {}
- )
+ PokitCaution(type: .미분류_링크없음)
+ .onAction {
+
+ }
}
diff --git a/Projects/DSKit/Sources/Components/PokitLinkPopup.swift b/Projects/DSKit/Sources/Components/PokitLinkPopup.swift
index 866acb2d..84057cc3 100644
--- a/Projects/DSKit/Sources/Components/PokitLinkPopup.swift
+++ b/Projects/DSKit/Sources/Components/PokitLinkPopup.swift
@@ -15,17 +15,36 @@ public struct PokitLinkPopup: View {
@State
private var second: Int = 0
private let action: (() -> Void)?
+ private let until: Int
private let timer = Timer.publish(
every: 1,
on: .main,
in: .common
).autoconnect()
- public init(
+ public init(type: Binding) {
+ self._type = type
+ switch type.wrappedValue {
+ case let .link(_, _, until),
+ let .text(_, until),
+ let .success(_, until),
+ let .error(_, until),
+ let .warning(_, until),
+ let .report(_, until):
+ self.until = until
+ default:
+ self.until = 2
+ }
+ self.action = nil
+ }
+
+ private init(
type: Binding,
- action: (() -> Void)? = nil
+ until: Int,
+ action: (() -> Void)?
) {
self._type = type
+ self.until = until
self.action = action
}
@@ -40,7 +59,7 @@ public struct PokitLinkPopup: View {
.frame(width: 335, height: 60)
.transition(.move(edge: .bottom).combined(with: .opacity))
.onReceive(timer) { _ in
- guard second < 2 else {
+ guard second < until else {
closedPopup()
return
}
@@ -61,7 +80,7 @@ public struct PokitLinkPopup: View {
.multilineTextAlignment(.leading)
.foregroundStyle(textColor)
- if case let .link(_, url) = type {
+ if case let .link(_, url, _) = type {
Text(url)
.lineLimit(1)
.pokitFont(.detail2)
@@ -167,26 +186,34 @@ public struct PokitLinkPopup: View {
private var title: String {
switch type {
- case let .link(title, _),
- let .text(title),
- let .success(title),
- let .error(title),
- let .warning(title),
- let .report(title):
+ case let .link(title, _, _),
+ let .text(title, _),
+ let .success(title, _),
+ let .error(title, _),
+ let .warning(title, _),
+ let .report(title, _):
return title
default: return ""
}
}
+
+ public func onAction(_ action: @escaping () -> Void) -> Self {
+ PokitLinkPopup(
+ type: self.$type,
+ until: self.until,
+ action: action
+ )
+ }
}
public extension PokitLinkPopup {
enum PopupType: Equatable {
- case link(title: String, url: String)
- case text(title: String)
- case success(title: String)
- case error(title: String)
- case warning(title: String)
- case report(title: String)
+ case link(title: String, url: String, until: Int = 2)
+ case text(title: String, until: Int = 2)
+ case success(title: String, until: Int = 2)
+ case error(title: String, until: Int = 2)
+ case warning(title: String, until: Int = 2)
+ case report(title: String, until: Int = 2)
}
}
diff --git a/Projects/Domain/Sources/Base/BaseContentItem.swift b/Projects/Domain/Sources/Base/BaseContentItem.swift
index 27ebd387..bddcb66d 100644
--- a/Projects/Domain/Sources/Base/BaseContentItem.swift
+++ b/Projects/Domain/Sources/Base/BaseContentItem.swift
@@ -19,7 +19,7 @@ public struct BaseContentItem: Identifiable, Equatable, PokitLinkCardItem, Sorta
public let data: String
public let domain: String
public let createdAt: String
- public let isRead: Bool?
+ public var isRead: Bool?
public var isFavorite: Bool?
public let keyword: String?
diff --git a/Projects/Feature/FeatureCategoryDetail/Sources/CategoryDetailFeature.swift b/Projects/Feature/FeatureCategoryDetail/Sources/CategoryDetailFeature.swift
index 0425f105..9b3a9c24 100644
--- a/Projects/Feature/FeatureCategoryDetail/Sources/CategoryDetailFeature.swift
+++ b/Projects/Feature/FeatureCategoryDetail/Sources/CategoryDetailFeature.swift
@@ -65,9 +65,6 @@ public struct CategoryDetailFeature {
domain.contentList.hasNext
}
var isLoading: Bool = true
- var isContentsNotEmpty: Bool {
- (isFavoriteCategory && contents.contains { $0.content.isFavorite == true }) || (!isFavoriteCategory && !contents.isEmpty)
- }
public init(category: BaseCategoryItem) {
self.domain = .init(categpry: category)
@@ -199,11 +196,14 @@ private extension CategoryDetailFeature {
)
case let .분류_버튼_눌렀을때(type):
- if type == .즐겨찾기 {
+ switch type {
+ case .즐겨찾기:
state.domain.condition.isFavoriteFlitered.toggle()
+ guard state.domain.condition.isFavoriteFlitered else { break }
state.domain.condition.isUnreadFlitered = !state.domain.condition.isFavoriteFlitered
- } else {
+ case .안읽음:
state.domain.condition.isUnreadFlitered.toggle()
+ guard state.domain.condition.isUnreadFlitered else { break }
state.domain.condition.isFavoriteFlitered = !state.domain.condition.isUnreadFlitered
}
return .concatenate(
diff --git a/Projects/Feature/FeatureCategoryDetail/Sources/CategoryDetailView.swift b/Projects/Feature/FeatureCategoryDetail/Sources/CategoryDetailView.swift
index 5d0d80f6..7e319ed7 100644
--- a/Projects/Feature/FeatureCategoryDetail/Sources/CategoryDetailView.swift
+++ b/Projects/Feature/FeatureCategoryDetail/Sources/CategoryDetailView.swift
@@ -65,7 +65,7 @@ public extension CategoryDetailView {
.padding(.top, 12)
.pokitNavigationBar { navigationBar }
.overlay(
- if: store.isContentsNotEmpty,
+ if: !store.isFavoriteCategory,
alignment: .bottomTrailing
) {
Button(action: { send(.링크_추가_버튼_눌렀을때) }) {
@@ -215,30 +215,32 @@ private extension CategoryDetailView {
var filterHeader: some View {
let isFavoriteCategory = store.isFavoriteCategory
let favoriteContentsCount = store.contents.filter { $0.content.isFavorite ?? false }.count
- if store.isContentsNotEmpty {
- HStack(spacing: isFavoriteCategory ? 2 : 8) {
- if isFavoriteCategory {
- Image(.icon(.link))
- .resizable()
- .frame(width: 16, height: 16)
- .foregroundStyle(.pokit(.icon(.secondary)))
- Text("\(favoriteContentsCount)개")
- .foregroundStyle(.pokit(.text(.tertiary)))
- .pokitFont(.b2(.m))
- } else {
- favoriteButton
-
- unreadButton
- }
+
+ HStack(spacing: isFavoriteCategory ? 2 : 8) {
+ if isFavoriteCategory {
+ Image(.icon(.link))
+ .resizable()
+ .frame(width: 16, height: 16)
+ .foregroundStyle(.pokit(.icon(.secondary)))
- Spacer()
- PokitIconLTextLink(
- store.sortType.title,
- icon: .icon(.align),
- action: { send(.정렬_버튼_눌렀을때) }
- )
- .contentTransition(.numericText())
+ Text("\(favoriteContentsCount)개")
+ .foregroundStyle(.pokit(.text(.tertiary)))
+ .pokitFont(.b2(.m))
+
+ } else {
+ favoriteButton
+
+ unreadButton
}
+
+ Spacer()
+
+ PokitIconLTextLink(
+ store.sortType.title,
+ icon: .icon(.align),
+ action: { send(.정렬_버튼_눌렀을때) }
+ )
+ .contentTransition(.numericText())
}
}
@@ -286,53 +288,47 @@ private extension CategoryDetailView {
}
}
+ @ViewBuilder
var contentScrollView: some View {
- Group {
- if !store.isLoading {
- if store.contents.isEmpty {
- PokitCaution(
- type: .포킷상세_링크없음,
- action: { send(.링크_추가_버튼_눌렀을때) }
- )
- } else {
- LazyVStack(spacing: 0) {
- ForEach(
- Array(store.scope(state: \.contents, action: \.contents))
- ) { store in
- let isFirst = store.state.id == self.store.contents.first?.id
- let isLast = store.state.id == self.store.contents.last?.id
-
- if !self.store.isFavoriteCategory {
- ContentCardView(
- store: store,
- type: .linkList,
- isFirst: isFirst,
- isLast: isLast
- )
- } else {
- if store.content.isFavorite == true {
- ContentCardView(
- store: store,
- type: .linkList,
- isFirst: isFirst,
- isLast: isLast
- )
- }
- }
- }
+ if !store.isLoading {
+ if store.contents.isEmpty {
+ PokitCaution(type: .포킷상세_링크없음)
+ } else {
+ LazyVStack(spacing: 0) {
+ ForEach(
+ Array(store.scope(state: \.contents, action: \.contents))
+ ) { store in
+ let isFirst = store.state.id == self.store.contents.first?.id
+ let isLast = store.state.id == self.store.contents.last?.id
- if store.hasNext {
- PokitLoading()
- .task { await send(.pagenation).finish() }
+ if !self.store.isFavoriteCategory {
+ ContentCardView(
+ store: store,
+ type: .linkList,
+ isFirst: isFirst,
+ isLast: isLast
+ )
+ } else if store.content.isFavorite == true {
+ ContentCardView(
+ store: store,
+ type: .linkList,
+ isFirst: isFirst,
+ isLast: isLast
+ )
}
-
- Spacer()
}
- .padding(.bottom, 36)
+
+ if store.hasNext {
+ PokitLoading()
+ .task { await send(.pagenation).finish() }
+ }
+
+ Spacer()
}
- } else {
- PokitLoading()
+ .padding(.bottom, 36)
}
+ } else {
+ PokitLoading()
}
}
diff --git a/Projects/Feature/FeatureContentCard/Sources/ContentCard/ContentCardFeature.swift b/Projects/Feature/FeatureContentCard/Sources/ContentCard/ContentCardFeature.swift
index d5bfae8c..12fd5eb3 100644
--- a/Projects/Feature/FeatureContentCard/Sources/ContentCard/ContentCardFeature.swift
+++ b/Projects/Feature/FeatureContentCard/Sources/ContentCard/ContentCardFeature.swift
@@ -52,6 +52,7 @@ public struct ContentCardFeature {
public enum InnerAction: Equatable {
case 메타데이터_조회_수행_반영(String)
case 즐겨찾기_API_반영(Bool)
+ case 컨텐츠_상세_조회_API_반영
}
@CasePathable
@@ -60,6 +61,7 @@ public struct ContentCardFeature {
case 즐겨찾기_API
case 즐겨찾기_취소_API
case 썸네일_수정_API
+ case 컨텐츠_상세_조회_API
}
public enum ScopeAction: Equatable { case doNothing }
@@ -111,7 +113,10 @@ private extension ContentCardFeature {
guard let url = URL(string: state.content.data) else {
return .none
}
- return .run { _ in await openURL(url) }
+ return .run { send in
+ await send(.async(.컨텐츠_상세_조회_API))
+ await openURL(url)
+ }
case .컨텐츠_항목_케밥_버튼_눌렀을때:
return .send(.delegate(.컨텐츠_항목_케밥_버튼_눌렀을때(content: state.content)))
case .메타데이터_조회:
@@ -137,6 +142,9 @@ private extension ContentCardFeature {
case .즐겨찾기_API_반영(let favorite):
state.content.isFavorite = favorite
return .none
+ case .컨텐츠_상세_조회_API_반영:
+ state.content.isRead = true
+ return .none
}
}
@@ -167,6 +175,11 @@ private extension ContentCardFeature {
try await contentClient.썸네일_수정("\(content.id)", request)
}
+ case .컨텐츠_상세_조회_API:
+ return .run { [id = state.content.id] send in
+ let _ = try await contentClient.컨텐츠_상세_조회("\(id)")
+ await send(.inner(.컨텐츠_상세_조회_API_반영))
+ }
}
}
diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift
index e8d33455..76c032e9 100644
--- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift
+++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift
@@ -46,10 +46,9 @@ public extension ContentSettingView {
}
.overlay(alignment: .bottom) {
if store.linkPopup != nil {
- PokitLinkPopup(
- type: $store.linkPopup,
- action: { send(.링크팝업_버튼_눌렀을때, animation: .pokitSpring) }
- )
+ PokitLinkPopup(type: $store.linkPopup)
+ .onAction { send(.링크팝업_버튼_눌렀을때, animation: .pokitSpring) }
+
}
}
.pokitMaxWidth()
diff --git a/Projects/Feature/FeaturePokit/Sources/PokitLinkEditFeature.swift b/Projects/Feature/FeaturePokit/Sources/PokitLinkEditFeature.swift
index 61a291ce..2b9df4b5 100644
--- a/Projects/Feature/FeaturePokit/Sources/PokitLinkEditFeature.swift
+++ b/Projects/Feature/FeaturePokit/Sources/PokitLinkEditFeature.swift
@@ -32,7 +32,7 @@ public struct PokitLinkEditFeature {
var list = IdentifiedArrayOf()
/// 선택한 링크 목록
var selectedItems = IdentifiedArrayOf()
- var isActive: Bool = false
+ var isActive: Bool { !selectedItems.isEmpty }
/// 포킷 이동 눌렀을 때 sheet
var categorySelectSheetPresetend: Bool = false
var linkDeleteSheetPresented: Bool = false
@@ -160,8 +160,6 @@ private extension PokitLinkEditFeature {
} else {
state.selectedItems.append(item)
}
-
- state.isActive = !state.selectedItems.isEmpty
return .none
case let .카테고리_선택했을때(pokit):
@@ -257,12 +255,10 @@ private extension PokitLinkEditFeature {
case .전체선택_버튼_눌렀을때:
state.selectedItems = state.list
- state.isActive = !state.selectedItems.isEmpty
return .none
case .전체해제_버튼_눌렀을때:
state.selectedItems.removeAll()
- state.isActive = !state.selectedItems.isEmpty
return .none
case .포킷이동_버튼_눌렀을때:
diff --git a/Projects/Feature/FeaturePokit/Sources/PokitLinkEditView.swift b/Projects/Feature/FeaturePokit/Sources/PokitLinkEditView.swift
index 1c6b7e56..26307a7c 100644
--- a/Projects/Feature/FeaturePokit/Sources/PokitLinkEditView.swift
+++ b/Projects/Feature/FeaturePokit/Sources/PokitLinkEditView.swift
@@ -63,11 +63,9 @@ public extension PokitLinkEditView {
}
.overlay(alignment: .bottom) {
if store.linkPopup != nil {
- PokitLinkPopup(
- type: $store.linkPopup,
- action: { send(.링크팝업_버튼_눌렀을때, animation: .pokitSpring) }
- )
- .pokitMaxWidth()
+ PokitLinkPopup(type: $store.linkPopup)
+ .onAction { send(.링크팝업_버튼_눌렀을때, animation: .pokitSpring) }
+ .pokitMaxWidth()
}
}
/// fullScreenCover를 통해 새로운 Destination을 만들었음
@@ -123,7 +121,7 @@ private extension PokitLinkEditView {
var actionFloatButtonView: some View {
PokitLinkEditFloatView(
- isActive: $store.isActive,
+ isActive: store.isActive,
delegateSend: { store.send(.scope(.floatButtonAction($0))) }
)
}
diff --git a/Projects/Feature/FeaturePokit/Sources/PokitRootView.swift b/Projects/Feature/FeaturePokit/Sources/PokitRootView.swift
index f5771274..91e46d4f 100644
--- a/Projects/Feature/FeaturePokit/Sources/PokitRootView.swift
+++ b/Projects/Feature/FeaturePokit/Sources/PokitRootView.swift
@@ -134,10 +134,8 @@ private extension PokitRootView {
var pokitView: some View {
if let categories = store.categories {
if categories.isEmpty {
- PokitCaution(
- type: .카테고리없음,
- action: { send(.포킷추가_버튼_눌렀을때) }
- )
+ PokitCaution(type: .카테고리없음)
+ .onAction { send(.포킷추가_버튼_눌렀을때) }
} else {
pokitList(categories)
}
@@ -181,10 +179,8 @@ private extension PokitRootView {
var unclassifiedView: some View {
if !store.isLoading {
if store.contents.isEmpty {
- PokitCaution(
- type: .미분류_링크없음,
- action: { send(.링크추가_버튼_눌렀을때) }
- )
+ PokitCaution(type: .미분류_링크없음)
+ .onAction { send(.링크추가_버튼_눌렀을때) }
} else {
unclassifiedList
.padding(.top, 20)
diff --git a/Projects/Feature/FeaturePokit/Sources/Sheet/PokitLinkEditFloatView.swift b/Projects/Feature/FeaturePokit/Sources/Sheet/PokitLinkEditFloatView.swift
index 5b94da51..db0bc79b 100644
--- a/Projects/Feature/FeaturePokit/Sources/Sheet/PokitLinkEditFloatView.swift
+++ b/Projects/Feature/FeaturePokit/Sources/Sheet/PokitLinkEditFloatView.swift
@@ -11,14 +11,14 @@ import SwiftUI
public struct PokitLinkEditFloatView: View {
/// 전체 선택/해제 toggle
@State private var isChecked: Bool = false
- @Binding private var isActive: Bool
+ private let isActive: Bool
private let delegateSend: ((PokitLinkEditFloatView.Delegate) -> Void)?
public init(
- isActive: Binding,
+ isActive: Bool,
delegateSend: ((PokitLinkEditFloatView.Delegate) -> Void)?
) {
- self._isActive = isActive
+ self.isActive = isActive
self.delegateSend = delegateSend
}
@@ -114,7 +114,7 @@ public extension PokitLinkEditFloatView {
}
#Preview {
PokitLinkEditFloatView(
- isActive: .constant(true),
+ isActive: true,
delegateSend: {_ in }
).padding(20)
}
diff --git a/Projects/Feature/FeatureRecommend/Sources/Recommend/RecommendFeature.swift b/Projects/Feature/FeatureRecommend/Sources/Recommend/RecommendFeature.swift
index 9f3376db..df1ba34b 100644
--- a/Projects/Feature/FeatureRecommend/Sources/Recommend/RecommendFeature.swift
+++ b/Projects/Feature/FeatureRecommend/Sources/Recommend/RecommendFeature.swift
@@ -168,7 +168,7 @@ private extension RecommendFeature {
case .onAppear:
return .merge(
shared(.async(.추천_조회_API), state: &state),
- shared(.async(.유저_관심사_조회_API), state: &state)
+ shared(.async(.관심사_조회_API), state: &state)
)
case .pagination:
return shared(.async(.추천_조회_페이징_API), state: &state)
@@ -215,7 +215,8 @@ private extension RecommendFeature {
guard let url = URL(string: urlString) else { return .none }
return .run { _ in await openURL(url) }
case .관심사_편집_버튼_눌렀을때:
- return shared(.async(.관심사_조회_API), state: &state)
+ state.showKeywordSheet = true
+ return .none
case let .키워드_선택_버튼_눌렀을때(interests):
state.showKeywordSheet = false
state.selectedInterest = nil
@@ -255,14 +256,18 @@ private extension RecommendFeature {
state.isLoading = false
return .none
case let .유저_관심사_조회_API_반영(interests):
- state.domain.myInterests = interests
- interests.forEach { state.selectedInterestList.insert($0) }
+ state.domain.myInterests = interests.filter { interest in
+ state.interests.contains(interest)
+ }
+ interests.forEach {
+ guard state.interests.contains($0) else { return }
+ state.selectedInterestList.insert($0)
+ }
return .none
case let .관심사_조회_API_반영(interests):
state.domain.interests = interests.filter({ interest in
interest.code != "default"
})
- state.showKeywordSheet = true
return .none
case let .컨텐츠_신고_API_반영(contentId):
state.domain.contentList.data?.removeAll(where: { $0.id == contentId })
@@ -319,13 +324,20 @@ private extension RecommendFeature {
return contentListFetch(state: &state)
case .유저_관심사_조회_API:
return .run { send in
- let interests = try await userClient.유저_관심사_목록_조회().map { $0.toDomian() }
+ let interests = try await userClient.유저_관심사_목록_조회()
+ .map { $0.toDomian() }
+ .sorted { $0.description < $1.description }
+
await send(.inner(.유저_관심사_조회_API_반영(interests)))
}
case .관심사_조회_API:
return .run { send in
- let interests = try await userClient.관심사_목록_조회().map { $0.toDomian() }
+ let interests = try await userClient.관심사_목록_조회()
+ .map { $0.toDomian() }
+ .sorted { $0.description < $1.description }
+
await send(.inner(.관심사_조회_API_반영(interests)))
+ await send(.async(.유저_관심사_조회_API))
}
case let .컨텐츠_신고_API(contentId):
return .run { send in
diff --git a/Projects/Feature/FeatureSetting/Sources/Alert/PokitAlertBoxView.swift b/Projects/Feature/FeatureSetting/Sources/Alert/PokitAlertBoxView.swift
index f0e1e0ce..d658ebca 100644
--- a/Projects/Feature/FeatureSetting/Sources/Alert/PokitAlertBoxView.swift
+++ b/Projects/Feature/FeatureSetting/Sources/Alert/PokitAlertBoxView.swift
@@ -30,7 +30,7 @@ public extension PokitAlertBoxView {
if alertContents.isEmpty {
VStack {
PokitCaution(type: .알림없음)
- .padding(.top, 84)
+ .padding(.top, 84)
Spacer()
}
} else {
diff --git a/Projects/Feature/FeatureSetting/Sources/Search/PokitSearchView.swift b/Projects/Feature/FeatureSetting/Sources/Search/PokitSearchView.swift
index 6a819894..2225fda2 100644
--- a/Projects/Feature/FeatureSetting/Sources/Search/PokitSearchView.swift
+++ b/Projects/Feature/FeatureSetting/Sources/Search/PokitSearchView.swift
@@ -265,30 +265,21 @@ private extension PokitSearchView {
var resultList: some View {
VStack(alignment: .leading, spacing: 20) {
+ if store.isSearching {
+ PokitIconLTextLink(
+ store.isResultAscending ? "오래된순" : "최신순",
+ icon: .icon(.align),
+ action: { send(.정렬_버튼_눌렀을때) }
+ )
+ .contentTransition(.numericText())
+ .padding(.horizontal, 20)
+ }
+
if !store.isLoading {
- ScrollView {
- LazyVStack(spacing: 0) {
- ForEach(
- Array(store.scope(state: \.contents, action: \.contents))
- ) { store in
- let isFirst = store.state.id == self.store.contents.first?.id
- let isLast = store.state.id == self.store.contents.last?.id
-
- ContentCardView(
- store: store,
- type: .linkList,
- isFirst: isFirst,
- isLast: isLast
- )
- }
-
- if store.hasNext {
- PokitLoading()
- .task { await send(.로딩중일때, animation: .pokitDissolve).finish() }
- }
- }
- .padding(.horizontal, 20)
- .padding(.bottom, 36)
+ if store.contents.isEmpty && store.isSearching {
+ resultEmptyLabel
+ } else {
+ resultListContent
}
} else {
PokitLoading()
@@ -296,6 +287,47 @@ private extension PokitSearchView {
}
.padding(.top, 24)
}
+
+ var resultListContent: some View {
+ ScrollView {
+ LazyVStack(spacing: 0) {
+ ForEach(
+ Array(store.scope(state: \.contents, action: \.contents))
+ ) { store in
+ let isFirst = store.state.id == self.store.contents.first?.id
+ let isLast = store.state.id == self.store.contents.last?.id
+
+ ContentCardView(
+ store: store,
+ type: .linkList,
+ isFirst: isFirst,
+ isLast: isLast
+ )
+ }
+
+ if store.hasNext {
+ PokitLoading()
+ .task { await send(.로딩중일때, animation: .pokitDissolve).finish() }
+ }
+ }
+ .padding(.horizontal, 20)
+ .padding(.bottom, 36)
+ }
+ }
+
+ var resultEmptyLabel: some View {
+ VStack(spacing: 8) {
+ Text("검색어가 없어요")
+ .pokitFont(.title2)
+
+ Text("링크 제목, 포킷으로 검색해주세요")
+ .pokitFont(.b2(.m))
+ }
+ .padding(.top, 100)
+ .padding(.bottom, 80)
+ .frame(maxWidth: .infinity)
+ .foregroundStyle(.pokit(.text(.tertiary)))
+ }
}
//MARK: - Preview
#Preview {
diff --git a/Projects/Util/Sources/Constants.swift b/Projects/Util/Sources/Constants.swift
index 4c12153f..a5ff72ed 100644
--- a/Projects/Util/Sources/Constants.swift
+++ b/Projects/Util/Sources/Constants.swift
@@ -28,7 +28,7 @@ public enum Constants {
public static let 포킷_최대_갯수_문구: String = "최대 30개의 포킷을 생성할 수 있습니다.\n포킷을 삭제한 뒤에 추가해주세요."
public static let 복사한_링크_저장하기_문구: String = "복사한 링크 저장하기"
public static let 제목을_입력해주세요_문구: String = "제목을 입력해주세요"
- public static let 링크_저장_완료_문구: String = "링크 저장 완료"
+ public static let 링크_저장_완료_문구: String = "저정한 링크 보러가기"
public static let 메모_수정_완료_문구: String = "메모 수정 완료"
public static let 한글_영어_숫자_입력_문구: String = "한글, 영어, 숫자로만 입력이 가능합니다."
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 164214f1..04ed08e4 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -41,6 +41,7 @@ platform :ios do
workspace: "Pokit.xcworkspace",
scheme: "App",
configuration: "Debug",
+ destination: "platform=iOS Simulator,name=iPhone 15,OS=17.5",
export_method: "development",
export_options: {
provisioningProfiles: {
@@ -72,6 +73,7 @@ platform :ios do
workspace: "Pokit.xcworkspace",
scheme: "App",
configuration: "Release",
+ destination: "generic/platform=iOS",
export_method: "app-store",
export_options: {
provisioningProfiles: {