Calendar events can optionally have one reminder, which appears in the UI as a popup offering a choice of periods (eg, 1 minute, 10 minutes, 30 minutes, etc) in advance of the event's starting time that the reminder will appear.
In the content model, choosing a reminder period has the effect of adding a new attribute to the calendar event item: reminderTime, the absolute time that the reminder is due to appear
A block (in the style of Donn's Timer block in Projects.ReminderProposal) is attached to the main view. This block watches an item collection whose query looks for CalendarMixinItems that have the reminderTime attribute (queries with the hasAttribute function aren't working now; I'll follow up with Ted).
At startup, and whenever the collection changes, the item collection's results are sorted by reminderTime and the first (earliest) reminder is used to set the Timer attached to the block.
When the timer fires, an alert is presented that lists the events with pending reminders the alert offers buttons to let the user dismiss the selected reminder or all reminders, or to snooze a reminder for five minutes. (Snoozing seemed like a useful mechanism; though I expect the UI around it will change, I wanted to make sure the design covered it).
Each item in the alert's list shows the event name and the relative time to the event ("Now", "5 minutes ago", etc). The relative time messages are updated each minute while the list remains displayed. If new reminders come due while the alert is up, they'll get added to the list.
When the user dismisses a reminder, the calendar event's reminderTime attribute is deleted.
When the user snoozes a reminder, the calendar event's reminderTime is set to "five minutes from now".
At startup, any reminders in the past will be displayed.
Issues and known problems
Currently, the repository query mechanism requires a commit to trigger item collection notifications even for notifications on the same repository view (and the reminder alert block and the detail view do live in the same view); I'm expecting that this'll get fixed in the query mechanism.
Related: If the current detail view's reminder fires and the user dismisses the reminder, the current detail view's reminder popup doesn't get updated.
Because the popup displays a relative time based on the starting time, a snoozed event will have an arbitrary relative time. This is currently handled by displaying "No reminder" if the relative time doesn't happen to exactly match one of the available choices.
There are a lot of "it'd be nice if" possibilities: play a sound when a reminder comes due, do a platform-specific notification (like a taskbar icon or toast popup on Windows). None of these are 0.5 items :).
Quickest way to see a reminder
Run Chandler
Stamp the Welcome message as a Calendar item - it'll have a starting time within 30 minutes of now.
Change the reminder popup to "90 minutes" - this'll mean the reminder is due now, but we need to force a commit to make it happen for now.
Stamp the item as a Task too - this will cause a commit, which will trigger the reminder popup.