Slideshow Functionality

The photo app supports the concept of a slideshow, that is, automatically display the next image after a period of time. This page explains the details of the slideshow functionality: what it does, and how it’s implemented.

Behavior

  • The slideshow is controlled from the Photo.jsx component.
  • When the Photo.jsx component loads, it determines whether the slideshow is by default on (random photos) or by default off (everything else) and kicks off the slideshow if needed.
  • The slideshow can be toggled by an interaction with the Photo component. The toggle switches from on to off, or from off to on.
  • The photo component can pause the slideshow when a message (e.g. the photo details lightbox) is displayed. Pausing is not the same as stopping. A paused slideshow is resumed when the message goes away, and continues at the actual time left. A slideshow that is stopped will, when it is started again, start with the full interval.
  • There is a slideshow status which can be displayed by the Photo component:
    • off
    • running, normal operation.
    • paused, slideshow is temporarily paused when displaying a lightbox over the actual photo.
    • waiting, when it is on and running, but the actual photo data has not yet been received.
    The status, when displayed, will only display for a limited time, and then go away.
  • The Photo component displays the status:
    • Upon entering, if the default status is on (random photos only).
    • Any time the status changes, the new status is displayed.
  • The time a photo is displayed starts counting when the actual photo is displayed. If the photo is displayed for two seconds, and it takes five seconds to load the photo, the photo will still be on the screen for exactly two seconds. The slideshow will be in waiting status until the image data is received.

Implementation in Photo.jsx Component

At initial load, the component checks if the slideshow must be started. If it does, it starts the slideshow and saves the token.

If the token changes, the component invokes the onNext() function.

If the slideshow is running, and there is no image ID or image data, the slideshow is put in waiting status.

If the slideshow is waiting, and there is both an image ID and image data, the slideshow is (re-)started. The token is saved.

Logic for the message display:

  • If paused, display "Paused slideshow"
  • Else if running, display "Slideshow running"
  • Else if waiting, display "Waiting for photo"
  • Else display "Slideshow stopped"

Changing of the message triggers a timer that displays the message for the next five seconds, after which it is removed. Need to figure out how to code this...?

Implementation in Store

The store and component interact about the slideshow through the token. The token itself doesn’t mean anything, but a change of the token triggers switching to the next image.

Starting, Stopping, Waiting

The start/stop/wait status is independent of the paused state. The pause and resume functions affect the paused state; the start, stop, and wait functions affect the status.

The wait status is controlled by the component, not the store. When the slideshow is in wait status, and the image data comes in, the component will recognize that the data is now there and will start the slide show.

  • startSlideshow() returns the current token. This will clear the pause state.
  • stopSlideshow(). This will clear the pause state.
  • waitSlideshow()
  • getSlideshowStatus() returns one of the values SL_STOPPED, SL_RUNNING, or SL_WAIT.
  • getSlideshowToken() returns the current token, if the slideshow is running or waiting, or null if the slideshow is stopped.

Pausing and resuming

  • pauseSlideshow() sets the pause indicator, only if the slideshow is running or waiting.
  • resumeSlideshow() clears the pause indicator.
  • isSlideshowPaused() returns true only if the slideshow is paused while running or waiting.

When the slideshow timer runs out, the store advances the token. The component recognizes the change in the token and advances to the next image.

Store-Component Interactions

The getStateFromStores() checks if the slideshow is running; the interactions below are only if the slideshow is running or waiting.

  Component                               Store
+-----------------------+               +-----------------------+
| onMount, if random    |-------------->| startSlideShow()      |
| (slide show is off    |               | returns token, no     |
| if not random)        |               | emit change....?      |
|                       |               |                       |
| stores token          |<--------------| starts timer          |
|-----------------------|               |-----------------------|
| toggle slideshow, if  |-------------->| stopSlideshow()       |
| running               |               | stops timer, no emit  |
|                       |<--------------| change?               |
|-----------------------|               |-----------------------|
| toggle slideshow, if  |-------------->| startSlideshow()      |
| stopped               |               | returns token, no     |
|                       |               | emit change           |
|                       |               |                       |
| stores token          |<--------------| starts timer          |
+-----------------------+               +-----------------------+

+-----------------------+               +-----------------------+
| getStateFromStores    |<--------------| timer runs out,       |
| recognize new token   |               | advance token, emit   |
| call onNext()         |               | change                |
|-----------------------|               |-----------------------|
| parent onNext calls   |-------------->| store advances image  |
| store to change image |               | ID and starts loading |
| ID on next tick       |               | emit change           |
|-----------------------|               |-----------------------|
| getStateFromStores,   |-------------->| waitSlideshow(), no   |
| new image ID, no data |               | emit change           |
|-----------------------|               |-----------------------|
| getStateFromStores,   |<--------------| image data comes in,  |
| same image ID, has    |               | emit change           |
| data, starts slide    |               |                       |
| show                  |-------------->| startSlideShow()      |
|                       |               | start timer, no emit  |
|                       |               | change.               |
|                       |               |                       |
| stores token          |<--------------| returns token         |
|-----------------------|               |-----------------------|
| getStateFromStores,   |-------------->| startSlideShow()      |
| new image ID, has     |               | start timer, no emit  |
| data                  |               | change                |
|                       |               |                       |
| stores token          |<--------------| returns token         |
|-----------------------|               |-----------------------|
| getStateFromStores,   |-------------->| startSlideshow()      |
| same image ID, new    |<--------------| returns token, no     |
| data, store token     |               | emit change           |
+-----------------------+               +-----------------------+