66 lines
1.7 KiB
JavaScript
66 lines
1.7 KiB
JavaScript
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<UserSettingsState>}
|
|
*/
|
|
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;
|