Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "anxiety_emotion_graphic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "anxiety_emotion_graphic@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "anxiety_emotion_graphic@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "calm_emotion_graphic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "calm_emotion_graphic@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "calm_emotion_graphic@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "fatigue_emotion_graphic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "fatigue_emotion_graphic@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "fatigue_emotion_graphic@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "lethargy_emotion_graphic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "lethargy_emotion_graphic@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "lethargy_emotion_graphic@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "satisfaction_emotion_graphic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "satisfaction_emotion_graphic@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "satisfaction_emotion_graphic@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "vitality_emotion_graphic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "vitality_emotion_graphic@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "vitality_emotion_graphic@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ final class ActivityHistoryViewController: BaseViewController<ActivityHistoryVie

private let scrollView = UIScrollView()
private let contentView = UIView()
private var dimmedView: UIView?

private let badgeSectionBackgroundImageView = UIImageView()
private let badgeSectionView = ActivityBadgeSectionView()
Expand Down Expand Up @@ -192,11 +193,41 @@ final class ActivityHistoryViewController: BaseViewController<ActivityHistoryVie
}

private func presentEmotionDetail(date: Date, emotion: Marble) {
dimmedView?.removeFromSuperview()

let newDimmedView = UIView()
newDimmedView.backgroundColor = .black.withAlphaComponent(0.0)
newDimmedView.frame = view.bounds
view.addSubview(newDimmedView)
dimmedView = newDimmedView

UIView.animate(withDuration: 0.25) {
newDimmedView.backgroundColor = UIColor.black.withAlphaComponent(0.7)
}

let emotionDetailViewController = EmotionDetailViewController(date: date, emotion: emotion)
if let sheet = emotionDetailViewController.sheetPresentationController {
sheet.detents = [.medium()]
sheet.prefersGrabberVisible = true
sheet.prefersGrabberVisible = false
if #available(iOS 16.0, *) {
sheet.detents = [.custom { _ in 382 }]
} else {
sheet.detents = [.medium()]
}
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
sheet.preferredCornerRadius = 20
}

emotionDetailViewController.onDismiss = { [weak self] in
guard let self else { return }
guard let dimmedView = self.dimmedView else { return }
UIView.animate(withDuration: 0.1, animations: {
dimmedView.alpha = 0
}, completion: { _ in
dimmedView.removeFromSuperview()
self.dimmedView = nil
})
}

present(emotionDetailViewController, animated: true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ extension EmotionCalendarView: FSCalendarDataSource, FSCalendarDelegate, FSCalen
return cell
}

func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
let key = date.convertToString(dateType: .yearMonthDate)
return emotionRecords[key] != nil
}

func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
let key = date.convertToString(dateType: .yearMonthDate)
let emotion = emotionRecords[key]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,27 @@ import SnapKit
import UIKit

final class EmotionDetailViewController: UIViewController {
private enum Layout {
static let horizontalMargin: CGFloat = 24
static let headerStackViewSpacing: CGFloat = 10
static let headerStackViewTopSpacing: CGFloat = 18
static let headerStackViewTrailingSpacing: CGFloat = 4
static let headerStackViewHeight: CGFloat = 44
static let closeButtonSize: CGFloat = 44
static let closeButtonImageSize: CGFloat = 24
static let emotionImageViewTopSpacing: CGFloat = 30
}

private let date: Date
private let emotion: Marble
private let label = UILabel()

private let headerStackView = UIStackView()
private let dateLabel = UILabel()
private let closeButtonImage = UIImageView()
private let closeButton = UIButton()
private let descriptionLabel = UILabel()
private let emotionImageView = UIImageView()
var onDismiss: (() -> Void)?

init(date: Date, emotion: Marble) {
self.date = date
Expand All @@ -25,9 +43,82 @@ final class EmotionDetailViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
print("\(emotion.koreanDescription)")
view.backgroundColor = .white
configureAttribute()
configureLayout()
}

override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
onDismiss?()
}

private func configureAttribute() {
view.backgroundColor = BitnagilColor.gray99

headerStackView.axis = .horizontal
headerStackView.alignment = .center
headerStackView.spacing = Layout.headerStackViewSpacing

dateLabel.text = "\(date.convertToString(dateType: .yearMonthDateLong))의 감정"
dateLabel.font = BitnagilFont(style: .title3, weight: .semiBold).font
dateLabel.textColor = BitnagilColor.gray10

descriptionLabel.attributedText = BitnagilFont(style: .body2, weight: .medium).attributedString(text: emotion.emotionDescription)
descriptionLabel.numberOfLines = 2
descriptionLabel.font = BitnagilFont(style: .body2, weight: .medium).font
descriptionLabel.textColor = BitnagilColor.gray40

closeButtonImage.image = BitnagilIcon.closeIcon
closeButtonImage.contentMode = .scaleAspectFit
closeButton.addTarget(self, action: #selector(didTapCloseButton), for: .touchUpInside)

emotionImageView.image = emotion.emotionGraphic
emotionImageView.contentMode = .scaleAspectFit
}

private func configureLayout() {
let spacerView = UIView()
[dateLabel, spacerView, closeButton].forEach {
headerStackView.addArrangedSubview($0)
}
closeButton.addSubview(closeButtonImage)

[headerStackView, descriptionLabel, emotionImageView].forEach {
view.addSubview($0)
}

headerStackView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(Layout.headerStackViewTopSpacing)
make.leading.equalToSuperview().offset(Layout.horizontalMargin)
make.trailing.equalToSuperview().inset(Layout.headerStackViewTrailingSpacing)
make.height.equalTo(Layout.headerStackViewHeight)
}

closeButton.snp.makeConstraints { make in
make.size.equalTo(Layout.closeButtonSize)
}

closeButtonImage.snp.makeConstraints { make in
make.center.equalToSuperview()
make.size.equalTo(Layout.closeButtonImageSize)
}

descriptionLabel.snp.makeConstraints { make in
make.top.equalTo(headerStackView.snp.bottom)
make.leading.equalToSuperview().offset(Layout.horizontalMargin)
}
Comment on lines +106 to +109

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

descriptionLabel에 trailing/width 제약이 없어 2줄 줄바꿈이 깨질 수 있습니다.

numberOfLines = 2만 설정하고 leading만 고정되어 있어, 라벨의 preferredMaxLayoutWidth를 결정할 폭 제약이 없습니다. 이 경우 UILabel의 intrinsicContentSize는 줄바꿈 없는 한 줄 기준으로 계산되어 텍스트가 화면 우측으로 넘치거나 잘릴 수 있습니다(목업의 "이날은 평온했나봐요! 평온함은..." 2줄 표시와 다르게 렌더링될 위험).

🐛 제안하는 수정
         descriptionLabel.snp.makeConstraints { make in
             make.top.equalTo(headerStackView.snp.bottom)
             make.leading.equalToSuperview().offset(Layout.horizontalMargin)
+            make.trailing.equalToSuperview().inset(Layout.horizontalMargin)
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
descriptionLabel.snp.makeConstraints { make in
make.top.equalTo(headerStackView.snp.bottom)
make.leading.equalToSuperview().offset(Layout.horizontalMargin)
}
descriptionLabel.snp.makeConstraints { make in
make.top.equalTo(headerStackView.snp.bottom)
make.leading.equalToSuperview().offset(Layout.horizontalMargin)
make.trailing.equalToSuperview().inset(Layout.horizontalMargin)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Projects/Presentation/Sources/ActivityHistory/View/EmotionDetailViewController.swift`
around lines 106 - 109, Update the descriptionLabel constraints in
EmotionDetailViewController so its available width is bounded by adding a
trailing constraint or equivalent width constraint alongside the existing
leading constraint. Preserve the two-line numberOfLines configuration and ensure
the label wraps within the screen margins.


emotionImageView.snp.makeConstraints { make in
make.top.equalTo(descriptionLabel.snp.bottom).offset(Layout.emotionImageViewTopSpacing)
make.horizontalEdges.equalToSuperview().inset(Layout.horizontalMargin)
if let image = emotion.emotionGraphic {
let aspectRatio = image.size.height / image.size.width
make.height.equalTo(emotionImageView.snp.width).multipliedBy(aspectRatio)
}
}
}

@objc private func didTapCloseButton() {
dismiss(animated: true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,12 @@ enum BitnagilGraphic {
static let routineMultipleBadgeGraphic = UIImage(named: "routine_multiple_badge", in: bundle, with: nil)
static let reportSingleBadgeGraphic = UIImage(named: "report_single_badge", in: bundle, with: nil)
static let reportMultipleBadgeGraphic = UIImage(named: "report_multiple_badge", in: bundle, with: nil)

// MARK: - Emotion Marble
static let anxietyEmotionGraphic = UIImage(named: "anxiety_emotion_graphic", in: bundle, with: nil)
static let calmEmotionGraphic = UIImage(named: "calm_emotion_graphic", in: bundle, with: nil)
static let fatigueEmotionGraphic = UIImage(named: "fatigue_emotion_graphic", in: bundle, with: nil)
static let lethargyEmotionGraphic = UIImage(named: "lethargy_emotion_graphic", in: bundle, with: nil)
static let satisfactionEmotionGraphic = UIImage(named: "satisfaction_emotion_graphic", in: bundle, with: nil)
static let vitalityEmotionGraphic = UIImage(named: "vitality_emotion_graphic", in: bundle, with: nil)
}
Loading
Loading