Files

24 KiB
Raw Permalink Blame History

PRD: 메인 탭 당겨서 새로고침

문서 정보

항목 내용
문서 상태 후속 변경 구현 완료 / 사용자 수동 검증 대기
작성일 2026-08-18
최종 수정일 2026-08-25
대상 제품 메인 홈, 콘텐츠, 대화 탭 당겨서 새로고침 및 Lottie 표시 영역
작성자·결정권자 사용자, Sisyphus
관련 API Contract 기존 각 탭 API 계약 재사용, 신규 endpoint 없음
관련 구현 계획 docs/20260818_메인_탭_당겨서_새로고침/plan-task.md
관련 review 없음

요구사항 상태

상태 의미 구현 처리
확정 제품·기술 결정이 완료되어 구현 기준으로 사용 plan-task.md의 Task와 완료 증거로 추적
미결 제품·UX·운영 결정이 더 필요함 권고안과 결정 주체를 기록하고 임의 구현 금지
제외 현재 릴리스에서 구현하지 않기로 결정 제외 이유와 후속 조건을 Decision Log에 기록

1. Overview

메인 하단 , 콘텐츠, 대화 탭에 iOS 기본 당겨서 새로고침 동작을 추가한다. 사용자가 현재 보고 있는 내부 탭과 필터 상태를 유지한 채 해당 화면의 첫 페이지 또는 단일 조회 API를 다시 호출해 최신 데이터를 표시한다.

구현 결과와 사용자 수동 검증 대기 상태는 관련 구현 계획에서 추적한다.

2. Problem Statement

현재 V2 메인 화면의 주요 조회 탭은 최초 진입 또는 내부 필터 변경 시에만 데이터를 불러온다. 사용자가 이미 보고 있는 화면에서 최신 상태를 직접 확인하려면 탭을 이동하거나 앱 흐름을 다시 진입해야 한다.

문제를 해결했다는 판단은 , 콘텐츠, 대화 탭에서 현재 선택 상태 그대로 당겨서 새로고침을 실행하고, 성공·빈 목록·오류 상태에서도 재시도 가능한 것으로 한다.

3. Goals

3.1 제품 목표

  • , 콘텐츠, 대화 하단 탭에서 사용자가 수동으로 최신 데이터를 다시 조회할 수 있다.
  • 새로고침은 현재 선택된 내부 탭·필터·정렬 상태만 대상으로 한다.
  • 새로고침 실패 시 기존 오류 노출 패턴을 유지하고, 사용자는 같은 화면에서 다시 당겨서 재시도할 수 있다.

3.2 UX 목표

  • iOS 기본 pull-to-refresh 제스처와 표시 방식을 사용한다.
  • loading, empty, error, content 상태 어디서든 당겨서 새로고침을 시도할 수 있다.
  • 새로고침은 현재 선택된 탭을 바꾸지 않고 스크롤 가능한 화면 문맥 안에서 동작한다.

4. Non-Goals

  • 마이 탭에는 당겨서 새로고침을 추가하지 않는다.
  • 하단 탭 전체 데이터를 한 번에 새로고침하지 않는다.
  • background 자동 갱신, 주기적 polling, push 기반 갱신은 추가하지 않는다.
  • 신규 API endpoint, DTO, Repository를 만들지 않는다.
  • 새 공통 추상화나 refresh protocol을 만들지 않는다. 기존 ViewModel fetch 경로를 화면별로 연결한다.

5. Target Users and Permissions

5.1 사용자

사용자 목표 주요 작업 사용 환경
로그인 사용자 메인 화면의 최신 홈·콘텐츠·대화 데이터를 직접 갱신 당겨서 새로고침 iOS 앱
비로그인 또는 로그인 필요 상태 사용자 실패/제한 상태에서 재시도 당겨서 새로고침 iOS 앱

5.2 권한

  • 인증 주체: 기존 앱 인증 상태와 각 API의 현재 인증 정책을 그대로 사용한다.
  • 허용 역할: 기존 각 탭 접근 정책을 따른다.
  • 거부 조건: 기존 API 실패·로그인 필요 상태를 그대로 표시한다.
  • 리소스 소유권: 기존 API와 화면 모델의 소유권 검증을 변경하지 않는다.

6. 핵심 사용자 흐름

  1. 사용자가 메인 하단 , 콘텐츠, 대화 중 하나에 진입한다.
  2. 사용자는 내부 탭 또는 필터를 선택해 특정 상태를 보고 있다.
  3. 사용자가 화면을 아래로 당긴다.
  4. 앱은 현재 선택 상태를 유지하고 해당 상태의 첫 페이지 또는 단일 조회 API를 다시 호출한다.
  5. 성공하면 최신 데이터로 교체하고, 실패하면 기존 오류 메시지/토스트 정책을 유지한다.
  6. 빈 목록이나 오류 상태에서도 사용자는 다시 당겨서 새로고침할 수 있다.

7. 정보 구조와 라우팅

MainView
  MainTab.home
    MainHomeTab.recommendation
    MainHomeTab.ranking
    MainHomeTab.following
  MainTab.content
    MainContentTab.recommendation
    MainContentTab.ranking
      AudioRankingType
    MainContentTab.all
      MainContentAllType
      ContentSort
      SeriesPublishedDaysOfWeek
  MainTab.chat
    MainChatFilter.all
    MainChatFilter.ai
    MainChatFilter.dm
  • 새로고침은 라우팅을 변경하지 않는다.
  • 현재 하단 탭과 내부 선택 상태는 유지한다.
  • 목록 아이템 상세 진입, 검색, 충전, 보관함 라우팅은 변경하지 않는다.

8. 기능 요구사항

8.1 공통 새로고침 동작

ID 상태 요구사항 수용 기준 계약/Goal 연결
REFRESH-001 확정 , 콘텐츠, 대화 하단 탭에 당겨서 새로고침을 제공한다. 각 탭에서 아래로 당기면 현재 화면의 조회 API가 다시 호출된다. P1-T1, P2-T1, P3-T1
REFRESH-002 확정 현재 선택된 내부 탭·필터·정렬·요일 상태만 새로고침한다. 선택 상태가 변경되지 않고 해당 조건의 데이터만 첫 페이지부터 다시 조회된다. P1-T1, P2-T1, P3-T1
REFRESH-003 확정 loading, empty, error, content 상태 모두에서 새로고침을 시도할 수 있다. 빈/오류 화면에서도 pull-to-refresh 제스처 또는 동등한 재시도 흐름이 가능하다. P1-GATE, P2-GATE, P3-GATE
REFRESH-004 확정 새로고침은 기존 loading guard와 요청 경합 방지 정책을 깨지 않는다. 중복 요청이 화면 상태를 역전시키지 않고, 기존 최신 요청 우선 패턴을 유지한다. P2-T1, P3-T1

8.2 홈 탭

ID 상태 요구사항 수용 기준 계약/Goal 연결
HOME-REFRESH-001 확정 추천 선택 시 MainHomeRecommendationViewModel.fetchRecommendations() 경로로 다시 조회한다. 기존 추천 섹션 데이터가 최신 응답으로 교체된다. P1-T1
HOME-REFRESH-002 확정 랭킹 선택 시 MainHomeRankingViewModel.fetchRankings() 경로로 다시 조회한다. 기존 랭킹 데이터와 rank change 표시가 최신 응답으로 교체된다. P1-T1
HOME-REFRESH-003 확정 팔로잉 선택 시 MainHomeFollowingViewModel.fetchFollowing() 경로로 다시 조회한다. 로그인 필요, 빈 상태, 콘텐츠 상태가 최신 응답 기준으로 갱신된다. P1-T1

8.3 콘텐츠 탭

ID 상태 요구사항 수용 기준 계약/Goal 연결
CONTENT-REFRESH-001 확정 콘텐츠 추천 선택 시 MainContentRecommendationViewModel.fetchRecommendations() 경로로 다시 조회한다. 추천 콘텐츠 섹션 데이터가 최신 응답으로 교체된다. P2-T1
CONTENT-REFRESH-002 확정 콘텐츠 랭킹 선택 시 현재 AudioRankingType을 유지하고 MainContentRankingViewModel.fetchRankings() 경로로 다시 조회한다. 선택된 랭킹 타입이 유지되고 목록이 최신 응답으로 교체된다. P2-T1
CONTENT-REFRESH-003 확정 콘텐츠 전체 선택 시 현재 MainContentAllType, ContentSort, SeriesPublishedDaysOfWeek를 유지하고 첫 페이지를 다시 조회한다. 기존 목록이 첫 페이지 결과로 교체되고 다음 페이지 상태가 초기화된다. P2-T1

8.4 대화 탭

ID 상태 요구사항 수용 기준 계약/Goal 연결
CHAT-REFRESH-001 확정 대화 탭에서 현재 MainChatFilter를 유지하고 첫 페이지를 다시 조회한다. ALL, AI, DM 중 선택된 필터가 유지되고 rooms가 첫 페이지 결과로 교체된다. P3-T1
CHAT-REFRESH-002 확정 새로고침 후 pagination 상태를 첫 페이지 기준으로 초기화한다. hasMore, nextCursor가 최신 첫 페이지 응답 기준으로 갱신된다. P3-T1

9. 반응형 기능 범위

기능 iPhone iPad 비고
당겨서 새로고침 전체 전체 SwiftUI 기본 동작 기준
빈/오류 상태 재시도 전체 전체 상태 화면도 스크롤 가능한 컨테이너 안에서 표시

10. UI/UX Expectations

10.1 디자인과 component 원칙

  • SwiftUI .refreshable 또는 동등한 iOS 기본 refresh affordance를 사용한다.
  • 별도 커스텀 spinner, 신규 refresh button, 신규 공통 컴포넌트는 만들지 않는다.
  • 기존 Color.black, ProgressView, sodaToast, empty state 스타일을 유지한다.

10.2 화면 상태

  • 첫 로딩 상태와 수동 새로고침 상태를 구분하되, 기존 화면 레이아웃을 크게 바꾸지 않는다.
  • 빈/오류 상태에서도 새로고침 가능해야 하므로 상태 화면을 refresh 가능한 스크롤 컨테이너로 감싸는 방식을 계획한다.
  • 새로고침 실패 시 현재 탭 선택 상태는 유지한다.

10.3 접근성

  • 기본 iOS refresh control 접근성 동작을 해치지 않는다.
  • 기존 버튼, 탭, 리스트 아이템의 focus/touch target을 변경하지 않는다.

11. API 계약

11.1 공통 규칙

  • 신규 endpoint 없음.
  • 기존 Repository와 API 계약을 그대로 사용한다.
  • 콘텐츠 전체와 대화 탭은 첫 페이지 재조회 시 기존 pagination cursor/page 상태를 초기화한다.

11.2 Endpoint 추적

요구사항 Method Path 계약 상태 API Contract 소유 Goal
HOME-REFRESH-001 GET 기존 홈 추천 API 제공됨 기존 MainHomeRecommendationRepository P1-T1
HOME-REFRESH-002 GET 기존 홈 랭킹 API 제공됨 기존 MainHomeRankingRepository P1-T1
HOME-REFRESH-003 GET 기존 홈 팔로잉 API 제공됨 기존 MainHomeFollowingRepository P1-T1
CONTENT-REFRESH-001 GET 기존 콘텐츠 추천 API 제공됨 기존 MainContentRecommendationRepository P2-T1
CONTENT-REFRESH-002 GET 기존 콘텐츠 랭킹 API 제공됨 기존 MainContentRankingRepository P2-T1
CONTENT-REFRESH-003 GET 기존 콘텐츠 전체 API 제공됨 기존 MainContentAllRepository P2-T1
CHAT-REFRESH-001 GET /api/v2/chat/rooms 제공됨 docs/20260708_홈_채팅_탭/prd.md P3-T1

12. 보안과 데이터 취급

  • 인증 header, token 저장, 언어 header 흐름은 변경하지 않는다.
  • 새로고침 실패 로그에 token, 개인 메시지 본문, signed URL 등 민감정보를 기록하지 않는다.
  • 기존 AuthPlugin, UserDefaultsKey.token 처리 로직은 수정 대상이 아니다.

13. 성능과 품질 요구사항

  • 이미 로딩 중인 동일 화면에서 중복 새로고침이 과도하게 발생하지 않도록 기존 loading guard를 유지하거나 같은 수준의 guard를 둔다.
  • 콘텐츠 전체와 대화 탭은 첫 페이지 새로고침 시 기존 다음 페이지 로딩 상태를 초기화한다.
  • 새 공통 abstraction을 만들지 않고 화면별 최소 변경으로 구현한다.
  • 현재 테스트 번들 타깃이 명확하지 않으므로 구현 검증은 focused 코드 리뷰, xcodebuild 빌드, 수동 QA를 필수로 한다.

14. 성공 기준

14.1 기능 수용 기준

  • 추천, 랭킹, 팔로잉에서 각각 현재 선택된 내부 탭만 새로고침된다. (HOME-REFRESH-001~003)
  • 콘텐츠 추천, 랭킹, 전체에서 각각 현재 선택된 내부 탭과 필터 상태만 새로고침된다. (CONTENT-REFRESH-001~003)
  • 대화 전체, AI, DM에서 현재 필터만 유지해 첫 페이지를 새로고침한다. (CHAT-REFRESH-001~002)
  • 빈/오류 상태에서도 사용자가 당겨서 재시도할 수 있다. (REFRESH-003)

14.2 UI/UX 수용 기준

  • iOS 기본 refresh affordance가 보인다.
  • 새로고침 후 선택된 하단 탭과 내부 탭/필터가 변경되지 않는다.
  • 새로고침 실패 시 기존 토스트/오류 상태 정책을 유지한다.

14.3 추적성 완료 기준

  • 모든 확정 요구사항이 plan-task.md의 Task/Goal 완료 증거로 연결된다.
  • 신규 API 또는 신규 dependency가 없다는 결정이 Decision Log에 남아 있다.
  • 코드 구현 전 이 문서와 계획 문서가 먼저 작성되어 있다.

15. Open Questions

ID 상태 결정 필요 사항 현재 권고 결정 주체 결정 기한/시점 영향 Goal
없음 확정 남은 제품 결정 없음 없음 사용자 2026-08-18 전체

16. 요구사항 추적표

요구사항 범위 API Contract 계획 Phase Goal 자동 검증 수동 검증
REFRESH-001~004 기존 API 재사용 1~3 P1-T1, P2-T1, P3-T1 빌드 홈/콘텐츠/대화 새로고침
HOME-REFRESH-001~003 홈 기존 Repository 1 P1-T1, P1-GATE 빌드 홈 내부 탭별 새로고침
CONTENT-REFRESH-001~003 콘텐츠 기존 Repository 2 P2-T1, P2-GATE 빌드 콘텐츠 내부 탭/필터별 새로고침
CHAT-REFRESH-001~002 /api/v2/chat/rooms 3 P3-T1, P3-GATE 빌드 대화 필터별 새로고침
REFRESH-ANIMATION-001~005 local Lottie asset, 신규 API 없음 4 P4-T1, P4-T2, P4-GATE asset 검사, 두 scheme 빌드 Lottie 재생·크기·Reduce Motion·범위 제외

17. Decision Log

날짜 ID 상태 결정 근거 영향 요구사항·계약·Goal
2026-08-18 DEC-001 확정 당겨서 새로고침은 현재 선택된 내부 탭·필터·정렬 상태만 대상으로 한다. 사용자 인터뷰 A안 선택 REFRESH-002, 전체 Goal
2026-08-18 DEC-002 확정 빈/오류 상태에서도 당겨서 새로고침을 허용한다. 사용자 인터뷰 A안 선택 REFRESH-003, 전체 Gate
2026-08-18 DEC-003 확정 신규 API, 신규 dependency, 신규 공통 refresh abstraction은 만들지 않는다. 기존 화면별 fetch 경로 존재, 최소 변경 원칙 REFRESH-004, 전체 Goal

18. 변경 관리

요구사항 변경 시 다음을 확인한다.

  • Decision Log에 변경 이유와 날짜를 기록했다.
  • 관련 요구사항 상태·본문·수용 기준을 갱신했다.
  • plan-task.md의 범위·Files·체크박스·완료 증거를 코드 변경 전에 갱신했다.
  • 기존 Progress·review·검증 기록을 삭제하거나 덮어쓰지 않았다.

19. 후속 변경 확정: Lottie 새로고침 표시

19.1 확인된 현재 상태

  • 2026-08-25 사용자 요청은 기존 pull-to-refresh 동작의 표시 영역을 Resources/pull-to-refresh.json 기반 Lottie animation으로 변경하는 것이다.
  • 구현 전 pull-to-refresh는 메인 홈·콘텐츠·대화의 7개 SwiftUI View에 있고, loading·empty·error·content 분기를 합쳐 .refreshable modifier가 20곳에 적용되어 있었다.
  • Lottie 4.6.1 Swift Package가 SodaLive, SodaLive-dev 두 target에 연결되어 있다.
  • 공식 Lottie iOS API는 SwiftUI용 LottieView와 local JSON loading, playback mode 및 progress 제어를 제공한다.
  • SodaLive/Resources/pull-to-refresh.json150×150, 30fps, frame 0..<45, marker 없음인 local Lottie asset이며 SodaLive, SodaLive-dev 두 target의 Resources build phase에 포함되어 있다.
  • asset의 frame 0은 trim path 시작·끝 값이 모두 3이라 비어 있고, frame 1부터 stroke가 표시된다.
  • Phase 4 요구사항 인터뷰 요청에서는 문서 작성만 수행했고, 이후 사용자 승인으로 코드 구현과 자동 검증을 완료했다.

19.2 후속 요구사항

ID 상태 요구사항 수용 기준 계약/Goal 연결
REFRESH-ANIMATION-001 확정 기존 메인 홈·콘텐츠·대화의 pull-to-refresh 표시 영역에 지정된 Lottie animation을 사용한다. 기존 7개 View의 모든 refresh 가능 상태에서 동일한 Lottie asset이 표시되고 기존 데이터 새로고침 동작은 유지된다. P4-T1, P4-T2
REFRESH-ANIMATION-002 확정 당김 영역이 보이면 Lottie animation을 반복 재생하고, 새로고침 완료 또는 당김 취소로 영역이 사라질 때 정지·처음 frame으로 초기화한다. 당기는 거리에 따른 progress 제어 없이 영역 노출 중 반복 재생하며, 영역이 사라졌다가 다시 나타나면 처음부터 재생한다. DEC-006, P4-T1
REFRESH-ANIMATION-003 확정 Lottie animation을 원본 비율을 유지한 최대 48×48pt로 중앙 정렬하고 상하 8pt 여백을 둔다. 64pt 높이의 refresh 영역에서 animation이 늘어나거나 잘리지 않고 iPhone·iPad에 동일하게 표시된다. DEC-007, P4-T1, P4-GATE
REFRESH-ANIMATION-004 확정 Reduce Motion 활성화 시 반복 재생하지 않고 asset의 첫 번째 유효 frame인 frame 1을 표시한다. 동작 줄이기가 켜지면 animation이 재생되지 않으며, frame 1의 stroke가 영역 노출 중 정지 상태로 표시된다. DEC-008, DEC-009, P4-T1, P4-GATE
REFRESH-ANIMATION-005 확정 Lottie 표시를 기존 PRD 범위인 메인 홈·콘텐츠·대화 7개 View에만 적용한다. 7개 View의 20개 refresh 가능 상태에서 Lottie만 표시하고 기존 indicator를 함께 노출하지 않으며, LiveNowAllViewContentDetailView는 변경되지 않는다. DEC-010, P4-T2, P4-GATE

19.3 후속 Open Questions

ID 상태 결정 필요 사항 현재 권고 결정 주체 결정 기한/시점 영향 Goal
OQ-002 확정 당기는 중과 refresh 실행 중 Lottie playback을 각각 어떻게 제어할지 영역 노출 중 반복 재생, 영역 종료 시 정지·초기화 사용자 2026-08-25 후속 Phase 전체
OQ-003 확정 Lottie 표시 크기, refresh 영역 높이와 수평·수직 정렬 최대 48×48pt, 원본 비율 유지, 중앙 정렬, 상하 8pt 여백 사용자 2026-08-25 후속 UI Gate
OQ-004 확정 iOS Reduce Motion 활성화 시 표시할 정지 frame 비어 있는 frame 0 대신 첫 번째 유효 frame 1 표시 사용자 2026-08-25 후속 접근성 Gate
OQ-005 확정 메인 7개 View만 적용할지, 다른 기존 pull-to-refresh 화면도 포함할지 기존 PRD 범위인 메인 7개 View만 적용 사용자 2026-08-25 후속 Phase 전체

19.4 후속 변경 제약

  • 기존 refresh() 호출, 선택 탭·필터 유지, pagination 초기화와 오류 처리 동작은 변경하지 않는다.
  • Lottie 4.6.1 외에 새 dependency를 추가하지 않는다.
  • 20개 modifier마다 구현을 복제하지 않고, 기존 7개 View의 공통 요구를 충족하는 최소 재사용 단위만 구현한다.
  • SwiftUI .refreshable의 기본 indicator는 custom Lottie로 교체할 공개 API가 없으므로, V2 공용 refresh component 한 개에서 당김 offset·비동기 refresh 상태·Lottie 표시를 관리한다.
  • 기존 RefreshableScrollView 1.1.1은 indicator가 내부에 고정되어 있으므로 후속 V2 component의 기반으로 사용하지 않고, package source도 수정하지 않는다.
  • Lottie visual은 접근성 트리에서 숨기고, 공용 refresh component는 기존 I18n.LiveNow.refreshButton 문구를 재사용한 명시적 accessibility refresh action을 제공한다.
  • SodaLive.xcodeproj/project.pbxproj, SodaLive.xcworkspace/xcshareddata/swiftpm/Package.resolved의 현재 Lottie 관련 변경은 사용자 작업으로 보존한다.
  • SodaLive/Sources/Live/Now/All/LiveNowAllView.swift, SodaLive/Sources/Content/Detail/ContentDetailView.swift의 기존 pull-to-refresh는 이번 범위에서 제외한다.

19.5 후속 변경 Decision Log

날짜 ID 상태 결정 근거 영향 요구사항·계약·Goal
2026-08-25 DEC-004 확정 기존 iOS 기본 refresh 표시를 지정된 Lottie animation으로 변경하고, 이미 추가된 Lottie 4.6.1을 사용한다. 사용자 직접 요청과 현재 Swift Package 설정 REFRESH-ANIMATION-001~004
2026-08-25 DEC-005 확정 Phase 4 요구사항 인터뷰 실행에서는 문서 작성만 수행하고 코드 구현은 하지 않는다. 사용자 직접 요청 후속 Phase 전체
2026-08-25 DEC-006 확정 Lottie는 당김 영역이 보이는 동안 반복 재생하고, 영역이 사라질 때 정지 후 처음 frame으로 초기화한다. 사용자 인터뷰 A안 선택 REFRESH-ANIMATION-002, OQ-002
2026-08-25 DEC-007 확정 Lottie는 원본 비율을 유지한 최대 48×48pt로 중앙 정렬하고, 상하 8pt 여백을 포함한 총 64pt refresh 영역에 표시한다. 사용자 인터뷰 A안 선택과 기존 SodaSpacing REFRESH-ANIMATION-003, OQ-003
2026-08-25 DEC-008 확정 iOS Reduce Motion이 활성화되면 Lottie를 반복 재생하지 않고 정지 frame을 표시한다. 사용자 인터뷰 A안 선택 REFRESH-ANIMATION-004, OQ-004
2026-08-25 DEC-009 확정 Reduce Motion 정지 화면은 비어 있는 frame 0을 건너뛰고 asset의 첫 번째 유효 frame인 frame 1을 사용한다. 사용자 인터뷰 A안 선택과 asset frame 확인 REFRESH-ANIMATION-004, OQ-004
2026-08-25 DEC-010 확정 Lottie 적용 범위는 기존 PRD의 메인 홈·콘텐츠·대화 7개 View로 제한하고 legacy pull-to-refresh 2개 화면은 제외한다. 사용자 인터뷰 A안 선택 REFRESH-ANIMATION-005, OQ-005
2026-08-25 DEC-011 정정 DEC-003의 공통 refresh abstraction 제외는 Phase 1~3에 유지하되, Phase 4에서는 7개 View·20개 상태의 표시 중복을 막기 위한 V2 공용 component 한 개만 허용한다. 동일한 Lottie 상태·접근성·비동기 guard를 한 곳에서 유지하기 위한 최소 재사용 단위 P4-T1, P4-T2

19.6 인터뷰 종료 결과

차원 명확성
Goal 1.00
Scope 1.00
Constraints 0.90
Success 1.00
Context 0.90
  • 최종 모호성: 0.03
  • 결정사항: DEC-004~011에 Lottie asset·재생·크기·Reduce Motion·적용 범위·최소 공용 component를 기록했다.
  • 열린 질문: 없음.

19.7 후속 성공 기준

  • V2 공용 Lottie refresh component 2개가 SodaLive, SodaLive-dev 두 target에서 빌드된다. (REFRESH-ANIMATION-001~004)
  • 메인 7개 View의 기존 .refreshable 20곳이 공용 component로 교체되고 기본 indicator 경로가 남아 있지 않다. (REFRESH-ANIMATION-001, REFRESH-ANIMATION-005)
  • 기존 7개 ViewModel과 LiveNowAllView, ContentDetailView에 구현 diff가 없다. (REFRESH-ANIMATION-005)
  • 실제 당김·취소·새로고침 완료에서 Lottie 반복·초기화와 단일 요청 동작을 확인한다. (REFRESH-ANIMATION-002)
  • Reduce Motion frame 1, 최대 48×48pt, 총 64pt 영역과 iPhone·iPad 레이아웃을 확인한다. (REFRESH-ANIMATION-003~004)