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({});
 | 
			
		||||
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 🏔',
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,6 +105,10 @@ export function ToastManager({
 | 
			
		|||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (toastType === ToastType.PinnedConversationsFull) {
 | 
			
		||||
    return <Toast onClose={hideToast}>{i18n('pinnedConversationsFull')}</Toast>;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (toastType === ToastType.StoryMuted) {
 | 
			
		||||
    return (
 | 
			
		||||
      <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'),
 | 
			
		||||
  onMarkUnread: action('onMarkUnread'),
 | 
			
		||||
  onMoveToInbox: action('onMoveToInbox'),
 | 
			
		||||
  onSetPin: action('onSetPin'),
 | 
			
		||||
  setMuteExpiration: action('onSetMuteNotifications'),
 | 
			
		||||
  setPinned: action('setPinned'),
 | 
			
		||||
  viewUserStories: action('viewUserStories'),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<PropsType, StateType> {
 | 
			
		|||
      onArchive,
 | 
			
		||||
      onMarkUnread,
 | 
			
		||||
      onMoveToInbox,
 | 
			
		||||
      onSetPin,
 | 
			
		||||
      onShowAllMedia,
 | 
			
		||||
      onShowConversationDetails,
 | 
			
		||||
      onShowGroupMembers,
 | 
			
		||||
      setDisappearingMessages,
 | 
			
		||||
      setMuteExpiration,
 | 
			
		||||
      setPinned,
 | 
			
		||||
      type,
 | 
			
		||||
    } = this.props;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -502,11 +502,11 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
 | 
			
		|||
          {i18n('deleteMessages')}
 | 
			
		||||
        </MenuItem>
 | 
			
		||||
        {isPinned ? (
 | 
			
		||||
          <MenuItem onClick={() => onSetPin(false)}>
 | 
			
		||||
          <MenuItem onClick={() => setPinned(id, false)}>
 | 
			
		||||
            {i18n('unpinConversation')}
 | 
			
		||||
          </MenuItem>
 | 
			
		||||
        ) : (
 | 
			
		||||
          <MenuItem onClick={() => onSetPin(true)}>
 | 
			
		||||
          <MenuItem onClick={() => setPinned(id, true)}>
 | 
			
		||||
            {i18n('pinConversation')}
 | 
			
		||||
          </MenuItem>
 | 
			
		||||
        )}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<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(
 | 
			
		||||
  conversationId: string
 | 
			
		||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ export enum ToastType {
 | 
			
		|||
  Error = 'Error',
 | 
			
		||||
  FailedToDeleteUsername = 'FailedToDeleteUsername',
 | 
			
		||||
  MessageBodyTooLong = 'MessageBodyTooLong',
 | 
			
		||||
  PinnedConversationsFull = 'PinnedConversationsFull',
 | 
			
		||||
  ReportedSpamAndBlocked = 'ReportedSpamAndBlocked',
 | 
			
		||||
  StoryMuted = 'StoryMuted',
 | 
			
		||||
  StoryReact = 'StoryReact',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,6 @@ export type OwnProps = {
 | 
			
		|||
  onMarkUnread: () => void;
 | 
			
		||||
  onMoveToInbox: () => void;
 | 
			
		||||
  onSearchInConversation: () => void;
 | 
			
		||||
  onSetPin: (value: boolean) => void;
 | 
			
		||||
  onShowAllMedia: () => void;
 | 
			
		||||
  onShowConversationDetails: () => void;
 | 
			
		||||
  onShowGroupMembers: () => void;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<ConversationModel> {
 | 
			
		|||
    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 {
 | 
			
		||||
    // setupHeader
 | 
			
		||||
    const conversationHeaderProps = {
 | 
			
		||||
| 
						 | 
				
			
			@ -325,7 +307,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
 | 
			
		|||
        const { searchInConversation } = window.reduxActions.search;
 | 
			
		||||
        searchInConversation(this.model.id);
 | 
			
		||||
      },
 | 
			
		||||
      onSetPin: this.setPin.bind(this),
 | 
			
		||||
      onShowConversationDetails: () => {
 | 
			
		||||
        this.showConversationDetails();
 | 
			
		||||
      },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue