Development Spec

Implementation guidelines authored by Jesus Espino (Core features team) @jesus.espino


Custom status feature is just adding a new visible data field to the user profile that represent the current status of the user, set by the user itself, and not bound to any other state of the application.

To implement this we decided to go for a simple solution that doesn't affect the backend at all, leveraging the Props field of the User model.

The Props field of the user model is an object with string keys and string values, so we can store whatever we need there, and is going to be synchronize through the WebSockets messages that are already being propagated to all the connected clients.

This implementation can be divide in different tasks, and each one can depend on others. This is the list of tasks required for both the mattermost-mobile and mattermost-webapp repos. These 3 tasks are exactly the same for the mobile and webapp platforms, but the work in mobile/webapp is completely independent:

  1. Create redux store actions to Set/Unset the custom status (this doesn't need to be in the mattermost-redux repo, it can be in the mattermost-webapp repo):

    • Apart from the custom status we need to store the last 5 recent custom statuses created.

    • This is going to use the client patchMe function to set the user props
      with the new custom-status and recent-custom-statuses field.

    • The custom status is going to be an object with the fields emojitext
      and expire, the emoji and the text are introduced by the user, by the
      expire date is calculated based on the user input, the have multiple ways
      to express that time, but we need to save here when the emoji expires.

    • The recent custom statuses is going to be a list of objects with the fields
      emojitext and duration, this 3 fields, are the fields provided by
      the user. If the list gets bigger than 5, gets truncated removing the
      oldest one.

    • The props save key values with key string and value string, we need to
      serialize our custom-status and recent-custom-statuses objects.

  2. Create the interface that allows the user to set the custom status (this requires the task 1).

    • Almost 90% of this task can be completed without the code of the task 1 still working.

    • This requires to implement the new components for setting the custom status (see the UX design for more information).

  3. Show the custom status where the UX design specify it (for testing it requires the tasks 1 and 2 to be complete, but the implementations doesn't need any previous work).

    • We are going to create a new component that is going to render the custom-status.

    • The custom status component needs to deserialize the
      user.props['custom-status'] (if is set), and check if the expire date has
      passed. If has passed or there is not custom-status set, is going to
      render null.

    • If the custom-status is set and is not expired, is going to render the
      custom status and use setTimeout to check it again when the "expire" date
      passes.

    • We can maintain an internal state expired that is set once the expire
      date is reached, and in that case re-render de component to render null.

    • The developer has pay special attention to the setTimeout to avoid any
      setTimout leak, we need to set the timeout on mount, and unset on unmount,
      but also we need update (unset and set) the timeout when the user.props
      gets updated. Special care here is needed because the amount of
      mount/unmount/updates of this component are going to be high, and leaking
      anything there can end up generating and important degradation in the app.