Skip to content

[Refactor] #210 - 스프린트4발 QA 쳐내기#211

Open
Remaked-Swain wants to merge 3 commits intodevelopfrom
refactor/#210-sprint4-qa
Open

[Refactor] #210 - 스프린트4발 QA 쳐내기#211
Remaked-Swain wants to merge 3 commits intodevelopfrom
refactor/#210-sprint4-qa

Conversation

@Remaked-Swain
Copy link
Copy Markdown
Member

@Remaked-Swain Remaked-Swain commented Apr 18, 2026

🌴 작업한 브랜치

✅ 작업한 내용

  1. NekiToast 지속시간을 줄였습니다. 이제 토스트가 UI를 가리는 시간이 단축되어 사용자가 곧바로 다음 행동을 취하기에 불편함이 줄어듭니다.
  2. 동일 좌표 POI의 마커 오버레이가 서로 겹쳐 나타나는 문제를 해소했습니다.

❗️PR Point

  1. NekiToast 기본 지속시간 3초에서 1.8초로 변경했습니다. UI를 가리는 시간을 줄이면서도 사용자에게 안내문구를 노출하는 적절한 시간을 찾기 위해 직접 조절해가면서 결정했는데, 저 외의 다른 사람들도 체감상 괜찮은지 다시 QA 필요합니다.
  2. 동일 좌표 POI 마커 오버레이에 대해서 이제 기준 좌표를 중앙으로 하여 원형을 그리며 퍼뜨려져 나타냅니다.

📸 스크린샷

QA시트에 스크린샷 첨부해두었습니다. 이것으로 대체합니다.

📟 관련 이슈

Summary by CodeRabbit

  • 버그 수정

    • 지도에서 동일한 좌표에 위치한 여러 포토부스 마커들이 이제 중복되지 않도록 적절히 분산되어 표시됩니다.
  • 작업

    • 토스트 알림 메시지의 기본 표시 시간이 3초에서 1.8초로 단축되었습니다.

@Remaked-Swain Remaked-Swain added this to the 4차 스프린트 milestone Apr 18, 2026
@Remaked-Swain Remaked-Swain requested a review from OneTen19 April 18, 2026 07:48
@Remaked-Swain Remaked-Swain self-assigned this Apr 18, 2026
@Remaked-Swain Remaked-Swain added Chore 🪡 자잘한 코드 수정 Refactor 🏗️ 코드 리팩토링 Style 🖼️ UI 작업 금용 🐲 금용 작업 labels Apr 18, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 18, 2026

Walkthrough

지도 뷰에서 동일 좌표 마커의 겹침 문제를 해결하기 위해 좌표 추적 및 지터(jitter) 기반 위치 오프셋을 도입하였으며, 토스트 알림의 기본 표시 시간을 3초에서 1.8초로 단축하였습니다.

Changes

Cohort / File(s) Summary
좌표 겹침 처리
Neki-iOS/Features/Map/Sources/Presentation/Sources/View/NaverMapView.swift
마커 위치 생성 시 겹치는 좌표에 대해 coordinateFrequency 맵으로 추적 후, 각 겹침 인덱스에 따라 calculateJitteredPosition() 메서드로 미세한 거리 오프셋(반경 0.00005)을 적용하여 마커 가시성 확보.
토스트 팝업 지속 시간
Neki-iOS/Shared/DesignSystem/Sources/Component/NekiToast/NekiToast.swift
NekiToastItem 초기화 메서드의 duration 기본값을 3.0초에서 1.8초로 단축하여 팝업 자동 종료 시간 개선.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive PR 제목이 변경사항의 주요 내용(토스트 지속시간 단축, 마커 오버레이 개선)을 명확하게 요약하지 못하고 있으며, 이슈 번호와 한국어만 포함되어 있어 구체적인 변경사항을 파악하기 어렵습니다. 제목을 더 구체적으로 개선하세요. 예: '[Refactor] 토스트 지속시간 단축 및 마커 오버레이 겹침 문제 해결' 같은 형식으로 주요 변경사항을 명시하는 것이 좋습니다.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed PR 설명이 템플릿의 모든 필수 섹션을 포함하고 있으며, 작업 내용, PR Point, 관련 이슈 등이 명확하게 기술되어 있습니다.
Linked Issues check ✅ Passed PR의 모든 코드 변경사항이 이슈 #210의 요구사항을 충족합니다: NekiToast 지속시간을 3초에서 1.8초로 단축, 동일 좌표 POI 마커 오버레이 분산 처리 구현.
Out of Scope Changes check ✅ Passed 모든 코드 변경사항이 이슈 #210의 범위 내에서 이루어졌으며, 범위 외의 변경사항은 발견되지 않습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/#210-sprint4-qa

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Neki-iOS/Features/Map/Sources/Presentation/Sources/View/NaverMapView.swift (1)

258-298: ⚠️ Potential issue | 🟠 Major

지터 위치의 안정성/확장성에 대한 우려

현재 구현에 두 가지 잠재적 이슈가 있습니다.

  1. overlapIndexphotoBooths 순회 순서에 의존합니다. coordinateFrequencyupdateMarkers 호출마다 새로 계산되지만, 지터 위치는 isNew || isSelectedAffected인 경우에만 재계산되어 currentKeyByID에 저장됩니다. 만약 store.visiblePhotoBooths의 정렬/순서가 업데이트 사이에 바뀌면(예: 거리순 재정렬), 동일 좌표의 부스가 선택 변경으로 re-key 될 때 이전과 다른 overlapIndex를 받아 마커 위치가 점프할 수 있습니다. 또한 같은 좌표에 이미 index 0으로 배치된 부스 A가 있고 나중에 새 부스 B가 순회에서 A보다 먼저 나오면, B는 index 0을 받아 A와 겹치게 됩니다. 결정론적 분산을 보장하려면 부스 ID 기반의 정렬(예: booth.id 오름차순)으로 인덱스를 할당하거나, 좌표별로 ID 집합을 기억해 두고 그 안에서의 정렬 위치를 overlapIndex로 사용하는 방식이 안전합니다.

  2. angle = overlapIndex * π/3은 6개까지만 유일한 방향을 갖습니다. index 6은 angle 로 index 0이 있었다면 그 근방(반경 방향)과 충돌하고, index 7 이후는 index 1, 2 …와 동일한 오프셋이 되어 다시 겹칩니다. 동일 좌표의 부스 수가 6을 넘을 가능성이 있다면 반경을 링(ring)별로 늘리거나(ring = overlapIndex / 6, offsetRadius * (1 + ring)), 해당 좌표의 총 개수에 맞춰 2π / count로 각도를 재산정하는 방식을 고려해 주세요.

♻️ 링 기반 분산 예시
-        func calculateJitteredPosition(latitude: Double, longitude: Double, overlapIndex: Int) -> NMGLatLng {
-            guard overlapIndex > .zero else { return NMGLatLng(lat: latitude, lng: longitude) }
-            
-            let offsetRadius = 0.00005
-            let angle = Double(overlapIndex) * (Double.pi / 3)
-            let latitudeOffset = offsetRadius * cos(angle)
-            let longitudeOffset = offsetRadius * sin(angle)
-            return NMGLatLng(lat: latitude + latitudeOffset, lng: longitude + longitudeOffset)
-        }
+        func calculateJitteredPosition(latitude: Double, longitude: Double, overlapIndex: Int) -> NMGLatLng {
+            guard overlapIndex > .zero else { return NMGLatLng(lat: latitude, lng: longitude) }
+            
+            let slotsPerRing = 6
+            let baseRadius = 0.00005
+            let ring = (overlapIndex - 1) / slotsPerRing + 1
+            let slot = (overlapIndex - 1) % slotsPerRing
+            let angle = Double(slot) * (2 * .pi / Double(slotsPerRing))
+            let radius = baseRadius * Double(ring)
+            return NMGLatLng(
+                lat: latitude + radius * cos(angle),
+                lng: longitude + radius * sin(angle)
+            )
+        }

추가로, 순회 순서 의존성을 제거하려면 updateMarkers 앞단에서 부스를 id 기준으로 그룹핑해 각 좌표 내 정렬을 고정한 뒤 overlapIndex를 결정하시는 것을 권장드립니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Neki-iOS/Features/Map/Sources/Presentation/Sources/View/NaverMapView.swift`
around lines 258 - 298, The jitter placement is non-deterministic and repeats
every 6 indices causing overlaps; modify updateMarkers to first group
photoBooths by coordinateKey (the same key used in coordinateFrequency), sort
each group by booth.id to deterministically assign overlapIndex per booth.id
(update currentKeyByID and BoothClusteringKey assignment to use this stable
index), and change calculateJitteredPosition to accept both overlapIndex and the
group's total count (or compute ring = overlapIndex / 6) so you compute angle =
2π * (indexWithinRing) / max(countInRing,1) or scale radius by (1 + ring) to
avoid collisions for index >=6; ensure calls to calculateJitteredPosition and
any stored keys use the new signature/logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@Neki-iOS/Features/Map/Sources/Presentation/Sources/View/NaverMapView.swift`:
- Around line 258-298: The jitter placement is non-deterministic and repeats
every 6 indices causing overlaps; modify updateMarkers to first group
photoBooths by coordinateKey (the same key used in coordinateFrequency), sort
each group by booth.id to deterministically assign overlapIndex per booth.id
(update currentKeyByID and BoothClusteringKey assignment to use this stable
index), and change calculateJitteredPosition to accept both overlapIndex and the
group's total count (or compute ring = overlapIndex / 6) so you compute angle =
2π * (indexWithinRing) / max(countInRing,1) or scale radius by (1 + ring) to
avoid collisions for index >=6; ensure calls to calculateJitteredPosition and
any stored keys use the new signature/logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d0cae3df-041b-4cd3-8065-3cdf70b881c3

📥 Commits

Reviewing files that changed from the base of the PR and between 8eb4498 and 59a27fc.

📒 Files selected for processing (2)
  • Neki-iOS/Features/Map/Sources/Presentation/Sources/View/NaverMapView.swift
  • Neki-iOS/Shared/DesignSystem/Sources/Component/NekiToast/NekiToast.swift

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Chore 🪡 자잘한 코드 수정 Refactor 🏗️ 코드 리팩토링 Style 🖼️ UI 작업 금용 🐲 금용 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Refactor] 스프린트4 QA 쳐내기

1 participant