signal-desktop/ts/state/ducks/emojis.ts

81 lines
1.7 KiB
TypeScript
Raw Normal View History

2020-10-30 20:34:04 +00:00
// Copyright 2019-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
2019-05-24 23:58:27 +00:00
import { take, uniq } from 'lodash';
import type { ThunkAction } from 'redux-thunk';
import type { EmojiPickDataType } from '../../components/emoji/EmojiPicker';
import dataInterface from '../../sql/Client';
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
2021-09-17 22:24:21 +00:00
import { useBoundActions } from '../../hooks/useBoundActions';
const { updateEmojiUsage } = dataInterface;
2019-05-24 23:58:27 +00:00
// State
export type EmojisStateType = {
readonly recents: Array<string>;
};
// Actions
type UseEmojiAction = {
2019-05-24 23:58:27 +00:00
type: 'emojis/USE_EMOJI';
payload: string;
2019-05-24 23:58:27 +00:00
};
type EmojisActionType = UseEmojiAction;
2019-05-24 23:58:27 +00:00
// Action Creators
export const actions = {
onUseEmoji,
useEmoji,
2019-05-24 23:58:27 +00:00
};
export const useActions = (): BoundActionCreatorsMapObject<typeof actions> =>
useBoundActions(actions);
function onUseEmoji({
shortName,
}: EmojiPickDataType): ThunkAction<void, unknown, unknown, UseEmojiAction> {
return async dispatch => {
try {
await updateEmojiUsage(shortName);
dispatch(useEmoji(shortName));
} catch (err) {
// Errors are ignored.
}
2019-05-24 23:58:27 +00:00
};
}
function useEmoji(payload: string): UseEmojiAction {
return {
type: 'emojis/USE_EMOJI',
payload,
};
2019-05-24 23:58:27 +00:00
}
// Reducer
function getEmptyState(): EmojisStateType {
return {
recents: [],
};
}
export function reducer(
state: Readonly<EmojisStateType> = getEmptyState(),
action: Readonly<EmojisActionType>
2019-05-24 23:58:27 +00:00
): EmojisStateType {
if (action.type === 'emojis/USE_EMOJI') {
2019-05-24 23:58:27 +00:00
const { payload } = action;
return {
...state,
recents: take(uniq([payload, ...state.recents]), 32),
};
}
return state;
}