Skip to content

fix(schedule): focus created schedules and dock voice input - #248

Open
znnnnnnn-wil wants to merge 1 commit into
1024XEngineer:mainfrom
znnnnnnn-wil:codex/fix-schedule-focus-assistant-input-bar
Open

fix(schedule): focus created schedules and dock voice input#248
znnnnnnn-wil wants to merge 1 commit into
1024XEngineer:mainfrom
znnnnnnn-wil:codex/fix-schedule-focus-assistant-input-bar

Conversation

@znnnnnnn-wil

@znnnnnnn-wil znnnnnnn-wil commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Part of #176

Summary

  • Voice-created dated schedules focus the calendar on the created date after the existing refresh signal reloads data.
  • Recurring schedules resolve the nearest future occurrence through the existing RRULE parser, timezone conversion, and calendar occurrence query.
  • Location schedules refresh without changing the selected calendar date.
  • The assistant voice control is docked in normal layout flow instead of overlaying the schedule list.
  • The final schedule remains visible and clickable, while existing voice, ASR, LLM, TTS, and assistant behavior is preserved.

Fixes in This Update

  • Restrict calendar focus to operation === create_schedule, status === applied, and the singular command.schedule; list, update, delete, and plural read results never focus the calendar.
  • Wire the reply bubble to the existing ptt.dismissReply() action without restoring a full-screen transparent press layer.
  • Contain recurring occurrence lookup failures through the existing calendar error state while preserving the current selected date.
  • Replace the arbitrary 366-day lookup window with the project's RRULE and timezone utilities, then confirm the candidate through getSchedulesByRange, including multi-year intervals.

Visual Evidence

Mobile target: 390 x 844.

The bottom input bar is a normal flex sibling below ScheduleCalendarScreen, so the scrollable schedule area ends above the bar instead of being covered by it. The deployed preview is available at Vercel preview. A local runtime screenshot was not attached because this environment has no browser screenshot runner; no screenshot files are committed.

Verification

  • npm.cmd run lint passed.
  • npm.cmd run typecheck passed.
  • npm.cmd run test:vitest passed: 47 tests.
  • npm.cmd run test:jest -- --forceExit passed: 295 tests.
  • npx.cmd expo export --platform android passed.
  • git diff --check passed.
  • Targeted Prettier checks passed for all changed files.

GitHub CI for commit 1d65685 is pending after this update.

Scope

This PR does not modify schedule business rules, schedule models, SQLite schema or migrations, sync, HTTP/WebSocket contracts, Agent interface names or payloads, ASR/LLM/TTS behavior, reminder semantics, Schedule Detail Sheet, unrelated screens, or the global theme.

@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
timeflow Ready Ready Preview Aug 14, 2026 8:11am

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reviewed the calendar-focus flow from assistant command results through local occurrence expansion, plus the docked voice-control layout. The new layout avoids covering the final schedule row, but the command filtering and reply lifecycle still introduce user-visible regressions; the recurring lookup also needs the same failure containment as the normal calendar loads. Local targeted Jest execution was unavailable because this checkout has no installed frontend/node_modules; the fixed diff passes git diff --check.

command: AppliedCommand | null,
): CalendarFocusTarget | null {
if (command === null || command.status !== 'applied') return null;
const raw = command.schedule ?? command.schedules?.find((item) => typeof item.id === 'string');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P1] Restrict calendar focus to created schedules

voice.command.result populates schedules for list_schedules, and HomeScreen calls this helper for every applied command. Falling back to the first item in command.schedules therefore makes a read-only request such as “list my schedules” jump the calendar to an arbitrary first result; time-schedule update/delete results are also focused even though the PR contract is specifically voice-created schedules. Gate this on the intended create operation and singular command.schedule instead of treating every applied result as a focus target.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

????calendarFocusTargetFromCommand() ????? operation === create_schedule?status === applied,????? singular command.schedule;list_schedules ? plural schedules?update ? delete ?????? null,??????????? calendarFocus.test.ts ?? list/update/delete ? plural read ???

<View style={styles.container}>
<View pointerEvents="box-none" style={styles.overlay}>
{ptt.replyText ? (
<Pressable onPress={() => {}} style={styles.bubble}>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Keep a working way to dismiss the reply bubble

Removing the full-screen dismiss target fixes calendar hit-testing, but the replacement bubble press handler is a no-op. replyText is otherwise cleared only by dismissReply() or when another recording starts, so after a completed push-to-talk reply the bubble permanently consumes vertical space until the user begins a new turn. Wire the bubble (or a dedicated close affordance) to ptt.dismissReply so the existing reply lifecycle remains usable without blocking the calendar.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

???????????????? ptt.dismissReply();???? dismiss layer ????,?????????????????? overlay ??????????????????????

Comment on lines +79 to +80
void findNextOccurrenceDate(service, accountId, timezone, focusTarget.scheduleId).then(
(date) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Contain recurring focus lookup failures

Unlike the normal month and location loads below, this newly launched promise has no rejection handler. If getSchedulesByRange rejects while resolving a recurring command (for example a transient SQLite/read failure), the effect produces an unhandled promise rejection instead of leaving the current selection intact and using the calendar's existing error path. Add a catch or handle the lookup in an async block with failure containment before applying the date.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

?????? focus ?????? .then(...).catch(...),??????????????? selectedDate/visibleMonth ??,???? unhandled rejection ???;?????????

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.

1 participant