Time Tortoise: Idle Time User Interface

Idle Time

This is one in a series of articles about Time Tortoise, a Universal Windows Platform app for planning and tracking your work schedule. For more on the development of this app and the ideas behind it, see my Time Tortoise category page.

After several weeks of infrastructure work, it’s finally time to make the idle time feature available in the Time Tortoise UI.

Design

As shown in the screenshot above, this first iteration of the idle time UI works as follows:

  • When the user is timing an activity and stops using both the mouse and keyboard for longer than some threshold, a timer appears below the date selector, showing the user’s current idle time, along with the start and end time for the idle time segment. For testing purposes, I’m using 10 seconds as the idle threshold, but for regular use it would be more like 300 seconds to allow for normal pauses in work. While the idle timer is running, the activity timer also continues to run.
  • When the idle timer is visible, two buttons are enabled: Include and Exclude. Clicking Include means the idle time should be treated as work time. This causes the activity timer to continue running with no changes to the active time segment. Clicking Exclude means the idle time should be excluded from the activity time. It also stops the activity timer. In both the Include and Exclude cases, the idle timer is removed.

Time Tortoise only allows one idle time segment at a time, so ignoring the timer and not clicking either button is like choosing Include, except that the idle timer is not removed. If the user becomes idle again while an idle time segment is still displayed, the new idle segment replaces the old one. Having only one idle time segment is designed to encourage the user to make an Include or Exclude decision while they still remember what they were doing during their idle time.

Example

Here’s how the idle timer could work in the Exclude case:

  • User selects an activity and clicks Start. This creates a new time segment and starts the activity timer.
  • User is active on the mouse and/or keyboard from 10 AM until 10:15 AM.
  • User doesn’t use the mouse and keyboard from 10:15 AM to 10:30 AM. After the threshold time (e.g., 5 minutes after the idle time starts, 10:20 AM), the idle timer appears and starts counting up from 0 seconds. The activity timer continues to run.
  • User returns to the computer at 10:30 AM and clicks Exclude at 10:31 AM. This causes the activity timer to stop, and the time segment is recorded with a start time of 10 AM and an end time of 10:15 AM.

Implementation

The idle time user interface relies on the infrastructure from the past few weeks, including the Time Tortoise Companion app, SignalR communication between the companion app and the main app, and idle time detection by the companion app.

Using the SignalR infrastructure, the companion app could send any kind of data to Time Tortoise. In previous weeks, I have been testing with strings. This week, I switched the data type to a DateTime value that represents the moment when user activity was last observed. That date/time value appears as a parameter to SendMessage in the SignalR server class, a corresponding parameter in the method with the same name in MessageHub, and finally a parameter to ReceiveMessage in the SignalRClient class that the Time Tortoise UWP app consumes.

The important idle time UI code is in MainPage.xaml.cs and MainViewModel. The MainPage code has an existing DispatcherTimer_Tick that’s used to regulate the activity timer. It makes sense to use it for the idle timer as well, so they tick in sync. On each tick, the page now retrieves the most recent message from the SignalR client and, if necessary, adjusts the idle timer UI elements.

In MainViewModel, we now have several fields and methods to read and write information about idle time, and implement Include and Exclude behavior. Per the MVVM pattern, these are associated with corresponding UI elements on MainPage.

Next Steps

Now that basic idle time functionality is implemented and testable from end to end, it’s time to check edge cases and make sure the feature works as intended in all scenarios. As always, that will require some unit test work and code refactoring.