Skip to content

fix: 이전 값을 저장하여 회전하도록 수정#32

Merged
KwonDeaGeun merged 8 commits intomainfrom
fix/bus-rotate
Nov 15, 2025
Merged

fix: 이전 값을 저장하여 회전하도록 수정#32
KwonDeaGeun merged 8 commits intomainfrom
fix/bus-rotate

Conversation

@KwonDeaGeun
Copy link
Owner

@KwonDeaGeun KwonDeaGeun commented Nov 15, 2025

Summary by CodeRabbit

릴리스 노트

  • 성능 개선

    • 버스 마커 캐싱으로 지도 렌더링 성능 향상
    • 회전 애니메이션 보정으로 방향 전환이 더 부드러움
    • 오버레이 정리 개선으로 메모리·리소스 관리 강화
  • 변경사항

    • 버스 위치 갱신 주기 조정: 5초 → 7초
    • 지도 변경 시 오버레이 일괄 정리로 표시 일관성 향상
    • 기본 환경 설정에 기본 API 엔드포인트 추가 (비어 있지 않은 기본값 설정)

@KwonDeaGeun KwonDeaGeun self-assigned this Nov 15, 2025
@vercel
Copy link

vercel bot commented Nov 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
what-the-bus-web Ready Ready Preview Comment Nov 15, 2025 5:11am

@coderabbitai
Copy link

coderabbitai bot commented Nov 15, 2025

Warning

Rate limit exceeded

@KwonDeaGeun has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 13 minutes and 20 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e14ae6b and 7d31def.

📒 Files selected for processing (9)
  • src/App.tsx (4 hunks)
  • src/api/bus.ts (2 hunks)
  • src/components/Bubble.tsx (2 hunks)
  • src/components/SettingsPanel.tsx (1 hunks)
  • src/components/ui/button.tsx (0 hunks)
  • src/contexts/LanguageContext.tsx (3 hunks)
  • src/hooks/useBusSelection.ts (1 hunks)
  • src/hooks/useMapOverlays.ts (2 hunks)
  • src/utils/mapOverlays.ts (6 hunks)

Walkthrough

환경 기본값으로 VITE_API_BASE_URL가 설정되고, 버스 위치 폴링 간격이 5000ms에서 7000ms로 늘어났으며, 버스 오버레이에 캐시·회전 정규화·setMap 정리 API(clearAllBusOverlays 포함)와 정류소/버스 오버레이 라이프사이클 분리가 도입되었습니다.

Changes

코호트 / 파일(s) 변경 요약
환경 구성
\.env.sample
VITE_API_BASE_URL의 기본값을 공백 → https://whatthebus.duckdns.org로 변경
API 폴링
src/api/bus.ts
useBusLocationsrefetchInterval을 5000ms → 7000ms로 조정
타입 공개 및 확장
src/types/kakao.d.ts
KakaoLatLng, KakaoMap, KakaoOverlay를 export로 변경; KakaoLatLnggetLat/getLng, KakaoMapsetZoomable, KakaoOverlay에 위치/콘텐츠/가시성/ZIndex 관련 getter/setter 메서드 추가
훅 리팩토링
src/hooks/useMapOverlays.ts, src/hooks/useKakaoMap.ts
useMapOverlaysmap 파라미터 타입을 `KakaoMap
맵 오버레이 유틸 변경
src/utils/mapOverlays.ts
버스별 오버레이 캐시(busOverlayCache) 도입, normalizeRotation 추가, cached overlay 재사용 및 CSS 회전 적용, 비활성 버스 정리 로직 개선, clearAllBusOverlays 공개 함수 추가, 여러 함수 시그니처에서 map 타입을 KakaoMap으로 변경

Sequence Diagram(s)

sequenceDiagram
    participant Hook as useMapOverlays
    participant Utils as mapOverlays
    participant Cache as BusOverlayCache
    participant Map as KakaoMap

    Note over Hook,Map: 초기 마운트
    Hook->>Utils: createBusStopOverlays(map, busStops)
    Utils->>Map: setMap(overlay) for stops
    Hook->>Utils: createBusOverlays(map, buses)
    Utils->>Cache: check cache per bus
    Cache-->>Utils: miss → create overlay, store in cache
    Utils->>Map: setPosition + add to map

    Note over Hook,Map: 버스 위치 업데이트
    Hook->>Utils: createBusOverlays(map, buses)
    Utils->>Cache: hit → reuse cached overlay
    Utils->>Utils: normalizeRotation(newAngle, prevAngle)
    Utils->>Map: setPosition + apply CSS transform (rotate)

    Note over Hook,Map: 언마운트 / 전체 정리
    Hook->>Utils: clearAllBusOverlays()
    Utils->>Map: setMap(null) for cached overlays
    Utils->>Cache: clear cache
Loading

Estimated code review effort

🎯 3 (중간) | ⏱️ ~20분

  • 추가 검토 권장 항목:
    • src/utils/mapOverlays.ts의 normalizeRotation 수학적 정확성 및 회전 엣지 케이스
    • 캐시 수명 관리(메모리 누수, setMap(null) 처리) 및 cleanup 경로
    • useMapOverlays에서 이펙트 분리로 인한 의존성/타이밍 문제
    • src/types/kakao.d.ts의 공개 타입 변경이 외부 사용처에 미치는 영향

Possibly related PRs

Poem

🐰 버스는 살금살금, 캐시 속에 숨고,
바퀴 대신 CSS가 부드럽게 돌고,
폴링은 느긋하게, URL은 채워져서,
정류소와 버스, 각자의 생을 정리하네. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning PR 제목은 회전 애니메이션 관련 수정에만 부분적으로 초점을 맞추고 있으나, 실제 변경사항에는 타입 정의 추가(KakaoMap, KakaoOverlay 등), API 기본 URL 변경, 쿼리 간격 조정, 오버레이 캐싱 및 관리 로직의 대규모 리팩토링 등 훨씬 광범위한 변경이 포함되어 있습니다. PR 제목을 주요 변경사항 전체를 포괄하는 보다 포괄적인 설명으로 수정하거나, 회전 애니메이션 수정만을 주요 변경사항으로 하는 별도 PR로 분리하는 것을 고려하세요.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

@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.

Actionable comments posted: 0

🧹 Nitpick comments (5)
src/types/kakao.d.ts (1)

18-21: KakaoOverlay.setPosition 타입 추가 방향 좋습니다

CustomOverlay.setPosition를 정식으로 타입에 반영해서, createBusOverlays 쪽에서 쓰는 패턴과 잘 맞습니다.
후속으로 src/utils/mapOverlays.ts

(cached.overlay as { setPosition: (pos: unknown) => void }).setPosition?.(busPosition);

부분을 별도 임시 타입 대신 KakaoOverlay를 활용하도록 정리하면 캐스팅을 조금 더 줄일 수 있을 것 같습니다(지금 코드도 동작상 문제는 없어 보입니다).

src/api/bus.ts (1)

7-27: 버스 위치 폴링 주기 조정은 문제 없어 보입니다

5초 → 7초로 늘려서 서버 부하를 조금 줄이면서도 실시간성은 크게 해치지 않을 것 같습니다.
다만 이 값이 도메인 상 “버스 위치 갱신 주기”와 강하게 연결된 의미라면, 예를 들어

const BUS_LOCATION_POLL_INTERVAL_MS = 7000;

같은 상수로 분리해 두면 나중에 튜닝·공유 시 의도가 더 드러날 것 같습니다.

.env.sample (1)

1-3: .env.sample 기본 URL 추가는 괜찮고, 정렬은 컨벤션에 맞추면 될 것 같습니다

샘플에 VITE_API_BASE_URL=https://whatthebus.duckdns.org를 넣어두면 로컬 설정 시 편의성이 높아져서 좋습니다.
dotenv-linter 경고처럼 키 알파벳 순서를 맞추고 싶다면 아래처럼 순서를 바꾸는 정도만 해두면 됩니다(필수는 아니고 팀 컨벤션에 맞추면 될 것 같습니다).

VITE_API_BASE_URL=https://whatthebus.duckdns.org
VITE_KAKAO_MAP_API_KEY=
VITE_API_KEY=
src/hooks/useMapOverlays.ts (1)

17-50: 정류장/버스 오버레이 분리는 명확하고, map 변경 시 동작만 한 번 더 점검해 보면 좋겠습니다

  • 정류장 오버레이를 stopOverlays로 관리하고 의존성 변경 시마다 setMap(null) + cleanup을 호출하는 구조는 깔끔하고 메모리/리스너 누수도 잘 방지하고 있습니다.
  • 버스 오버레이는 createBusOverlays(map, buses)가 내부 캐시와 previousBusPositions로 관리하고, 언마운트 시 clearAllBusOverlays()만 호출하는 설계도 PR 의도(이전 위치 기반 회전 유지, DOM 재생성 최소화)에 잘 맞습니다.

다만 한 가지 케이스만 고려해 볼 수 있습니다:

  • 만약 Kakao map 인스턴스 자체가 재생성되어 useMapOverlays에 다른 map 객체가 들어오는 상황이 생기면,
    현재 createBusOverlays는 캐시된 overlay에 대해 setMap(map)을 다시 호출하지 않고 setPosition만 호출하고 있어서, 캐시에 남아 있는 기존 overlay가 이전 map에 붙어 있을 가능성이 있습니다.
  • 이 앱에서 map 인스턴스가 초기화 이후 사실상 바뀌지 않는 구조라면 지금도 실사용에서 문제는 없을 듯하지만, 방어적으로는
    • map이 변경될 때 한 번 clearAllBusOverlays()를 호출하거나,
    • 혹은 createBusOverlays의 cached 분기에서 setMap(map)도 다시 호출해 주는 방식을 고려해 볼 수 있습니다.

전체적으로 타입은 unknown을 유지하면서 any를 피하고 있어서, 이전 PR에서 말씀하신 타입 안정성 선호도와도 잘 맞는 방향 같습니다. (Based on learnings)

src/utils/mapOverlays.ts (1)

13-27: 버스 오버레이 캐시/정리 로직이 잘 구성되어 있고, map 간 공유 가능성만 염두에 두면 좋겠습니다

  • busOverlayCache를 도입해서 { overlay, img, div }를 묶어 관리하고,
    createBusOverlays 상단에서 활성 버스 ID 집합과 비교해 비활성 버스를 setMap(null) + delete로 제거하는 흐름은 메모리 누수 방지 측면에서 좋습니다.
  • clearAllBusOverlayssetMap(null) 호출 후 busOverlayCachepreviousBusPositions를 함께 정리해서, 페이지 이동/언마운트 시 상태가 깨끗하게 초기화됩니다.
  • for (const busId of busOverlayCache.keys()) { ... busOverlayCache.delete(busId); } 패턴은 JS Map에서 합법적인 사용이라 순회 중 삭제로 인한 누락 위험도 거의 없습니다.
  • createBusOverlays 반환값의 cleanup이 현재는 busOverlayCache.delete + previousBusPositions.delete까지만 담당하고 있고 setMap(null)은 호출하지 않지만, 실제 사용처에서는 cleanup 자체가 호출되지 않고 clearAllBusOverlays를 통해 일괄 정리되고 있어서 실동작에는 문제가 없습니다.
    다만 API 일관성을 위해 나중에 cleanup에서도 setMap(null)까지 포함시키는 것을 고려해 볼 수 있습니다.

전체적으로 캐시 설계와 정리 타이밍은 PR 의도(불필요한 DOM 재생성 제거 + 버스별 오버레이 재사용)에 잘 맞는 구현입니다.

Also applies to: 271-282, 318-361, 369-373

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d4bdd2f and 0e09841.

📒 Files selected for processing (5)
  • .env.sample (1 hunks)
  • src/api/bus.ts (1 hunks)
  • src/hooks/useMapOverlays.ts (3 hunks)
  • src/types/kakao.d.ts (1 hunks)
  • src/utils/mapOverlays.ts (5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: KwonDeaGeun
Repo: KwonDeaGeun/WhatTheBus-Web PR: 21
File: src/App.tsx:16-23
Timestamp: 2025-09-22T04:45:54.455Z
Learning: KwonDeaGeun은 TypeScript에서 any 타입 사용을 피하고 더 타입 안전한 코드를 선호한다.
🧬 Code graph analysis (1)
src/hooks/useMapOverlays.ts (1)
src/utils/mapOverlays.ts (3)
  • createBusStopOverlays (190-260)
  • createBusOverlays (262-376)
  • clearAllBusOverlays (21-27)
🪛 dotenv-linter (4.0.0)
.env.sample

[warning] 2-2: [UnorderedKey] The VITE_API_BASE_URL key should go before the VITE_KAKAO_MAP_API_KEY key

(UnorderedKey)

🔇 Additional comments (1)
src/utils/mapOverlays.ts (1)

49-67: 회전 각도 정규화와 이전 값 재사용 로직이 PR 목적에 잘 부합합니다

  • normalizeRotation에서
    • 이전/새 각도를 각각 0~360도로 정규화하고,
    • 차이를 [-180, 180] 범위 내 최단 경로로 조정한 뒤,
    • 다시 0~360도로 돌려놓는 수식은 기대하는 “최단 거리 회전” 동작을 정확히 구현하고 있습니다.
  • createBusOverlays에서
    • 위치가 실제로 바뀐 경우에만 calculateAngle을 사용해 새 각도를 계산하고,
    • 위치가 그대로면 이전 rotation 값을 그대로 재사용하는 것도 불필요한 회전/transition을 막는 좋은 처리입니다.
  • 첫 입력에서는 previousData가 없어서 0도로 시작하고, 이후부터는 previousBusPositions에 저장된 회전값을 기준으로 부드럽게 이어지는 구조라 PR 제목(“이전 값을 저장하여 회전하도록 수정”)과도 잘 맞습니다.
  • CSS 측면에서도 transformOrigin = "center center" + transition: transform 0.3s ease-out으로 시각적으로 자연스러운 회전을 줄 수 있어 보여서, 구현 전반이 안정적입니다.

이 부분은 현재 상태 그대로도 충분히 만족스러운 것 같습니다.

Also applies to: 287-316, 297-305, 327-348

Copy link

@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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/utils/mapOverlays.ts (1)

13-27: 캐싱 메커니즘이 잘 구현되었습니다.

버스 오버레이를 재사용하여 DOM 재생성을 방지하는 좋은 접근 방식입니다. 다만, clearAllBusOverlays 함수에서 Map을 순회하면서 동시에 삭제하는 것보다 더 명확한 패턴을 고려해보세요.

다음과 같이 리팩토링하면 의도가 더 명확해집니다:

 export const clearAllBusOverlays = () => {
-    for (const [busId, cached] of busOverlayCache.entries()) {
+    const entries = Array.from(busOverlayCache.entries());
+    for (const [busId, cached] of entries) {
         (cached.overlay as { setMap: (m: unknown) => void }).setMap(null);
-        busOverlayCache.delete(busId);
-        previousBusPositions.delete(busId);
     }
+    busOverlayCache.clear();
+    previousBusPositions.clear();
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e09841 and d46172b.

📒 Files selected for processing (1)
  • src/utils/mapOverlays.ts (5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: KwonDeaGeun
Repo: KwonDeaGeun/WhatTheBus-Web PR: 21
File: src/App.tsx:16-23
Timestamp: 2025-09-22T04:45:54.455Z
Learning: KwonDeaGeun은 TypeScript에서 any 타입 사용을 피하고 더 타입 안전한 코드를 선호한다.
🔇 Additional comments (4)
src/utils/mapOverlays.ts (4)

49-67: 최단 경로 회전 로직이 정확하게 구현되었습니다.

normalizeRotation 함수는 각도 차이가 180도를 넘을 때 반대 방향으로 회전하도록 하여 시각적으로 자연스러운 회전을 제공합니다. 알고리즘이 수학적으로 정확합니다.


271-281: 비활성 버스 정리 로직이 올바르게 구현되었습니다.

더 이상 활성 상태가 아닌 버스를 캐시와 이전 위치 맵에서 제거하여 메모리 누수를 효과적으로 방지합니다.


297-304: 회전 정규화가 올바르게 적용되었습니다.

이전 회전 값을 고려하여 최단 경로로 회전하도록 하여 부드러운 애니메이션 효과를 제공합니다.


366-381: setMap 및 cleanup 로직이 안전하게 구현되었습니다.

cached 변수는 이 시점에서 항상 정의되어 있지만, 방어적으로 존재 여부를 확인하는 것은 안전한 코딩 관행입니다. cleanup에서 오버레이를 지도에서 제거하고 캐시와 이전 위치 데이터를 모두 정리하는 것이 적절합니다.

Copy link

@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.

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
src/utils/mapOverlays.ts (1)

256-268: 불필요한 타입 캐스팅을 제거하세요.

KakaoOverlay 타입이 이미 setMap 메서드를 포함하도록 정의되어 있으므로, Line 262와 266-267의 타입 캐스팅은 불필요합니다.

Based on learnings

다음과 같이 수정하세요:

         const markerPosition = new window.kakao.maps.LatLng(stop.lat, stop.lng);
-        const overlay = new window.kakao.maps.CustomOverlay({
+        const overlay: KakaoOverlay = new window.kakao.maps.CustomOverlay({
             position: markerPosition,
             content: busIconDiv,
             yAnchor: 1,
         });
-        (overlay as unknown as { setMap: (m: unknown) => void }).setMap(map);
+        overlay.setMap(map);

         // Return overlay with cleanup method
         return {
-            setMap: (m: unknown) => {
-                (overlay as unknown as { setMap: (m: unknown) => void }).setMap(m);
+            setMap: (m) => {
+                overlay.setMap(m);
             },
             cleanup: () => {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d46172b and e14ae6b.

📒 Files selected for processing (4)
  • src/hooks/useKakaoMap.ts (2 hunks)
  • src/hooks/useMapOverlays.ts (2 hunks)
  • src/types/kakao.d.ts (2 hunks)
  • src/utils/mapOverlays.ts (7 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: KwonDeaGeun
Repo: KwonDeaGeun/WhatTheBus-Web PR: 21
File: src/App.tsx:16-23
Timestamp: 2025-09-22T04:45:54.455Z
Learning: KwonDeaGeun은 TypeScript에서 any 타입 사용을 피하고 더 타입 안전한 코드를 선호한다.
📚 Learning: 2025-09-22T04:45:54.455Z
Learnt from: KwonDeaGeun
Repo: KwonDeaGeun/WhatTheBus-Web PR: 21
File: src/App.tsx:16-23
Timestamp: 2025-09-22T04:45:54.455Z
Learning: KwonDeaGeun은 TypeScript에서 any 타입 사용을 피하고 더 타입 안전한 코드를 선호한다.

Applied to files:

  • src/utils/mapOverlays.ts
🧬 Code graph analysis (3)
src/utils/mapOverlays.ts (2)
src/types/kakao.d.ts (2)
  • KakaoMap (8-16)
  • KakaoOverlay (18-28)
src/data/bus.ts (1)
  • Bus (1-6)
src/hooks/useMapOverlays.ts (2)
src/types/kakao.d.ts (1)
  • KakaoMap (8-16)
src/utils/mapOverlays.ts (3)
  • createBusStopOverlays (205-275)
  • clearAllBusOverlays (36-42)
  • createBusOverlays (277-398)
src/hooks/useKakaoMap.ts (1)
src/types/kakao.d.ts (1)
  • KakaoMap (8-16)
🔇 Additional comments (9)
src/types/kakao.d.ts (1)

1-28: 타입 정의가 명확하고 안전하게 개선되었습니다.

KakaoLatLng, KakaoMap, KakaoOverlay 인터페이스를 export하여 다른 파일에서 타입 안전하게 사용할 수 있게 했습니다. 이는 이전에 학습한 내용처럼 unknownany 타입 사용을 줄이는 좋은 접근입니다.

Based on learnings

src/hooks/useKakaoMap.ts (1)

2-2: 타입 안전성이 크게 개선되었습니다.

unknown에서 KakaoMap | null로 변경하여 타입 안전한 코드를 작성할 수 있게 되었습니다.

Based on learnings

Also applies to: 14-14

src/hooks/useMapOverlays.ts (1)

18-54: 오버레이 관리 로직이 잘 분리되었습니다.

버스 정류장 오버레이와 버스 오버레이를 별도의 effect로 관리하여 각각의 생명주기를 독립적으로 처리하는 것은 좋은 설계입니다. 버스 오버레이 업데이트 시 캐싱을 활용하여 성능도 최적화했습니다.

src/utils/mapOverlays.ts (6)

6-18: 매직 넘버를 상수로 추출한 것은 좋은 개선입니다.

하드코딩된 값들을 명명된 상수로 추출하여 가독성과 유지보수성이 향상되었습니다.


29-42: 타입 안전성과 메모리 관리가 개선되었습니다.

캐시 타입을 unknown에서 KakaoOverlay로 변경했고, clearAllBusOverlays 함수로 모든 오버레이를 정리하여 메모리 누수를 방지합니다.

Based on learnings


64-82: 회전 정규화 로직이 정확합니다.

최단 경로로 회전하도록 각도를 정규화하는 로직이 올바르게 구현되었습니다. 360도 경계를 넘을 때 부드러운 회전 애니메이션을 보장합니다.


283-296: 비활성 버스 정리 로직이 메모리 누수를 효과적으로 방지합니다.

현재 활성 버스 집합과 캐시를 비교하여 비활성 버스의 오버레이를 제거하고 캐시에서 삭제하는 로직이 올바르게 구현되었습니다.


333-379: 캐시 재사용 로직이 효율적으로 구현되었습니다.

DOM 요소를 재사용하고 CSS transform으로 회전을 업데이트하는 것은 성능에 좋은 접근입니다. 이전 리뷰에서 지적된 불필요한 타입 캐스팅도 제거되어 cached.overlay.setPosition()cached.overlay.setMap()을 직접 호출합니다.


306-324: 회전 계산 로직이 정확하고 효율적입니다.

위치가 변경된 경우에만 각도를 계산하고, 변경되지 않은 경우 이전 회전 값을 재사용하여 불필요한 계산을 방지합니다. normalizeRotation을 사용하여 부드러운 회전을 보장합니다.

@KwonDeaGeun KwonDeaGeun merged commit a092c75 into main Nov 15, 2025
4 checks passed
@KwonDeaGeun KwonDeaGeun deleted the fix/bus-rotate branch November 15, 2025 05:11
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