Skip to content

Commit 14ce411

Browse files
committed
ui: PushNotficationSettingsView에서 피커용 시트 툴바에 ProgressView 추가
1 parent e88b3b3 commit 14ce411

3 files changed

Lines changed: 60 additions & 16 deletions

File tree

Application/DevLogPresentation/Sources/Settings/PushNotificationSettingsFeature.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ struct PushNotificationSettingsFeature {
8989
state.timePicker = nil
9090
case .timePicker(.presented(.tapDoneButton)):
9191
guard let time = state.timePicker?.time else { break }
92-
state.timePicker = nil
9392
state.viewPushNotificationTime = time
9493
state.activeLoadingRow = .customTime
9594
return updatePushNotificationSettingsEffect(settings: Self.settings(from: state))
@@ -202,6 +201,7 @@ private extension PushNotificationSettingsFeature {
202201
do {
203202
try await updatePushSettingsUseCase.execute(settings)
204203
await send(.loading(.end(target: .default, mode: .delayed)))
204+
await send(.timePicker(.dismiss))
205205
await send(.clearActiveLoadingRow)
206206
} catch {
207207
await send(.loading(.end(target: .default, mode: .delayed)))

Application/DevLogPresentation/Sources/Settings/PushNotificationSettingsView.swift

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,11 @@ struct PushNotificationSettingsView: View {
5353
HStack {
5454
Text(String(localized: "push_settings_custom"))
5555
Spacer()
56-
if store.isLoading && store.activeLoadingRow == .customTime {
57-
ProgressView()
58-
} else {
59-
Text(formattedTimeString(store.viewPushNotificationTime))
60-
.foregroundStyle(.secondary)
61-
if store.activeLoadingRow != .customTime &&
62-
store.pushNotificationMinute != 0 {
63-
Image(systemName: "checkmark")
64-
.foregroundStyle(Color.blue)
65-
}
56+
Text(formattedTimeString(store.viewPushNotificationTime))
57+
.foregroundStyle(.secondary)
58+
if store.pushNotificationMinute != 0 {
59+
Image(systemName: "checkmark")
60+
.foregroundStyle(Color.blue)
6661
}
6762
}
6863
.contentShape(Rectangle())
@@ -75,8 +70,11 @@ struct PushNotificationSettingsView: View {
7570
.navigationTitle(String(localized: "nav_push_settings"))
7671
.onAppear { store.send(.fetchSettings) }
7772
.alert($store.scope(state: \.alert, action: \.alert))
78-
.sheet(item: $store.scope(state: \.timePicker, action: \.timePicker)) { store in
79-
TimePickerView(store: store)
73+
.sheet(item: $store.scope(state: \.timePicker, action: \.timePicker)) { timePickerStore in
74+
TimePickerView(
75+
store: timePickerStore,
76+
showsProgressView: store.isLoading && store.activeLoadingRow == .customTime
77+
)
8078
}
8179
}
8280

@@ -90,6 +88,7 @@ private struct TimePickerView: View {
9088
PushNotificationSettingsFeature.TimePickerState,
9189
PushNotificationSettingsFeature.Action.TimePicker
9290
>
91+
let showsProgressView: Bool
9392

9493
var body: some View {
9594
NavigationStack {
@@ -106,8 +105,17 @@ private struct TimePickerView: View {
106105
ToolbarLeadingButton {
107106
store.send(.tapCloseButton)
108107
}
109-
ToolbarTrailingButton {
110-
store.send(.tapDoneButton)
108+
if showsProgressView {
109+
if #available(iOS 26.0, *) {
110+
ToolbarSpacer(.fixed, placement: .topBarTrailing)
111+
}
112+
ToolbarItem(placement: .topBarTrailing) {
113+
ProgressView()
114+
}
115+
} else {
116+
ToolbarTrailingButton {
117+
store.send(.tapDoneButton)
118+
}
111119
}
112120
}
113121
.background(

Application/DevLogPresentation/Tests/Settings/PushNotificationSettingsFeatureTests.swift

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,42 @@ struct PushNotificationSettingsFeatureTests {
187187
#expect(adapter.activeLoadingRow == nil)
188188
}
189189

190+
@Test("커스텀 시간 업데이트가 지연되면 시트를 유지하고 Done 버튼 로딩 상태를 표시한다")
191+
func 커스텀_시간_업데이트가_지연되면_시트를_유지하고_Done_버튼_로딩_상태를_표시한다() async {
192+
let clock = TestClock()
193+
let updateSpy = UpdatePushSettingsUseCaseSpy()
194+
updateSpy.shouldSuspend = true
195+
let adapter = PushNotificationSettingsStoreTestAdapter(
196+
updateUseCase: updateSpy,
197+
configureDependencies: {
198+
$0.continuousClock = clock
199+
}
200+
)
201+
let date = makeDate(hour: 10, minute: 35)
202+
203+
await adapter.setShowTimePicker(true)
204+
await adapter.setPushNotificationTime(sheet: date)
205+
await adapter.confirmUpdate()
206+
207+
#expect(adapter.showTimePicker)
208+
#expect(adapter.activeLoadingRow == .customTime)
209+
#expect(!adapter.isLoading)
210+
211+
await clock.advance(by: .milliseconds(300))
212+
await adapter.receiveDelayedLoading()
213+
214+
#expect(adapter.showTimePicker)
215+
#expect(adapter.isLoading)
216+
#expect(adapter.activeLoadingRow == .customTime)
217+
218+
updateSpy.resume()
219+
await adapter.drainReceivedActions()
220+
221+
#expect(!adapter.showTimePicker)
222+
#expect(!adapter.isLoading)
223+
#expect(adapter.activeLoadingRow == nil)
224+
}
225+
190226
@Test("푸시 설정 조회에 실패하면 공통 에러 알림을 표시한다")
191227
func 푸시_설정_조회에_실패하면_공통_에러_알림을_표시한다() async {
192228
let fetchSpy = FetchPushSettingsUseCaseSpy()
@@ -309,10 +345,10 @@ private struct PushNotificationSettingsStoreTestAdapter {
309345
func confirmUpdate() async {
310346
let time = store.state.timePicker?.time
311347
await store.send(.timePicker(.presented(.tapDoneButton))) {
312-
$0.timePicker = nil
313348
if let time {
314349
$0.viewPushNotificationTime = time
315350
}
351+
$0.activeLoadingRow = .customTime
316352
}
317353
await drainReceivedActions()
318354
}

0 commit comments

Comments
 (0)