diff --git a/ts/components/ToastManager.stories.tsx b/ts/components/ToastManager.stories.tsx index 939e25736..5328c4bd6 100644 --- a/ts/components/ToastManager.stories.tsx +++ b/ts/components/ToastManager.stories.tsx @@ -39,6 +39,86 @@ InvalidToast.args = { }, }; +export const AddingUserToGroup = Template.bind({}); +AddingUserToGroup.args = { + toast: { + toastType: ToastType.AddingUserToGroup, + parameters: { + contact: 'Sam Mirete', + }, + }, +}; + +export const CannotStartGroupCall = Template.bind({}); +CannotStartGroupCall.args = { + toast: { + toastType: ToastType.CannotStartGroupCall, + }, +}; + +export const CopiedUsername = Template.bind({}); +CopiedUsername.args = { + toast: { + toastType: ToastType.CopiedUsername, + }, +}; + +export const CopiedUsernameLink = Template.bind({}); +CopiedUsernameLink.args = { + toast: { + toastType: ToastType.CopiedUsernameLink, + }, +}; + +export const DeleteForEveryoneFailed = Template.bind({}); +DeleteForEveryoneFailed.args = { + toast: { + toastType: ToastType.DeleteForEveryoneFailed, + }, +}; + +export const Error = Template.bind({}); +Error.args = { + toast: { + toastType: ToastType.Error, + }, +}; + +export const FailedToDeleteUsername = Template.bind({}); +FailedToDeleteUsername.args = { + toast: { + toastType: ToastType.FailedToDeleteUsername, + }, +}; + +export const MessageBodyTooLong = Template.bind({}); +MessageBodyTooLong.args = { + toast: { + toastType: ToastType.MessageBodyTooLong, + }, +}; + +export const PinnedConversationsFull = Template.bind({}); +PinnedConversationsFull.args = { + toast: { + toastType: ToastType.PinnedConversationsFull, + }, +}; + +export const StoryMuted = Template.bind({}); +StoryMuted.args = { + toast: { + toastType: ToastType.StoryMuted, + }, +}; + +export const ReportedSpamAndBlocked = Template.bind({}); +ReportedSpamAndBlocked.args = { + toast: { + toastType: ToastType.ReportedSpamAndBlocked, + }, +}; + export const StoryReact = Template.bind({}); StoryReact.args = { toast: { @@ -53,10 +133,10 @@ StoryReply.args = { }, }; -export const MessageBodyTooLong = Template.bind({}); -MessageBodyTooLong.args = { +export const StoryVideoError = Template.bind({}); +StoryVideoError.args = { toast: { - toastType: ToastType.MessageBodyTooLong, + toastType: ToastType.StoryVideoError, }, }; @@ -74,16 +154,13 @@ StoryVideoUnsupported.args = { }, }; -export const StoryVideoError = Template.bind({}); -StoryVideoError.args = { +export const UserAddedToGroup = Template.bind({}); +UserAddedToGroup.args = { toast: { - toastType: ToastType.StoryVideoError, - }, -}; - -export const ReportedSpamAndBlocked = Template.bind({}); -ReportedSpamAndBlocked.args = { - toast: { - toastType: ToastType.ReportedSpamAndBlocked, + toastType: ToastType.UserAddedToGroup, + parameters: { + contact: 'Sam Mirete', + group: 'Hike Group 🏔', + }, }, }; diff --git a/ts/components/ToastManager.tsx b/ts/components/ToastManager.tsx index 12b39c7fc..dbe1cbea5 100644 --- a/ts/components/ToastManager.tsx +++ b/ts/components/ToastManager.tsx @@ -105,6 +105,10 @@ export function ToastManager({ ); } + if (toastType === ToastType.PinnedConversationsFull) { + return {i18n('pinnedConversationsFull')}; + } + if (toastType === ToastType.StoryMuted) { return ( diff --git a/ts/components/ToastPinnedConversationsFull.stories.tsx b/ts/components/ToastPinnedConversationsFull.stories.tsx deleted file mode 100644 index 8dbf52350..000000000 --- a/ts/components/ToastPinnedConversationsFull.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2021 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React from 'react'; -import { action } from '@storybook/addon-actions'; -import { ToastPinnedConversationsFull } from './ToastPinnedConversationsFull'; - -import { setupI18n } from '../util/setupI18n'; -import enMessages from '../../_locales/en/messages.json'; - -const i18n = setupI18n('en', enMessages); - -const defaultProps = { - i18n, - onClose: action('onClose'), -}; - -export default { - title: 'Components/ToastPinnedConversationsFull', -}; - -export const _ToastPinnedConversationsFull = (): JSX.Element => ( - -); - -_ToastPinnedConversationsFull.story = { - name: 'ToastPinnedConversationsFull', -}; diff --git a/ts/components/ToastPinnedConversationsFull.tsx b/ts/components/ToastPinnedConversationsFull.tsx deleted file mode 100644 index 91bc040a4..000000000 --- a/ts/components/ToastPinnedConversationsFull.tsx +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2021 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React from 'react'; -import type { LocalizerType } from '../types/Util'; -import { Toast } from './Toast'; - -type PropsType = { - i18n: LocalizerType; - onClose: () => unknown; -}; - -export function ToastPinnedConversationsFull({ - i18n, - onClose, -}: PropsType): JSX.Element { - return {i18n('pinnedConversationsFull')}; -} diff --git a/ts/components/conversation/ConversationHeader.stories.tsx b/ts/components/conversation/ConversationHeader.stories.tsx index 228520c3a..21aa6ed79 100644 --- a/ts/components/conversation/ConversationHeader.stories.tsx +++ b/ts/components/conversation/ConversationHeader.stories.tsx @@ -55,8 +55,8 @@ const commonProps = { onArchive: action('onArchive'), onMarkUnread: action('onMarkUnread'), onMoveToInbox: action('onMoveToInbox'), - onSetPin: action('onSetPin'), setMuteExpiration: action('onSetMuteNotifications'), + setPinned: action('setPinned'), viewUserStories: action('viewUserStories'), }; diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx index 728118e2e..efc97eb15 100644 --- a/ts/components/conversation/ConversationHeader.tsx +++ b/ts/components/conversation/ConversationHeader.tsx @@ -84,7 +84,6 @@ export type PropsActionsType = { onSearchInConversation: () => void; onOutgoingAudioCallInConversation: (conversationId: string) => void; onOutgoingVideoCallInConversation: (conversationId: string) => void; - onSetPin: (value: boolean) => void; onShowConversationDetails: () => void; onShowAllMedia: () => void; @@ -99,6 +98,7 @@ export type PropsActionsType = { conversationId: string, seconds: DurationInSeconds ) => void; + setPinned: (conversationId: string, value: boolean) => void; viewUserStories: ViewUserStoriesActionCreatorType; }; @@ -349,12 +349,12 @@ export class ConversationHeader extends React.Component { onArchive, onMarkUnread, onMoveToInbox, - onSetPin, onShowAllMedia, onShowConversationDetails, onShowGroupMembers, setDisappearingMessages, setMuteExpiration, + setPinned, type, } = this.props; @@ -502,11 +502,11 @@ export class ConversationHeader extends React.Component { {i18n('deleteMessages')} {isPinned ? ( - onSetPin(false)}> + setPinned(id, false)}> {i18n('unpinConversation')} ) : ( - onSetPin(true)}> + setPinned(id, true)}> {i18n('pinConversation')} )} diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index feaa3b1a1..2ef67b0ff 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -909,6 +909,7 @@ export const actions = { setIsNearBottom, setMessageLoadingState, setMuteExpiration, + setPinned, setPreJoinConversation, setSelectedConversationHeaderTitle, setSelectedConversationPanelDepth, @@ -1161,6 +1162,40 @@ function setMuteExpiration( }; } +function setPinned( + conversationId: string, + value: boolean +): NoopActionType | ShowToastActionType { + const conversation = window.ConversationController.get(conversationId); + if (!conversation) { + throw new Error('setPinned: No conversation found'); + } + + if (value) { + const pinnedConversationIds = window.storage.get( + 'pinnedConversationIds', + new Array() + ); + + if (pinnedConversationIds.length >= 4) { + return { + type: SHOW_TOAST, + payload: { + toastType: ToastType.PinnedConversationsFull, + }, + }; + } + conversation.pin(); + } else { + conversation.unpin(); + } + + return { + type: 'NOOP', + payload: null, + }; +} + function destroyMessages( conversationId: string ): ThunkAction { diff --git a/ts/state/ducks/toast.ts b/ts/state/ducks/toast.ts index fe48cebdd..ad53e9444 100644 --- a/ts/state/ducks/toast.ts +++ b/ts/state/ducks/toast.ts @@ -13,6 +13,7 @@ export enum ToastType { Error = 'Error', FailedToDeleteUsername = 'FailedToDeleteUsername', MessageBodyTooLong = 'MessageBodyTooLong', + PinnedConversationsFull = 'PinnedConversationsFull', ReportedSpamAndBlocked = 'ReportedSpamAndBlocked', StoryMuted = 'StoryMuted', StoryReact = 'StoryReact', diff --git a/ts/state/smart/ConversationHeader.tsx b/ts/state/smart/ConversationHeader.tsx index 093192348..97740e797 100644 --- a/ts/state/smart/ConversationHeader.tsx +++ b/ts/state/smart/ConversationHeader.tsx @@ -34,7 +34,6 @@ export type OwnProps = { onMarkUnread: () => void; onMoveToInbox: () => void; onSearchInConversation: () => void; - onSetPin: (value: boolean) => void; onShowAllMedia: () => void; onShowConversationDetails: () => void; onShowGroupMembers: () => void; diff --git a/ts/util/showToast.tsx b/ts/util/showToast.tsx index dc093772e..e6d445805 100644 --- a/ts/util/showToast.tsx +++ b/ts/util/showToast.tsx @@ -44,7 +44,6 @@ import type { ToastMaxAttachments } from '../components/ToastMaxAttachments'; import type { ToastMessageBodyTooLong } from '../components/ToastMessageBodyTooLong'; import type { ToastOriginalMessageNotFound } from '../components/ToastOriginalMessageNotFound'; -import type { ToastPinnedConversationsFull } from '../components/ToastPinnedConversationsFull'; import type { ToastReactionFailed } from '../components/ToastReactionFailed'; import type { ToastStickerPackInstallFailed } from '../components/ToastStickerPackInstallFailed'; import type { ToastTapToViewExpiredIncoming } from '../components/ToastTapToViewExpiredIncoming'; @@ -93,7 +92,6 @@ export function showToast(Toast: typeof ToastMaxAttachments): void; export function showToast(Toast: typeof ToastMessageBodyTooLong): void; export function showToast(Toast: typeof ToastUnsupportedMultiAttachment): void; export function showToast(Toast: typeof ToastOriginalMessageNotFound): void; -export function showToast(Toast: typeof ToastPinnedConversationsFull): void; export function showToast(Toast: typeof ToastReactionFailed): void; export function showToast(Toast: typeof ToastStickerPackInstallFailed): void; export function showToast(Toast: typeof ToastTapToViewExpiredIncoming): void; diff --git a/ts/views/conversation_view.tsx b/ts/views/conversation_view.tsx index caf8df534..8446a2475 100644 --- a/ts/views/conversation_view.tsx +++ b/ts/views/conversation_view.tsx @@ -70,7 +70,6 @@ import { ToastMaxAttachments } from '../components/ToastMaxAttachments'; import { ToastMessageBodyTooLong } from '../components/ToastMessageBodyTooLong'; import { ToastUnsupportedMultiAttachment } from '../components/ToastUnsupportedMultiAttachment'; import { ToastOriginalMessageNotFound } from '../components/ToastOriginalMessageNotFound'; -import { ToastPinnedConversationsFull } from '../components/ToastPinnedConversationsFull'; import { ToastReactionFailed } from '../components/ToastReactionFailed'; import { ToastTapToViewExpiredIncoming } from '../components/ToastTapToViewExpiredIncoming'; import { ToastTapToViewExpiredOutgoing } from '../components/ToastTapToViewExpiredOutgoing'; @@ -299,23 +298,6 @@ export class ConversationView extends window.Backbone.View { return this; } - setPin(value: boolean): void { - if (value) { - const pinnedConversationIds = window.storage.get( - 'pinnedConversationIds', - new Array() - ); - - if (pinnedConversationIds.length >= 4) { - showToast(ToastPinnedConversationsFull); - return; - } - this.model.pin(); - } else { - this.model.unpin(); - } - } - setupConversationView(): void { // setupHeader const conversationHeaderProps = { @@ -325,7 +307,6 @@ export class ConversationView extends window.Backbone.View { const { searchInConversation } = window.reduxActions.search; searchInConversation(this.model.id); }, - onSetPin: this.setPin.bind(this), onShowConversationDetails: () => { this.showConversationDetails(); },