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:
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 newcustom-status
andrecent-custom-statuses
field.The custom status is going to be an object with the fields
emoji
,text
andexpire
, 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
emoji
,text
andduration
, 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.
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).
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 notcustom-status
set, is going to
rendernull
.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 rendernull
.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.