Skip to content

[#624] 버튼의 인터렉션에 의한 작업 중의 UI는 버튼에 뜨도록 수정한다#629

Merged
opficdev merged 13 commits into
developfrom
ui/#624-Button-Loading
Jun 20, 2026
Merged

[#624] 버튼의 인터렉션에 의한 작업 중의 UI는 버튼에 뜨도록 수정한다#629
opficdev merged 13 commits into
developfrom
ui/#624-Button-Loading

Conversation

@opficdev

Copy link
Copy Markdown
Owner

🔗 연관된 이슈

🎯 의도

  • 버튼 인터랙션으로 시작되는 비동기 작업에서 전체 화면 LoadingView 대신 작업을 시작한 버튼 또는 row 위치에 ProgressView를 표시하도록 개선

📝 작업 내용

📌 요약

  • 로그인, 설정, 계정 연동, Todo 저장, 웹페이지 추가, 푸시 알림 설정의 로딩 표시 위치 조정
  • 여러 버튼 중 실제 작업을 시작한 버튼에만 ProgressView가 표시되도록 active loading 상태 추가
  • 시트 내부에서 제출하는 작업은 시트 툴바 버튼 위치에 ProgressView 표시
  • 로딩 중 중복 인터랙션 방지를 위한 disabled 처리 추가
  • 관련 Feature 테스트 보강

🔍 상세

  • LoginView

    • Google / Github / Apple 로그인 버튼별 active provider 상태 추가
    • 로그인 중 선택된 버튼 중앙에만 ProgressView 표시
    • 로그인 중 다른 로그인 버튼 인터랙션 차단
  • SettingsView

    • 임시 데이터 삭제, 로그아웃, 회원 탈퇴 row별 active loading 상태 추가
    • alert 확인 후 전체 overlay 대신 해당 row에 ProgressView 표시
    • 로그아웃은 root 전환 전까지 loading 상태 유지
  • AccountView

    • 소셜 계정 연결 / 해제 버튼별 active provider 상태 추가
    • 버튼 크기 변화로 row 높이가 흔들리지 않도록 hidden placeholder와 overlay 구조 적용
  • PushNotificationSettingsView

    • enable toggle, preset time row, custom time row의 로딩 표시를 row 단위로 분리
    • custom time picker 시트의 Done 버튼은 저장 중 ProgressView로 교체
    • custom time 저장 성공 시에만 시트 dismiss 처리
  • TodoEditorView

    • 저장 / 수정 중 우측 toolbar 확인 버튼 위치에 ProgressView 표시
  • HomeView

    • 웹페이지 URL 입력 시트에서 추가 중 우측 toolbar 버튼 위치에 ProgressView 표시
    • 웹페이지 추가 성공 시에만 시트 dismiss 처리
    • 실패 시 입력 시트를 유지해 URL 수정 후 재시도 가능하도록 처리
  • 테스트

    • 로그인 active provider 상태 검증 추가
    • Settings / Account active loading 상태 검증 추가
    • Home 웹페이지 추가 성공 / 실패 시 시트 유지 여부 검증 추가
    • PushNotification custom time picker loading 및 dismiss 흐름 검증 추가
  • 검증

    • 변경 Swift 파일 SwiftLint 통과
    • xcodebuild build-for-testing 성공

📸 영상 / 이미지 (Optional)

없음

@opficdev opficdev self-assigned this Jun 20, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

이번 풀리퀘스트는 앱 전반(로그인, 계정 설정, 푸시 알림 설정, 일반 설정 등)에서 화면 전체를 덮는 LoadingView 대신, 동작이 발생한 버튼이나 행에 인라인으로 ProgressView를 표시하도록 개선하여 사용자 경험을 향상시킵니다. 이를 위해 각 Feature에 구체적인 로딩 대상을 추적하는 상태(activeSignInProvider, activeLoadingProvider, activeLoadingRow 등)를 추가하고 관련 테스트 코드를 보완했습니다. 피드백으로는 SettingsFeature.swift에서 캐시 삭제(.removeCache) 작업이 완료된 후에도 activeLoadingRownil로 초기화되지 않아 UI에 로딩 표시가 계속 남아있는 버그가 발견되었습니다. 해당 작업 완료 시 상태를 올바르게 초기화하도록 수정이 필요합니다.

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 Application/DevLogPresentation/Sources/Settings/SettingsFeature.swift Outdated
@github-actions

Copy link
Copy Markdown

❌ iOS CI failed.

Tests failed

Failed schemes:

  • DevLogPresentation (ios-test-Persistence-Presentation)
✔ Test "fetchSettings는 서버 상태 반영 중 설정 업데이트를 다시 호출하지 않는다" passed after 0.147 seconds.
◇ Test "setPushNotificationEnable은 활성화 상태를 변경한다" started.
✘ Test "setPushNotificationEnable은 활성화 상태를 변경한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:296:25: Issue recorded
↳ An "ifLet" at "DevLogPresentation/PushNotificationSettingsFeature.swift:125" received a presentation action when destination state was absent.
Action:
PushNotificationSettingsFeature.Action.timePicker(.dismiss)
This is generally considered an application logic error, and can happen for a few reasons:
A parent reducer set destination state to "nil" before this reducer ran. This reducer must run before any other reducer sets destination state to "nil". This ensures that destination reducers can handle their actions while their state is still present.
This action was sent to the store while destination state was "nil". Make sure that actions for this reducer can only be sent from a store when state is present, or from effects that start from this reducer.
✘ Test "setPushNotificationEnable은 활성화 상태를 변경한다" failed after 20.184 seconds with 1 issue.
◇ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" started.
✘ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:338:25: Issue recorded
✘ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" failed after 1.024 seconds with 1 issue.
◇ Test "setShowTimePicker는 현재 화면 시간으로 시트를 연다" started.
✔ Test "setShowTimePicker는 현재 화면 시간으로 시트를 연다" passed after 0.187 seconds.
◇ Test "시트 시간 변경은 확정 전까지 화면 시간을 변경하지 않는다" started.
✔ Test "시트 시간 변경은 확정 전까지 화면 시간을 변경하지 않는다" passed after 0.382 seconds.
◇ Test "confirmUpdate는 시트 시간을 화면 시간에 반영하고 시트를 닫는다" started.
✔ Test "confirmUpdate는 시트 시간을 화면 시간에 반영하고 시트를 닫는다" passed after 0.293 seconds.
◇ Test "rollbackUpdate는 화면 시간을 유지하고 시트를 닫는다" started.
✔ Test "rollbackUpdate는 화면 시간을 유지하고 시트를 닫는다" passed after 0.036 seconds.
✔ Test "푸시 설정 조회가 지연되면 로딩 상태를 표시하고 완료되면 해제한다" passed after 0.045 seconds.
◇ Test "프리셋 시간 업데이트가 지연되면 해당 시간 row에 로딩 상태를 표시한다" started.
✘ Test "프리셋 시간 업데이트가 지연되면 해당 시간 row에 로딩 상태를 표시한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:338:25: Issue recorded

Check the uploaded test log artifacts for full diagnostics.

@opficdev opficdev force-pushed the ui/#624-Button-Loading branch from df8cc6c to 60719f9 Compare June 20, 2026 10:23
@github-actions

Copy link
Copy Markdown

❌ iOS CI failed.

Tests failed

Failed schemes:

  • DevLogPresentation (ios-test-Persistence-Presentation)
✔ Test "fetchSettings는 서버 상태 반영 중 설정 업데이트를 다시 호출하지 않는다" passed after 0.045 seconds.
◇ Test "setPushNotificationEnable은 활성화 상태를 변경한다" started.
✘ Test "setPushNotificationEnable은 활성화 상태를 변경한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:296:25: Issue recorded
↳ An "ifLet" at "DevLogPresentation/PushNotificationSettingsFeature.swift:125" received a presentation action when destination state was absent.
Action:
PushNotificationSettingsFeature.Action.timePicker(.dismiss)
This is generally considered an application logic error, and can happen for a few reasons:
A parent reducer set destination state to "nil" before this reducer ran. This reducer must run before any other reducer sets destination state to "nil". This ensures that destination reducers can handle their actions while their state is still present.
This action was sent to the store while destination state was "nil". Make sure that actions for this reducer can only be sent from a store when state is present, or from effects that start from this reducer.
✘ Test "setPushNotificationEnable은 활성화 상태를 변경한다" failed after 3.943 seconds with 1 issue.
◇ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" started.
✘ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:338:25: Issue recorded
✘ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" failed after 0.069 seconds with 1 issue.
◇ Test "setShowTimePicker는 현재 화면 시간으로 시트를 연다" started.
✔ Test "setShowTimePicker는 현재 화면 시간으로 시트를 연다" passed after 0.028 seconds.
◇ Test "시트 시간 변경은 확정 전까지 화면 시간을 변경하지 않는다" started.
✔ Test "시트 시간 변경은 확정 전까지 화면 시간을 변경하지 않는다" passed after 0.019 seconds.
◇ Test "confirmUpdate는 시트 시간을 화면 시간에 반영하고 시트를 닫는다" started.
✔ Test "confirmUpdate는 시트 시간을 화면 시간에 반영하고 시트를 닫는다" passed after 0.044 seconds.
◇ Test "rollbackUpdate는 화면 시간을 유지하고 시트를 닫는다" started.
✔ Test "rollbackUpdate는 화면 시간을 유지하고 시트를 닫는다" passed after 0.040 seconds.
✔ Test "푸시 설정 조회가 지연되면 로딩 상태를 표시하고 완료되면 해제한다" passed after 0.071 seconds.
◇ Test "프리셋 시간 업데이트가 지연되면 해당 시간 row에 로딩 상태를 표시한다" started.
✘ Test "프리셋 시간 업데이트가 지연되면 해당 시간 row에 로딩 상태를 표시한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:338:25: Issue recorded

Check the uploaded test log artifacts for full diagnostics.

@github-actions

Copy link
Copy Markdown

❌ iOS CI failed.

Tests failed

Failed schemes:

  • DevLogPresentation (ios-test-Persistence-Presentation)
✔ Test "fetchSettings는 서버 상태 반영 중 설정 업데이트를 다시 호출하지 않는다" passed after 0.032 seconds.
◇ Test "setPushNotificationEnable은 활성화 상태를 변경한다" started.
✘ Test "setPushNotificationEnable은 활성화 상태를 변경한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:296:25: Issue recorded
↳ An "ifLet" at "DevLogPresentation/PushNotificationSettingsFeature.swift:125" received a presentation action when destination state was absent.
Action:
PushNotificationSettingsFeature.Action.timePicker(.dismiss)
This is generally considered an application logic error, and can happen for a few reasons:
A parent reducer set destination state to "nil" before this reducer ran. This reducer must run before any other reducer sets destination state to "nil". This ensures that destination reducers can handle their actions while their state is still present.
This action was sent to the store while destination state was "nil". Make sure that actions for this reducer can only be sent from a store when state is present, or from effects that start from this reducer.
✘ Test "setPushNotificationEnable은 활성화 상태를 변경한다" failed after 6.249 seconds with 1 issue.
◇ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" started.
✘ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:338:25: Issue recorded
✘ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" failed after 0.100 seconds with 1 issue.
◇ Test "setShowTimePicker는 현재 화면 시간으로 시트를 연다" started.
✔ Test "setShowTimePicker는 현재 화면 시간으로 시트를 연다" passed after 0.095 seconds.
◇ Test "시트 시간 변경은 확정 전까지 화면 시간을 변경하지 않는다" started.
✔ Test "시트 시간 변경은 확정 전까지 화면 시간을 변경하지 않는다" passed after 0.038 seconds.
◇ Test "confirmUpdate는 시트 시간을 화면 시간에 반영하고 시트를 닫는다" started.
✔ Test "confirmUpdate는 시트 시간을 화면 시간에 반영하고 시트를 닫는다" passed after 0.063 seconds.
◇ Test "rollbackUpdate는 화면 시간을 유지하고 시트를 닫는다" started.
✔ Test "rollbackUpdate는 화면 시간을 유지하고 시트를 닫는다" passed after 0.033 seconds.
✔ Test "푸시 설정 조회가 지연되면 로딩 상태를 표시하고 완료되면 해제한다" passed after 0.453 seconds.
◇ Test "프리셋 시간 업데이트가 지연되면 해당 시간 row에 로딩 상태를 표시한다" started.
✘ Test "프리셋 시간 업데이트가 지연되면 해당 시간 row에 로딩 상태를 표시한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:338:25: Issue recorded

Check the uploaded test log artifacts for full diagnostics.

@opficdev opficdev force-pushed the ui/#624-Button-Loading branch from 60719f9 to 854e834 Compare June 20, 2026 14:09
@github-actions

Copy link
Copy Markdown

❌ iOS CI failed.

Tests failed

Failed schemes:

  • DevLogPresentation (ios-test-Persistence-Presentation)
✔ Test "fetchSettings는 서버 상태 반영 중 설정 업데이트를 다시 호출하지 않는다" passed after 0.097 seconds.
◇ Test "setPushNotificationEnable은 활성화 상태를 변경한다" started.
✘ Test "setPushNotificationEnable은 활성화 상태를 변경한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:296:25: Issue recorded
↳ An "ifLet" at "DevLogPresentation/PushNotificationSettingsFeature.swift:125" received a presentation action when destination state was absent.
Action:
PushNotificationSettingsFeature.Action.timePicker(.dismiss)
This is generally considered an application logic error, and can happen for a few reasons:
A parent reducer set destination state to "nil" before this reducer ran. This reducer must run before any other reducer sets destination state to "nil". This ensures that destination reducers can handle their actions while their state is still present.
This action was sent to the store while destination state was "nil". Make sure that actions for this reducer can only be sent from a store when state is present, or from effects that start from this reducer.
✘ Test "setPushNotificationEnable은 활성화 상태를 변경한다" failed after 4.580 seconds with 1 issue.
◇ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" started.
✘ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:338:25: Issue recorded
✘ Test "selectPresetTime은 화면과 시트 시간을 함께 변경한다" failed after 0.091 seconds with 1 issue.
◇ Test "setShowTimePicker는 현재 화면 시간으로 시트를 연다" started.
✔ Test "setShowTimePicker는 현재 화면 시간으로 시트를 연다" passed after 0.064 seconds.
◇ Test "시트 시간 변경은 확정 전까지 화면 시간을 변경하지 않는다" started.
✔ Test "시트 시간 변경은 확정 전까지 화면 시간을 변경하지 않는다" passed after 0.036 seconds.
◇ Test "confirmUpdate는 시트 시간을 화면 시간에 반영하고 시트를 닫는다" started.
✔ Test "confirmUpdate는 시트 시간을 화면 시간에 반영하고 시트를 닫는다" passed after 0.071 seconds.
◇ Test "rollbackUpdate는 화면 시간을 유지하고 시트를 닫는다" started.
✔ Test "rollbackUpdate는 화면 시간을 유지하고 시트를 닫는다" passed after 0.032 seconds.
✔ Test "푸시 설정 조회가 지연되면 로딩 상태를 표시하고 완료되면 해제한다" passed after 0.072 seconds.
◇ Test "프리셋 시간 업데이트가 지연되면 해당 시간 row에 로딩 상태를 표시한다" started.
✘ Test "프리셋 시간 업데이트가 지연되면 해당 시간 row에 로딩 상태를 표시한다" recorded an issue at PushNotificationSettingsFeatureTests.swift:338:25: Issue recorded

Check the uploaded test log artifacts for full diagnostics.

@opficdev opficdev merged commit bee0cf5 into develop Jun 20, 2026
5 checks passed
@opficdev opficdev deleted the ui/#624-Button-Loading branch June 20, 2026 15:06
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.

버튼의 인터렉션에 의한 작업 중의 UI는 버튼에 뜨도록 수정한다

1 participant