2023-01-03 19:55:46 +00:00
|
|
|
// Copyright 2019 Signal Messenger, LLC
|
2020-10-30 20:34:04 +00:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2019-05-24 23:58:27 +00:00
|
|
|
import { take, uniq } from 'lodash';
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { ThunkAction } from 'redux-thunk';
|
2023-01-13 20:07:26 +00:00
|
|
|
import type { ReadonlyDeep } from 'type-fest';
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { EmojiPickDataType } from '../../components/emoji/EmojiPicker';
|
2020-04-01 18:59:11 +00:00
|
|
|
import dataInterface from '../../sql/Client';
|
2022-12-09 17:35:34 +00:00
|
|
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
2021-09-17 22:24:21 +00:00
|
|
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
2020-04-01 18:59:11 +00:00
|
|
|
|
|
|
|
const { updateEmojiUsage } = dataInterface;
|
2019-05-24 23:58:27 +00:00
|
|
|
|
|
|
|
// State
|
|
|
|
|
2023-01-13 20:07:26 +00:00
|
|
|
export type EmojisStateType = ReadonlyDeep<{
|
|
|
|
recents: Array<string>;
|
|
|
|
}>;
|
2019-05-24 23:58:27 +00:00
|
|
|
|
|
|
|
// Actions
|
|
|
|
|
2023-01-13 20:07:26 +00:00
|
|
|
type UseEmojiAction = ReadonlyDeep<{
|
2019-05-24 23:58:27 +00:00
|
|
|
type: 'emojis/USE_EMOJI';
|
2020-10-30 18:00:01 +00:00
|
|
|
payload: string;
|
2023-01-13 20:07:26 +00:00
|
|
|
}>;
|
2019-05-24 23:58:27 +00:00
|
|
|
|
2023-01-13 20:07:26 +00:00
|
|
|
type EmojisActionType = ReadonlyDeep<UseEmojiAction>;
|
2019-05-24 23:58:27 +00:00
|
|
|
|
|
|
|
// Action Creators
|
|
|
|
|
|
|
|
export const actions = {
|
2020-05-05 19:49:34 +00:00
|
|
|
onUseEmoji,
|
2020-10-30 18:00:01 +00:00
|
|
|
useEmoji,
|
2019-05-24 23:58:27 +00:00
|
|
|
};
|
|
|
|
|
2024-03-12 16:29:31 +00:00
|
|
|
export const useEmojisActions = (): BoundActionCreatorsMapObject<
|
|
|
|
typeof actions
|
|
|
|
> => useBoundActions(actions);
|
2020-05-05 19:49:34 +00:00
|
|
|
|
2020-10-30 18:00:01 +00:00
|
|
|
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
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-10-30 18:00:01 +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(
|
2023-01-13 20:07:26 +00:00
|
|
|
state: EmojisStateType = getEmptyState(),
|
|
|
|
action: EmojisActionType
|
2019-05-24 23:58:27 +00:00
|
|
|
): EmojisStateType {
|
2020-10-30 18:00:01 +00:00
|
|
|
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;
|
|
|
|
}
|