Skip to content

feat: 코스 polyline 색 전환 빈도 감소#125

Merged
caseBread merged 3 commits into
mainfrom
fix/tracking-course-mark
Jun 4, 2026
Merged

feat: 코스 polyline 색 전환 빈도 감소#125
caseBread merged 3 commits into
mainfrom
fix/tracking-course-mark

Conversation

@caseBread

Copy link
Copy Markdown
Member

Summary

  • 좌표 수가 MIN_SEGMENT_COORDS(8) 미만인 짧은 세그먼트를 앞 세그먼트에 흡수하는 mergeShortSegments 함수 추가
  • courseDetail.segments 렌더 시 병합된 세그먼트 사용

Test plan

  • 코스 선택 후 지도에서 polyline 색 전환이 이전보다 완만하게 줄어드는지 확인
  • 기존 코스 경로 형태(시작/종료 마커, 흰색 테두리)에 이상 없는지 확인

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a 'mergeShortSegments' utility function to merge short path segments, reducing the frequency of color transitions on the map overlay. It also cleans up unused imports, constants, and formats several code blocks. The review feedback suggests making 'mergeShortSegments' more robust by handling null or undefined inputs, using optional chaining when accessing 'courseDetail.segments', and memoizing the merged segments with 'useMemo' to prevent redundant calculations during frequent component re-renders.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread app/(tabs)/tracking.tsx
Comment on lines +108 to +124
function mergeShortSegments(
segments: { startIdx: number; endIdx: number; grade: string }[],
): { startIdx: number; endIdx: number; grade: string }[] {
return segments.reduce<{ startIdx: number; endIdx: number; grade: string }[]>(
(acc, seg) => {
const len = seg.endIdx - seg.startIdx + 1;
const last = acc[acc.length - 1];
if (last && len < MIN_SEGMENT_COORDS) {
last.endIdx = seg.endIdx;
} else {
acc.push({ ...seg });
}
return acc;
},
[],
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

mergeShortSegments 함수가 segments 인자로 null 또는 undefined를 받을 수 있도록 안전하게 처리하는 것이 좋습니다. courseDetail이 API로부터 로드되기 전에는 segments가 없을 수 있으므로, 방어적 프로그래밍 관점에서 예외 처리를 추가하면 런타임 에러를 방지할 수 있습니다.

Suggested change
function mergeShortSegments(
segments: { startIdx: number; endIdx: number; grade: string }[],
): { startIdx: number; endIdx: number; grade: string }[] {
return segments.reduce<{ startIdx: number; endIdx: number; grade: string }[]>(
(acc, seg) => {
const len = seg.endIdx - seg.startIdx + 1;
const last = acc[acc.length - 1];
if (last && len < MIN_SEGMENT_COORDS) {
last.endIdx = seg.endIdx;
} else {
acc.push({ ...seg });
}
return acc;
},
[],
);
}
function mergeShortSegments(
segments?: { startIdx: number; endIdx: number; grade: string }[] | null,
): { startIdx: number; endIdx: number; grade: string }[] {
if (!segments) return [];
return segments.reduce<{ startIdx: number; endIdx: number; grade: string }[]>(
(acc, seg) => {
const len = seg.endIdx - seg.startIdx + 1;
const last = acc[acc.length - 1];
if (last && len < MIN_SEGMENT_COORDS) {
last.endIdx = seg.endIdx;
} else {
acc.push({ ...seg });
}
return acc;
},
[],
);
}

Comment thread app/(tabs)/tracking.tsx
Comment on lines +540 to +547
{mergeShortSegments(courseDetail.segments).map((seg, i) => {
const coords = courseCoords.slice(
seg.startIdx,
seg.endIdx + 1,
);
if (coords.length < 2) return null;
const { color } = SEGMENT_COLORS[seg.grade] ?? SEGMENT_COLORS.FLAT;
const { color } =
SEGMENT_COLORS[seg.grade] ?? SEGMENT_COLORS.FLAT;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

courseDetail이 로딩 중이거나 없을 때 런타임 에러가 발생하지 않도록 courseDetail?.segments와 같이 옵셔널 체이닝을 사용하는 것이 안전합니다.

또한, TrackingScreen 컴포넌트는 타이머(elapsedSeconds)로 인해 매초 리렌더링이 발생합니다. staticMapOverlaysrecordedCoords 등에 의존하여 자주 재평가되므로, mergeShortSegments 연산이 불필요하게 반복 실행될 수 있습니다. 성능 최적화를 위해 컴포넌트 상단에서 useMemo를 사용하여 병합된 세그먼트를 메모이제이션하는 것을 권장합니다.

const mergedSegments = useMemo(() => {
  return mergeShortSegments(courseDetail?.segments);
}, [courseDetail?.segments]);
Suggested change
{mergeShortSegments(courseDetail.segments).map((seg, i) => {
const coords = courseCoords.slice(
seg.startIdx,
seg.endIdx + 1,
);
if (coords.length < 2) return null;
const { color } = SEGMENT_COLORS[seg.grade] ?? SEGMENT_COLORS.FLAT;
const { color } =
SEGMENT_COLORS[seg.grade] ?? SEGMENT_COLORS.FLAT;
{mergeShortSegments(courseDetail?.segments).map((seg, i) => {
const coords = courseCoords.slice(
seg.startIdx,
seg.endIdx + 1,
);
if (coords.length < 2) return null;
const { color } =
SEGMENT_COLORS[seg.grade] ?? SEGMENT_COLORS.FLAT;

caseBread and others added 2 commits June 4, 2026 23:51
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@caseBread caseBread merged commit 40a6121 into main Jun 4, 2026
2 checks passed
@caseBread caseBread deleted the fix/tracking-course-mark branch June 4, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant