Auto-select a newly created distribution list or group when sending story
This commit is contained in:
parent
81e4564687
commit
2db14e8d6f
14 changed files with 94 additions and 26 deletions
|
@ -56,7 +56,7 @@ export type PropsType = {
|
||||||
onDistributionListCreated: (
|
onDistributionListCreated: (
|
||||||
name: string,
|
name: string,
|
||||||
viewerUuids: Array<UUIDStringType>
|
viewerUuids: Array<UUIDStringType>
|
||||||
) => unknown;
|
) => Promise<UUIDStringType>;
|
||||||
onSelectedStoryList: (options: {
|
onSelectedStoryList: (options: {
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
distributionId: string | undefined;
|
distributionId: string | undefined;
|
||||||
|
@ -67,7 +67,7 @@ export type PropsType = {
|
||||||
conversationIds: Array<string>
|
conversationIds: Array<string>
|
||||||
) => unknown;
|
) => unknown;
|
||||||
signalConnections: Array<ConversationType>;
|
signalConnections: Array<ConversationType>;
|
||||||
toggleGroupsForStorySend: (cids: Array<string>) => unknown;
|
toggleGroupsForStorySend: (cids: Array<string>) => Promise<void>;
|
||||||
mostRecentActiveStoryTimestampByGroupOrDistributionList: Record<
|
mostRecentActiveStoryTimestampByGroupOrDistributionList: Record<
|
||||||
string,
|
string,
|
||||||
number
|
number
|
||||||
|
@ -419,9 +419,17 @@ export function SendStoryModal({
|
||||||
candidateConversations={candidateConversations}
|
candidateConversations={candidateConversations}
|
||||||
getPreferredBadge={getPreferredBadge}
|
getPreferredBadge={getPreferredBadge}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
onCreateList={(name, uuids) => {
|
onCreateList={async (name, uuids) => {
|
||||||
|
const newDistributionListId = await onDistributionListCreated(
|
||||||
|
name,
|
||||||
|
uuids
|
||||||
|
);
|
||||||
|
|
||||||
setSelectedContacts([]);
|
setSelectedContacts([]);
|
||||||
onDistributionListCreated(name, uuids);
|
setSelectedListIds(
|
||||||
|
listIds => new Set([...listIds, newDistributionListId])
|
||||||
|
);
|
||||||
|
|
||||||
setPage(Page.SendStory);
|
setPage(Page.SendStory);
|
||||||
}}
|
}}
|
||||||
onViewersUpdated={uuids => {
|
onViewersUpdated={uuids => {
|
||||||
|
@ -480,9 +488,10 @@ export function SendStoryModal({
|
||||||
aria-label={i18n('ok')}
|
aria-label={i18n('ok')}
|
||||||
className="SendStoryModal__ok"
|
className="SendStoryModal__ok"
|
||||||
disabled={!chosenGroupIds.size}
|
disabled={!chosenGroupIds.size}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
toggleGroupsForStorySend(Array.from(chosenGroupIds));
|
await toggleGroupsForStorySend(Array.from(chosenGroupIds));
|
||||||
setChosenGroupIds(new Set());
|
setChosenGroupIds(new Set());
|
||||||
|
setSelectedGroupIds(chosenGroupIds);
|
||||||
setPage(Page.SendStory);
|
setPage(Page.SendStory);
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
@ -54,7 +54,7 @@ export type PropsType = {
|
||||||
onDistributionListCreated: (
|
onDistributionListCreated: (
|
||||||
name: string,
|
name: string,
|
||||||
viewerUuids: Array<UUIDStringType>
|
viewerUuids: Array<UUIDStringType>
|
||||||
) => unknown;
|
) => Promise<string>;
|
||||||
onHideMyStoriesFrom: (viewerUuids: Array<UUIDStringType>) => unknown;
|
onHideMyStoriesFrom: (viewerUuids: Array<UUIDStringType>) => unknown;
|
||||||
onRemoveMembers: (listId: string, uuids: Array<UUIDStringType>) => unknown;
|
onRemoveMembers: (listId: string, uuids: Array<UUIDStringType>) => unknown;
|
||||||
onRepliesNReactionsChanged: (
|
onRepliesNReactionsChanged: (
|
||||||
|
|
|
@ -2,16 +2,45 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { ActionCreatorsMapObject } from 'redux';
|
import type { ActionCreatorsMapObject } from 'redux';
|
||||||
|
import type { ThunkAction } from 'redux-thunk';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type-level function from an action creator (which may be ThunkAction creator) to a
|
||||||
|
* bound action creator.
|
||||||
|
*
|
||||||
|
* binding a thunk action creator changes it from:
|
||||||
|
* (params) => ThunkAction<R, ...>
|
||||||
|
* to:
|
||||||
|
* (params) => R
|
||||||
|
*
|
||||||
|
* a regular action creator's type is unchanged
|
||||||
|
*/
|
||||||
|
type BoundActionCreator<A> = A extends (
|
||||||
|
...params: infer P
|
||||||
|
) => ThunkAction<infer R, any, any, any>
|
||||||
|
? (...params: P) => R
|
||||||
|
: A;
|
||||||
|
|
||||||
|
export type BoundActionCreatorsMapObject<T extends ActionCreatorsMapObject> = {
|
||||||
|
[Property in keyof T]: BoundActionCreator<T[Property]>;
|
||||||
|
};
|
||||||
|
|
||||||
export const useBoundActions = <T extends ActionCreatorsMapObject>(
|
export const useBoundActions = <T extends ActionCreatorsMapObject>(
|
||||||
actions: T
|
actions: T
|
||||||
): T => {
|
): BoundActionCreatorsMapObject<T> => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return bindActionCreators(actions, dispatch);
|
// bindActionCreators from redux has the wrong type when using thunk actions
|
||||||
|
// so we cast to the correct type
|
||||||
|
return bindActionCreators(
|
||||||
|
actions,
|
||||||
|
dispatch
|
||||||
|
) as any as BoundActionCreatorsMapObject<T>;
|
||||||
}, [actions, dispatch]);
|
}, [actions, dispatch]);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { ThunkAction } from 'redux-thunk';
|
import type { ThunkAction } from 'redux-thunk';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
import { Sound } from '../../util/Sound';
|
import { Sound } from '../../util/Sound';
|
||||||
import * as Errors from '../../types/errors';
|
import * as Errors from '../../types/errors';
|
||||||
|
@ -106,7 +107,8 @@ export const actions = {
|
||||||
setIsPlaying,
|
setIsPlaying,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useActions = (): typeof actions => useBoundActions(actions);
|
export const useActions = (): BoundActionCreatorsMapObject<typeof actions> =>
|
||||||
|
useBoundActions(actions);
|
||||||
|
|
||||||
function setCurrentTime(value: number): CurrentTimeUpdated {
|
function setCurrentTime(value: number): CurrentTimeUpdated {
|
||||||
globalMessageAudio.currentTime = value;
|
globalMessageAudio.currentTime = value;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import type { StateType as RootStateType } from '../reducer';
|
||||||
import { fileToBytes } from '../../util/fileToBytes';
|
import { fileToBytes } from '../../util/fileToBytes';
|
||||||
import { recorder } from '../../services/audioRecorder';
|
import { recorder } from '../../services/audioRecorder';
|
||||||
import { stringToMIMEType } from '../../types/MIME';
|
import { stringToMIMEType } from '../../types/MIME';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
|
|
||||||
export enum ErrorDialogAudioRecorderType {
|
export enum ErrorDialogAudioRecorderType {
|
||||||
|
@ -76,7 +77,8 @@ export const actions = {
|
||||||
startRecording,
|
startRecording,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useActions = (): typeof actions => useBoundActions(actions);
|
export const useActions = (): BoundActionCreatorsMapObject<typeof actions> =>
|
||||||
|
useBoundActions(actions);
|
||||||
|
|
||||||
function startRecording(): ThunkAction<
|
function startRecording(): ThunkAction<
|
||||||
void,
|
void,
|
||||||
|
|
|
@ -83,6 +83,7 @@ import {
|
||||||
SelectedMessageSource,
|
SelectedMessageSource,
|
||||||
} from './conversationsEnums';
|
} from './conversationsEnums';
|
||||||
import { markViewed as messageUpdaterMarkViewed } from '../../services/MessageUpdater';
|
import { markViewed as messageUpdaterMarkViewed } from '../../services/MessageUpdater';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
|
|
||||||
import type { NoopActionType } from './noop';
|
import type { NoopActionType } from './noop';
|
||||||
|
@ -935,8 +936,9 @@ export const actions = {
|
||||||
verifyConversationsStoppingSend,
|
verifyConversationsStoppingSend,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useConversationsActions = (): typeof actions =>
|
export const useConversationsActions = (): BoundActionCreatorsMapObject<
|
||||||
useBoundActions(actions);
|
typeof actions
|
||||||
|
> => useBoundActions(actions);
|
||||||
|
|
||||||
function filterAvatarData(
|
function filterAvatarData(
|
||||||
avatars: ReadonlyArray<AvatarDataType>,
|
avatars: ReadonlyArray<AvatarDataType>,
|
||||||
|
@ -2621,7 +2623,7 @@ function addMemberToGroup(
|
||||||
|
|
||||||
function toggleGroupsForStorySend(
|
function toggleGroupsForStorySend(
|
||||||
conversationIds: Array<string>
|
conversationIds: Array<string>
|
||||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
): ThunkAction<Promise<void>, RootStateType, unknown, NoopActionType> {
|
||||||
return async dispatch => {
|
return async dispatch => {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
conversationIds.map(async conversationId => {
|
conversationIds.map(async conversationId => {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { take, uniq } from 'lodash';
|
||||||
import type { ThunkAction } from 'redux-thunk';
|
import type { ThunkAction } from 'redux-thunk';
|
||||||
import type { EmojiPickDataType } from '../../components/emoji/EmojiPicker';
|
import type { EmojiPickDataType } from '../../components/emoji/EmojiPicker';
|
||||||
import dataInterface from '../../sql/Client';
|
import dataInterface from '../../sql/Client';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
|
|
||||||
const { updateEmojiUsage } = dataInterface;
|
const { updateEmojiUsage } = dataInterface;
|
||||||
|
@ -31,7 +32,8 @@ export const actions = {
|
||||||
useEmoji,
|
useEmoji,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useActions = (): typeof actions => useBoundActions(actions);
|
export const useActions = (): BoundActionCreatorsMapObject<typeof actions> =>
|
||||||
|
useBoundActions(actions);
|
||||||
|
|
||||||
function onUseEmoji({
|
function onUseEmoji({
|
||||||
shortName,
|
shortName,
|
||||||
|
|
|
@ -12,6 +12,7 @@ import type { UUIDStringType } from '../../types/UUID';
|
||||||
import * as SingleServePromise from '../../services/singleServePromise';
|
import * as SingleServePromise from '../../services/singleServePromise';
|
||||||
import { getMessageById } from '../../messages/getMessageById';
|
import { getMessageById } from '../../messages/getMessageById';
|
||||||
import { getMessagePropsSelector } from '../selectors/message';
|
import { getMessagePropsSelector } from '../selectors/message';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { longRunningTaskWrapper } from '../../util/longRunningTaskWrapper';
|
import { longRunningTaskWrapper } from '../../util/longRunningTaskWrapper';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
import { isGroupV1 } from '../../util/whatTypeOfConversation';
|
import { isGroupV1 } from '../../util/whatTypeOfConversation';
|
||||||
|
@ -215,8 +216,9 @@ export const actions = {
|
||||||
closeGV2MigrationDialog,
|
closeGV2MigrationDialog,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGlobalModalActions = (): typeof actions =>
|
export const useGlobalModalActions = (): BoundActionCreatorsMapObject<
|
||||||
useBoundActions(actions);
|
typeof actions
|
||||||
|
> => useBoundActions(actions);
|
||||||
|
|
||||||
function hideContactModal(): HideContactModalActionType {
|
function hideContactModal(): HideContactModalActionType {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { v4 as getGuid } from 'uuid';
|
||||||
import type { ThunkAction } from 'redux-thunk';
|
import type { ThunkAction } from 'redux-thunk';
|
||||||
import type { StateType as RootStateType } from '../reducer';
|
import type { StateType as RootStateType } from '../reducer';
|
||||||
import * as storageShim from '../../shims/storage';
|
import * as storageShim from '../../shims/storage';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
import type {
|
import type {
|
||||||
ConversationColorType,
|
ConversationColorType,
|
||||||
|
@ -93,7 +94,8 @@ export const actions = {
|
||||||
resetItems,
|
resetItems,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useActions = (): typeof actions => useBoundActions(actions);
|
export const useActions = (): BoundActionCreatorsMapObject<typeof actions> =>
|
||||||
|
useBoundActions(actions);
|
||||||
|
|
||||||
function putItem<K extends keyof StorageAccessType>(
|
function putItem<K extends keyof StorageAccessType>(
|
||||||
key: K,
|
key: K,
|
||||||
|
|
|
@ -12,6 +12,7 @@ import type {
|
||||||
} from '../../types/LinkPreview';
|
} from '../../types/LinkPreview';
|
||||||
import { assignWithNoUnnecessaryAllocation } from '../../util/assignWithNoUnnecessaryAllocation';
|
import { assignWithNoUnnecessaryAllocation } from '../../util/assignWithNoUnnecessaryAllocation';
|
||||||
import { maybeGrabLinkPreview } from '../../services/LinkPreview';
|
import { maybeGrabLinkPreview } from '../../services/LinkPreview';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
@ -84,8 +85,9 @@ export const actions = {
|
||||||
removeLinkPreview,
|
removeLinkPreview,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useLinkPreviewActions = (): typeof actions =>
|
export const useLinkPreviewActions = (): BoundActionCreatorsMapObject<
|
||||||
useBoundActions(actions);
|
typeof actions
|
||||||
|
> => useBoundActions(actions);
|
||||||
|
|
||||||
// Reducer
|
// Reducer
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { omit } from 'lodash';
|
||||||
import * as log from '../../logging/log';
|
import * as log from '../../logging/log';
|
||||||
import * as Errors from '../../types/errors';
|
import * as Errors from '../../types/errors';
|
||||||
import { replaceIndex } from '../../util/replaceIndex';
|
import { replaceIndex } from '../../util/replaceIndex';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
import type { StateType as RootStateType } from '../reducer';
|
import type { StateType as RootStateType } from '../reducer';
|
||||||
import { DEFAULT_PREFERRED_REACTION_EMOJI_SHORT_NAMES } from '../../reactions/constants';
|
import { DEFAULT_PREFERRED_REACTION_EMOJI_SHORT_NAMES } from '../../reactions/constants';
|
||||||
|
@ -97,7 +98,8 @@ export const actions = {
|
||||||
selectDraftEmojiToBeReplaced,
|
selectDraftEmojiToBeReplaced,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useActions = (): typeof actions => useBoundActions(actions);
|
export const useActions = (): BoundActionCreatorsMapObject<typeof actions> =>
|
||||||
|
useBoundActions(actions);
|
||||||
|
|
||||||
function cancelCustomizePreferredReactionsModal(): CancelCustomizePreferredReactionsModalActionType {
|
function cancelCustomizePreferredReactionsModal(): CancelCustomizePreferredReactionsModalActionType {
|
||||||
return { type: CANCEL_CUSTOMIZE_PREFERRED_REACTIONS_MODAL };
|
return { type: CANCEL_CUSTOMIZE_PREFERRED_REACTIONS_MODAL };
|
||||||
|
|
|
@ -51,6 +51,7 @@ import { isGroup } from '../../util/whatTypeOfConversation';
|
||||||
import { isNotNil } from '../../util/isNotNil';
|
import { isNotNil } from '../../util/isNotNil';
|
||||||
import { isStory } from '../../messages/helpers';
|
import { isStory } from '../../messages/helpers';
|
||||||
import { sendStoryMessage as doSendStoryMessage } from '../../util/sendStoryMessage';
|
import { sendStoryMessage as doSendStoryMessage } from '../../util/sendStoryMessage';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
import { verifyStoryListMembers as doVerifyStoryListMembers } from '../../util/verifyStoryListMembers';
|
import { verifyStoryListMembers as doVerifyStoryListMembers } from '../../util/verifyStoryListMembers';
|
||||||
import { viewSyncJobQueue } from '../../jobs/viewSyncJobQueue';
|
import { viewSyncJobQueue } from '../../jobs/viewSyncJobQueue';
|
||||||
|
@ -1317,7 +1318,9 @@ export const actions = {
|
||||||
setStorySending,
|
setStorySending,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useStoriesActions = (): typeof actions => useBoundActions(actions);
|
export const useStoriesActions = (): BoundActionCreatorsMapObject<
|
||||||
|
typeof actions
|
||||||
|
> => useBoundActions(actions);
|
||||||
|
|
||||||
// Reducer
|
// Reducer
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { UUID } from '../../types/UUID';
|
||||||
import { deleteStoryForEveryone } from '../../util/deleteStoryForEveryone';
|
import { deleteStoryForEveryone } from '../../util/deleteStoryForEveryone';
|
||||||
import { replaceIndex } from '../../util/replaceIndex';
|
import { replaceIndex } from '../../util/replaceIndex';
|
||||||
import { storageServiceUploadJob } from '../../services/storage';
|
import { storageServiceUploadJob } from '../../services/storage';
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
@ -156,7 +157,12 @@ function createDistributionList(
|
||||||
memberUuids: Array<UUIDStringType>,
|
memberUuids: Array<UUIDStringType>,
|
||||||
storageServiceDistributionListRecord?: StoryDistributionWithMembersType,
|
storageServiceDistributionListRecord?: StoryDistributionWithMembersType,
|
||||||
shouldSave = true
|
shouldSave = true
|
||||||
): ThunkAction<void, RootStateType, null, CreateListActionType> {
|
): ThunkAction<
|
||||||
|
Promise<UUIDStringType>,
|
||||||
|
RootStateType,
|
||||||
|
string,
|
||||||
|
CreateListActionType
|
||||||
|
> {
|
||||||
return async dispatch => {
|
return async dispatch => {
|
||||||
const storyDistribution: StoryDistributionWithMembersType = {
|
const storyDistribution: StoryDistributionWithMembersType = {
|
||||||
allowsReplies: true,
|
allowsReplies: true,
|
||||||
|
@ -188,6 +194,8 @@ function createDistributionList(
|
||||||
name: storyDistribution.name,
|
name: storyDistribution.name,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return storyDistribution.id;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,8 +491,8 @@ export const actions = {
|
||||||
updateStoryViewers,
|
updateStoryViewers,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useStoryDistributionListsActions = (): typeof actions =>
|
export const useStoryDistributionListsActions =
|
||||||
useBoundActions(actions);
|
(): BoundActionCreatorsMapObject<typeof actions> => useBoundActions(actions);
|
||||||
|
|
||||||
// Reducer
|
// Reducer
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
import type { ReplacementValuesType } from '../../types/Util';
|
import type { ReplacementValuesType } from '../../types/Util';
|
||||||
|
|
||||||
|
@ -94,7 +95,9 @@ export const actions = {
|
||||||
showToast,
|
showToast,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useToastActions = (): typeof actions => useBoundActions(actions);
|
export const useToastActions = (): BoundActionCreatorsMapObject<
|
||||||
|
typeof actions
|
||||||
|
> => useBoundActions(actions);
|
||||||
|
|
||||||
// Reducer
|
// Reducer
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue