-
Notifications
You must be signed in to change notification settings - Fork 1
[Feat-T3-178] 루틴 완료 디자인 반영 및 서버 v2 연동 #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,19 +16,21 @@ final class DateView: UIView { | |||||||||||||
| static let dateButtonTopSpacing: CGFloat = 7 | ||||||||||||||
| static let dateButtonSize: CGFloat = 30 | ||||||||||||||
| static let dateLabelHeight: CGFloat = 17 | ||||||||||||||
| static let allCompletedIconTopSpacing: CGFloat = 5 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private let dayLabel = UILabel() | ||||||||||||||
| private let dateButton = UIButton() | ||||||||||||||
| private let dateLabel = UILabel() | ||||||||||||||
| private let allCompletedIcon = UIImageView() | ||||||||||||||
| private let date: Date | ||||||||||||||
| private let isToday: Bool | ||||||||||||||
| private var isSelected: Bool { | ||||||||||||||
| didSet { | ||||||||||||||
| updateAttribute() | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| var didTappedDateButton: ((Date) -> Void)? | ||||||||||||||
| var didTapDateButton: ((Date) -> Void)? | ||||||||||||||
|
|
||||||||||||||
| init( | ||||||||||||||
| date: Date, | ||||||||||||||
|
|
@@ -66,12 +68,16 @@ final class DateView: UIView { | |||||||||||||
| dateLabel.text = "\(date.convertToString(dateType: .date))" | ||||||||||||||
| dateLabel.font = BitnagilFont(style: .body2, weight: .medium).font | ||||||||||||||
| dateLabel.textColor = BitnagilColor.gray70 | ||||||||||||||
|
|
||||||||||||||
| allCompletedIcon.image = BitnagilIcon.asteriskIcon | ||||||||||||||
| allCompletedIcon.isHidden = true | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private func configureLayout() { | ||||||||||||||
| addSubview(dayLabel) | ||||||||||||||
| addSubview(dateButton) | ||||||||||||||
| dateButton.addSubview(dateLabel) | ||||||||||||||
| addSubview(allCompletedIcon) | ||||||||||||||
|
|
||||||||||||||
| dayLabel.snp.makeConstraints { make in | ||||||||||||||
| make.top.leading.trailing.equalToSuperview() | ||||||||||||||
|
|
@@ -89,6 +95,11 @@ final class DateView: UIView { | |||||||||||||
| make.center.equalToSuperview() | ||||||||||||||
| make.height.equalTo(Layout.dateLabelHeight) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| allCompletedIcon.snp.makeConstraints { make in | ||||||||||||||
| make.top.equalTo(dateButton.snp.bottom).offset(Layout.allCompletedIconTopSpacing) | ||||||||||||||
| make.centerX.equalToSuperview() | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private func updateAttribute() { | ||||||||||||||
|
|
@@ -106,10 +117,14 @@ final class DateView: UIView { | |||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private func selectDate() { | ||||||||||||||
| didTappedDateButton?(date) | ||||||||||||||
| didTapDateButton?(date) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| func updateSelectState(isSelected: Bool) { | ||||||||||||||
| self.isSelected = isSelected | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| func updateAllCompleted() { | ||||||||||||||
| allCompletedIcon.isHidden.toggle() | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+127
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain토글 기반 아이콘 표시 로직은 재바인딩/중복 갱신 시 오동작합니다 — 불리언 인자를 받도록 시그니처 변경 권장 WeekView 등에서 동일 날짜에 대해 여러 번 호출되면 isHidden.toggle()로 인해 실제 완료 상태와 표시가 뒤집힐 수 있습니다. 외부 상태를 그대로 반영하도록 변경해 주세요. 적용 diff: - func updateAllCompleted() {
- allCompletedIcon.isHidden.toggle()
- }
+ func updateAllCompleted(isCompleted: Bool) {
+ allCompletedIcon.isHidden = !isCompleted
+ }호출부 예시(다른 파일 적용용): // WeekView.updateAllCompletedState(allCompletedDates:)
let isCompleted = allCompletedDates.contains(date)
dateView.updateAllCompleted(isCompleted: isCompleted)다음 스크립트로 기존 호출부를 점검하고 일괄 치환 대상 라인을 확인해 주세요. 🏁 Script executed: #!/bin/bash
# updateAllCompleted 사용처 확인
rg -nP --type=swift '\bupdateAllCompleted\s*\(' -C2Length of output: 1567 updateAllCompleted() 토글 로직→명시적 불리언 인자 반영으로 개선 필요 토글 기반의 • DateView.swift (127~129 줄) - func updateAllCompleted() {
- allCompletedIcon.isHidden.toggle()
- }
+ func updateAllCompleted(isCompleted: Bool) {
+ allCompletedIcon.isHidden = !isCompleted
+ }• WeekView.swift 호출부 수정
예시: - let isAllCompleted = allCompletedDates.contains(date)
- if isAllCompleted {
- dateView.updateAllCompleted()
- }
+ let isAllCompleted = allCompletedDates.contains(date)
+ dateView.updateAllCompleted(isCompleted: isAllCompleted)
…
- for dateView in dateViews {
- if allCompletedDates.contains(dateView.key) {
- dateView.value.updateAllCompleted()
- }
- }
+ for dateView in dateViews {
+ let isAll = allCompletedDates.contains(dateView.key)
+ dateView.value.updateAllCompleted(isCompleted: isAll)
+ }이렇게 변경하면 외부 상태에 따라 항상 정확한 아이콘 표시가 보장됩니다. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| } | ||||||||||||||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
v2 DTO 필드 매핑/배열 정합성 검증 필요
routineCompleteYn,subRoutineCompleteYn키명이 정확한지 재검증이 필요합니다(이전 스펙의completeYn와 혼재 위험).subRoutineCompleteYn는 서브루틴 개수와 정확히 동일한 길이여야 합니다. 불일치 시 서버에서 400/422가 날 수 있으니, 전송 전 길이 검증을 권장합니다.아래처럼 전송 전에 길이 검증과 방어 로깅을 추가해 주세요.
func updateRoutineCompletions(routines: [RoutineEntity]) async throws { - let completionDTO = routines.map({ RoutineCompletionDTO( - routineId: $0.routineId, - routineCompleteYn: $0.routineCompleteYn, - subRoutineCompleteYn: $0.subRoutineCompleteYn) }) + // 방어: 서브루틴 이름/완료 여부 배열 길이 정합성 확인 + try routines.forEach { r in + guard r.subRoutineNames.count == r.subRoutineCompleteYn.count else { + throw RoutineRepositoryError.invalidSubRoutineLength( + routineId: r.routineId, + names: r.subRoutineNames.count, + completes: r.subRoutineCompleteYn.count + ) + } + } + let completionDTO = routines.map { + RoutineCompletionDTO( + routineId: $0.routineId, + routineCompleteYn: $0.routineCompleteYn, + subRoutineCompleteYn: $0.subRoutineCompleteYn + ) + }필요 시
RoutineRepositoryError를 내부 enum으로 정의해 주세요.📝 Committable suggestion