trying to get this shit finished
This commit is contained in:
@@ -2,6 +2,7 @@ import {
|
||||
GetActiveSession,
|
||||
RemoveActiveSession,
|
||||
SaveActiveSession,
|
||||
type ActiveSession,
|
||||
} from '@/lib/asyncStorage';
|
||||
import {
|
||||
DEFAULT_FOCUS_DURATION_MINUTES,
|
||||
@@ -289,8 +290,11 @@ export default function TimerScreen() {
|
||||
outputRange: [20, 0],
|
||||
});
|
||||
|
||||
const finalizeSprintSession = React.useCallback(async (finalStatus: 'completed' | 'cancelled' | 'expired') => {
|
||||
const activeSession = await GetActiveSession();
|
||||
const finalizeSprintSession = React.useCallback(async (
|
||||
finalStatus: 'completed' | 'cancelled' | 'expired',
|
||||
activeSessionOverride?: ActiveSession | null
|
||||
) => {
|
||||
const activeSession = activeSessionOverride ?? await GetActiveSession();
|
||||
|
||||
if (!activeSession) {
|
||||
return;
|
||||
@@ -377,11 +381,7 @@ export default function TimerScreen() {
|
||||
|
||||
const finishTimer = React.useCallback(() => {
|
||||
clearCountdownInterval();
|
||||
const completedSessionType = currentSessionType;
|
||||
const completedReturnTaskId =
|
||||
completedSessionType === 'focus' ? (tId ?? null) : (returnTaskId ?? null);
|
||||
|
||||
void finalizeSprintSession('completed');
|
||||
const activeSessionPromise = GetActiveSession();
|
||||
|
||||
Animated.parallel([
|
||||
Animated.timing(countdownAnimation, {
|
||||
@@ -412,12 +412,23 @@ export default function TimerScreen() {
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
]).start(() => {
|
||||
setIsRunning(false);
|
||||
resetSessionValues();
|
||||
setPostSessionPrompt({
|
||||
completedSessionType,
|
||||
returnTaskId: completedReturnTaskId,
|
||||
});
|
||||
void (async () => {
|
||||
const completedSession = await activeSessionPromise;
|
||||
const completedSessionType = completedSession?.sessionType ?? currentSessionType;
|
||||
const completedReturnTaskId =
|
||||
completedSessionType === 'focus'
|
||||
? (completedSession?.taskId ?? tId ?? null)
|
||||
: (returnTaskId ?? null);
|
||||
|
||||
setIsRunning(false);
|
||||
resetSessionValues();
|
||||
setPostSessionPrompt({
|
||||
completedSessionType,
|
||||
returnTaskId: completedReturnTaskId,
|
||||
});
|
||||
|
||||
await finalizeSprintSession('completed', completedSession);
|
||||
})();
|
||||
});
|
||||
});
|
||||
}, [
|
||||
|
||||
@@ -9,6 +9,14 @@ The goal is not to expand the app into a large productivity platform. The goal i
|
||||
|
||||
The app direction assumes the current backend-based architecture remains in place. The report can explain that the project moved from a local-storage-first idea to a database-backed model because authentication and cross-device persistence would otherwise provide little practical value.
|
||||
|
||||
This note has been updated after the main May 3 and May 4 timer, dashboard, setup, and progress work. That means the earlier gaps around dashboard progress, recent session history, consistent progress labels, and most of the main sprint-start friction are no longer the main blockers.
|
||||
|
||||
What remains now is smaller, but more important:
|
||||
- finishing the last missing part of the focus-and-break loop
|
||||
- making session lifecycle behavior fully consistent
|
||||
- tightening first-time routing so incomplete users are guided automatically
|
||||
- making sure the final app behavior and final report tell the same story
|
||||
|
||||
---
|
||||
|
||||
## #Gap1FocusSessionsAndBreaks
|
||||
@@ -16,30 +24,34 @@ The app direction assumes the current backend-based architecture remains in plac
|
||||
### #VisionGap
|
||||
The vision describes a study app built around focus sessions and breaks.
|
||||
|
||||
The current app supports task-linked focus sprints, but it does not yet complete the full study loop with a real break flow.
|
||||
The current app now supports task-linked focus sessions, short breaks, and post-session choices.
|
||||
|
||||
The main missing piece is that the break flow still stops short of a simple complete cycle rule.
|
||||
|
||||
### #WhyThisMatters
|
||||
Without break handling, the timer is only a session starter and stopper.
|
||||
|
||||
That means the app is missing part of the core study pattern the vision promises.
|
||||
The app is much closer to the promised study pattern than before, but it still does not fully behave like a complete focus-and-break system if every finished focus session only leads to the same short-break path.
|
||||
|
||||
### #Plan
|
||||
1. Add a lightweight session model that distinguishes between `focus`, `short break`, and `long break`.
|
||||
2. Keep task linkage only on `focus` sessions so break sessions stay simple.
|
||||
3. After a completed focus sprint, show a post-session choice screen with:
|
||||
1. Keep the existing lightweight session model that distinguishes between `focus`, `short_break`, and `long_break`.
|
||||
2. Keep task linkage only on `focus` sessions so break sessions remain simple.
|
||||
3. Preserve the current post-focus action path:
|
||||
- `Start short break`
|
||||
- `Skip break`
|
||||
4. After a completed short break, show:
|
||||
- `Continue with same task`
|
||||
- `Back to dashboard`
|
||||
5. Add a simple cycle rule:
|
||||
- after a chosen number of completed focus sessions, offer `long break` instead of `short break`
|
||||
6. Keep the first implementation minimal by using fixed default durations before considering user customization.
|
||||
- continue same task
|
||||
- back to dashboard
|
||||
4. Preserve the current post-break action path:
|
||||
- continue with same task
|
||||
- back to dashboard
|
||||
5. Add the missing simple cycle rule:
|
||||
- after a chosen number of completed focus sessions, offer `long_break` instead of `short_break`
|
||||
6. Keep the implementation intentionally small:
|
||||
- fixed default durations are enough
|
||||
- no need for advanced timer customization to satisfy the vision
|
||||
|
||||
### #DoneWhen
|
||||
- The app supports a full `focus -> break -> continue` flow.
|
||||
- The app supports a full `focus -> short break -> continue` flow.
|
||||
- The app also supports a simple `long_break` cycle so break behavior feels intentional rather than incomplete.
|
||||
- Breaks are treated as real app states, not just something the user has to manage manually.
|
||||
- The timer flow now matches the vision wording about focus sessions and breaks.
|
||||
- The timer flow fully matches the vision wording about focus sessions and breaks.
|
||||
|
||||
---
|
||||
|
||||
@@ -111,29 +123,29 @@ If `progress` means one thing on one screen and something unrelated on another,
|
||||
### #VisionGap
|
||||
The vision emphasizes low friction and ease of use from the first launch.
|
||||
|
||||
The current app uses authentication and a structured hierarchy, which is reasonable for the chosen architecture, but it still needs a smoother first-run experience.
|
||||
The current app already has onboarding copy, guided setup, and clearer empty states.
|
||||
|
||||
The remaining issue is that setup guidance is still too easy to bypass after login.
|
||||
|
||||
### #WhyThisMatters
|
||||
The app can still meet the low-friction goal even with auth, but only if the user is guided quickly into the first meaningful action.
|
||||
The app can still meet the low-friction goal even with auth, but only if incomplete users are routed toward the next meaningful action automatically instead of being left to discover setup on their own.
|
||||
|
||||
### #Plan
|
||||
1. Add a short explanation on the login or signup flow that says:
|
||||
- what the app does
|
||||
- why an account exists
|
||||
- that progress follows the user
|
||||
2. After the first successful signup, route the user into a guided setup flow instead of a generic empty dashboard.
|
||||
3. Build the setup flow as a strict sequence:
|
||||
1. Keep the current login and signup explanation copy about what the app does and why the account exists.
|
||||
2. Keep the guided setup flow as the main onboarding structure:
|
||||
- create first subject
|
||||
- create first assignment
|
||||
- create first task
|
||||
- start first sprint
|
||||
4. Add clear empty states on key screens so each one gives only one obvious next action.
|
||||
5. Use prefilled examples or short placeholder hints where that reduces thinking for the user.
|
||||
6. Avoid giving the user too many choices before they have created their first workable study path.
|
||||
3. Add routing logic so users who still have no real study structure, or who have not completed the first sprint, are sent into setup automatically after login when appropriate.
|
||||
4. Keep the dashboard empty state, but do not rely on it as the only onboarding recovery path.
|
||||
5. Re-check that setup completion is based on a real first-use milestone:
|
||||
- not just account creation
|
||||
- but reaching the first meaningful study action
|
||||
|
||||
### #DoneWhen
|
||||
- A new user can reach their first sprint with minimal confusion.
|
||||
- The app no longer feels empty or directionless after authentication.
|
||||
- An incomplete user is guided back into setup instead of being dropped into a less helpful dashboard state.
|
||||
- The structured hierarchy feels guided instead of heavy.
|
||||
|
||||
---
|
||||
@@ -169,7 +181,7 @@ Even a good feature set can feel wrong if the path to action is too slow or too
|
||||
|
||||
#################################################################
|
||||
#################################################################
|
||||
The steps above have been completed##############################
|
||||
Most of the steps above have been completed#####################
|
||||
#################################################################
|
||||
#################################################################
|
||||
|
||||
@@ -179,30 +191,36 @@ The steps above have been completed##############################
|
||||
### #VisionGap
|
||||
The vision identifies reliability as critical.
|
||||
|
||||
The app already has a stronger session model than before, but reliability work should explicitly close the loop for running, finishing, cancelling, resuming, and displaying sessions.
|
||||
The app already has a stronger session model than before, but reliability work is now the most important remaining gap.
|
||||
|
||||
The biggest issue is not the presence of session data, but making sure every path updates both persisted active-session state and recorded session history consistently.
|
||||
|
||||
### #WhyThisMatters
|
||||
If the timer or sprint state feels inconsistent, the app loses trust very quickly.
|
||||
If the timer or sprint state feels inconsistent, the app loses trust very quickly, especially now that the app already exposes session history and progress metrics on the dashboard.
|
||||
|
||||
### #Plan
|
||||
1. Review the full sprint lifecycle and make sure every session ends in a valid final state:
|
||||
1. Review the full session lifecycle and make sure every session ends in a valid final state:
|
||||
- `completed`
|
||||
- `cancelled`
|
||||
- `expired`
|
||||
- break equivalents if breaks are added
|
||||
2. Make sure dashboard history, task totals, and active sprint state all reflect the same underlying session truth.
|
||||
3. Confirm that reopening the app after a session should have ended produces the correct finalization behavior.
|
||||
4. Confirm that cancelled sessions do not accidentally remain active in local resume storage.
|
||||
5. Test the edge cases around:
|
||||
- break sessions included
|
||||
2. Remove remaining places where the app only clears local active-session storage without also correctly finalizing the underlying recorded session.
|
||||
3. Make sure dashboard history, task totals, and active session state all reflect the same underlying session truth.
|
||||
4. Confirm that reopening the app after a session should have ended produces the correct finalization behavior.
|
||||
5. Confirm that replaced or interrupted sessions are explicitly treated as cancelled rather than silently disappearing.
|
||||
6. Confirm that cancelled sessions do not accidentally remain active in local resume storage.
|
||||
7. Test the edge cases around:
|
||||
- app backgrounding
|
||||
- app reopen
|
||||
- expired sprint reopen
|
||||
- expired session reopen
|
||||
- replacing one active session with another
|
||||
- switching between timer and dashboard
|
||||
6. Document any remaining non-ideal behavior clearly if platform limitations prevent a perfect solution.
|
||||
8. Document any remaining non-ideal behavior clearly if platform limitations prevent a perfect solution.
|
||||
|
||||
### #DoneWhen
|
||||
- Session state transitions are predictable.
|
||||
- History, task totals, and active sprint status stay in sync.
|
||||
- History, task totals, and active session status stay in sync.
|
||||
- Replaced or interrupted sessions are not lost or misrepresented.
|
||||
- The timer feels dependable enough to support the vision's reliability requirement.
|
||||
|
||||
---
|
||||
@@ -215,15 +233,15 @@ The vision values a realistic scope and a smaller polished product over a larger
|
||||
To stay aligned with that, the remaining work needs to focus only on the features that directly close the vision gaps.
|
||||
|
||||
### #WhyThisMatters
|
||||
The fastest way to miss the vision now is to expand sideways into extra features instead of finishing the core loop properly.
|
||||
The fastest way to miss the vision now is to expand sideways into extra features instead of finishing the core loop properly and then leaving the report out of sync with the implemented product.
|
||||
|
||||
### #Plan
|
||||
1. Treat these as the remaining priority set:
|
||||
- focus and break flow
|
||||
- dashboard progress summary
|
||||
- session history visibility
|
||||
- onboarding and empty-state friction reduction
|
||||
- final focus/break cycle completion
|
||||
- session lifecycle consistency
|
||||
- setup-routing polish for incomplete users
|
||||
- reliability and session-state cleanup
|
||||
- final vision/report alignment
|
||||
2. Explicitly avoid adding large optional features during this phase, such as:
|
||||
- social login
|
||||
- advanced analytics
|
||||
@@ -232,6 +250,11 @@ The fastest way to miss the vision now is to expand sideways into extra features
|
||||
- broad gamification
|
||||
3. Update the report wording so the architectural shift to DB/auth is explained as a pragmatic decision, not as a contradiction left unresolved.
|
||||
4. Re-check the final app against the vision using product outcomes rather than older implementation assumptions like strictly local persistence.
|
||||
5. Make sure the report does not describe older gaps as if they are still unresolved:
|
||||
- dashboard progress visibility
|
||||
- recent session history
|
||||
- progress meaning across screens
|
||||
- basic focus-to-break flow
|
||||
|
||||
### #DoneWhen
|
||||
- The team is working only on features that directly close vision gaps.
|
||||
@@ -241,13 +264,11 @@ The fastest way to miss the vision now is to expand sideways into extra features
|
||||
---
|
||||
|
||||
## #SuggestedImplementationOrder
|
||||
1. Implement the focus and break session flow.
|
||||
2. Add dashboard progress summary and recent session history.
|
||||
3. Make progress definitions consistent across subject, assignment, task, and dashboard screens.
|
||||
4. Build the first-time setup flow and improve empty states.
|
||||
5. Tighten the main sprint-start flow and post-session actions.
|
||||
6. Run reliability testing across active sprint, cancelled sprint, expired sprint, and restored sprint paths.
|
||||
7. Update the report so the DB/auth decision and final scope are explained clearly.
|
||||
1. Finish the remaining focus/break cycle logic by adding the simple `long_break` offer.
|
||||
2. Fix the remaining session-lifecycle inconsistencies so replacing, expiring, cancelling, and resuming sessions all update the same underlying truth.
|
||||
3. Tighten onboarding routing so incomplete users are guided into setup automatically after login when needed.
|
||||
4. Run reliability testing across active, cancelled, expired, replaced, break, and restored session paths.
|
||||
5. Update the report so the DB/auth decision, the now-completed vision gaps, and the final remaining scope are described accurately.
|
||||
|
||||
---
|
||||
|
||||
@@ -259,7 +280,9 @@ A user should be able to:
|
||||
- create a simple study structure without confusion
|
||||
- start a focus session tied to a task
|
||||
- continue naturally into a break
|
||||
- move through a simple and intentional break cycle
|
||||
- return and continue studying
|
||||
- see visible proof of progress on the dashboard
|
||||
- trust that session history and active-session state reflect the same reality
|
||||
|
||||
That is the point where the current app most clearly matches the project vision.
|
||||
|
||||
@@ -9,6 +9,8 @@ Later in the same work session, the scope narrowed further into the timer screen
|
||||
|
||||
The scope also expanded into the help-flow modal on the dashboard and subjects screens so its explanation of the app structure matches the way the app now actually works.
|
||||
|
||||
After that, one more timer-flow bug surfaced in the post-session overlay itself. A completed break could still reuse the focus-session action menu, which incorrectly offered the user another break instead of only the actions that make sense after a break has ended.
|
||||
|
||||
---
|
||||
|
||||
## #ImplementedFeatures
|
||||
@@ -120,6 +122,22 @@ This keeps the help flow aligned with the app's actual current behavior instead
|
||||
|
||||
---
|
||||
|
||||
### #PostBreakMenuFix
|
||||
Fixed a timer completion bug where a finished break could still produce the same action menu as a finished focus session:
|
||||
- the post-session overlay had to know which session type actually just ended
|
||||
- the previous flow could fall back to local screen state instead of the persisted active session
|
||||
- this caused a break completion to sometimes be treated like a focus completion
|
||||
- changed the completion flow so it reads the stored active session before building the post-session prompt
|
||||
- reused that same session snapshot when finalizing the session in Supabase
|
||||
|
||||
This means the overlay now behaves correctly after a break finishes:
|
||||
- it does not offer `Start short break` again
|
||||
- it instead keeps the narrower break-finished path:
|
||||
- continue with the same task
|
||||
- go back to the dashboard
|
||||
|
||||
---
|
||||
|
||||
## #ProblemsAndSetbacks
|
||||
|
||||
### #PickerStateReset
|
||||
@@ -131,6 +149,13 @@ The first implementation reopened the picker route correctly, but it also update
|
||||
|
||||
The fix was to keep picker selection local to `app/task/timer.tsx` while the picker is open, and only use route params to decide whether the picker mode should be shown in the first place.
|
||||
|
||||
### #PostSessionTypeMismatch
|
||||
Another issue appeared after the post-session focus actions were introduced.
|
||||
|
||||
The completion overlay already had separate UI for `focus` and `break` sessions, but the value used to choose between them was not robust enough. In practice, that made it possible for a finished break to reopen the focus-style menu and incorrectly offer another break.
|
||||
|
||||
The fix was to derive the completed session type from the persisted active session that had actually been running, rather than relying only on the screen's local state at the moment the animation finished.
|
||||
|
||||
---
|
||||
|
||||
## #CurrentState
|
||||
@@ -146,6 +171,7 @@ The app now supports:
|
||||
- an optional custom-duration picker path instead of a forced picker
|
||||
- explicit post-focus next actions for break, continue, or dashboard return
|
||||
- a stable picker implementation that keeps its selected value while the user scrolls
|
||||
- a corrected break-finished overlay that no longer offers another pause when the completed session was already a break
|
||||
- a help-flow explanation that now matches the real sprint, break, dashboard, and subjects flow more closely
|
||||
|
||||
At this point, the timer flow is more aligned with the vision requirement that starting work should feel fast, focused, and low-friction rather than like a chain of setup steps.
|
||||
@@ -156,10 +182,15 @@ At this point, the timer flow is more aligned with the vision requirement that s
|
||||
|
||||
Static checks were run after the implementation work and after the picker bug fix:
|
||||
|
||||
An additional static check was also run after the post-break menu fix:
|
||||
|
||||
```text
|
||||
npx tsc --noEmit
|
||||
exited successfully
|
||||
|
||||
npm run lint
|
||||
exited successfully
|
||||
|
||||
npx tsc --noEmit
|
||||
exited successfully
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user