Skip to content

Commit c8566e9

Browse files
authored
Merge pull request #368 from DevKor-github/codex/issue-364-ready-state
[codex] Show ready state after preparation completion
2 parents 1ac9141 + 810f321 commit c8566e9

8 files changed

Lines changed: 80 additions & 9 deletions

File tree

lib/l10n/app_en.arb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@
9595
"@finishPreparation": {
9696
"description": "Button text to finish preparing"
9797
},
98+
"preparationReadyToGo": "Ready to go",
99+
"@preparationReadyToGo": {
100+
"description": "Center timer label shown after all preparation steps are complete and there is still time before leaving"
101+
},
98102
"signInSlogan": "We'll find your lost leisure.",
99103
"@signInSlogan": {
100104
"description": "Slogan on the sign-in screen"

lib/l10n/app_ko.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"preparationCompletedDescription": "준비 단계를 모두 완료했어요.\n지금 종료하거나 계속 준비할 수 있어요.",
2424
"continuePreparing": "계속 준비",
2525
"finishPreparation": "준비 종료",
26+
"preparationReadyToGo": "출발 준비 완료",
2627
"signInSlogan": "당신의 잃어버린 여유를 찾아드립니다.",
2728
"welcome": "반가워요!",
2829
"onboardingStartSubtitle": "Ontime과 함께 준비하기 위해서\n평소 본인의 준비 과정을 알려주세요",

lib/l10n/app_localizations.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ abstract class AppLocalizations {
242242
/// **'Finish Preparation'**
243243
String get finishPreparation;
244244

245+
/// Center timer label shown after all preparation steps are complete and there is still time before leaving
246+
///
247+
/// In en, this message translates to:
248+
/// **'Ready to go'**
249+
String get preparationReadyToGo;
250+
245251
/// Slogan on the sign-in screen
246252
///
247253
/// In en, this message translates to:

lib/l10n/app_localizations_en.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ class AppLocalizationsEn extends AppLocalizations {
8585
@override
8686
String get finishPreparation => 'Finish Preparation';
8787

88+
@override
89+
String get preparationReadyToGo => 'Ready to go';
90+
8891
@override
8992
String get signInSlogan => 'We\'ll find your lost leisure.';
9093

lib/l10n/app_localizations_ko.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class AppLocalizationsKo extends AppLocalizations {
8383
@override
8484
String get finishPreparation => '준비 종료';
8585

86+
@override
87+
String get preparationReadyToGo => '출발 준비 완료';
88+
8689
@override
8790
String get signInSlogan => '당신의 잃어버린 여유를 찾아드립니다.';
8891

lib/presentation/alarm/screens/alarm_screen.dart

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,22 @@ class _AlarmScreenState extends State<AlarmScreen> {
259259
final timeRemainingBeforeLeaving = _timeRemainingBeforeLeaving(schedule);
260260
final isLate = timeRemainingBeforeLeaving.isNegative;
261261
final preparation = schedule.preparation;
262-
final isLateContinueMode =
263-
preparation.isAllStepsDone && _isContinuingAfterCompletion && isLate;
264-
final timerLabel =
265-
isLateContinueMode ? '지각이에요' : preparation.currentStepName;
262+
final l10n = AppLocalizations.of(context)!;
263+
final isContinuingAfterCompletion =
264+
preparation.isAllStepsDone && _isContinuingAfterCompletion;
265+
final isLateContinueMode = isContinuingAfterCompletion && isLate;
266+
final isReadyContinueMode = isContinuingAfterCompletion && !isLate;
267+
final timerLabel = isLateContinueMode
268+
? '지각이에요'
269+
: isReadyContinueMode
270+
? l10n.preparationReadyToGo
271+
: preparation.currentStepName;
266272
final displayProgress = isLateContinueMode ? 0.0 : preparation.progress;
267-
final displayRemainingSeconds =
268-
preparation.isAllStepsDone && _isContinuingAfterCompletion
269-
? timeRemainingBeforeLeaving.inSeconds.abs()
270-
: preparation.currentStepRemainingTime.inSeconds;
273+
final displayRemainingSeconds = isContinuingAfterCompletion
274+
? timeRemainingBeforeLeaving.inSeconds.abs()
275+
: preparation.currentStepRemainingTime.inSeconds;
271276

272-
if (!(preparation.isAllStepsDone && _isContinuingAfterCompletion)) {
277+
if (!isContinuingAfterCompletion) {
273278
_ensureUiTicker(false);
274279
}
275280

plans/364-ready-state-plan.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Issue 364 Ready State Plan
2+
3+
## Goal
4+
Make the alarm UI show an explicit ready/on-time state after every preparation step is complete, when the user chooses to keep the alarm screen open and the leave threshold has not yet passed.
5+
6+
## Context
7+
- GitHub issue: https://github.com/DevKor-github/OnTime-front/issues/364
8+
- Current alarm UI logic lives in `lib/presentation/alarm/screens/alarm_screen.dart`.
9+
- `_buildAlarmScreen` currently sets `timerLabel` to `'지각이에요'` only for late-continue mode; otherwise it uses `preparation.currentStepName`.
10+
- When all steps are done, the user has tapped continue, and the leave threshold has not passed, `displayRemainingSeconds` already uses `timeRemainingBeforeLeaving`, so only the center label still looks like an active preparation step.
11+
- The completion dialog behavior should stay unchanged: completing all preparation steps shows the dialog but does not auto-finish the schedule.
12+
- Late-continue behavior should stay unchanged once `timeRemainingBeforeLeaving.isNegative` becomes true.
13+
- Localization sources live in `lib/l10n/app_en.arb` and `lib/l10n/app_ko.arb`; generated files live beside them.
14+
- Existing widget coverage is concentrated in `test/presentation/alarm/screens/preparation_flow_widget_test.dart`.
15+
16+
## Decisions
17+
- Add a new localization key for the ready-state label rather than hard-coding copy in `AlarmScreen`.
18+
- Use `Ready to go` for English.
19+
- Use `출발 준비 완료` for Korean unless product/design requests different final wording.
20+
- Keep the current blue/on-time theme and progress behavior for all-done, continuing, not-late state.
21+
- Keep the red late-continue theme, zero graph progress, overdue countdown, and late label after the leave threshold.
22+
23+
## Steps
24+
1. Add a ready-state localization key to `lib/l10n/app_en.arb` and `lib/l10n/app_ko.arb`, including an English description in the template ARB.
25+
2. Regenerate localization outputs with Flutter gen-l10n so `app_localizations.dart`, `app_localizations_en.dart`, and `app_localizations_ko.dart` expose the new getter.
26+
3. In `AlarmScreen._buildAlarmScreen`, derive three readable booleans:
27+
- `isContinuingAfterCompletion = preparation.isAllStepsDone && _isContinuingAfterCompletion`
28+
- `isLateContinueMode = isContinuingAfterCompletion && isLate`
29+
- `isReadyContinueMode = isContinuingAfterCompletion && !isLate`
30+
4. Set `timerLabel` to:
31+
- `l10n.lateContinueLabel` or the existing late copy key if one is introduced for the current hard-coded `'지각이에요'`
32+
- `l10n.preparationReadyToGo` for ready-continue mode
33+
- `preparation.currentStepName` for normal active-step mode
34+
5. Preserve the current `displayRemainingSeconds` behavior so both ready-continue and late-continue modes use `timeRemainingBeforeLeaving.inSeconds.abs()`, while active preparation still uses `preparation.currentStepRemainingTime`.
35+
6. Update `completion dialog continue shows live leave countdown for ongoing flow` to assert the ready label is visible and the final step name is no longer used as the center timer label in the ready-continue state.
36+
7. Update or keep `completion dialog continue keeps overdue timer running after leave time` to assert the late label still appears after crossing the threshold, the overdue countdown remains visible, and the step list can still show the completed step name.
37+
8. Add Korean-ready-label expectations only where the test locale is Korean; if the test harness defaults to Korean, assert `출발 준비 완료`. If an English-locale path is easy to set up in the existing helpers, add a small English assertion for `Ready to go`.
38+
39+
## Validation
40+
- `flutter gen-l10n`
41+
- `dart format lib/l10n lib/presentation/alarm/screens/alarm_screen.dart test/presentation/alarm/screens/preparation_flow_widget_test.dart`
42+
- `flutter test test/presentation/alarm/screens/preparation_flow_widget_test.dart`
43+
- `flutter analyze`
44+
45+
## Open Questions
46+
- Confirm whether `출발 준비 완료` is the final Korean copy. It is a safe implementation default because it is short, explicit, and clearly distinct from both an active preparation step and a late state.

test/presentation/alarm/screens/preparation_flow_widget_test.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,7 @@ void main() {
10431043
const Color(0xFF5C79FB).value,
10441044
);
10451045
expect(find.text('EARLYLATE'), findsNothing);
1046+
expect(find.text('Ready to go'), findsOneWidget);
10461047
expect(find.text('5분 뒤에 나가야 해요'), findsOneWidget);
10471048
expect(find.text('05 : 00'), findsOneWidget);
10481049
expect(finishUseCase.calls, isEmpty);
@@ -1051,6 +1052,7 @@ void main() {
10511052
await tester.pump(const Duration(seconds: 1));
10521053

10531054
expect(find.text('4분 뒤에 나가야 해요'), findsOneWidget);
1055+
expect(find.text('Ready to go'), findsOneWidget);
10541056
expect(find.text('04 : 00'), findsOneWidget);
10551057

10561058
alarmBloc.add(const ScheduleFinished(0));
@@ -1237,6 +1239,7 @@ void main() {
12371239
);
12381240
expect(find.text('준비시간을 1분 초과했어요'), findsOneWidget);
12391241
expect(find.text('지각이에요'), findsOneWidget);
1242+
expect(find.text('Ready to go'), findsNothing);
12401243
expect(find.text('01 : 00'), findsOneWidget);
12411244
expect(find.text('Prep'), findsOneWidget);
12421245

0 commit comments

Comments
 (0)