ConversationView: Move setPin to redux
This commit is contained in:
parent
e9b7a74b32
commit
ff6750e4fd
11 changed files with 135 additions and 86 deletions
|
@ -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({});
|
export const StoryReact = Template.bind({});
|
||||||
StoryReact.args = {
|
StoryReact.args = {
|
||||||
toast: {
|
toast: {
|
||||||
|
@ -53,10 +133,10 @@ StoryReply.args = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MessageBodyTooLong = Template.bind({});
|
export const StoryVideoError = Template.bind({});
|
||||||
MessageBodyTooLong.args = {
|
StoryVideoError.args = {
|
||||||
toast: {
|
toast: {
|
||||||
toastType: ToastType.MessageBodyTooLong,
|
toastType: ToastType.StoryVideoError,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,16 +154,13 @@ StoryVideoUnsupported.args = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StoryVideoError = Template.bind({});
|
export const UserAddedToGroup = Template.bind({});
|
||||||
StoryVideoError.args = {
|
UserAddedToGroup.args = {
|
||||||
toast: {
|
toast: {
|
||||||
toastType: ToastType.StoryVideoError,
|
toastType: ToastType.UserAddedToGroup,
|
||||||
},
|
parameters: {
|
||||||
};
|
contact: 'Sam Mirete',
|
||||||
|
group: 'Hike Group 🏔',
|
||||||
export const ReportedSpamAndBlocked = Template.bind({});
|
},
|
||||||
ReportedSpamAndBlocked.args = {
|
|
||||||
toast: {
|
|
||||||
toastType: ToastType.ReportedSpamAndBlocked,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -105,6 +105,10 @@ export function ToastManager({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (toastType === ToastType.PinnedConversationsFull) {
|
||||||
|
return <Toast onClose={hideToast}>{i18n('pinnedConversationsFull')}</Toast>;
|
||||||
|
}
|
||||||
|
|
||||||
if (toastType === ToastType.StoryMuted) {
|
if (toastType === ToastType.StoryMuted) {
|
||||||
return (
|
return (
|
||||||
<Toast onClose={hideToast} timeout={SHORT_TIMEOUT}>
|
<Toast onClose={hideToast} timeout={SHORT_TIMEOUT}>
|
||||||
|
|
|
@ -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 {...defaultProps} />
|
|
||||||
);
|
|
||||||
|
|
||||||
_ToastPinnedConversationsFull.story = {
|
|
||||||
name: 'ToastPinnedConversationsFull',
|
|
||||||
};
|
|
|
@ -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 <Toast onClose={onClose}>{i18n('pinnedConversationsFull')}</Toast>;
|
|
||||||
}
|
|
|
@ -55,8 +55,8 @@ const commonProps = {
|
||||||
onArchive: action('onArchive'),
|
onArchive: action('onArchive'),
|
||||||
onMarkUnread: action('onMarkUnread'),
|
onMarkUnread: action('onMarkUnread'),
|
||||||
onMoveToInbox: action('onMoveToInbox'),
|
onMoveToInbox: action('onMoveToInbox'),
|
||||||
onSetPin: action('onSetPin'),
|
|
||||||
setMuteExpiration: action('onSetMuteNotifications'),
|
setMuteExpiration: action('onSetMuteNotifications'),
|
||||||
|
setPinned: action('setPinned'),
|
||||||
viewUserStories: action('viewUserStories'),
|
viewUserStories: action('viewUserStories'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,6 @@ export type PropsActionsType = {
|
||||||
onSearchInConversation: () => void;
|
onSearchInConversation: () => void;
|
||||||
onOutgoingAudioCallInConversation: (conversationId: string) => void;
|
onOutgoingAudioCallInConversation: (conversationId: string) => void;
|
||||||
onOutgoingVideoCallInConversation: (conversationId: string) => void;
|
onOutgoingVideoCallInConversation: (conversationId: string) => void;
|
||||||
onSetPin: (value: boolean) => void;
|
|
||||||
|
|
||||||
onShowConversationDetails: () => void;
|
onShowConversationDetails: () => void;
|
||||||
onShowAllMedia: () => void;
|
onShowAllMedia: () => void;
|
||||||
|
@ -99,6 +98,7 @@ export type PropsActionsType = {
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
seconds: DurationInSeconds
|
seconds: DurationInSeconds
|
||||||
) => void;
|
) => void;
|
||||||
|
setPinned: (conversationId: string, value: boolean) => void;
|
||||||
viewUserStories: ViewUserStoriesActionCreatorType;
|
viewUserStories: ViewUserStoriesActionCreatorType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -349,12 +349,12 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
onArchive,
|
onArchive,
|
||||||
onMarkUnread,
|
onMarkUnread,
|
||||||
onMoveToInbox,
|
onMoveToInbox,
|
||||||
onSetPin,
|
|
||||||
onShowAllMedia,
|
onShowAllMedia,
|
||||||
onShowConversationDetails,
|
onShowConversationDetails,
|
||||||
onShowGroupMembers,
|
onShowGroupMembers,
|
||||||
setDisappearingMessages,
|
setDisappearingMessages,
|
||||||
setMuteExpiration,
|
setMuteExpiration,
|
||||||
|
setPinned,
|
||||||
type,
|
type,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -502,11 +502,11 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
{i18n('deleteMessages')}
|
{i18n('deleteMessages')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{isPinned ? (
|
{isPinned ? (
|
||||||
<MenuItem onClick={() => onSetPin(false)}>
|
<MenuItem onClick={() => setPinned(id, false)}>
|
||||||
{i18n('unpinConversation')}
|
{i18n('unpinConversation')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
) : (
|
) : (
|
||||||
<MenuItem onClick={() => onSetPin(true)}>
|
<MenuItem onClick={() => setPinned(id, true)}>
|
||||||
{i18n('pinConversation')}
|
{i18n('pinConversation')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -909,6 +909,7 @@ export const actions = {
|
||||||
setIsNearBottom,
|
setIsNearBottom,
|
||||||
setMessageLoadingState,
|
setMessageLoadingState,
|
||||||
setMuteExpiration,
|
setMuteExpiration,
|
||||||
|
setPinned,
|
||||||
setPreJoinConversation,
|
setPreJoinConversation,
|
||||||
setSelectedConversationHeaderTitle,
|
setSelectedConversationHeaderTitle,
|
||||||
setSelectedConversationPanelDepth,
|
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<string>()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pinnedConversationIds.length >= 4) {
|
||||||
|
return {
|
||||||
|
type: SHOW_TOAST,
|
||||||
|
payload: {
|
||||||
|
toastType: ToastType.PinnedConversationsFull,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
conversation.pin();
|
||||||
|
} else {
|
||||||
|
conversation.unpin();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'NOOP',
|
||||||
|
payload: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function destroyMessages(
|
function destroyMessages(
|
||||||
conversationId: string
|
conversationId: string
|
||||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
||||||
|
|
|
@ -13,6 +13,7 @@ export enum ToastType {
|
||||||
Error = 'Error',
|
Error = 'Error',
|
||||||
FailedToDeleteUsername = 'FailedToDeleteUsername',
|
FailedToDeleteUsername = 'FailedToDeleteUsername',
|
||||||
MessageBodyTooLong = 'MessageBodyTooLong',
|
MessageBodyTooLong = 'MessageBodyTooLong',
|
||||||
|
PinnedConversationsFull = 'PinnedConversationsFull',
|
||||||
ReportedSpamAndBlocked = 'ReportedSpamAndBlocked',
|
ReportedSpamAndBlocked = 'ReportedSpamAndBlocked',
|
||||||
StoryMuted = 'StoryMuted',
|
StoryMuted = 'StoryMuted',
|
||||||
StoryReact = 'StoryReact',
|
StoryReact = 'StoryReact',
|
||||||
|
|
|
@ -34,7 +34,6 @@ export type OwnProps = {
|
||||||
onMarkUnread: () => void;
|
onMarkUnread: () => void;
|
||||||
onMoveToInbox: () => void;
|
onMoveToInbox: () => void;
|
||||||
onSearchInConversation: () => void;
|
onSearchInConversation: () => void;
|
||||||
onSetPin: (value: boolean) => void;
|
|
||||||
onShowAllMedia: () => void;
|
onShowAllMedia: () => void;
|
||||||
onShowConversationDetails: () => void;
|
onShowConversationDetails: () => void;
|
||||||
onShowGroupMembers: () => void;
|
onShowGroupMembers: () => void;
|
||||||
|
|
|
@ -44,7 +44,6 @@ import type { ToastMaxAttachments } from '../components/ToastMaxAttachments';
|
||||||
import type { ToastMessageBodyTooLong } from '../components/ToastMessageBodyTooLong';
|
import type { ToastMessageBodyTooLong } from '../components/ToastMessageBodyTooLong';
|
||||||
|
|
||||||
import type { ToastOriginalMessageNotFound } from '../components/ToastOriginalMessageNotFound';
|
import type { ToastOriginalMessageNotFound } from '../components/ToastOriginalMessageNotFound';
|
||||||
import type { ToastPinnedConversationsFull } from '../components/ToastPinnedConversationsFull';
|
|
||||||
import type { ToastReactionFailed } from '../components/ToastReactionFailed';
|
import type { ToastReactionFailed } from '../components/ToastReactionFailed';
|
||||||
import type { ToastStickerPackInstallFailed } from '../components/ToastStickerPackInstallFailed';
|
import type { ToastStickerPackInstallFailed } from '../components/ToastStickerPackInstallFailed';
|
||||||
import type { ToastTapToViewExpiredIncoming } from '../components/ToastTapToViewExpiredIncoming';
|
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 ToastMessageBodyTooLong): void;
|
||||||
export function showToast(Toast: typeof ToastUnsupportedMultiAttachment): void;
|
export function showToast(Toast: typeof ToastUnsupportedMultiAttachment): void;
|
||||||
export function showToast(Toast: typeof ToastOriginalMessageNotFound): 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 ToastReactionFailed): void;
|
||||||
export function showToast(Toast: typeof ToastStickerPackInstallFailed): void;
|
export function showToast(Toast: typeof ToastStickerPackInstallFailed): void;
|
||||||
export function showToast(Toast: typeof ToastTapToViewExpiredIncoming): void;
|
export function showToast(Toast: typeof ToastTapToViewExpiredIncoming): void;
|
||||||
|
|
|
@ -70,7 +70,6 @@ import { ToastMaxAttachments } from '../components/ToastMaxAttachments';
|
||||||
import { ToastMessageBodyTooLong } from '../components/ToastMessageBodyTooLong';
|
import { ToastMessageBodyTooLong } from '../components/ToastMessageBodyTooLong';
|
||||||
import { ToastUnsupportedMultiAttachment } from '../components/ToastUnsupportedMultiAttachment';
|
import { ToastUnsupportedMultiAttachment } from '../components/ToastUnsupportedMultiAttachment';
|
||||||
import { ToastOriginalMessageNotFound } from '../components/ToastOriginalMessageNotFound';
|
import { ToastOriginalMessageNotFound } from '../components/ToastOriginalMessageNotFound';
|
||||||
import { ToastPinnedConversationsFull } from '../components/ToastPinnedConversationsFull';
|
|
||||||
import { ToastReactionFailed } from '../components/ToastReactionFailed';
|
import { ToastReactionFailed } from '../components/ToastReactionFailed';
|
||||||
import { ToastTapToViewExpiredIncoming } from '../components/ToastTapToViewExpiredIncoming';
|
import { ToastTapToViewExpiredIncoming } from '../components/ToastTapToViewExpiredIncoming';
|
||||||
import { ToastTapToViewExpiredOutgoing } from '../components/ToastTapToViewExpiredOutgoing';
|
import { ToastTapToViewExpiredOutgoing } from '../components/ToastTapToViewExpiredOutgoing';
|
||||||
|
@ -299,23 +298,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setPin(value: boolean): void {
|
|
||||||
if (value) {
|
|
||||||
const pinnedConversationIds = window.storage.get(
|
|
||||||
'pinnedConversationIds',
|
|
||||||
new Array<string>()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pinnedConversationIds.length >= 4) {
|
|
||||||
showToast(ToastPinnedConversationsFull);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.model.pin();
|
|
||||||
} else {
|
|
||||||
this.model.unpin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setupConversationView(): void {
|
setupConversationView(): void {
|
||||||
// setupHeader
|
// setupHeader
|
||||||
const conversationHeaderProps = {
|
const conversationHeaderProps = {
|
||||||
|
@ -325,7 +307,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
const { searchInConversation } = window.reduxActions.search;
|
const { searchInConversation } = window.reduxActions.search;
|
||||||
searchInConversation(this.model.id);
|
searchInConversation(this.model.id);
|
||||||
},
|
},
|
||||||
onSetPin: this.setPin.bind(this),
|
|
||||||
onShowConversationDetails: () => {
|
onShowConversationDetails: () => {
|
||||||
this.showConversationDetails();
|
this.showConversationDetails();
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue