import { Automat } from 'react-automat'; /** * @typedef {'top'|'right'|'below'} ViewerPosition */ /** * @typedef {Object} UserSettingsState * @property {ViewerPosition} viewerPosition Preferred docking position of the * attachment viewer (text editor / PDF preview) relative to the article list. * @property {number} chatDrawerWidth Preferred width of the chat drawer in pixels. */ /** @type {UserSettingsState} */ const initialState = { viewerPosition: 'top', chatDrawerWidth: 460, }; /** * Persisted per-user UI preferences. Unlike the other automats this one is * backed by IndexedDB (`persist: true`) so settings survive reloads and * sessions. * * @type {Automat} */ const userSettingsAutomat = new Automat( initialState, { /** * Set the docking position of the attachment viewer. * * @param {ViewerPosition} position One of `'top'`, `'right'` or `'below'`. * @returns {void} */ setViewerPosition(position) { if (position !== 'top' && position !== 'right' && position !== 'below') { return; } userSettingsAutomat.setState({ viewerPosition: position }); }, /** * Set the width of the chat drawer in pixels. * * @param {number} width * @returns {void} */ setChatDrawerWidth(width) { const num = Number(width); if (Number.isNaN(num) || num < 280) { return; } userSettingsAutomat.setState({ chatDrawerWidth: Math.round(num) }); }, }, { name: 'userSettings', persist: true, } ); export default userSettingsAutomat; export const { setViewerPosition, setChatDrawerWidth } = userSettingsAutomat.actions; export const selectChatDrawerWidth = () => userSettingsAutomat.state.chatDrawerWidth || 460;