From 25c7ecd7e859cc0b4757066defbf2726d474f51f Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Sun, 8 Feb 2026 20:36:44 +0900
Subject: [PATCH 01/21] =?UTF-8?q?[BOOK-499]=20feat:=20=E2=80=9C=EB=82=B4?=
=?UTF-8?q?=20=EA=B8=B0=EB=A1=9D=20=EB=AA=A8=EC=9D=8C=E2=80=9D=20=EB=B6=80?=
=?UTF-8?q?=EB=B6=84=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EC=83=89=EC=83=81=20?=
=?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Sources/MainFlow/BookDetail/View/BookDetailViewHeader.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewHeader.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewHeader.swift
index 050ed24b..c48549a9 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewHeader.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewHeader.swift
@@ -9,7 +9,7 @@ final class BookDetailViewHeader: BaseView {
private let titleLabel = BKLabel(
fontStyle: .headline2(weight: .semiBold),
- highlightColor: .bkContentColor(.brand)
+ highlightColor: .bkContentColor(.tertiary)
)
private let sortButtonStack: UIStackView = {
From f198b074681a5ffb88088740feee6a18bab0ffe9 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Sun, 8 Feb 2026 20:37:10 +0900
Subject: [PATCH 02/21] =?UTF-8?q?[BOOK-499]=20feat:=20=EB=8F=84=EC=84=9C?=
=?UTF-8?q?=20=EC=83=81=EC=84=B8=20=ED=97=A4=EB=8D=94=20=EA=B0=84=EA=B2=A9?=
=?UTF-8?q?=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../MainFlow/BookDetail/View/BookDetailView.swift | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
index f433379a..2ea76cc8 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
@@ -38,6 +38,15 @@ final class BookDetailView: BaseView {
stackView.spacing = LayoutConstants.buttonGroupSpacing
stackView.distribution = .fill
stackView.alignment = .fill
+
+ stackView.isLayoutMarginsRelativeArrangement = true
+ stackView.layoutMargins = UIEdgeInsets(
+ top: LayoutConstants.buttonGroupHSpacing,
+ left: 0,
+ bottom: LayoutConstants.buttonGroupHSpacing,
+ right: 0
+ )
+
return stackView
}()
@@ -142,7 +151,6 @@ final class BookDetailView: BaseView {
seedReportView.snp.makeConstraints {
$0.top.equalTo(buttonGroup.snp.bottom)
- .offset(LayoutConstants.seedReportViewTopInset)
$0.horizontalEdges.equalToSuperview()
.inset(LayoutConstants.horizontalInset)
seedReportZeroHeight = $0.height.equalTo(0).priority(.low).constraint
@@ -366,8 +374,8 @@ private extension BookDetailView {
static let summaryViewTopInset = BKInset.inset2
static let summaryViewHeight: CGFloat = 98
static let buttonGroupSpacing = BKSpacing.spacing2
- static let buttonGroupTopInset = BKInset.inset8
- static let seedReportViewTopInset = BKInset.inset8
+ static let buttonGroupHSpacing = BKSpacing.spacing4
+ static let buttonGroupTopInset = BKSpacing.spacing1
static let dividerVerticalOffset = BKInset.inset6
static let collectionViewTopOffset = BKInset.inset4
static let collectionViewCellMaxHeight: CGFloat = 180
From c348d2e3bb37968da4f1aa9ce4b22d54585508dc Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Sun, 8 Feb 2026 20:38:48 +0900
Subject: [PATCH 03/21] =?UTF-8?q?[BOOK-499]=20feat:=20=E2=80=9C=EB=82=B4?=
=?UTF-8?q?=20=EA=B8=B0=EB=A1=9D=20=EB=AA=A8=EC=9D=8C=E2=80=9D=20=EC=83=81?=
=?UTF-8?q?=EB=8B=A8=20=EA=B0=84=EA=B2=A9=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Sources/MainFlow/BookDetail/View/BookDetailView.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
index 2ea76cc8..3af08459 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
@@ -376,7 +376,7 @@ private extension BookDetailView {
static let buttonGroupSpacing = BKSpacing.spacing2
static let buttonGroupHSpacing = BKSpacing.spacing4
static let buttonGroupTopInset = BKSpacing.spacing1
- static let dividerVerticalOffset = BKInset.inset6
+ static let dividerVerticalOffset = BKInset.inset8
static let collectionViewTopOffset = BKInset.inset4
static let collectionViewCellMaxHeight: CGFloat = 180
static let collectionViewCellSpacing = BKSpacing.spacing3
From 10091097eb785cdea3299f69cfe07584a54ad657 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Sun, 8 Feb 2026 21:03:39 +0900
Subject: [PATCH 04/21] =?UTF-8?q?[BOOK-499]=20feat:=20BookDetailItem=20pag?=
=?UTF-8?q?e=20->=20Int=3F=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Projects/BKCore/Sources/Extension/Optional.swift | 10 ++++++++++
.../MainFlow/BookDetail/Models/BookDetailItem.swift | 2 +-
.../MainFlow/BookDetail/View/BookDetailView.swift | 11 ++++++++++-
3 files changed, 21 insertions(+), 2 deletions(-)
create mode 100644 src/Projects/BKCore/Sources/Extension/Optional.swift
diff --git a/src/Projects/BKCore/Sources/Extension/Optional.swift b/src/Projects/BKCore/Sources/Extension/Optional.swift
new file mode 100644
index 00000000..556d2798
--- /dev/null
+++ b/src/Projects/BKCore/Sources/Extension/Optional.swift
@@ -0,0 +1,10 @@
+// Copyright © 2026 Booket. All rights reserved
+
+import UIKit
+
+public extension Optional where Wrapped == Int {
+ /// Int? 값을 "123p" 또는 값이 없을 경우 "-p" 문자열로 반환합니다.
+ var toPageString: String {
+ return self.map { "\($0)p" } ?? "-p"
+ }
+}
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/BookDetailItem.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/BookDetailItem.swift
index 9a176921..6bd4f321 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/BookDetailItem.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/BookDetailItem.swift
@@ -14,7 +14,7 @@ struct BookDetailItem: Hashable {
/// 감정
let emotion: EmotionSeed?
let createdAt: Date
- let page: Int
+ let page: Int?
let bookTitle: String
static func from(recordInfo: RecordInfo) -> Self {
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
index 3af08459..08566cba 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
@@ -19,7 +19,16 @@ enum SortOption: String, CaseIterable {
case .newest:
return { $0.createdAt > $1.createdAt }
case .pageDescending:
- return { $0.page > $1.page }
+ return {
+ let p0 = $0.page ?? Int.max
+ let p1 = $1.page ?? Int.max
+
+ if p0 == p1 {
+ return $0.createdAt > $1.createdAt
+ }
+
+ return p0 > p1
+ }
}
}
}
From e89a389c2ecac607823818d3ab74e603ab292946 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Sun, 8 Feb 2026 21:41:11 +0900
Subject: [PATCH 05/21] =?UTF-8?q?[BOOK-499]=20feat:=20BookDetailViewCell?=
=?UTF-8?q?=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../BookDetail/View/BookDetailViewCell.swift | 48 ++++++-------------
1 file changed, 15 insertions(+), 33 deletions(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift
index 74dcb76e..a51c9ee8 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift
@@ -1,6 +1,7 @@
// Copyright © 2025 Booket. All rights reserved
import BKDesign
+import BKCore
import SnapKit
import UIKit
@@ -20,9 +21,8 @@ final class BookDetailViewCell: UICollectionViewCell {
return stackView
}()
- private let emotionIcon = UIImageView()
- private let emotionLabel = BKLabel2(
- fontStyle: .body1(weight: .semiBold),
+ private let pageLabel = BKLabel2(
+ fontStyle: .italic,
color: .bkContentColor(.brand)
)
@@ -31,8 +31,8 @@ final class BookDetailViewCell: UICollectionViewCell {
color: .bkContentColor(.tertiary)
)
- private let pageLabel = BKLabel2(
- fontStyle: .italic,
+ private let emotionTagLabel = BKLabel2(
+ fontStyle: .label1(weight: .medium),
color: .bkContentColor(.tertiary)
)
@@ -56,14 +56,6 @@ final class BookDetailViewCell: UICollectionViewCell {
return stackView
}()
- private let emotionStack: UIStackView = {
- let stackView = UIStackView()
- stackView.axis = .horizontal
- stackView.spacing = LayoutConstants.emotionStackSpacing
- stackView.alignment = .center
- return stackView
- }()
-
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
@@ -78,10 +70,9 @@ final class BookDetailViewCell: UICollectionViewCell {
override func prepareForReuse() {
super.prepareForReuse()
noteLabel.setText(text: "")
- emotionIcon.image = nil
- emotionLabel.setText(text: "")
- creationLabel.setText(text: "")
pageLabel.setText(text: "")
+ creationLabel.setText(text: "")
+ emotionTagLabel.setText(text: "")
}
func configure(
@@ -91,11 +82,9 @@ final class BookDetailViewCell: UICollectionViewCell {
let displayedNote = "\"\(item.note)\""
noteLabel.setText(text: displayedNote)
- emotionIcon.image = emotion.circleImage
- emotionIcon.contentMode = .scaleAspectFit
- emotionLabel.setText(text: "#\(emotion.rawValue)")
+ pageLabel.setText(text: item.page.toPageString)
creationLabel.setText(text: item.createdAt.toKoreanDotDateString())
- pageLabel.setText(text: "\(item.page)p")
+ emotionTagLabel.setText(text: "#\(emotion.rawValue)")
}
func applyMoreButtonGesture(
@@ -113,9 +102,8 @@ final class BookDetailViewCell: UICollectionViewCell {
private extension BookDetailViewCell {
func setupViews() {
contentView.addSubviews(upperStack, noteLabel, lowerStack)
- [emotionStack, moreButton].forEach(upperStack.addArrangedSubview)
- [creationLabel, pageLabel].forEach(lowerStack.addArrangedSubview)
- [emotionIcon, emotionLabel].forEach(emotionStack.addArrangedSubview)
+ [pageLabel, moreButton].forEach(upperStack.addArrangedSubview)
+ [emotionTagLabel, creationLabel].forEach(lowerStack.addArrangedSubview)
}
func configure() {
@@ -151,6 +139,7 @@ private extension BookDetailViewCell {
.offset(LayoutConstants.lowerLabelTopInset)
$0.horizontalEdges.equalToSuperview()
.inset(LayoutConstants.horizontalInset)
+ $0.height.equalTo(LayoutConstants.lowerLabelHeight)
$0.bottom.equalToSuperview()
.inset(LayoutConstants.bottomInset)
}
@@ -158,10 +147,6 @@ private extension BookDetailViewCell {
moreButton.snp.makeConstraints {
$0.size.equalTo(LayoutConstants.moreButtonSize)
}
-
- emotionIcon.snp.makeConstraints {
- $0.size.equalTo(LayoutConstants.emotionImageSize)
- }
}
@objc func handleMoreButtonTapped() {
@@ -171,17 +156,14 @@ private extension BookDetailViewCell {
private extension BookDetailViewCell {
enum LayoutConstants {
- static let emotionStackSpacing = BKSpacing.spacing2
- static let noteLabelTopInset = BKInset.inset3
- static let lowerLabelTopInset = BKInset.inset2
+ static let noteLabelTopInset = BKInset.inset4
+ static let lowerLabelTopInset = BKInset.inset3
static let horizontalInset = BKInset.inset5
- static let contentSpacing = BKSpacing.spacing4
static let topInset = BKInset.inset5
static let bottomInset = BKInset.inset4
static let cornerRadius = BKRadius.medium
- static let emotionImageSize: CGSize = CGSize(width: 32, height: 32)
+ static let lowerLabelHeight = 22
static let moreButtonSize: CGSize = CGSize(width: 20, height: 20)
- static let imageCornerRadius: CGFloat = 20
}
enum Constants {
From f6c138d20dbee9af17a144d9c9328206de2ab7e1 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Sun, 8 Feb 2026 23:01:01 +0900
Subject: [PATCH 06/21] =?UTF-8?q?[BOOK-499]=20feat:=20Colorsystem=20?=
=?UTF-8?q?=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Sources/Extensions/UIColor+.swift | 13 +++++
.../ColorSystem/BKAtomicColor.swift | 54 +++++++++++++++----
.../ColorSystem/BKSemanticColor.swift | 35 ++++++++++--
.../BookDetail/Models/EmotionSeed.swift | 9 ++++
4 files changed, 96 insertions(+), 15 deletions(-)
diff --git a/src/Projects/BKDesign/Sources/Extensions/UIColor+.swift b/src/Projects/BKDesign/Sources/Extensions/UIColor+.swift
index 1af7d98e..2a3983a6 100644
--- a/src/Projects/BKDesign/Sources/Extensions/UIColor+.swift
+++ b/src/Projects/BKDesign/Sources/Extensions/UIColor+.swift
@@ -127,6 +127,19 @@ public extension UIColor {
}
}
+ static func bkEmotionGraphTintColor(
+ _ semanticColor: BKSemanticColor.EmotionGraphTint
+ ) -> UIColor {
+ return UIColor { traitCollection in
+ switch traitCollection.userInterfaceStyle {
+ case .dark:
+ return semanticColor.resolve(for: .light)
+ default:
+ return semanticColor.resolve(for: .light)
+ }
+ }
+ }
+
static func bkShadowColor(
_ semanticColor: BKSemanticColor.Shadow
) -> UIColor {
diff --git a/src/Projects/BKDesign/Sources/Foundation/ColorSystem/BKAtomicColor.swift b/src/Projects/BKDesign/Sources/Foundation/ColorSystem/BKAtomicColor.swift
index e408ff9a..97bdec7b 100644
--- a/src/Projects/BKDesign/Sources/Foundation/ColorSystem/BKAtomicColor.swift
+++ b/src/Projects/BKDesign/Sources/Foundation/ColorSystem/BKAtomicColor.swift
@@ -89,16 +89,50 @@ public enum BKAtomicColor {
// Blue Palette
public enum Blue: String {
- case b50 = "#e3f4ff"
- case b100 = "#bbe2ff"
- case b200 = "#8dd0ff"
- case b300 = "#56bdff"
- case b400 = "#1dadff"
- case b500 = "#009eff"
- case b600 = "#008fff"
- case b700 = "#007bff"
- case b800 = "#1269ec"
- case b900 = "#1f47cd"
+ case b50 = "#EBF3FF"
+ case b100 = "#C0D8FF"
+ case b200 = "#94BDFF"
+ case b300 = "#68A3FF"
+ case b400 = "#3C88FF"
+ case b500 = "#2A74E9"
+ case b600 = "#195CC7"
+ case b700 = "#0B47A5"
+ case b800 = "#013383"
+ case b900 = "#002661"
+
+ public var color: UIColor {
+ return UIColor(hex: self.rawValue)
+ }
+ }
+
+ public enum Orange: String {
+ case o50 = "#FFF1EB"
+ case o100 = "#FFD2BE"
+ case o200 = "#FFB392"
+ case o300 = "#FF9365"
+ case o400 = "#EF6D35"
+ case o500 = "#CD5622"
+ case o600 = "#AB4114"
+ case o700 = "#892F08"
+ case o800 = "#672001"
+ case o900 = "#451500"
+
+ public var color: UIColor {
+ return UIColor(hex: self.rawValue)
+ }
+ }
+
+ public enum Violet: String {
+ case v50 = "#F7F0FF"
+ case v100 = "#E6CEFF"
+ case v200 = "#D4ADFF"
+ case v300 = "#C38CFF"
+ case v400 = "#B26AFF"
+ case v500 = "#9A55E4"
+ case v600 = "#7F40C2"
+ case v700 = "#652EA0"
+ case v800 = "#4C1E7E"
+ case v900 = "#36125C"
public var color: UIColor {
return UIColor(hex: self.rawValue)
diff --git a/src/Projects/BKDesign/Sources/Foundation/ColorSystem/BKSemanticColor.swift b/src/Projects/BKDesign/Sources/Foundation/ColorSystem/BKSemanticColor.swift
index c9e12323..cd7bbe1a 100644
--- a/src/Projects/BKDesign/Sources/Foundation/ColorSystem/BKSemanticColor.swift
+++ b/src/Projects/BKDesign/Sources/Foundation/ColorSystem/BKSemanticColor.swift
@@ -129,22 +129,24 @@ public enum BKSemanticColor {
case joy
case insight
case sadness
+ case etc
public func resolve(for mode: BKColorMode) -> UIColor {
switch mode {
case .light:
switch self {
- case .warmth: return UIColor(hex: "#E3931B")
- case .joy: return UIColor(hex: "#EE6B33")
- case .insight: return UIColor(hex: "#9A55E4")
- case .sadness: return UIColor(hex: "#2872E9")
+ case .warmth: return BKAtomicColor.Yellow.y700.color
+ case .joy: return BKAtomicColor.Orange.o400.color
+ case .insight: return BKAtomicColor.Violet.v500.color
+ case .sadness: return BKAtomicColor.Blue.b500.color
+ case .etc: return .bkContentColor(.secondary)
}
// case .dark:
// switch self { /* dark mode colors */ }
}
}
}
-
+
public enum EmotionBase {
case warmth
case joy
@@ -166,6 +168,29 @@ public enum BKSemanticColor {
}
}
+ public enum EmotionGraphTint {
+ case warmth
+ case joy
+ case insight
+ case sadness
+ case etc
+
+ public func resolve(for mode: BKColorMode) -> UIColor {
+ switch mode {
+ case .light:
+ switch self {
+ case .warmth: return BKAtomicColor.Yellow.y300.color
+ case .joy: return BKAtomicColor.Orange.o300.color
+ case .insight: return BKAtomicColor.Violet.v300.color
+ case .sadness: return BKAtomicColor.Blue.b300.color
+ case .etc: return BKAtomicColor.Neutral.n300.color
+ }
+ // case .dark:
+ // switch self { /* dark mode colors */ }
+ }
+ }
+ }
+
public enum Shadow {
case primary
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
index 02ae94a6..e92b9721 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
@@ -47,6 +47,15 @@ enum EmotionSeed: String, CaseIterable {
}
}
+ var graphTintColor: UIColor {
+ switch self {
+ case .warmth: return .bkEmotionGraphTintColor(.warmth)
+ case .joy: return .bkEmotionGraphTintColor(.joy)
+ case .insight: return .bkEmotionGraphTintColor(.insight)
+ case .sad: return .bkEmotionGraphTintColor(.sadness)
+ }
+ }
+
static func from(emotion: Emotion) -> Self {
switch emotion {
case .joy: return .joy
From 91c05ae40907bcfbb2e872a8a8186910025a2b50 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 10:44:45 +0900
Subject: [PATCH 07/21] =?UTF-8?q?[BOOK-499]=20feat:=20SeedGraphView(progre?=
=?UTF-8?q?ss=20bar)=20=EA=B0=9C=EB=B0=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../BookDetail/View/BookDetailView.swift | 3 +-
.../BookDetail/View/SeedGraphView.swift | 59 +++++++++++++++++++
2 files changed, 61 insertions(+), 1 deletion(-)
create mode 100644 src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedGraphView.swift
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
index 08566cba..9d224512 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
@@ -239,7 +239,8 @@ final class BookDetailView: BaseView {
}
func applySeedReport(with seeds: [Seed]) {
- seedReportView.applyReport(with: seeds)
+ seedReportView.setEmotionHeader(with: Emotion.joy)
+ seedReportView.applyGraph(with: seeds)
}
func applySort(option: SortOption) {
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedGraphView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedGraphView.swift
new file mode 100644
index 00000000..f9aecc60
--- /dev/null
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedGraphView.swift
@@ -0,0 +1,59 @@
+// Copyright © 2026 Booket. All rights reserved
+
+import BKDesign
+import BKDomain
+import SnapKit
+import UIKit
+
+final class SeedGraphView: BaseView {
+ private let stackView: UIStackView = {
+ let stackView = UIStackView()
+ stackView.axis = .horizontal
+ stackView.distribution = .fill
+ stackView.alignment = .fill
+ stackView.spacing = 0
+ stackView.clipsToBounds = true
+ stackView.layer.cornerRadius = 6
+ return stackView
+ }()
+
+ override func setupView() {
+ addSubview(stackView)
+ }
+
+ override func setupLayout() {
+ stackView.snp.makeConstraints {
+ $0.edges.equalToSuperview()
+ }
+ }
+
+ func applyGraph(with seeds: [Seed]) {
+ stackView.arrangedSubviews.forEach {
+ stackView.removeArrangedSubview($0)
+ $0.removeFromSuperview()
+ }
+
+ let totalCount = CGFloat(seeds.reduce(0) { $0 + $1.count })
+
+ guard totalCount > 0 else { return }
+
+ for (index, seed) in seeds.enumerated() {
+ let segment = UIView()
+ let emotion = EmotionSeed.from(seed: seed)
+
+ segment.backgroundColor = emotion?.graphTintColor ?? .lightGray
+ stackView.addArrangedSubview(segment)
+
+ segment.snp.makeConstraints {
+ let ratio = CGFloat(seed.count) / totalCount
+
+ if index < seeds.count - 1 {
+ $0.width.equalTo(stackView.snp.width).multipliedBy(ratio)
+ }
+ }
+ }
+
+ self.layoutIfNeeded()
+ }
+
+}
From c9fe268c9deef8352c66d14161143444dc78f026 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 11:30:45 +0900
Subject: [PATCH 08/21] =?UTF-8?q?[BOOK-499]=20feat:=20SeedItemView=20?=
=?UTF-8?q?=EA=B0=9C=EB=B0=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../BookDetail/View/SeedItemView.swift | 75 +++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100644 src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedItemView.swift
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedItemView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedItemView.swift
new file mode 100644
index 00000000..981ea4eb
--- /dev/null
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedItemView.swift
@@ -0,0 +1,75 @@
+// Copyright © 2026 Booket. All rights reserved
+
+import BKDesign
+import BKDomain
+import SnapKit
+import UIKit
+
+final class SeedItemView: BaseView {
+ // MARK: - UI Components
+ private let dotView: UIView = {
+ let view = UIView()
+ view.layer.cornerRadius = LayoutConstants.dotRadius
+ return view
+ }()
+
+ private let nameLabel = BKLabel(
+ fontStyle: .label2(weight: .regular),
+ color: .bkContentColor(.secondary),
+ alignment: .center
+ )
+
+ private let countLabel = BKLabel(
+ fontStyle: .caption1(weight: .regular),
+ color: .bkContentColor(.tertiary),
+ alignment: .center
+ )
+
+ override func setupView() {
+ addSubviews(dotView, nameLabel, countLabel)
+ }
+
+ override func configure() {
+ backgroundColor = .bkBaseColor(.primary)
+ layer.cornerRadius = LayoutConstants.bgRadius
+ clipsToBounds = true
+ }
+
+ override func setupLayout() {
+ dotView.snp.makeConstraints {
+ $0.top.equalToSuperview().inset(LayoutConstants.dotToTopInset)
+ $0.centerX.equalToSuperview()
+ $0.size.equalTo(LayoutConstants.dotSize)
+ }
+
+ nameLabel.snp.makeConstraints {
+ $0.top.equalTo(dotView.snp.bottom).offset(LayoutConstants.nameToDot)
+ $0.centerX.equalToSuperview()
+ }
+
+ countLabel.snp.makeConstraints {
+ $0.top.equalTo(nameLabel.snp.bottom)
+ $0.centerX.equalToSuperview()
+ $0.bottom.equalToSuperview().inset(LayoutConstants.countLabelBottomInset)
+ }
+ }
+
+ func configure(with seed: Seed) {
+ let emotion = EmotionSeed.from(seed: seed)
+ dotView.backgroundColor = emotion?.graphTintColor
+ nameLabel.setText(text: seed.name)
+ countLabel.setText(text: "\(seed.count)개")
+ }
+}
+
+private extension SeedItemView {
+ enum LayoutConstants {
+ static let dotRadius = BKRadius.xsmall
+ static let bgRadius = BKRadius.medium
+ static let dotToTopInset = BKSpacing.spacing3
+ static let dotSize = CGSize(width: 10, height: 10)
+
+ static let nameToDot = BKSpacing.spacing2
+ static let countLabelBottomInset = BKSpacing.spacing2
+ }
+}
From fbd54e34a1bb93032a220e19e0dd0d2ef1718339 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 12:50:34 +0900
Subject: [PATCH 09/21] =?UTF-8?q?[BOOK-499]=20feat:=20SeedReportView=20?=
=?UTF-8?q?=EB=82=B4=EB=B6=80=20=EB=B7=B0=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../BookDetail/View/SeedReportView.swift | 264 +++++++++---------
1 file changed, 132 insertions(+), 132 deletions(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
index 2140d941..5fc93ef6 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
@@ -6,189 +6,189 @@ import SnapKit
import UIKit
final class SeedReportView: BaseView {
- private let titleLabel = BKLabel(
- text: "내가 모은 씨앗",
- fontStyle: .body2(weight: .medium),
- color: .bkContentColor(.secondary)
- )
+ // MARK: - Properties
+ private var isExpanded = false
- private var emotionReport: UIStackView = {
+ // MARK: - UI Components
+ private let containerStackView: UIStackView = {
let stackView = UIStackView()
- stackView.axis = .horizontal
- stackView.distribution = .equalSpacing
+ stackView.axis = .vertical
+ stackView.spacing = 16
stackView.alignment = .fill
return stackView
}()
+ private let headerView = UIView()
+ private let emotionImageView = UIImageView()
+
private let reportLabel = BKLabel2(
- fontStyle: .label2(weight: .regular),
+ fontStyle: .label1(weight: .medium),
color: .bkContentColor(.secondary),
highlightColor: .bkContentColor(.brand),
- highlightFont: BKTextStyle.label2(weight: .semiBold).uiFont
+ highlightFont: BKTextStyle.label1(weight: .semiBold).uiFont
)
- private let reportContainer = UIView()
+ private let foldButton: UIImageView = {
+ let imageView = UIImageView(
+ image: BKImage.Icon.chevronDown
+ .withRenderingMode(.alwaysTemplate)
+ )
+ imageView.tintColor = .bkContentColor(.tertiary)
+ imageView.isUserInteractionEnabled = true
+ return imageView
+ }()
+
+ private let divider = BKDivider(type: .small)
+
+ private let expandedView: UIView = {
+ let view = UIView()
+ view.isHidden = true
+ view.alpha = 0
+ return view
+ }()
+
+ private let graphView = SeedGraphView()
+
+ private let labelsStackView: UIStackView = {
+ let stackView = UIStackView()
+ stackView.axis = .horizontal
+ stackView.distribution = .fillEqually
+ stackView.alignment = .fill
+ stackView.spacing = 4
+ return stackView
+ }()
override func setupView() {
- addSubviews(titleLabel, emotionReport, reportContainer)
- reportContainer.addSubview(reportLabel)
+ addSubview(containerStackView)
+
+ headerView.addSubviews(emotionImageView, reportLabel, foldButton)
+ [headerView, expandedView].forEach(containerStackView.addArrangedSubview)
+ expandedView.addSubviews(divider, graphView, labelsStackView)
+
+ let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggleExpansion))
+ foldButton.addGestureRecognizer(tapGesture)
}
override func configure() {
layer.cornerRadius = LayoutConstants.cornerRadius
clipsToBounds = true
backgroundColor = .bkBaseColor(.secondary)
- reportContainer.backgroundColor = .bkBaseColor(.primary)
- reportContainer.layer.borderWidth = LayoutConstants.reportContainerBorderWidth
- reportContainer.layer.cornerRadius = LayoutConstants.reportContainerCornerRadius
- reportContainer.layer.borderColor = UIColor.bkBorderColor(.primary).cgColor
- reportContainer.clipsToBounds = true
+
+ emotionImageView.image = BKImage.Graphics.warmCircle
+ reportLabel.setText(text: "테스트용 텍스트입니다.")
}
override func setupLayout() {
- titleLabel.snp.makeConstraints {
- $0.top.trailing.leading.equalToSuperview()
- .inset(LayoutConstants.contentInset)
+ containerStackView.snp.makeConstraints {
+ $0.edges.equalToSuperview().inset(LayoutConstants.contentInset)
}
- emotionReport.snp.makeConstraints {
- $0.top.equalTo(titleLabel.snp.bottom)
- .offset(LayoutConstants.contentSpacing)
- $0.height.equalTo(LayoutConstants.emotionReportHeight)
- $0.leading.trailing.equalToSuperview()
- .inset(LayoutConstants.contentInset * 2)
+ headerView.snp.makeConstraints {
+ $0.height.equalTo(LayoutConstants.emotionStackHeight)
}
- reportContainer.snp.makeConstraints {
- $0.top.equalTo(emotionReport.snp.bottom)
- .offset(LayoutConstants.contentSpacing)
- $0.leading.trailing.bottom.equalToSuperview()
- .inset(LayoutConstants.contentInset)
- $0.height.equalTo(42)
+ emotionImageView.snp.makeConstraints {
+ $0.leading.equalToSuperview()
+ $0.centerY.equalToSuperview()
+ $0.size.equalTo(
+ CGSize(
+ width: LayoutConstants.emotionStackHeight,
+ height: LayoutConstants.emotionStackHeight
+ )
+ )
}
reportLabel.snp.makeConstraints {
- $0.center.equalToSuperview()
+ $0.leading
+ .equalTo(emotionImageView.snp.trailing)
+ .offset(LayoutConstants.labelLeadingInset)
+ $0.centerY.equalToSuperview()
}
- }
-
- func applyReport(with seeds: [Seed]) {
- var counts: [EmotionSeed: Int] = [:]
- for s in seeds {
- if let key = EmotionSeed.from(seed: s) {
- counts[key, default: 0] += s.count
- }
- }
- applyReportCore(counts: counts)
- }
-}
-
-private extension SeedReportView {
- func applyReportCore(counts: [EmotionSeed: Int]) {
- emotionReport.arrangedSubviews.forEach {
- emotionReport.removeArrangedSubview($0)
- $0.removeFromSuperview()
+
+ foldButton.snp.makeConstraints {
+ $0.trailing.equalToSuperview()
+ $0.centerY.equalToSuperview()
+ $0.size.equalTo(LayoutConstants.iconSize)
}
-
- for seed in EmotionSeed.allCases {
- let count = counts[seed] ?? 0
- emotionReport.addArrangedSubview(makeInnerView(with: seed, count: count))
+
+ divider.snp.makeConstraints {
+ $0.top.horizontalEdges.equalToSuperview()
}
-
- let (summary, highlightedWord) = generateEmotionSummary(from: counts)
- reportLabel.setText(text: summary)
- reportLabel.highlightedWord = highlightedWord
- }
-
- func generateEmotionSummary(
- from counts: [EmotionSeed: Int]
- ) -> (String, String) {
- let sorted = EmotionSeed.allCases
- .map { ($0, counts[$0] ?? 0) }
- .sorted { $0.1 > $1.1 }
- guard let maxCount = sorted.first?.1, maxCount > 0 else {
- return ("감정 데이터가 부족해요.", "")
+ graphView.snp.makeConstraints {
+ $0.top.equalTo(divider.snp.bottom).offset(LayoutConstants.graphTopOffset)
+ $0.horizontalEdges.equalToSuperview()
+ $0.height.equalTo(LayoutConstants.graphHeight)
}
- let top = sorted.filter { $0.1 == maxCount }.map { $0.0 }
- if top.count >= 3 {
- return ("이 책에서 여러 감정이 고르게 담겼어요", "여러 감정이 고르게 담겼어요")
- } else {
- let names = top.map { $0.rawValue }.joined(separator: ", ")
- return ("이 책에서 \(names) 감정을 많이 느꼈어요", names)
+ labelsStackView.snp.makeConstraints {
+ $0.top.equalTo(graphView.snp.bottom).offset(LayoutConstants.labelsTopOffset)
+ $0.height.equalTo(72)
+ $0.horizontalEdges.equalToSuperview()
+ $0.bottom.equalToSuperview()
}
}
- func makeInnerView(
- with emotion: EmotionSeed,
- count: Int
- ) -> UIView {
- let containerView = UIView()
- let imageView = UIImageView(image: emotion.image)
- let labelContainer = UIView()
- let emotionLabel = BKLabel(
- text: emotion.rawValue,
- fontStyle: .label2(weight: .semiBold),
- color: emotion.color
- )
- labelContainer.backgroundColor = emotion.baseColor
- labelContainer.layer.cornerRadius = LayoutConstants.labelContainerCornerRadius
- labelContainer.clipsToBounds = true
- let countLabel = BKLabel(
- text: "\(count)",
- fontStyle: .label2(weight: .regular),
- color: .bkContentColor(.secondary)
- )
-
- containerView.addSubviews(imageView, labelContainer, countLabel)
- labelContainer.addSubview(emotionLabel)
+ func setEmotionHeader(with emotion: Emotion) {
+ let emotion = EmotionSeed.from(emotion: emotion)
+ let emotionText = "\'\(emotion.rawValue)\'"
+ emotionImageView.image = emotion.circleImage
+ reportLabel.highlightColor = emotion.color
+ reportLabel.setText(text: "\(emotionText) 감정을 많이 느꼈어요")
+ reportLabel.highlightedWord = emotionText
+ }
+
+ func applyGraph(with seeds: [Seed]) {
+ graphView.applyGraph(with: seeds)
- imageView.snp.makeConstraints {
- $0.top.leading.trailing.equalToSuperview()
- $0.size.equalTo(LayoutConstants.imageSize)
+ labelsStackView.arrangedSubviews.forEach {
+ $0.removeFromSuperview()
}
+ print(seeds)
+ let seedDictionary = Dictionary(uniqueKeysWithValues: seeds.map { ($0.name, $0) })
+ print(seedDictionary)
- labelContainer.snp.makeConstraints {
- $0.top.equalTo(imageView.snp.bottom)
- .offset(LayoutConstants.labelContainerOffset)
- $0.height.equalTo(LayoutConstants.labelContainerHeight)
- $0.centerX.equalToSuperview()
+ EmotionSeed.allCases.forEach { emotionCase in
+ seeds.forEach { seed in
+ if seed.name == emotionCase.rawValue && seed.count >= 1 {
+ let itemView = SeedItemView()
+ itemView.configure(with: seed)
+ labelsStackView.addArrangedSubview(itemView)
+ }
+ }
}
- emotionLabel.snp.makeConstraints {
- $0.horizontalEdges.equalToSuperview()
- .inset(LayoutConstants.emotionLabelHorizontalInset)
- $0.verticalEdges.equalToSuperview()
- .inset(LayoutConstants.emotionLabelVerticalInset)
- }
+ self.setNeedsLayout()
+ self.layoutIfNeeded()
+ }
+}
+
+private extension SeedReportView {
+ @objc private func toggleExpansion() {
+ isExpanded.toggle()
- countLabel.snp.makeConstraints {
- $0.top.equalTo(labelContainer.snp.bottom)
- .offset(LayoutConstants.countLabelOffset)
- $0.centerX.equalToSuperview()
- $0.bottom.equalToSuperview()
+ UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseInOut]) {
+ self.expandedView.isHidden = !self.isExpanded
+ self.expandedView.alpha = self.isExpanded ? 1 : 0
+
+ let angle: CGFloat = self.isExpanded ? .pi : 0
+ self.foldButton.transform = CGAffineTransform(rotationAngle: angle)
+
+ self.layoutIfNeeded()
}
-
- return containerView
}
}
private extension SeedReportView {
enum LayoutConstants {
static let contentInset = BKInset.inset4
- static let contentSpacing = BKSpacing.spacing5
static let cornerRadius = BKRadius.medium
- static let reportLabelVerticalInset = BKInset.inset3
- static let reportContainerBorderWidth = BKBorder.border1
- static let reportContainerCornerRadius = BKRadius.small
- static let labelContainerHeight: CGFloat = 24
- static let labelContainerCornerRadius: CGFloat = labelContainerHeight / 2
- static let imageSize: CGSize = CGSize(width: 50, height: 50)
- static let labelContainerOffset = BKInset.inset2
- static let countLabelOffset = BKInset.inset1
- static let emotionLabelHorizontalInset = BKInset.inset2
- static let emotionLabelVerticalInset = BKInset.inset1
- static let emotionReportHeight: CGFloat = 106
+ static let emotionStackHeight = 36
+ static let labelLeadingInset = BKSpacing.spacing2
+ static let iconSize: CGSize = CGSize(width: 24, height: 24)
+
+ static let graphHeight: CGFloat = 12
+ static let graphTopOffset: CGFloat = BKSpacing.spacing5
+ static let labelsTopOffset: CGFloat = BKSpacing.spacing4
}
}
From 3aaa79876f6ba81694a519e5256dd28d95237818 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 14:27:18 +0900
Subject: [PATCH 10/21] [BOOK-499] feat: add api-v2 base url
---
src/Projects/BKData/Sources/Constant/APIConfig.swift | 7 +++++++
src/SupportingFiles/Booket/Info.plist | 4 ++++
2 files changed, 11 insertions(+)
diff --git a/src/Projects/BKData/Sources/Constant/APIConfig.swift b/src/Projects/BKData/Sources/Constant/APIConfig.swift
index 9b882d8d..b26a1136 100644
--- a/src/Projects/BKData/Sources/Constant/APIConfig.swift
+++ b/src/Projects/BKData/Sources/Constant/APIConfig.swift
@@ -13,4 +13,11 @@ enum APIConfig {
}
return value
}()
+
+ static let baseV2URL: String = {
+ guard let value = bundle.object(forInfoDictionaryKey: "BASE_API_V2_URL") as? String else {
+ fatalError("Can't load environment: BKData.BASE_API_URL")
+ }
+ return value
+ }()
}
diff --git a/src/SupportingFiles/Booket/Info.plist b/src/SupportingFiles/Booket/Info.plist
index 607cf91b..4fc2e21d 100644
--- a/src/SupportingFiles/Booket/Info.plist
+++ b/src/SupportingFiles/Booket/Info.plist
@@ -8,6 +8,10 @@
문장 카드를 이미지로 저장하기 위해 사진첩 접근 권한이 필요합니다.
BASE_API_URL
$(BASE_API_URL)
+ BASE_API_V2_URL
+ $(BASE_API_V2_URL)
+ LSApplicationCategoryType
+
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
From d26e95cd4e0f22e36ce2fdf36c086a2e86906d9b Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 14:27:34 +0900
Subject: [PATCH 11/21] =?UTF-8?q?[BOOK-499]=20feat:=20etc=20emotion=20case?=
=?UTF-8?q?=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Projects/BKDomain/Sources/Entity/Emotion.swift | 1 +
.../MainFlow/BookDetail/Models/EmotionSeed.swift | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/src/Projects/BKDomain/Sources/Entity/Emotion.swift b/src/Projects/BKDomain/Sources/Entity/Emotion.swift
index ebe70c95..9641d909 100644
--- a/src/Projects/BKDomain/Sources/Entity/Emotion.swift
+++ b/src/Projects/BKDomain/Sources/Entity/Emotion.swift
@@ -5,4 +5,5 @@ public enum Emotion: String, CaseIterable, Decodable {
case joy = "즐거움"
case sad = "슬픔"
case insight = "깨달음"
+ case etc = "기타"
}
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
index e92b9721..7581195b 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
@@ -10,6 +10,7 @@ enum EmotionSeed: String, CaseIterable {
case joy = "즐거움"
case sad = "슬픔"
case insight = "깨달음"
+ case etc = "기타"
var image: UIImage {
switch self {
@@ -17,6 +18,7 @@ enum EmotionSeed: String, CaseIterable {
case .joy: return BKImage.Graphics.joy
case .insight: return BKImage.Graphics.insight
case .sad: return BKImage.Graphics.sad
+ case .etc: return BKImage.Graphics.sad
}
}
@@ -26,6 +28,7 @@ enum EmotionSeed: String, CaseIterable {
case .joy: return BKImage.Graphics.joyCircle
case .sad: return BKImage.Graphics.sadCircle
case .insight: return BKImage.Graphics.insightCircle
+ case .etc: return BKImage.Graphics.insightCircle
}
}
@@ -35,6 +38,7 @@ enum EmotionSeed: String, CaseIterable {
case .joy: return .bkEmotionColor(.joy)
case .insight: return .bkEmotionColor(.insight)
case .sad: return .bkEmotionColor(.sadness)
+ case .etc: return .bkEmotionColor(.etc)
}
}
@@ -44,6 +48,7 @@ enum EmotionSeed: String, CaseIterable {
case .joy: return .bkEmotionBaseColor(.joy)
case .insight: return .bkEmotionBaseColor(.insight)
case .sad: return .bkEmotionBaseColor(.sadness)
+ case .etc: return .bkEmotionColor(.etc)
}
}
@@ -53,6 +58,7 @@ enum EmotionSeed: String, CaseIterable {
case .joy: return .bkEmotionGraphTintColor(.joy)
case .insight: return .bkEmotionGraphTintColor(.insight)
case .sad: return .bkEmotionGraphTintColor(.sadness)
+ case .etc: return .bkEmotionGraphTintColor(.etc)
}
}
@@ -62,6 +68,7 @@ enum EmotionSeed: String, CaseIterable {
case .sad: return .sad
case .insight: return .insight
case .warmth: return .warmth
+ case .etc: return .etc
}
}
@@ -71,6 +78,7 @@ enum EmotionSeed: String, CaseIterable {
case "joy", "즐거움": return .joy
case "sad", "슬픔": return .sad
case "insight", "깨달음": return .insight
+ case "etc", "기타": return .etc
default: return nil
}
}
@@ -86,6 +94,7 @@ enum EmotionSeed: String, CaseIterable {
case .joy: return BKImage.Graphics.joyCard
case .insight: return BKImage.Graphics.insightCard
case .sad: return BKImage.Graphics.sadCard
+ case .etc: return BKImage.Graphics.sadCard
}
}
@@ -96,6 +105,7 @@ enum EmotionSeed: String, CaseIterable {
case .joy: return UIColor(hex: "FFF7F5")
case .insight: return UIColor(hex: "FBF8FF")
case .sad: return UIColor(hex: "F4F8FF")
+ case .etc: return UIColor(hex: "F4F8FF")
}
}
}
From 8ef8f5e539ddfaf25ebdae2a721a7b4261b6f54d Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 15:17:31 +0900
Subject: [PATCH 12/21] =?UTF-8?q?[BOOK-499]=20feat:=20api-v2=20=EC=A0=81?=
=?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8A=94=20=EC=BC=80=EC=9D=B4=EC=8A=A4?=
=?UTF-8?q?=EB=A7=8C=20=EB=94=B0=EB=A1=9C=20=EB=B6=84=EB=A5=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Projects/BKData/Sources/API/RecordAPI.swift | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/Projects/BKData/Sources/API/RecordAPI.swift b/src/Projects/BKData/Sources/API/RecordAPI.swift
index ae729d56..4aaab2e7 100644
--- a/src/Projects/BKData/Sources/API/RecordAPI.swift
+++ b/src/Projects/BKData/Sources/API/RecordAPI.swift
@@ -14,7 +14,12 @@ enum RecordAPI {
extension RecordAPI: RequestTarget {
var baseURL: String {
- return "\(APIConfig.baseURL)/reading-records"
+ switch self {
+ case .fetch, .seed:
+ return "\(APIConfig.baseV2URL)/reading-records"
+ default:
+ return "\(APIConfig.baseURL)/reading-records"
+ }
}
var path: String {
From f27f584a1cb31b1649a62407e448b698a01bb8ff Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 15:17:49 +0900
Subject: [PATCH 13/21] =?UTF-8?q?[BOOK-499]=20feat:=20fetch,=20seed=20v2?=
=?UTF-8?q?=20responseDTO=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Response/DetailRecordResponseDTO.swift | 36 +++++++++++++++++++
.../DTO/Response/FetchRecordResponseDTO.swift | 3 +-
.../Response/PrimaryEmotionResponseDTO.swift | 13 +++++++
3 files changed, 51 insertions(+), 1 deletion(-)
create mode 100644 src/Projects/BKData/Sources/DTO/Response/PrimaryEmotionResponseDTO.swift
diff --git a/src/Projects/BKData/Sources/DTO/Response/DetailRecordResponseDTO.swift b/src/Projects/BKData/Sources/DTO/Response/DetailRecordResponseDTO.swift
index d0303ad5..cc64b1dd 100644
--- a/src/Projects/BKData/Sources/DTO/Response/DetailRecordResponseDTO.swift
+++ b/src/Projects/BKData/Sources/DTO/Response/DetailRecordResponseDTO.swift
@@ -36,3 +36,39 @@ extension DetailRecordResponseDTO {
)
}
}
+
+// api-v2
+public struct DetailRecordV2ResponseDTO: Decodable {
+ public let id: String
+ public let userBookId: String
+ public let pageNumber: Int
+ public let quote: String
+ public let review: String?
+ public let primaryEmotion: PrimaryEmotionResponseDTO
+ public let detailEmotions: [DetailEmotionResponseDTO?]
+ public let createdAt: String
+ public let updatedAt: String
+ public let bookTitle: String
+ public let bookPublisher: String
+ public let bookCoverImageUrl: URL
+ public let author: String
+}
+
+extension DetailRecordV2ResponseDTO {
+ func toRecordInfo() -> RecordInfo {
+ return RecordInfo(
+ recordId: id,
+ bookId: userBookId,
+ pageNumber: pageNumber,
+ quote: quote,
+ review: review,
+ emotionTags: [primaryEmotion.displayName],
+ createdAt: DateParser.parseISO8601(createdAt) ?? .distantPast,
+ updatedAt: DateParser.parseISO8601(updatedAt),
+ bookTitle: bookTitle,
+ bookPublisher: bookPublisher,
+ bookCoverImageUrl: bookCoverImageUrl,
+ author: author
+ )
+ }
+}
diff --git a/src/Projects/BKData/Sources/DTO/Response/FetchRecordResponseDTO.swift b/src/Projects/BKData/Sources/DTO/Response/FetchRecordResponseDTO.swift
index 77400282..4739ccab 100644
--- a/src/Projects/BKData/Sources/DTO/Response/FetchRecordResponseDTO.swift
+++ b/src/Projects/BKData/Sources/DTO/Response/FetchRecordResponseDTO.swift
@@ -3,7 +3,8 @@
import BKDomain
struct FetchRecordResponseDTO: Decodable {
- let readingRecords: [DetailRecordResponseDTO]
+ let readingRecords: [DetailRecordV2ResponseDTO]
let lastPage: Bool
let totalResults: Int
+ let representativeEmotion: PrimaryEmotionResponseDTO?
}
diff --git a/src/Projects/BKData/Sources/DTO/Response/PrimaryEmotionResponseDTO.swift b/src/Projects/BKData/Sources/DTO/Response/PrimaryEmotionResponseDTO.swift
new file mode 100644
index 00000000..d10ab8e3
--- /dev/null
+++ b/src/Projects/BKData/Sources/DTO/Response/PrimaryEmotionResponseDTO.swift
@@ -0,0 +1,13 @@
+// Copyright © 2026 Booket. All rights reserved
+
+import BKDomain
+
+public struct PrimaryEmotionResponseDTO: Decodable {
+ let code: String
+ let displayName: Emotion
+}
+
+public struct DetailEmotionResponseDTO: Decodable {
+ let id: String
+ let name: String
+}
From 38d0ce38853574c2a554164c6d4053ff4370e07b Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 15:19:32 +0900
Subject: [PATCH 14/21] =?UTF-8?q?[BOOK-499]=20feat:=20fetch=20in=20RecordR?=
=?UTF-8?q?epo=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20RecordFetchResult=20Enti?=
=?UTF-8?q?ty=20=EC=83=9D=EC=84=B1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Repository/DefaultRecordRepository.swift | 11 ++++++++--
.../Sources/Entity/RecordFetchResult.swift | 22 +++++++++++++++++++
.../Repository/RecordRepository.swift | 2 +-
3 files changed, 32 insertions(+), 3 deletions(-)
create mode 100644 src/Projects/BKDomain/Sources/Entity/RecordFetchResult.swift
diff --git a/src/Projects/BKData/Sources/Repository/DefaultRecordRepository.swift b/src/Projects/BKData/Sources/Repository/DefaultRecordRepository.swift
index 2720d86c..2093ed2b 100644
--- a/src/Projects/BKData/Sources/Repository/DefaultRecordRepository.swift
+++ b/src/Projects/BKData/Sources/Repository/DefaultRecordRepository.swift
@@ -33,7 +33,7 @@ public final class DefaultRecordRepository: RecordRepository {
bookId: String,
sortType: LibrarySortType,
page: Int
- ) -> AnyPublisher<(infos: [RecordInfo], hasMore: Bool, totalCount: Int), DomainError> {
+ ) -> AnyPublisher {
networkProvider.request(
target: RecordAPI.fetch(
userBookId: bookId,
@@ -46,7 +46,14 @@ public final class DefaultRecordRepository: RecordRepository {
)
.mapError { $0.toDomainError() }
.debugError(logger: AppLogger.network)
- .map { ($0.readingRecords.map { $0.toRecordInfo() }, !$0.lastPage, $0.totalResults) }
+ .map {
+ RecordFetchResult(
+ infos: $0.readingRecords.map { $0.toRecordInfo() },
+ hasMore: !$0.lastPage,
+ totalCount: $0.totalResults,
+ mainEmotion: $0.representativeEmotion?.displayName
+ )
+ }
.eraseToAnyPublisher()
}
diff --git a/src/Projects/BKDomain/Sources/Entity/RecordFetchResult.swift b/src/Projects/BKDomain/Sources/Entity/RecordFetchResult.swift
new file mode 100644
index 00000000..7dae726f
--- /dev/null
+++ b/src/Projects/BKDomain/Sources/Entity/RecordFetchResult.swift
@@ -0,0 +1,22 @@
+// Copyright © 2026 Booket. All rights reserved
+
+import Foundation
+
+public struct RecordFetchResult {
+ public let infos: [RecordInfo]
+ public let hasMore: Bool
+ public let totalCount: Int
+ public let mainEmotion: Emotion?
+
+ public init(
+ infos: [RecordInfo],
+ hasMore: Bool,
+ totalCount: Int,
+ mainEmotion: Emotion?
+ ) {
+ self.infos = infos
+ self.hasMore = hasMore
+ self.totalCount = totalCount
+ self.mainEmotion = mainEmotion
+ }
+}
diff --git a/src/Projects/BKDomain/Sources/Interface/Repository/RecordRepository.swift b/src/Projects/BKDomain/Sources/Interface/Repository/RecordRepository.swift
index 5787bcc6..5654778f 100644
--- a/src/Projects/BKDomain/Sources/Interface/Repository/RecordRepository.swift
+++ b/src/Projects/BKDomain/Sources/Interface/Repository/RecordRepository.swift
@@ -13,7 +13,7 @@ public protocol RecordRepository {
bookId: String,
sortType: LibrarySortType,
page: Int
- ) -> AnyPublisher<(infos: [RecordInfo], hasMore: Bool, totalCount: Int), DomainError>
+ ) -> AnyPublisher
func findBy(
id recordId: String
From 76447894925fe5368f3de17ad27d5b808099709a Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 15:19:57 +0900
Subject: [PATCH 15/21] =?UTF-8?q?[BOOK-499]=20feat:=20FetchRecordsUseCase?=
=?UTF-8?q?=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Sources/Interface/Usecase/FetchRecordsUseCase.swift | 2 +-
.../BKDomain/Sources/UseCase/DefaultFetchRecordsUseCase.swift | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Projects/BKDomain/Sources/Interface/Usecase/FetchRecordsUseCase.swift b/src/Projects/BKDomain/Sources/Interface/Usecase/FetchRecordsUseCase.swift
index b0f0d602..ca813c9d 100644
--- a/src/Projects/BKDomain/Sources/Interface/Usecase/FetchRecordsUseCase.swift
+++ b/src/Projects/BKDomain/Sources/Interface/Usecase/FetchRecordsUseCase.swift
@@ -6,5 +6,5 @@ public protocol FetchRecordsUseCase {
func execute(
id: String,
page: Int
- ) -> AnyPublisher<(infos: [RecordInfo], hasMore: Bool, totalCount: Int), DomainError>
+ ) -> AnyPublisher
}
diff --git a/src/Projects/BKDomain/Sources/UseCase/DefaultFetchRecordsUseCase.swift b/src/Projects/BKDomain/Sources/UseCase/DefaultFetchRecordsUseCase.swift
index fcecb6b5..dbea511a 100644
--- a/src/Projects/BKDomain/Sources/UseCase/DefaultFetchRecordsUseCase.swift
+++ b/src/Projects/BKDomain/Sources/UseCase/DefaultFetchRecordsUseCase.swift
@@ -12,7 +12,7 @@ public struct DefaultFetchRecordsUseCase: FetchRecordsUseCase {
public func execute(
id: String,
page: Int
- ) -> AnyPublisher<(infos: [RecordInfo], hasMore: Bool, totalCount: Int), DomainError> {
+ ) -> AnyPublisher {
repository.fetch(
bookId: id,
sortType: .pageNumberDesc,
From 124cf2a6242c6a148edca22f4958e7a1b5f2ad0d Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 15:20:20 +0900
Subject: [PATCH 16/21] =?UTF-8?q?[BOOK-499]=20feat:=20=EB=8C=80=ED=91=9C?=
=?UTF-8?q?=EA=B0=90=EC=A0=95=20api=20=EC=97=B0=EA=B2=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../MainFlow/BookDetail/View/BookDetailView.swift | 5 ++++-
.../BookDetail/View/BookDetailViewController.swift | 9 +++++++++
.../BookDetail/ViewModel/BookDetailViewModel.swift | 14 +++++++++++---
3 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
index 9d224512..cbc24a48 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift
@@ -238,8 +238,11 @@ final class BookDetailView: BaseView {
}
}
+ func applySeedHeader(with mainEmotion: Emotion) {
+ seedReportView.setEmotionHeader(with: mainEmotion)
+ }
+
func applySeedReport(with seeds: [Seed]) {
- seedReportView.setEmotionHeader(with: Emotion.joy)
seedReportView.applyGraph(with: seeds)
}
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewController.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewController.swift
index 5353b10e..c9818f60 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewController.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewController.swift
@@ -214,6 +214,15 @@ final class BookDetailViewController: BaseViewController, Screen
}
.store(in: &cancellable)
+ viewModel.statePublisher
+ .receive(on: DispatchQueue.main)
+ .compactMap { $0.mainEmotion }
+ .removeDuplicates()
+ .sink { [weak self] in
+ self?.contentView.applySeedHeader(with: $0)
+ }
+ .store(in: &cancellable)
+
viewModel.statePublisher
.map { $0.deleteCompleted }
.removeDuplicates()
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/ViewModel/BookDetailViewModel.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/ViewModel/BookDetailViewModel.swift
index 92116aa4..4d3e24a3 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/ViewModel/BookDetailViewModel.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/ViewModel/BookDetailViewModel.swift
@@ -10,6 +10,7 @@ final class BookDetailViewModel: BaseViewModel {
var items: [BookDetailItem] = []
var currentBook: Book?
var sortOption: SortOption = .pageDescending
+ var mainEmotion: Emotion?
var seeds = [Seed]()
var isAddNoteTriggered = false
var isStatusButtonTriggered = false
@@ -40,7 +41,12 @@ final class BookDetailViewModel: BaseViewModel {
case cellTapHandled
case upsert(isbn: String, status: BookRegistrationStatus)
case upsertSuccessed(Book)
- case fetchRecordsSuccessed(items: [BookDetailItem], hasMore: Bool, totalResult: Int)
+ case fetchRecordsSuccessed(
+ items: [BookDetailItem],
+ hasMore: Bool,
+ totalResult: Int,
+ mainEmotion: Emotion?
+ )
case fetchSeedStatsSuccessed([Seed])
case fetchBookDetailSuccessed(Book)
case errorOccured(DomainError)
@@ -134,11 +140,12 @@ final class BookDetailViewModel: BaseViewModel {
case .fetchBookDetailSuccessed(let book):
newState.currentBook = book
- case .fetchRecordsSuccessed(let items, let hasMore, let totalResults):
+ case .fetchRecordsSuccessed(let items, let hasMore, let totalResults, let mainEmotion):
newState.items = items
newState.nextPage = 1
newState.hasMore = hasMore
newState.totalResults = totalResults
+ newState.mainEmotion = mainEmotion
case .fetchSeedStatsSuccessed(let seeds):
newState.seeds = seeds
@@ -246,7 +253,8 @@ final class BookDetailViewModel: BaseViewModel {
return page == 0 ? Action.fetchRecordsSuccessed(
items: items,
hasMore: $0.hasMore,
- totalResult: $0.totalCount
+ totalResult: $0.totalCount,
+ mainEmotion: $0.mainEmotion
) : Action.appendRecordsSuccessed(
items: items,
hasMore: $0.hasMore
From ad31bd2c09336381c1acd7e26a2647d0aa031ab3 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 15:20:51 +0900
Subject: [PATCH 17/21] =?UTF-8?q?[BOOK-499]=20fix:=20Emotion=20=EC=B6=94?=
=?UTF-8?q?=EA=B0=80=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EA=B4=80=EB=A0=A8?=
=?UTF-8?q?=ED=95=9C=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
추후 지용님 작업 내역과 merge 예정
---
.../Sources/MainFlow/Note/View/EmotionRegistrationView.swift | 4 ++++
.../MainFlow/NoteCompletion/View/AppreciationResultView.swift | 2 ++
2 files changed, 6 insertions(+)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/Note/View/EmotionRegistrationView.swift b/src/Projects/BKPresentation/Sources/MainFlow/Note/View/EmotionRegistrationView.swift
index c7b01866..3834a087 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/Note/View/EmotionRegistrationView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/Note/View/EmotionRegistrationView.swift
@@ -23,6 +23,8 @@ extension Emotion {
imageView.image = BKImage.Graphics.sadEmotion
case .insight:
imageView.image = BKImage.Graphics.insightEmotion
+ default:
+ imageView.image = BKImage.Graphics.warmEmotion
}
imageView.layer.cornerRadius = 12
@@ -154,6 +156,8 @@ private extension EmotionRegistrationView {
imageView.image = BKImage.Graphics.sadEmotion
case .insight:
imageView.image = BKImage.Graphics.insightEmotion
+ default:
+ imageView.image = BKImage.Graphics.warmEmotion
}
imageView.layer.cornerRadius = 12
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/NoteCompletion/View/AppreciationResultView.swift b/src/Projects/BKPresentation/Sources/MainFlow/NoteCompletion/View/AppreciationResultView.swift
index 930a83e6..09afd71e 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/NoteCompletion/View/AppreciationResultView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/NoteCompletion/View/AppreciationResultView.swift
@@ -30,6 +30,8 @@ enum EmotionIcon: String {
return .sadness
case .insight:
return .insight
+ default:
+ return .warmth
}
}
}
From 79bf7a9db18638cee49ecc5ea27742c7407cadf9 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 15:26:06 +0900
Subject: [PATCH 18/21] =?UTF-8?q?[BOOK-499]=20fix:=20=EB=B6=88=ED=95=84?=
=?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=B6=9C=EB=A0=A5=EB=AC=B8=20=EC=A0=9C?=
=?UTF-8?q?=EA=B1=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Sources/MainFlow/BookDetail/View/SeedReportView.swift | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
index 5fc93ef6..1f6ff7d9 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
@@ -144,9 +144,6 @@ final class SeedReportView: BaseView {
labelsStackView.arrangedSubviews.forEach {
$0.removeFromSuperview()
}
- print(seeds)
- let seedDictionary = Dictionary(uniqueKeysWithValues: seeds.map { ($0.name, $0) })
- print(seedDictionary)
EmotionSeed.allCases.forEach { emotionCase in
seeds.forEach { seed in
From 415d02143696d71fc123b06cd2278b6473e480d0 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 15:57:43 +0900
Subject: [PATCH 19/21] =?UTF-8?q?[BOOK-499]=20feat:=20=EC=84=A4=EB=AA=85?=
=?UTF-8?q?=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20EmotionSeed=20case=EC=97=90=20?=
=?UTF-8?q?=EB=94=B0=EB=9D=BC=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Sources/MainFlow/BookDetail/Models/EmotionSeed.swift | 9 +++++++++
.../MainFlow/BookDetail/View/SeedReportView.swift | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
index 7581195b..e42a23dd 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/Models/EmotionSeed.swift
@@ -108,4 +108,13 @@ enum EmotionSeed: String, CaseIterable {
case .etc: return UIColor(hex: "F4F8FF")
}
}
+
+ var descriptionText: String {
+ switch self {
+ case .etc:
+ return "감정으로 문장만 기록했어요"
+ default:
+ return "감정을 많이 느꼈어요"
+ }
+ }
}
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
index 1f6ff7d9..595111fc 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
@@ -134,7 +134,7 @@ final class SeedReportView: BaseView {
let emotionText = "\'\(emotion.rawValue)\'"
emotionImageView.image = emotion.circleImage
reportLabel.highlightColor = emotion.color
- reportLabel.setText(text: "\(emotionText) 감정을 많이 느꼈어요")
+ reportLabel.setText(text: "\(emotionText) \(emotion.descriptionText)")
reportLabel.highlightedWord = emotionText
}
From ca5ce5de9bf9db4bb51e7d1244f7ffa9d9d4a003 Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Mon, 9 Feb 2026 16:00:22 +0900
Subject: [PATCH 20/21] =?UTF-8?q?[BOOK-499]=20fix:=20codeRabbit=20review?=
=?UTF-8?q?=20=EB=B0=98=EC=98=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Projects/BKData/Sources/Constant/APIConfig.swift | 2 +-
.../Sources/MainFlow/BookDetail/View/SeedReportView.swift | 3 ---
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/Projects/BKData/Sources/Constant/APIConfig.swift b/src/Projects/BKData/Sources/Constant/APIConfig.swift
index b26a1136..561d71d3 100644
--- a/src/Projects/BKData/Sources/Constant/APIConfig.swift
+++ b/src/Projects/BKData/Sources/Constant/APIConfig.swift
@@ -16,7 +16,7 @@ enum APIConfig {
static let baseV2URL: String = {
guard let value = bundle.object(forInfoDictionaryKey: "BASE_API_V2_URL") as? String else {
- fatalError("Can't load environment: BKData.BASE_API_URL")
+ fatalError("Can't load environment: BKData.BASE_API_V2_URL")
}
return value
}()
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
index 595111fc..13c1cf60 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
@@ -73,9 +73,6 @@ final class SeedReportView: BaseView {
layer.cornerRadius = LayoutConstants.cornerRadius
clipsToBounds = true
backgroundColor = .bkBaseColor(.secondary)
-
- emotionImageView.image = BKImage.Graphics.warmCircle
- reportLabel.setText(text: "테스트용 텍스트입니다.")
}
override func setupLayout() {
From 131c1acde682eab0483b9d21174387e037c0c05d Mon Sep 17 00:00:00 2001
From: doyeonk429 <80318425+doyeonk429@users.noreply.github.com>
Date: Sat, 14 Feb 2026 13:49:15 +0900
Subject: [PATCH 21/21] =?UTF-8?q?[BOOK-499]=20fix:=20peer=20Review=20?=
=?UTF-8?q?=EB=B0=98=EC=98=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../MainFlow/BookDetail/View/SeedReportView.swift | 12 ++++++------
src/SupportingFiles/Booket/Info.plist | 2 --
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
index 13c1cf60..89ddbf90 100644
--- a/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
+++ b/src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift
@@ -142,13 +142,13 @@ final class SeedReportView: BaseView {
$0.removeFromSuperview()
}
+ let seedDict = Dictionary(seeds.map { ($0.name, $0) }, uniquingKeysWith: { first, last in last })
+
EmotionSeed.allCases.forEach { emotionCase in
- seeds.forEach { seed in
- if seed.name == emotionCase.rawValue && seed.count >= 1 {
- let itemView = SeedItemView()
- itemView.configure(with: seed)
- labelsStackView.addArrangedSubview(itemView)
- }
+ if let seed = seedDict[emotionCase.rawValue], seed.count >= 1 {
+ let itemView = SeedItemView()
+ itemView.configure(with: seed)
+ labelsStackView.addArrangedSubview(itemView)
}
}
diff --git a/src/SupportingFiles/Booket/Info.plist b/src/SupportingFiles/Booket/Info.plist
index 4fc2e21d..79750d62 100644
--- a/src/SupportingFiles/Booket/Info.plist
+++ b/src/SupportingFiles/Booket/Info.plist
@@ -10,8 +10,6 @@
$(BASE_API_URL)
BASE_API_V2_URL
$(BASE_API_V2_URL)
- LSApplicationCategoryType
-
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable