Removes ToastView, new React toast
This commit is contained in:
parent
024a3521e1
commit
e6d952d105
89 changed files with 1854 additions and 676 deletions
|
@ -76,15 +76,12 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="toast"></div>
|
||||
</div>
|
||||
<div class='lightbox-container'></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-tmpl-mustache" id="toast">
|
||||
{{ toastMessage }}
|
||||
</script>
|
||||
|
||||
<script type="text/x-tmpl-mustache" id="conversation">
|
||||
<div class='conversation-header'></div>
|
||||
<div class='main panel'>
|
||||
|
@ -114,11 +111,6 @@
|
|||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-tmpl-mustache" id="file-size-modal">
|
||||
{{ file-size-warning }}
|
||||
({{ limit }}{{ units }})
|
||||
</script>
|
||||
|
||||
<script type="text/x-tmpl-mustache" id="group-member-list">
|
||||
<div class='container' tabindex='0'>
|
||||
{{ #summary }} <div class='summary'>{{ summary }}</div>{{ /summary }}
|
||||
|
|
|
@ -33,7 +33,6 @@ window.getEnvironment = getEnvironment;
|
|||
|
||||
window.Backbone = require('backbone');
|
||||
require('./ts/backbone/views/whisper_view');
|
||||
require('./ts/backbone/views/toast_view');
|
||||
require('./ts/logging/set_up_renderer_logging').initialize();
|
||||
require('./ts/views/debug_log_view');
|
||||
|
||||
|
|
|
@ -464,7 +464,6 @@ try {
|
|||
require('./ts/models/conversations');
|
||||
|
||||
require('./ts/backbone/views/whisper_view');
|
||||
require('./ts/backbone/views/toast_view');
|
||||
require('./ts/views/conversation_view');
|
||||
require('./ts/views/inbox_view');
|
||||
require('./ts/views/install_view');
|
||||
|
|
|
@ -209,41 +209,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.toast {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
bottom: 62px;
|
||||
|
||||
text-align: center;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
border-radius: 4px;
|
||||
z-index: 100;
|
||||
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
letter-spacing: 0;
|
||||
|
||||
@include light-theme {
|
||||
background-color: $color-gray-75;
|
||||
color: $color-white;
|
||||
box-shadow: 0 4px 16px 0 $color-black-alpha-20,
|
||||
0 0 0 0.5px $color-black-alpha-05;
|
||||
}
|
||||
@include dark-theme {
|
||||
background-color: $color-gray-45;
|
||||
color: $color-white;
|
||||
box-shadow: 0 4px 16px 0 $color-white-alpha-20;
|
||||
}
|
||||
}
|
||||
|
||||
.toast-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.permissions-popup,
|
||||
.debug-log-window {
|
||||
.modal {
|
||||
|
|
31
stylesheets/components/Toast.scss
Normal file
31
stylesheets/components/Toast.scss
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
.Toast {
|
||||
@include font-body-2;
|
||||
|
||||
border-radius: 4px;
|
||||
bottom: 62px;
|
||||
left: 50%;
|
||||
padding: 8px 16px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: 100;
|
||||
|
||||
@include light-theme {
|
||||
background-color: $color-gray-75;
|
||||
color: $color-white;
|
||||
box-shadow: 0 4px 16px 0 $color-black-alpha-20,
|
||||
0 0 0 0.5px $color-black-alpha-05;
|
||||
}
|
||||
@include dark-theme {
|
||||
background-color: $color-gray-45;
|
||||
color: $color-white;
|
||||
box-shadow: 0 4px 16px 0 $color-white-alpha-20;
|
||||
}
|
||||
|
||||
&--clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
|
@ -83,6 +83,7 @@
|
|||
@import './components/Slider.scss';
|
||||
@import './components/SystemMessage.scss';
|
||||
@import './components/Tabs.scss';
|
||||
@import './components/Toast.scss';
|
||||
@import './components/TimelineWarning.scss';
|
||||
@import './components/TimelineWarnings.scss';
|
||||
@import './components/WhatsNew.scss';
|
||||
|
|
|
@ -50,10 +50,6 @@
|
|||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-tmpl-mustache" id="toast">
|
||||
{{ toastMessage }}
|
||||
</script>
|
||||
|
||||
<script type="text/x-tmpl-mustache" id="conversation">
|
||||
<div class='conversation-header'></div>
|
||||
<div class='main panel'>
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2015-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
window.Whisper.ToastView = window.Whisper.View.extend({
|
||||
className: 'toast',
|
||||
template: () => $('#toast').html(),
|
||||
initialize() {
|
||||
this.$el.hide();
|
||||
this.timeout = 2000;
|
||||
},
|
||||
|
||||
close() {
|
||||
this.$el.fadeOut(this.remove.bind(this));
|
||||
},
|
||||
|
||||
render() {
|
||||
this.$el.html(
|
||||
window.Mustache.render(
|
||||
window._.result(this, 'template', ''),
|
||||
window._.result(this, 'render_attributes', '')
|
||||
)
|
||||
);
|
||||
this.$el.attr('tabIndex', 0);
|
||||
this.$el.show();
|
||||
setTimeout(this.close.bind(this), this.timeout);
|
||||
},
|
||||
});
|
||||
|
||||
window.Whisper.ToastView.show = (View, el) => {
|
||||
const toast = new View();
|
||||
toast.$el.appendTo(el);
|
||||
toast.render();
|
||||
};
|
|
@ -104,6 +104,11 @@ import {
|
|||
getEmojiReducerState,
|
||||
} from './util/loadRecentEmojis';
|
||||
import { deleteAllLogs } from './util/deleteAllLogs';
|
||||
import { ToastCaptchaFailed } from './components/ToastCaptchaFailed';
|
||||
import { ToastCaptchaSolved } from './components/ToastCaptchaSolved';
|
||||
import { ToastConversationArchived } from './components/ToastConversationArchived';
|
||||
import { ToastConversationUnarchived } from './components/ToastConversationUnarchived';
|
||||
import { showToast } from './util/showToast';
|
||||
|
||||
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
|
||||
|
||||
|
@ -1405,10 +1410,7 @@ export async function startApp(): Promise<void> {
|
|||
) {
|
||||
conversation.setArchived(true);
|
||||
conversation.trigger('unload', 'keyboard shortcut archive');
|
||||
window.Whisper.ToastView.show(
|
||||
window.Whisper.ConversationArchivedToast,
|
||||
document.body
|
||||
);
|
||||
showToast(ToastConversationArchived);
|
||||
|
||||
// It's very likely that the act of archiving a conversation will set focus to
|
||||
// 'none,' or the top-level body element. This resets it to the left pane.
|
||||
|
@ -1433,10 +1435,7 @@ export async function startApp(): Promise<void> {
|
|||
(key === 'u' || key === 'U')
|
||||
) {
|
||||
conversation.setArchived(false);
|
||||
window.Whisper.ToastView.show(
|
||||
window.Whisper.ConversationUnarchivedToast,
|
||||
document.body
|
||||
);
|
||||
showToast(ToastConversationUnarchived);
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
@ -1660,19 +1659,11 @@ export async function startApp(): Promise<void> {
|
|||
onChallengeFailed() {
|
||||
// TODO: DESKTOP-1530
|
||||
// Display humanized `retryAfter`
|
||||
window.Whisper.ToastView.show(
|
||||
window.Whisper.CaptchaFailedToast,
|
||||
document.getElementsByClassName('conversation-stack')[0] ||
|
||||
document.body
|
||||
);
|
||||
showToast(ToastCaptchaFailed);
|
||||
},
|
||||
|
||||
onChallengeSolved() {
|
||||
window.Whisper.ToastView.show(
|
||||
window.Whisper.CaptchaSolvedToast,
|
||||
document.getElementsByClassName('conversation-stack')[0] ||
|
||||
document.body
|
||||
);
|
||||
showToast(ToastCaptchaSolved);
|
||||
},
|
||||
|
||||
setChallengeStatus(challengeStatus) {
|
||||
|
|
83
ts/components/Toast.tsx
Normal file
83
ts/components/Toast.tsx
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { KeyboardEvent, ReactNode, useEffect } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { onTimeout, removeTimeout } from '../services/timers';
|
||||
|
||||
export type PropsType = {
|
||||
autoDismissDisabled?: boolean;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
onClick?: () => unknown;
|
||||
onClose: () => unknown;
|
||||
timeout?: number;
|
||||
};
|
||||
|
||||
export const Toast = ({
|
||||
autoDismissDisabled = false,
|
||||
children,
|
||||
className,
|
||||
onClick,
|
||||
onClose,
|
||||
timeout = 2000,
|
||||
}: PropsType): JSX.Element | null => {
|
||||
const [root, setRoot] = React.useState<HTMLElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
setRoot(div);
|
||||
|
||||
return () => {
|
||||
document.body.removeChild(div);
|
||||
setRoot(null);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!root || autoDismissDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const timeoutId = onTimeout(Date.now() + timeout, onClose);
|
||||
|
||||
return () => {
|
||||
if (timeoutId) {
|
||||
removeTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
}, [autoDismissDisabled, onClose, root, timeout]);
|
||||
|
||||
let interactivityProps = {};
|
||||
if (onClick) {
|
||||
interactivityProps = {
|
||||
role: 'button',
|
||||
onClick() {
|
||||
onClick();
|
||||
},
|
||||
onKeyDown(ev: KeyboardEvent<HTMLDivElement>) {
|
||||
if (ev.key === 'Enter' || ev.key === ' ') {
|
||||
onClick();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return root
|
||||
? createPortal(
|
||||
<div
|
||||
className={classNames(
|
||||
'Toast',
|
||||
onClick ? 'Toast--clickable' : null,
|
||||
className
|
||||
)}
|
||||
{...interactivityProps}
|
||||
>
|
||||
{children}
|
||||
</div>,
|
||||
root
|
||||
)
|
||||
: null;
|
||||
};
|
23
ts/components/ToastAlreadyGroupMember.stories.tsx
Normal file
23
ts/components/ToastAlreadyGroupMember.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastAlreadyGroupMember } from './ToastAlreadyGroupMember';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastAlreadyGroupMember', module);
|
||||
|
||||
story.add('ToastAlreadyGroupMember', () => (
|
||||
<ToastAlreadyGroupMember {...defaultProps} />
|
||||
));
|
20
ts/components/ToastAlreadyGroupMember.tsx
Normal file
20
ts/components/ToastAlreadyGroupMember.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastAlreadyGroupMember = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>{i18n('GroupV2--join--already-in-group')}</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastAlreadyRequestedToJoin.stories.tsx
Normal file
23
ts/components/ToastAlreadyRequestedToJoin.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastAlreadyRequestedToJoin } from './ToastAlreadyRequestedToJoin';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastAlreadyRequestedToJoin', module);
|
||||
|
||||
story.add('ToastAlreadyRequestedToJoin', () => (
|
||||
<ToastAlreadyRequestedToJoin {...defaultProps} />
|
||||
));
|
22
ts/components/ToastAlreadyRequestedToJoin.tsx
Normal file
22
ts/components/ToastAlreadyRequestedToJoin.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastAlreadyRequestedToJoin = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>
|
||||
{i18n('GroupV2--join--already-awaiting-approval')}
|
||||
</Toast>
|
||||
);
|
||||
};
|
21
ts/components/ToastBlocked.stories.tsx
Normal file
21
ts/components/ToastBlocked.stories.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastBlocked } from './ToastBlocked';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastBlocked', module);
|
||||
|
||||
story.add('ToastBlocked', () => <ToastBlocked {...defaultProps} />);
|
15
ts/components/ToastBlocked.tsx
Normal file
15
ts/components/ToastBlocked.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastBlocked = ({ i18n, onClose }: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('unblockToSend')}</Toast>;
|
||||
};
|
21
ts/components/ToastBlockedGroup.stories.tsx
Normal file
21
ts/components/ToastBlockedGroup.stories.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastBlockedGroup } from './ToastBlockedGroup';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastBlockedGroup', module);
|
||||
|
||||
story.add('ToastBlockedGroup', () => <ToastBlockedGroup {...defaultProps} />);
|
18
ts/components/ToastBlockedGroup.tsx
Normal file
18
ts/components/ToastBlockedGroup.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastBlockedGroup = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('unblockGroupToSend')}</Toast>;
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastCannotMixImageAndNonImageAttachments } from './ToastCannotMixImageAndNonImageAttachments';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf(
|
||||
'Components/ToastCannotMixImageAndNonImageAttachments',
|
||||
module
|
||||
);
|
||||
|
||||
story.add('ToastCannotMixImageAndNonImageAttachments', () => (
|
||||
<ToastCannotMixImageAndNonImageAttachments {...defaultProps} />
|
||||
));
|
22
ts/components/ToastCannotMixImageAndNonImageAttachments.tsx
Normal file
22
ts/components/ToastCannotMixImageAndNonImageAttachments.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastCannotMixImageAndNonImageAttachments = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>
|
||||
{i18n('cannotMixImageAndNonImageAttachments')}
|
||||
</Toast>
|
||||
);
|
||||
};
|
20
ts/components/ToastCannotStartGroupCall.tsx
Normal file
20
ts/components/ToastCannotStartGroupCall.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastCannotStartGroupCall = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>{i18n('GroupV2--cannot-start-group-call')}</Toast>
|
||||
);
|
||||
};
|
21
ts/components/ToastCaptchaFailed.stories.tsx
Normal file
21
ts/components/ToastCaptchaFailed.stories.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastCaptchaFailed } from './ToastCaptchaFailed';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastCaptchaFailed', module);
|
||||
|
||||
story.add('ToastCaptchaFailed', () => <ToastCaptchaFailed {...defaultProps} />);
|
18
ts/components/ToastCaptchaFailed.tsx
Normal file
18
ts/components/ToastCaptchaFailed.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastCaptchaFailed = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('verificationFailed')}</Toast>;
|
||||
};
|
21
ts/components/ToastCaptchaSolved.stories.tsx
Normal file
21
ts/components/ToastCaptchaSolved.stories.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastCaptchaSolved } from './ToastCaptchaSolved';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastCaptchaSolved', module);
|
||||
|
||||
story.add('ToastCaptchaSolved', () => <ToastCaptchaSolved {...defaultProps} />);
|
18
ts/components/ToastCaptchaSolved.tsx
Normal file
18
ts/components/ToastCaptchaSolved.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastCaptchaSolved = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('verificationComplete')}</Toast>;
|
||||
};
|
23
ts/components/ToastConversationArchived.stories.tsx
Normal file
23
ts/components/ToastConversationArchived.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastConversationArchived } from './ToastConversationArchived';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastConversationArchived', module);
|
||||
|
||||
story.add('ToastConversationArchived', () => (
|
||||
<ToastConversationArchived {...defaultProps} />
|
||||
));
|
18
ts/components/ToastConversationArchived.tsx
Normal file
18
ts/components/ToastConversationArchived.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastConversationArchived = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('conversationArchived')}</Toast>;
|
||||
};
|
23
ts/components/ToastConversationMarkedUnread.stories.tsx
Normal file
23
ts/components/ToastConversationMarkedUnread.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastConversationMarkedUnread } from './ToastConversationMarkedUnread';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastConversationMarkedUnread', module);
|
||||
|
||||
story.add('ToastConversationMarkedUnread', () => (
|
||||
<ToastConversationMarkedUnread {...defaultProps} />
|
||||
));
|
18
ts/components/ToastConversationMarkedUnread.tsx
Normal file
18
ts/components/ToastConversationMarkedUnread.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastConversationMarkedUnread = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('conversationMarkedUnread')}</Toast>;
|
||||
};
|
23
ts/components/ToastConversationUnarchived.stories.tsx
Normal file
23
ts/components/ToastConversationUnarchived.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastConversationUnarchived } from './ToastConversationUnarchived';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastConversationUnarchived', module);
|
||||
|
||||
story.add('ToastConversationUnarchived', () => (
|
||||
<ToastConversationUnarchived {...defaultProps} />
|
||||
));
|
18
ts/components/ToastConversationUnarchived.tsx
Normal file
18
ts/components/ToastConversationUnarchived.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastConversationUnarchived = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('conversationReturnedToInbox')}</Toast>;
|
||||
};
|
23
ts/components/ToastDangerousFileType.stories.tsx
Normal file
23
ts/components/ToastDangerousFileType.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastDangerousFileType } from './ToastDangerousFileType';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastDangerousFileType', module);
|
||||
|
||||
story.add('ToastDangerousFileType', () => (
|
||||
<ToastDangerousFileType {...defaultProps} />
|
||||
));
|
18
ts/components/ToastDangerousFileType.tsx
Normal file
18
ts/components/ToastDangerousFileType.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastDangerousFileType = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('dangerousFileType')}</Toast>;
|
||||
};
|
24
ts/components/ToastDecryptionError.stories.tsx
Normal file
24
ts/components/ToastDecryptionError.stories.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastDecryptionError } from './ToastDecryptionError';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
onShowDebugLog: action('onShowDebugLog'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastDecryptionError', module);
|
||||
|
||||
story.add('ToastDecryptionError', () => (
|
||||
<ToastDecryptionError {...defaultProps} />
|
||||
));
|
32
ts/components/ToastDecryptionError.tsx
Normal file
32
ts/components/ToastDecryptionError.tsx
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
export type ToastPropsType = {
|
||||
onShowDebugLog: () => unknown;
|
||||
};
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
} & ToastPropsType;
|
||||
|
||||
export const ToastDecryptionError = ({
|
||||
i18n,
|
||||
onClose,
|
||||
onShowDebugLog,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast
|
||||
autoDismissDisabled
|
||||
className="decryption-error"
|
||||
onClick={onShowDebugLog}
|
||||
onClose={onClose}
|
||||
>
|
||||
{i18n('decryptionErrorToast')}
|
||||
</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastDeleteForEveryoneFailed.stories.tsx
Normal file
23
ts/components/ToastDeleteForEveryoneFailed.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastDeleteForEveryoneFailed } from './ToastDeleteForEveryoneFailed';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastDeleteForEveryoneFailed', module);
|
||||
|
||||
story.add('ToastDeleteForEveryoneFailed', () => (
|
||||
<ToastDeleteForEveryoneFailed {...defaultProps} />
|
||||
));
|
18
ts/components/ToastDeleteForEveryoneFailed.tsx
Normal file
18
ts/components/ToastDeleteForEveryoneFailed.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastDeleteForEveryoneFailed = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('deleteForEveryoneFailed')}</Toast>;
|
||||
};
|
21
ts/components/ToastExpired.stories.tsx
Normal file
21
ts/components/ToastExpired.stories.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastExpired } from './ToastExpired';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastExpired', module);
|
||||
|
||||
story.add('ToastExpired', () => <ToastExpired {...defaultProps} />);
|
15
ts/components/ToastExpired.tsx
Normal file
15
ts/components/ToastExpired.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastExpired = ({ i18n, onClose }: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('expiredWarning')}</Toast>;
|
||||
};
|
22
ts/components/ToastFileSaved.stories.tsx
Normal file
22
ts/components/ToastFileSaved.stories.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastFileSaved } from './ToastFileSaved';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
onOpenFile: action('onOpenFile'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastFileSaved', module);
|
||||
|
||||
story.add('ToastFileSaved', () => <ToastFileSaved {...defaultProps} />);
|
27
ts/components/ToastFileSaved.tsx
Normal file
27
ts/components/ToastFileSaved.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
export type ToastPropsType = {
|
||||
onOpenFile: () => unknown;
|
||||
};
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
} & ToastPropsType;
|
||||
|
||||
export const ToastFileSaved = ({
|
||||
i18n,
|
||||
onClose,
|
||||
onOpenFile,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClick={onOpenFile} onClose={onClose}>
|
||||
{i18n('attachmentSaved')}
|
||||
</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastFileSize.stories.tsx
Normal file
23
ts/components/ToastFileSize.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastFileSize } from './ToastFileSize';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastFileSize', module);
|
||||
|
||||
story.add('ToastFileSize', () => (
|
||||
<ToastFileSize {...defaultProps} limit={100} units="MB" />
|
||||
));
|
31
ts/components/ToastFileSize.tsx
Normal file
31
ts/components/ToastFileSize.tsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
export type ToastPropsType = {
|
||||
limit: number;
|
||||
units: string;
|
||||
};
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
} & ToastPropsType;
|
||||
|
||||
export const ToastFileSize = ({
|
||||
i18n,
|
||||
limit,
|
||||
onClose,
|
||||
units,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>
|
||||
{i18n('fileSizeWarning')}
|
||||
{limit}
|
||||
{units}
|
||||
</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastGroupLinkCopied.stories.tsx
Normal file
23
ts/components/ToastGroupLinkCopied.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastGroupLinkCopied } from './ToastGroupLinkCopied';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastGroupLinkCopied', module);
|
||||
|
||||
story.add('ToastGroupLinkCopied', () => (
|
||||
<ToastGroupLinkCopied {...defaultProps} />
|
||||
));
|
20
ts/components/ToastGroupLinkCopied.tsx
Normal file
20
ts/components/ToastGroupLinkCopied.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastGroupLinkCopied = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>{i18n('GroupLinkManagement--clipboard')}</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastInvalidConversation.stories.tsx
Normal file
23
ts/components/ToastInvalidConversation.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastInvalidConversation } from './ToastInvalidConversation';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastInvalidConversation', module);
|
||||
|
||||
story.add('ToastInvalidConversation', () => (
|
||||
<ToastInvalidConversation {...defaultProps} />
|
||||
));
|
18
ts/components/ToastInvalidConversation.tsx
Normal file
18
ts/components/ToastInvalidConversation.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastInvalidConversation = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('invalidConversation')}</Toast>;
|
||||
};
|
21
ts/components/ToastLeftGroup.stories.tsx
Normal file
21
ts/components/ToastLeftGroup.stories.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastLeftGroup } from './ToastLeftGroup';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastLeftGroup', module);
|
||||
|
||||
story.add('ToastLeftGroup', () => <ToastLeftGroup {...defaultProps} />);
|
15
ts/components/ToastLeftGroup.tsx
Normal file
15
ts/components/ToastLeftGroup.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastLeftGroup = ({ i18n, onClose }: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('youLeftTheGroup')}</Toast>;
|
||||
};
|
21
ts/components/ToastLinkCopied.stories.tsx
Normal file
21
ts/components/ToastLinkCopied.stories.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastLinkCopied } from './ToastLinkCopied';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastLinkCopied', module);
|
||||
|
||||
story.add('ToastLinkCopied', () => <ToastLinkCopied {...defaultProps} />);
|
15
ts/components/ToastLinkCopied.tsx
Normal file
15
ts/components/ToastLinkCopied.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastLinkCopied = ({ i18n, onClose }: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('debugLogLinkCopied')}</Toast>;
|
||||
};
|
23
ts/components/ToastLoadingFullLogs.stories.tsx
Normal file
23
ts/components/ToastLoadingFullLogs.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastLoadingFullLogs } from './ToastLoadingFullLogs';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastLoadingFullLogs', module);
|
||||
|
||||
story.add('ToastLoadingFullLogs', () => (
|
||||
<ToastLoadingFullLogs {...defaultProps} />
|
||||
));
|
18
ts/components/ToastLoadingFullLogs.tsx
Normal file
18
ts/components/ToastLoadingFullLogs.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastLoadingFullLogs = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('loading')}</Toast>;
|
||||
};
|
23
ts/components/ToastMaxAttachments.stories.tsx
Normal file
23
ts/components/ToastMaxAttachments.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastMaxAttachments } from './ToastMaxAttachments';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastMaxAttachments', module);
|
||||
|
||||
story.add('ToastMaxAttachments', () => (
|
||||
<ToastMaxAttachments {...defaultProps} />
|
||||
));
|
18
ts/components/ToastMaxAttachments.tsx
Normal file
18
ts/components/ToastMaxAttachments.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastMaxAttachments = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('maximumAttachments')}</Toast>;
|
||||
};
|
23
ts/components/ToastMessageBodyTooLong.stories.tsx
Normal file
23
ts/components/ToastMessageBodyTooLong.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastMessageBodyTooLong } from './ToastMessageBodyTooLong';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastMessageBodyTooLong', module);
|
||||
|
||||
story.add('ToastMessageBodyTooLong', () => (
|
||||
<ToastMessageBodyTooLong {...defaultProps} />
|
||||
));
|
18
ts/components/ToastMessageBodyTooLong.tsx
Normal file
18
ts/components/ToastMessageBodyTooLong.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastMessageBodyTooLong = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('messageBodyTooLong')}</Toast>;
|
||||
};
|
23
ts/components/ToastOneNonImageAtATime.stories.tsx
Normal file
23
ts/components/ToastOneNonImageAtATime.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastOneNonImageAtATime } from './ToastOneNonImageAtATime';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastOneNonImageAtATime', module);
|
||||
|
||||
story.add('ToastOneNonImageAtATime', () => (
|
||||
<ToastOneNonImageAtATime {...defaultProps} />
|
||||
));
|
18
ts/components/ToastOneNonImageAtATime.tsx
Normal file
18
ts/components/ToastOneNonImageAtATime.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastOneNonImageAtATime = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('oneNonImageAtATimeToast')}</Toast>;
|
||||
};
|
23
ts/components/ToastOriginalMessageNotFound.stories.tsx
Normal file
23
ts/components/ToastOriginalMessageNotFound.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastOriginalMessageNotFound } from './ToastOriginalMessageNotFound';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastOriginalMessageNotFound', module);
|
||||
|
||||
story.add('ToastOriginalMessageNotFound', () => (
|
||||
<ToastOriginalMessageNotFound {...defaultProps} />
|
||||
));
|
18
ts/components/ToastOriginalMessageNotFound.tsx
Normal file
18
ts/components/ToastOriginalMessageNotFound.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastOriginalMessageNotFound = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('originalMessageNotFound')}</Toast>;
|
||||
};
|
23
ts/components/ToastPinnedConversationsFull.stories.tsx
Normal file
23
ts/components/ToastPinnedConversationsFull.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/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'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastPinnedConversationsFull', module);
|
||||
|
||||
story.add('ToastPinnedConversationsFull', () => (
|
||||
<ToastPinnedConversationsFull {...defaultProps} />
|
||||
));
|
18
ts/components/ToastPinnedConversationsFull.tsx
Normal file
18
ts/components/ToastPinnedConversationsFull.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastPinnedConversationsFull = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('pinnedConversationsFull')}</Toast>;
|
||||
};
|
23
ts/components/ToastReactionFailed.stories.tsx
Normal file
23
ts/components/ToastReactionFailed.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastReactionFailed } from './ToastReactionFailed';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastReactionFailed', module);
|
||||
|
||||
story.add('ToastReactionFailed', () => (
|
||||
<ToastReactionFailed {...defaultProps} />
|
||||
));
|
22
ts/components/ToastReactionFailed.tsx
Normal file
22
ts/components/ToastReactionFailed.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastReactionFailed = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClick={onClose} onClose={onClose}>
|
||||
{i18n('Reactions--error')}
|
||||
</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastReportedSpamAndBlocked.stories.tsx
Normal file
23
ts/components/ToastReportedSpamAndBlocked.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastReportedSpamAndBlocked } from './ToastReportedSpamAndBlocked';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastReportedSpamAndBlocked', module);
|
||||
|
||||
story.add('ToastReportedSpamAndBlocked', () => (
|
||||
<ToastReportedSpamAndBlocked {...defaultProps} />
|
||||
));
|
22
ts/components/ToastReportedSpamAndBlocked.tsx
Normal file
22
ts/components/ToastReportedSpamAndBlocked.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastReportedSpamAndBlocked = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>
|
||||
{i18n('MessageRequests--block-and-report-spam-success-toast')}
|
||||
</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastStickerPackInstallFailed.stories.tsx
Normal file
23
ts/components/ToastStickerPackInstallFailed.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastStickerPackInstallFailed } from './ToastStickerPackInstallFailed';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastStickerPackInstallFailed', module);
|
||||
|
||||
story.add('ToastStickerPackInstallFailed', () => (
|
||||
<ToastStickerPackInstallFailed {...defaultProps} />
|
||||
));
|
20
ts/components/ToastStickerPackInstallFailed.tsx
Normal file
20
ts/components/ToastStickerPackInstallFailed.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastStickerPackInstallFailed = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>{i18n('stickers--toast--InstallFailed')}</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastTapToViewExpiredIncoming.stories.tsx
Normal file
23
ts/components/ToastTapToViewExpiredIncoming.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastTapToViewExpiredIncoming } from './ToastTapToViewExpiredIncoming';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastTapToViewExpiredIncoming', module);
|
||||
|
||||
story.add('ToastTapToViewExpiredIncoming', () => (
|
||||
<ToastTapToViewExpiredIncoming {...defaultProps} />
|
||||
));
|
22
ts/components/ToastTapToViewExpiredIncoming.tsx
Normal file
22
ts/components/ToastTapToViewExpiredIncoming.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastTapToViewExpiredIncoming = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>
|
||||
{i18n('Message--tap-to-view--incoming--expired-toast')}
|
||||
</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastTapToViewExpiredOutgoing.stories.tsx
Normal file
23
ts/components/ToastTapToViewExpiredOutgoing.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastTapToViewExpiredOutgoing } from './ToastTapToViewExpiredOutgoing';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastTapToViewExpiredOutgoing', module);
|
||||
|
||||
story.add('ToastTapToViewExpiredOutgoing', () => (
|
||||
<ToastTapToViewExpiredOutgoing {...defaultProps} />
|
||||
));
|
22
ts/components/ToastTapToViewExpiredOutgoing.tsx
Normal file
22
ts/components/ToastTapToViewExpiredOutgoing.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastTapToViewExpiredOutgoing = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>
|
||||
{i18n('Message--tap-to-view--outgoing--expired-toast')}
|
||||
</Toast>
|
||||
);
|
||||
};
|
23
ts/components/ToastUnableToLoadAttachment.stories.tsx
Normal file
23
ts/components/ToastUnableToLoadAttachment.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastUnableToLoadAttachment } from './ToastUnableToLoadAttachment';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastUnableToLoadAttachment', module);
|
||||
|
||||
story.add('ToastUnableToLoadAttachment', () => (
|
||||
<ToastUnableToLoadAttachment {...defaultProps} />
|
||||
));
|
18
ts/components/ToastUnableToLoadAttachment.tsx
Normal file
18
ts/components/ToastUnableToLoadAttachment.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastUnableToLoadAttachment = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('unableToLoadAttachment')}</Toast>;
|
||||
};
|
23
ts/components/ToastVoiceNoteLimit.stories.tsx
Normal file
23
ts/components/ToastVoiceNoteLimit.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastVoiceNoteLimit } from './ToastVoiceNoteLimit';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf('Components/ToastVoiceNoteLimit', module);
|
||||
|
||||
story.add('ToastVoiceNoteLimit', () => (
|
||||
<ToastVoiceNoteLimit {...defaultProps} />
|
||||
));
|
18
ts/components/ToastVoiceNoteLimit.tsx
Normal file
18
ts/components/ToastVoiceNoteLimit.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastVoiceNoteLimit = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return <Toast onClose={onClose}>{i18n('voiceNoteLimit')}</Toast>;
|
||||
};
|
26
ts/components/ToastVoiceNoteMustBeOnlyAttachment.stories.tsx
Normal file
26
ts/components/ToastVoiceNoteMustBeOnlyAttachment.stories.tsx
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ToastVoiceNoteMustBeOnlyAttachment } from './ToastVoiceNoteMustBeOnlyAttachment';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const defaultProps = {
|
||||
i18n,
|
||||
onClose: action('onClose'),
|
||||
};
|
||||
|
||||
const story = storiesOf(
|
||||
'Components/ToastVoiceNoteMustBeOnlyAttachment',
|
||||
module
|
||||
);
|
||||
|
||||
story.add('ToastVoiceNoteMustBeOnlyAttachment', () => (
|
||||
<ToastVoiceNoteMustBeOnlyAttachment {...defaultProps} />
|
||||
));
|
20
ts/components/ToastVoiceNoteMustBeOnlyAttachment.tsx
Normal file
20
ts/components/ToastVoiceNoteMustBeOnlyAttachment.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Toast } from './Toast';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => unknown;
|
||||
};
|
||||
|
||||
export const ToastVoiceNoteMustBeOnlyAttachment = ({
|
||||
i18n,
|
||||
onClose,
|
||||
}: PropsType): JSX.Element => {
|
||||
return (
|
||||
<Toast onClose={onClose}>{i18n('voiceNoteMustBeOnlyAttachment')}</Toast>
|
||||
);
|
||||
};
|
|
@ -21,6 +21,9 @@ import type { ConversationModel } from '../models/conversations';
|
|||
import type { PreJoinConversationType } from '../state/ducks/conversations';
|
||||
import { SignalService as Proto } from '../protobuf';
|
||||
import * as log from '../logging/log';
|
||||
import { showToast } from '../util/showToast';
|
||||
import { ToastAlreadyGroupMember } from '../components/ToastAlreadyGroupMember';
|
||||
import { ToastAlreadyRequestedToJoin } from '../components/ToastAlreadyRequestedToJoin';
|
||||
|
||||
export async function joinViaLink(hash: string): Promise<void> {
|
||||
let inviteLinkPassword: string;
|
||||
|
@ -65,10 +68,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
|||
window.reduxActions.conversations.openConversationInternal({
|
||||
conversationId: existingConversation.id,
|
||||
});
|
||||
window.Whisper.ToastView.show(
|
||||
window.Whisper.AlreadyGroupMemberToast,
|
||||
document.getElementsByClassName('conversation-stack')[0]
|
||||
);
|
||||
showToast(ToastAlreadyGroupMember);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -144,10 +144,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
|||
conversationId: existingConversation.id,
|
||||
});
|
||||
|
||||
window.Whisper.ToastView.show(
|
||||
window.Whisper.AlreadyRequestedToJoinToast,
|
||||
document.getElementsByClassName('conversation-stack')[0]
|
||||
);
|
||||
showToast(ToastAlreadyRequestedToJoin);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
10
ts/util/copyGroupLink.ts
Normal file
10
ts/util/copyGroupLink.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { showToast } from './showToast';
|
||||
import { ToastGroupLinkCopied } from '../components/ToastGroupLinkCopied';
|
||||
|
||||
export async function copyGroupLink(groupLink: string): Promise<void> {
|
||||
await window.navigator.clipboard.writeText(groupLink);
|
||||
showToast(ToastGroupLinkCopied);
|
||||
}
|
|
@ -17,6 +17,8 @@ import { parseIntOrThrow } from './parseIntOrThrow';
|
|||
import * as RemoteConfig from '../RemoteConfig';
|
||||
import { Address } from '../types/Address';
|
||||
import { QualifiedAddress } from '../types/QualifiedAddress';
|
||||
import { ToastDecryptionError } from '../components/ToastDecryptionError';
|
||||
import { showToast } from './showToast';
|
||||
|
||||
import { ConversationModel } from '../models/conversations';
|
||||
import {
|
||||
|
@ -131,10 +133,9 @@ function maybeShowDecryptionToast(logId: string) {
|
|||
}
|
||||
|
||||
log.info(`maybeShowDecryptionToast/${logId}: Showing decryption error toast`);
|
||||
window.Whisper.ToastView.show(
|
||||
window.Whisper.DecryptionErrorToast,
|
||||
document.getElementsByClassName('conversation-stack')[0]
|
||||
);
|
||||
showToast(ToastDecryptionError, {
|
||||
onShowDebugLog: () => window.showDebugLog(),
|
||||
});
|
||||
}
|
||||
|
||||
export async function onDecryptionError(
|
||||
|
|
33
ts/util/isAttachmentSizeOkay.ts
Normal file
33
ts/util/isAttachmentSizeOkay.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { AttachmentType } from '../types/Attachment';
|
||||
import { showToast } from './showToast';
|
||||
import { ToastFileSize } from '../components/ToastFileSize';
|
||||
|
||||
export function isAttachmentSizeOkay(
|
||||
attachment: Readonly<AttachmentType>
|
||||
): boolean {
|
||||
const limitKb = window.Signal.Types.Attachment.getUploadSizeLimitKb(
|
||||
attachment.contentType
|
||||
);
|
||||
// this needs to be cast properly
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
if ((attachment.data.byteLength / 1024).toFixed(4) >= limitKb) {
|
||||
const units = ['kB', 'MB', 'GB'];
|
||||
let u = -1;
|
||||
let limit = limitKb * 1000;
|
||||
do {
|
||||
limit /= 1000;
|
||||
u += 1;
|
||||
} while (limit >= 1000 && u < units.length - 1);
|
||||
showToast(ToastFileSize, {
|
||||
limit,
|
||||
units: units[u],
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -12076,69 +12076,6 @@
|
|||
"updated": "2018-09-17T20:50:40.689Z",
|
||||
"reasonDetail": "Hard-coded value"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/backbone/views/toast_view.js",
|
||||
"line": " template: () => $('#toast').html(),",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-02-26T19:21:25.912Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-appendTo(",
|
||||
"path": "ts/backbone/views/toast_view.js",
|
||||
"line": " toast.$el.appendTo(el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-02-26T18:44:56.450Z",
|
||||
"reasonDetail": "Add sub-view to DOM"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/backbone/views/toast_view.js",
|
||||
"line": " this.$el.html(window.Mustache.render(window._.result(this, 'template', ''), window._.result(this, 'render_attributes', '')));",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-02-26T18:44:56.450Z",
|
||||
"reasonDetail": "Adding Mustache render to DOM"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/backbone/views/toast_view.js",
|
||||
"line": " template: () => $('#toast').html(),",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-02-26T19:21:25.912Z",
|
||||
"reasonDetail": "Static selector, read-only access"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/backbone/views/toast_view.ts",
|
||||
"line": " template: () => $('#toast').html(),",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-02-26T18:44:56.450Z",
|
||||
"reasonDetail": "Static selector, read-only access"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-appendTo(",
|
||||
"path": "ts/backbone/views/toast_view.ts",
|
||||
"line": " toast.$el.appendTo(el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-02-26T18:44:56.450Z",
|
||||
"reasonDetail": "Adding sub-view to DOM"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/backbone/views/toast_view.ts",
|
||||
"line": " this.$el.html(",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-02-26T18:44:56.450Z",
|
||||
"reasonDetail": "Rendering provided template"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/backbone/views/toast_view.ts",
|
||||
"line": " template: () => $('#toast').html(),",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-02-26T19:23:51.217Z",
|
||||
"reasonDetail": "Static selector, read-only access"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/backbone/views/whisper_view.js",
|
||||
|
@ -13518,14 +13455,7 @@
|
|||
"path": "ts/views/inbox_view.js",
|
||||
"line": " view.$el.appendTo(this.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-appendTo(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " toast.$el.appendTo(this.$el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
"updated": "2021-09-20T22:27:31.785Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
|
@ -13646,13 +13576,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-appendTo(",
|
||||
"path": "ts/views/inbox_view.ts",
|
||||
"line": " toast.$el.appendTo(this.$el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/views/inbox_view.ts",
|
||||
|
|
115
ts/util/showToast.tsx
Normal file
115
ts/util/showToast.tsx
Normal file
|
@ -0,0 +1,115 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
|
||||
import { ToastAlreadyGroupMember } from '../components/ToastAlreadyGroupMember';
|
||||
import { ToastAlreadyRequestedToJoin } from '../components/ToastAlreadyRequestedToJoin';
|
||||
import { ToastBlocked } from '../components/ToastBlocked';
|
||||
import { ToastBlockedGroup } from '../components/ToastBlockedGroup';
|
||||
import { ToastCannotMixImageAndNonImageAttachments } from '../components/ToastCannotMixImageAndNonImageAttachments';
|
||||
import { ToastCannotStartGroupCall } from '../components/ToastCannotStartGroupCall';
|
||||
import { ToastCaptchaFailed } from '../components/ToastCaptchaFailed';
|
||||
import { ToastCaptchaSolved } from '../components/ToastCaptchaSolved';
|
||||
import { ToastConversationArchived } from '../components/ToastConversationArchived';
|
||||
import { ToastConversationMarkedUnread } from '../components/ToastConversationMarkedUnread';
|
||||
import { ToastConversationUnarchived } from '../components/ToastConversationUnarchived';
|
||||
import { ToastDangerousFileType } from '../components/ToastDangerousFileType';
|
||||
import {
|
||||
ToastDecryptionError,
|
||||
ToastPropsType as ToastDecryptionErrorPropsType,
|
||||
} from '../components/ToastDecryptionError';
|
||||
import { ToastDeleteForEveryoneFailed } from '../components/ToastDeleteForEveryoneFailed';
|
||||
import { ToastExpired } from '../components/ToastExpired';
|
||||
import {
|
||||
ToastFileSaved,
|
||||
ToastPropsType as ToastFileSavedPropsType,
|
||||
} from '../components/ToastFileSaved';
|
||||
import {
|
||||
ToastFileSize,
|
||||
ToastPropsType as ToastFileSizePropsType,
|
||||
} from '../components/ToastFileSize';
|
||||
import { ToastGroupLinkCopied } from '../components/ToastGroupLinkCopied';
|
||||
import { ToastInvalidConversation } from '../components/ToastInvalidConversation';
|
||||
import { ToastLeftGroup } from '../components/ToastLeftGroup';
|
||||
import { ToastLinkCopied } from '../components/ToastLinkCopied';
|
||||
import { ToastLoadingFullLogs } from '../components/ToastLoadingFullLogs';
|
||||
import { ToastMaxAttachments } from '../components/ToastMaxAttachments';
|
||||
import { ToastMessageBodyTooLong } from '../components/ToastMessageBodyTooLong';
|
||||
import { ToastOneNonImageAtATime } from '../components/ToastOneNonImageAtATime';
|
||||
import { ToastOriginalMessageNotFound } from '../components/ToastOriginalMessageNotFound';
|
||||
import { ToastPinnedConversationsFull } from '../components/ToastPinnedConversationsFull';
|
||||
import { ToastReactionFailed } from '../components/ToastReactionFailed';
|
||||
import { ToastReportedSpamAndBlocked } from '../components/ToastReportedSpamAndBlocked';
|
||||
import { ToastStickerPackInstallFailed } from '../components/ToastStickerPackInstallFailed';
|
||||
import { ToastTapToViewExpiredIncoming } from '../components/ToastTapToViewExpiredIncoming';
|
||||
import { ToastTapToViewExpiredOutgoing } from '../components/ToastTapToViewExpiredOutgoing';
|
||||
import { ToastUnableToLoadAttachment } from '../components/ToastUnableToLoadAttachment';
|
||||
import { ToastVoiceNoteLimit } from '../components/ToastVoiceNoteLimit';
|
||||
import { ToastVoiceNoteMustBeOnlyAttachment } from '../components/ToastVoiceNoteMustBeOnlyAttachment';
|
||||
|
||||
export function showToast(Toast: typeof ToastAlreadyGroupMember): void;
|
||||
export function showToast(Toast: typeof ToastAlreadyRequestedToJoin): void;
|
||||
export function showToast(Toast: typeof ToastBlocked): void;
|
||||
export function showToast(Toast: typeof ToastBlockedGroup): void;
|
||||
export function showToast(
|
||||
Toast: typeof ToastCannotMixImageAndNonImageAttachments
|
||||
): void;
|
||||
export function showToast(Toast: typeof ToastCannotStartGroupCall): void;
|
||||
export function showToast(Toast: typeof ToastCaptchaFailed): void;
|
||||
export function showToast(Toast: typeof ToastCaptchaSolved): void;
|
||||
export function showToast(Toast: typeof ToastConversationArchived): void;
|
||||
export function showToast(Toast: typeof ToastConversationMarkedUnread): void;
|
||||
export function showToast(Toast: typeof ToastConversationUnarchived): void;
|
||||
export function showToast(Toast: typeof ToastDangerousFileType): void;
|
||||
export function showToast(
|
||||
Toast: typeof ToastDecryptionError,
|
||||
props: ToastDecryptionErrorPropsType
|
||||
): void;
|
||||
export function showToast(Toast: typeof ToastDeleteForEveryoneFailed): void;
|
||||
export function showToast(Toast: typeof ToastExpired): void;
|
||||
export function showToast(
|
||||
Toast: typeof ToastFileSaved,
|
||||
props: ToastFileSavedPropsType
|
||||
): void;
|
||||
export function showToast(
|
||||
Toast: typeof ToastFileSize,
|
||||
props: ToastFileSizePropsType
|
||||
): void;
|
||||
export function showToast(Toast: typeof ToastGroupLinkCopied): void;
|
||||
export function showToast(Toast: typeof ToastInvalidConversation): void;
|
||||
export function showToast(Toast: typeof ToastLeftGroup): void;
|
||||
export function showToast(Toast: typeof ToastLinkCopied): void;
|
||||
export function showToast(Toast: typeof ToastLoadingFullLogs): void;
|
||||
export function showToast(Toast: typeof ToastMaxAttachments): void;
|
||||
export function showToast(Toast: typeof ToastMessageBodyTooLong): void;
|
||||
export function showToast(Toast: typeof ToastOneNonImageAtATime): 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 ToastReportedSpamAndBlocked): void;
|
||||
export function showToast(Toast: typeof ToastStickerPackInstallFailed): void;
|
||||
export function showToast(Toast: typeof ToastTapToViewExpiredIncoming): void;
|
||||
export function showToast(Toast: typeof ToastTapToViewExpiredOutgoing): void;
|
||||
export function showToast(Toast: typeof ToastUnableToLoadAttachment): void;
|
||||
export function showToast(Toast: typeof ToastVoiceNoteLimit): void;
|
||||
export function showToast(
|
||||
Toast: typeof ToastVoiceNoteMustBeOnlyAttachment
|
||||
): void;
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
||||
export function showToast(Toast: any, props = {}): void {
|
||||
const node = document.getElementById('toast');
|
||||
|
||||
function onClose() {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
unmountComponentAtNode(node);
|
||||
}
|
||||
|
||||
render(<Toast i18n={window.i18n} onClose={onClose} {...props} />, node);
|
||||
}
|
|
@ -85,6 +85,35 @@ import { dropNull } from '../util/dropNull';
|
|||
import { CompositionAPIType } from '../components/CompositionArea';
|
||||
import * as log from '../logging/log';
|
||||
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';
|
||||
import { ToastCannotStartGroupCall } from '../components/ToastCannotStartGroupCall';
|
||||
import { showToast } from '../util/showToast';
|
||||
import { ToastBlocked } from '../components/ToastBlocked';
|
||||
import { ToastBlockedGroup } from '../components/ToastBlockedGroup';
|
||||
import { ToastCannotMixImageAndNonImageAttachments } from '../components/ToastCannotMixImageAndNonImageAttachments';
|
||||
import { ToastConversationArchived } from '../components/ToastConversationArchived';
|
||||
import { ToastConversationMarkedUnread } from '../components/ToastConversationMarkedUnread';
|
||||
import { ToastConversationUnarchived } from '../components/ToastConversationUnarchived';
|
||||
import { ToastDangerousFileType } from '../components/ToastDangerousFileType';
|
||||
import { ToastDeleteForEveryoneFailed } from '../components/ToastDeleteForEveryoneFailed';
|
||||
import { ToastExpired } from '../components/ToastExpired';
|
||||
import { ToastFileSaved } from '../components/ToastFileSaved';
|
||||
import { ToastFileSize } from '../components/ToastFileSize';
|
||||
import { ToastInvalidConversation } from '../components/ToastInvalidConversation';
|
||||
import { ToastLeftGroup } from '../components/ToastLeftGroup';
|
||||
import { ToastMaxAttachments } from '../components/ToastMaxAttachments';
|
||||
import { ToastMessageBodyTooLong } from '../components/ToastMessageBodyTooLong';
|
||||
import { ToastOneNonImageAtATime } from '../components/ToastOneNonImageAtATime';
|
||||
import { ToastOriginalMessageNotFound } from '../components/ToastOriginalMessageNotFound';
|
||||
import { ToastPinnedConversationsFull } from '../components/ToastPinnedConversationsFull';
|
||||
import { ToastReactionFailed } from '../components/ToastReactionFailed';
|
||||
import { ToastReportedSpamAndBlocked } from '../components/ToastReportedSpamAndBlocked';
|
||||
import { ToastTapToViewExpiredIncoming } from '../components/ToastTapToViewExpiredIncoming';
|
||||
import { ToastTapToViewExpiredOutgoing } from '../components/ToastTapToViewExpiredOutgoing';
|
||||
import { ToastUnableToLoadAttachment } from '../components/ToastUnableToLoadAttachment';
|
||||
import { ToastVoiceNoteLimit } from '../components/ToastVoiceNoteLimit';
|
||||
import { ToastVoiceNoteMustBeOnlyAttachment } from '../components/ToastVoiceNoteMustBeOnlyAttachment';
|
||||
import { copyGroupLink } from '../util/copyGroupLink';
|
||||
import { isAttachmentSizeOkay } from '../util/isAttachmentSizeOkay';
|
||||
|
||||
type AttachmentOptions = {
|
||||
messageId: string;
|
||||
|
@ -186,314 +215,8 @@ type MediaType = {
|
|||
};
|
||||
};
|
||||
|
||||
Whisper.ExpiredToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('expiredWarning') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.BlockedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('unblockToSend') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.BlockedGroupToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('unblockGroupToSend') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.CaptchaSolvedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('verificationComplete') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.CaptchaFailedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('verificationFailed') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.LeftGroupToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('youLeftTheGroup') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.InvalidConversationToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('invalidConversation') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.OriginalNotFoundToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('originalMessageNotFound') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.OriginalNoLongerAvailableToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('originalMessageNotAvailable') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.FoundButNotLoadedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('messageFoundButNotLoaded') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.VoiceNoteLimit = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('voiceNoteLimit') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.VoiceNoteMustBeOnlyAttachmentToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('voiceNoteMustBeOnlyAttachment') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.ConversationArchivedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('conversationArchived') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.ConversationUnarchivedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('conversationReturnedToInbox') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.ConversationMarkedUnreadToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('conversationMarkedUnread') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.TapToViewExpiredIncomingToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return {
|
||||
toastMessage: window.i18n(
|
||||
'Message--tap-to-view--incoming--expired-toast'
|
||||
),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.TapToViewExpiredOutgoingToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return {
|
||||
toastMessage: window.i18n(
|
||||
'Message--tap-to-view--outgoing--expired-toast'
|
||||
),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.DecryptionErrorToast = Whisper.ToastView.extend({
|
||||
className: 'toast toast-clickable decryption-error',
|
||||
events: {
|
||||
click: 'onClick',
|
||||
keydown: 'onKeyDown',
|
||||
},
|
||||
render_attributes() {
|
||||
return {
|
||||
toastMessage: window.i18n('decryptionErrorToast'),
|
||||
};
|
||||
},
|
||||
// Note: this is the same thing as ToastView, except it's missing the setTimeout, so it
|
||||
// will stick around until the user interacts with it.
|
||||
render() {
|
||||
const toasts = document.getElementsByClassName('decryption-error');
|
||||
if (toasts.length > 1) {
|
||||
log.info(
|
||||
'DecryptionErrorToast: We are second decryption error toast. Closing.'
|
||||
);
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
|
||||
this.$el.html(
|
||||
window.Mustache.render(
|
||||
window._.result(this, 'template', ''),
|
||||
window._.result(this, 'render_attributes', '')
|
||||
)
|
||||
);
|
||||
this.$el.attr('tabIndex', 0);
|
||||
this.$el.show();
|
||||
if (window.getInteractionMode() === 'keyboard') {
|
||||
setTimeout(() => {
|
||||
this.$el.focus();
|
||||
}, 1);
|
||||
}
|
||||
},
|
||||
onClick() {
|
||||
this.close();
|
||||
window.showDebugLog();
|
||||
},
|
||||
onKeyDown(event: KeyboardEvent) {
|
||||
if (event.key !== 'Enter' && event.key !== ' ') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onClick();
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.FileSavedToast = Whisper.ToastView.extend({
|
||||
className: 'toast toast-clickable',
|
||||
initialize(options: Readonly<{ fullPath: string }>) {
|
||||
if (!options.fullPath) {
|
||||
throw new Error('FileSavedToast: name option was not provided!');
|
||||
}
|
||||
this.fullPath = options.fullPath;
|
||||
this.timeout = 10000;
|
||||
|
||||
if (window.getInteractionMode() === 'keyboard') {
|
||||
setTimeout(() => {
|
||||
this.$el.focus();
|
||||
}, 1);
|
||||
}
|
||||
},
|
||||
events: {
|
||||
click: 'onClick',
|
||||
keydown: 'onKeydown',
|
||||
},
|
||||
onClick() {
|
||||
openFileInFolder(this.fullPath);
|
||||
this.close();
|
||||
},
|
||||
onKeydown(event: KeyboardEvent) {
|
||||
if (event.key !== 'Enter' && event.key !== ' ') {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
openFileInFolder(this.fullPath);
|
||||
this.close();
|
||||
},
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('attachmentSaved') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.ReactionFailedToast = Whisper.ToastView.extend({
|
||||
className: 'toast toast-clickable',
|
||||
initialize() {
|
||||
this.timeout = 4000;
|
||||
|
||||
if (window.getInteractionMode() === 'keyboard') {
|
||||
setTimeout(() => {
|
||||
this.$el.focus();
|
||||
}, 1);
|
||||
}
|
||||
},
|
||||
events: {
|
||||
click: 'onClick',
|
||||
keydown: 'onKeydown',
|
||||
},
|
||||
onClick() {
|
||||
this.close();
|
||||
},
|
||||
onKeydown(event: KeyboardEvent) {
|
||||
if (event.key !== 'Enter' && event.key !== ' ') {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
this.close();
|
||||
},
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('Reactions--error') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.DeleteForEveryoneFailedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('deleteForEveryoneFailed') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.GroupLinkCopiedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('GroupLinkManagement--clipboard') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.PinnedConversationsFullToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('pinnedConversationsFull') };
|
||||
},
|
||||
});
|
||||
|
||||
const MAX_MESSAGE_BODY_LENGTH = 64 * 1024;
|
||||
|
||||
Whisper.MessageBodyTooLongToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('messageBodyTooLong') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.FileSizeToast = Whisper.ToastView.extend({
|
||||
template: () => $('#file-size-modal').html(),
|
||||
render_attributes() {
|
||||
return {
|
||||
'file-size-warning': window.i18n('fileSizeWarning'),
|
||||
limit: this.model.limit,
|
||||
units: this.model.units,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.UnableToLoadToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('unableToLoadAttachment') };
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.CannotStartGroupCallToast = Whisper.ToastView.extend({
|
||||
template: () => window.i18n('GroupV2--cannot-start-group-call'),
|
||||
});
|
||||
|
||||
Whisper.DangerousFileTypeToast = Whisper.ToastView.extend({
|
||||
template: () => window.i18n('dangerousFileType'),
|
||||
});
|
||||
|
||||
Whisper.OneNonImageAtATimeToast = Whisper.ToastView.extend({
|
||||
template: () => window.i18n('oneNonImageAtATimeToast'),
|
||||
});
|
||||
|
||||
Whisper.CannotMixImageAndNonImageAttachmentsToast = Whisper.ToastView.extend({
|
||||
template: () => window.i18n('cannotMixImageAndNonImageAttachments'),
|
||||
});
|
||||
|
||||
Whisper.MaxAttachmentsToast = Whisper.ToastView.extend({
|
||||
template: () => window.i18n('maximumAttachments'),
|
||||
});
|
||||
|
||||
Whisper.AlreadyGroupMemberToast = Whisper.ToastView.extend({
|
||||
template: () => window.i18n('GroupV2--join--already-in-group'),
|
||||
});
|
||||
|
||||
Whisper.AlreadyRequestedToJoinToast = Whisper.ToastView.extend({
|
||||
template: () => window.i18n('GroupV2--join--already-awaiting-approval'),
|
||||
});
|
||||
|
||||
const ReportedSpamAndBlockedToast = Whisper.ToastView.extend({
|
||||
template: () =>
|
||||
window.i18n('MessageRequests--block-and-report-spam-success-toast'),
|
||||
});
|
||||
|
||||
export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||
// Debounced functions
|
||||
private debouncedMaybeGrabLinkPreview: (
|
||||
|
@ -660,7 +383,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
);
|
||||
|
||||
if (pinnedConversationIds.length >= 4) {
|
||||
this.showToast(Whisper.PinnedConversationsFullToast);
|
||||
showToast(ToastPinnedConversationsFull);
|
||||
return;
|
||||
}
|
||||
this.model.pin();
|
||||
|
@ -726,7 +449,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
this.model.get('announcementsOnly') &&
|
||||
!this.model.areWeAdmin()
|
||||
) {
|
||||
this.showToast(Whisper.CannotStartGroupCallToast);
|
||||
showToast(ToastCannotStartGroupCall);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -769,26 +492,17 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
this.model.setArchived(true);
|
||||
this.model.trigger('unload', 'archive');
|
||||
|
||||
Whisper.ToastView.show(
|
||||
Whisper.ConversationArchivedToast,
|
||||
document.body
|
||||
);
|
||||
showToast(ToastConversationArchived);
|
||||
},
|
||||
onMarkUnread: () => {
|
||||
this.model.setMarkedUnread(true);
|
||||
|
||||
Whisper.ToastView.show(
|
||||
Whisper.ConversationMarkedUnreadToast,
|
||||
document.body
|
||||
);
|
||||
showToast(ToastConversationMarkedUnread);
|
||||
},
|
||||
onMoveToInbox: () => {
|
||||
this.model.setArchived(false);
|
||||
|
||||
Whisper.ToastView.show(
|
||||
Whisper.ConversationUnarchivedToast,
|
||||
document.body
|
||||
);
|
||||
showToast(ToastConversationUnarchived);
|
||||
},
|
||||
}
|
||||
),
|
||||
|
@ -824,7 +538,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
bodyRanges: Array<BodyRangeType>,
|
||||
caretLocation?: number
|
||||
) => this.onEditorStateChange(msg, bodyRanges, caretLocation),
|
||||
onTextTooLong: () => this.showToast(Whisper.MessageBodyTooLongToast),
|
||||
onTextTooLong: () => showToast(ToastMessageBodyTooLong),
|
||||
onChooseAttachment: this.onChooseAttachment.bind(this),
|
||||
getQuotedMessage: () => this.model.get('quotedMessageId'),
|
||||
clearQuotedMessage: () => this.setQuoteMessage(null),
|
||||
|
@ -1040,11 +754,11 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
};
|
||||
const showExpiredIncomingTapToViewToast = () => {
|
||||
log.info('Showing expired tap-to-view toast for an incoming message');
|
||||
this.showToast(Whisper.TapToViewExpiredIncomingToast);
|
||||
showToast(ToastTapToViewExpiredIncoming);
|
||||
};
|
||||
const showExpiredOutgoingTapToViewToast = () => {
|
||||
log.info('Showing expired tap-to-view toast for an outgoing message');
|
||||
this.showToast(Whisper.TapToViewExpiredOutgoingToast);
|
||||
showToast(ToastTapToViewExpiredOutgoing);
|
||||
};
|
||||
|
||||
const showForwardMessageModal = this.showForwardMessageModal.bind(this);
|
||||
|
@ -1115,7 +829,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
);
|
||||
|
||||
if (!message) {
|
||||
this.showToast(Whisper.OriginalNotFoundToast);
|
||||
showToast(ToastOriginalMessageNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1319,28 +1033,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
this.$('.timeline-placeholder').append(this.timelineView.el);
|
||||
}
|
||||
|
||||
private showToast(
|
||||
ToastView: typeof window.Whisper.ToastView,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
options?: any,
|
||||
element?: Element
|
||||
): void {
|
||||
const toast = new ToastView(options);
|
||||
|
||||
if (element) {
|
||||
toast.$el.appendTo(element);
|
||||
} else {
|
||||
const lightboxEl = $('.Lightbox');
|
||||
if (lightboxEl.length > 0) {
|
||||
toast.$el.appendTo(lightboxEl);
|
||||
} else {
|
||||
toast.$el.appendTo(this.$el);
|
||||
}
|
||||
}
|
||||
|
||||
toast.render();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async cleanModels(
|
||||
collection: MessageModelCollectionType | Array<MessageModel>
|
||||
|
@ -1785,7 +1477,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
jobQueue: reportSpamJobQueue,
|
||||
}),
|
||||
]);
|
||||
this.showToast(ReportedSpamAndBlockedToast);
|
||||
showToast(ToastReportedSpamAndBlocked);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -2031,22 +1723,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
}
|
||||
|
||||
showFileSizeError({
|
||||
limit,
|
||||
units,
|
||||
u,
|
||||
}: Readonly<{
|
||||
limit: number;
|
||||
units: Array<string>;
|
||||
u: number;
|
||||
}>): void {
|
||||
const toast = new Whisper.FileSizeToast({
|
||||
model: { limit, units: units[u] },
|
||||
});
|
||||
toast.$el.insertAfter(this.$el);
|
||||
toast.render();
|
||||
}
|
||||
|
||||
updateAttachmentsView(): void {
|
||||
const draftAttachments = this.model.get('draftAttachments') || [];
|
||||
window.reduxActions.composer.replaceAttachments(
|
||||
|
@ -2091,18 +1767,21 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
|
||||
const MB = 1000 * 1024;
|
||||
if (file.size > 100 * MB) {
|
||||
this.showFileSizeError({ limit: 100, units: ['MB'], u: 0 });
|
||||
showToast(ToastFileSize, {
|
||||
limit: 100,
|
||||
units: 'MB',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.Signal.Util.isFileDangerous(file.name)) {
|
||||
this.showToast(Whisper.DangerousFileTypeToast);
|
||||
showToast(ToastDangerousFileType);
|
||||
return;
|
||||
}
|
||||
|
||||
const draftAttachments = this.model.get('draftAttachments') || [];
|
||||
if (draftAttachments.length >= 32) {
|
||||
this.showToast(Whisper.MaxAttachmentsToast);
|
||||
showToast(ToastMaxAttachments);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2112,7 +1791,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
);
|
||||
// You can't add another attachment if you already have a non-image staged
|
||||
if (haveNonImage) {
|
||||
this.showToast(Whisper.OneNonImageAtATimeToast);
|
||||
showToast(ToastOneNonImageAtATime);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2120,7 +1799,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
|
||||
// You can't add a non-image attachment if you already have attachments staged
|
||||
if (!MIME.isImage(fileType) && draftAttachments.length > 0) {
|
||||
this.showToast(Whisper.CannotMixImageAndNonImageAttachmentsToast);
|
||||
showToast(ToastCannotMixImageAndNonImageAttachments);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2191,7 +1870,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
}
|
||||
|
||||
try {
|
||||
if (!this.isSizeOkay(attachment)) {
|
||||
if (!isAttachmentSizeOkay(attachment)) {
|
||||
this.removeDraftAttachment(attachment);
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -2201,7 +1880,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
);
|
||||
|
||||
this.removeDraftAttachment(attachment);
|
||||
this.showToast(Whisper.UnableToLoadToast);
|
||||
showToast(ToastUnableToLoadAttachment);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2213,32 +1892,10 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
error && error.stack ? error.stack : error
|
||||
);
|
||||
|
||||
this.showToast(Whisper.UnableToLoadToast);
|
||||
showToast(ToastUnableToLoadAttachment);
|
||||
}
|
||||
}
|
||||
|
||||
isSizeOkay(attachment: Readonly<AttachmentType>): boolean {
|
||||
const limitKb = window.Signal.Types.Attachment.getUploadSizeLimitKb(
|
||||
attachment.contentType
|
||||
);
|
||||
// this needs to be cast properly
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
if ((attachment.data.byteLength / 1024).toFixed(4) >= limitKb) {
|
||||
const units = ['kB', 'MB', 'GB'];
|
||||
let u = -1;
|
||||
let limit = limitKb * 1000;
|
||||
do {
|
||||
limit /= 1000;
|
||||
u += 1;
|
||||
} while (limit >= 1000 && u < units.length - 1);
|
||||
this.showFileSizeError({ limit, units, u });
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async handleVideoAttachment(
|
||||
file: Readonly<File>
|
||||
): Promise<InMemoryAttachmentDraftType> {
|
||||
|
@ -2312,11 +1969,11 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
}
|
||||
|
||||
if (this.hasFiles({ includePending: true })) {
|
||||
this.showToast(Whisper.VoiceNoteMustBeOnlyAttachmentToast);
|
||||
showToast(ToastVoiceNoteMustBeOnlyAttachment);
|
||||
return;
|
||||
}
|
||||
|
||||
this.showToast(Whisper.VoiceNoteLimit);
|
||||
showToast(ToastVoiceNoteLimit);
|
||||
|
||||
// Note - clicking anywhere will close the audio capture panel, due to
|
||||
// the onClick handler in InboxView, which calls its closeRecording method.
|
||||
|
@ -2504,12 +2161,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
this.debouncedMaybeGrabLinkPreview(messageText, caretLocation);
|
||||
}
|
||||
},
|
||||
onTextTooLong: () =>
|
||||
this.showToast(
|
||||
Whisper.MessageBodyTooLongToast,
|
||||
{},
|
||||
document.querySelector('.module-ForwardMessageModal') || undefined
|
||||
),
|
||||
onTextTooLong: () => showToast(ToastMessageBodyTooLong),
|
||||
}
|
||||
),
|
||||
});
|
||||
|
@ -2787,7 +2439,11 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
|
||||
if (fullPath) {
|
||||
this.showToast(Whisper.FileSavedToast, { fullPath });
|
||||
showToast(ToastFileSaved, {
|
||||
onOpenFile: () => {
|
||||
openFileInFolder(fullPath);
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2956,6 +2612,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
this.downloadAttachment({ attachment, timestamp, isDangerous });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async downloadAttachment({
|
||||
attachment,
|
||||
timestamp,
|
||||
|
@ -2966,7 +2623,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
isDangerous: boolean;
|
||||
}): Promise<void> {
|
||||
if (isDangerous) {
|
||||
this.showToast(Whisper.DangerousFileTypeToast);
|
||||
showToast(ToastDangerousFileType);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2978,7 +2635,11 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
|
||||
if (fullPath) {
|
||||
this.showToast(Whisper.FileSavedToast, { fullPath });
|
||||
showToast(ToastFileSaved, {
|
||||
onOpenFile: () => {
|
||||
openFileInFolder(fullPath);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3132,7 +2793,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
error && error.stack,
|
||||
messageId
|
||||
);
|
||||
this.showToast(Whisper.DeleteForEveryoneFailedToast);
|
||||
showToast(ToastDeleteForEveryoneFailed);
|
||||
}
|
||||
this.resetPanel();
|
||||
},
|
||||
|
@ -3184,7 +2845,11 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
|
||||
if (fullPath) {
|
||||
this.showToast(Whisper.FileSavedToast, { fullPath });
|
||||
showToast(ToastFileSaved, {
|
||||
onOpenFile: () => {
|
||||
openFileInFolder(fullPath);
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3293,7 +2958,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
{
|
||||
changeHasGroupLink: this.changeHasGroupLink.bind(this),
|
||||
conversationId: this.model.id,
|
||||
copyGroupLink: this.copyGroupLink.bind(this),
|
||||
copyGroupLink,
|
||||
generateNewGroupLink: this.generateNewGroupLink.bind(this),
|
||||
setAccessControlAddFromInviteLinkSetting: this.setAccessControlAddFromInviteLinkSetting.bind(
|
||||
this
|
||||
|
@ -3673,11 +3338,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
}
|
||||
|
||||
async copyGroupLink(groupLink: string): Promise<void> {
|
||||
await navigator.clipboard.writeText(groupLink);
|
||||
this.showToast(Whisper.GroupLinkCopiedToast);
|
||||
}
|
||||
|
||||
async generateNewGroupLink(): Promise<void> {
|
||||
const { model }: { model: ConversationModel } = this;
|
||||
|
||||
|
@ -3820,7 +3480,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
} catch (error) {
|
||||
log.error('Error sending reaction', error, messageId, reaction);
|
||||
this.showToast(Whisper.ReactionFailedToast);
|
||||
showToast(ToastReactionFailed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3960,13 +3620,20 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
showInvalidMessageToast(messageText?: string): boolean {
|
||||
const { model }: { model: ConversationModel } = this;
|
||||
|
||||
let ToastView: undefined | typeof window.Whisper.ToastView;
|
||||
let toastView:
|
||||
| undefined
|
||||
| typeof ToastBlocked
|
||||
| typeof ToastBlockedGroup
|
||||
| typeof ToastExpired
|
||||
| typeof ToastInvalidConversation
|
||||
| typeof ToastLeftGroup
|
||||
| typeof ToastMessageBodyTooLong;
|
||||
|
||||
if (window.reduxStore.getState().expiration.hasExpired) {
|
||||
ToastView = Whisper.ExpiredToast;
|
||||
toastView = ToastExpired;
|
||||
}
|
||||
if (!model.isValid()) {
|
||||
ToastView = Whisper.InvalidConversationToast;
|
||||
toastView = ToastInvalidConversation;
|
||||
}
|
||||
|
||||
const e164 = this.model.get('e164');
|
||||
|
@ -3976,7 +3643,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
((e164 && window.storage.blocked.isBlocked(e164)) ||
|
||||
(uuid && window.storage.blocked.isUuidBlocked(uuid)))
|
||||
) {
|
||||
ToastView = Whisper.BlockedToast;
|
||||
toastView = ToastBlocked;
|
||||
}
|
||||
|
||||
const groupId = this.model.get('groupId');
|
||||
|
@ -3985,18 +3652,18 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
groupId &&
|
||||
window.storage.blocked.isGroupBlocked(groupId)
|
||||
) {
|
||||
ToastView = Whisper.BlockedGroupToast;
|
||||
toastView = ToastBlockedGroup;
|
||||
}
|
||||
|
||||
if (!isDirectConversation(model.attributes) && model.get('left')) {
|
||||
ToastView = Whisper.LeftGroupToast;
|
||||
toastView = ToastLeftGroup;
|
||||
}
|
||||
if (messageText && messageText.length > MAX_MESSAGE_BODY_LENGTH) {
|
||||
ToastView = Whisper.MessageBodyTooLongToast;
|
||||
toastView = ToastMessageBodyTooLong;
|
||||
}
|
||||
|
||||
if (ToastView) {
|
||||
this.showToast(ToastView);
|
||||
if (toastView) {
|
||||
showToast(toastView);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
import copyText from 'copy-text-to-clipboard';
|
||||
import * as log from '../logging/log';
|
||||
import * as debugLog from '../logging/debuglogs';
|
||||
import { ToastLoadingFullLogs } from '../components/ToastLoadingFullLogs';
|
||||
import { ToastLinkCopied } from '../components/ToastLinkCopied';
|
||||
import { showToast } from '../util/showToast';
|
||||
|
||||
window.Whisper = window.Whisper || {};
|
||||
const { Whisper } = window;
|
||||
|
@ -18,18 +21,6 @@ const LoadState = {
|
|||
LogsInTextarea: 4,
|
||||
};
|
||||
|
||||
const LoadingFullLogsToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('loading') };
|
||||
},
|
||||
});
|
||||
|
||||
const LinkedCopiedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('debugLogLinkCopied') };
|
||||
},
|
||||
});
|
||||
|
||||
const DebugLogLinkView = Whisper.View.extend({
|
||||
template: () => $('#debug-log-link').html(),
|
||||
initialize(options: { url: string }) {
|
||||
|
@ -50,7 +41,7 @@ const DebugLogLinkView = Whisper.View.extend({
|
|||
e.preventDefault();
|
||||
const target = e.currentTarget as HTMLAnchorElement;
|
||||
copyText(target.href);
|
||||
Whisper.ToastView.show(LinkedCopiedToast, document.body);
|
||||
showToast(ToastLinkCopied);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -137,7 +128,7 @@ export const DebugLogView = Whisper.View.extend({
|
|||
throw new Error('Expected log text to be present');
|
||||
}
|
||||
this.loadState = LoadState.PuttingLogsInTextarea;
|
||||
Whisper.ToastView.show(LoadingFullLogsToast, document.body);
|
||||
showToast(ToastLoadingFullLogs);
|
||||
setTimeout(() => {
|
||||
this.textarea.value = this.logText;
|
||||
this.textarea.removeAttribute('readonly');
|
||||
|
|
|
@ -3,16 +3,12 @@
|
|||
|
||||
import * as log from '../logging/log';
|
||||
import { ConversationModel } from '../models/conversations';
|
||||
import { showToast } from '../util/showToast';
|
||||
import { ToastStickerPackInstallFailed } from '../components/ToastStickerPackInstallFailed';
|
||||
|
||||
window.Whisper = window.Whisper || {};
|
||||
const { Whisper } = window;
|
||||
|
||||
const StickerPackInstallFailedToast = Whisper.ToastView.extend({
|
||||
render_attributes() {
|
||||
return { toastMessage: window.i18n('stickers--toast--InstallFailed') };
|
||||
},
|
||||
});
|
||||
|
||||
const ConversationStack = Whisper.View.extend({
|
||||
className: 'conversation-stack',
|
||||
lastConversation: null,
|
||||
|
@ -146,9 +142,7 @@ Whisper.InboxView = Whisper.View.extend({
|
|||
}
|
||||
|
||||
Whisper.events.on('pack-install-failed', () => {
|
||||
const toast = new StickerPackInstallFailedToast();
|
||||
toast.$el.appendTo(this.$el);
|
||||
toast.render();
|
||||
showToast(ToastStickerPackInstallFailed);
|
||||
});
|
||||
},
|
||||
render_attributes: {
|
||||
|
|
39
ts/window.d.ts
vendored
39
ts/window.d.ts
vendored
|
@ -8,7 +8,7 @@ import * as Backbone from 'backbone';
|
|||
import * as Underscore from 'underscore';
|
||||
import moment from 'moment';
|
||||
import PQueue from 'p-queue/dist';
|
||||
import { Attributes, ComponentClass, FunctionComponent, Ref } from 'react';
|
||||
import { Ref } from 'react';
|
||||
import { imageToBlurHash } from './util/imageToBlurHash';
|
||||
import * as Util from './util';
|
||||
import {
|
||||
|
@ -623,42 +623,6 @@ export type WhisperType = {
|
|||
// Note: we can no longer use 'View.extend' once we've moved to Typescript's preferred
|
||||
// 'extend View' syntax. Thus, we'll need to typescriptify most of it at once.
|
||||
|
||||
// Toast
|
||||
AlreadyGroupMemberToast: typeof AnyViewClass;
|
||||
AlreadyRequestedToJoinToast: typeof AnyViewClass;
|
||||
BlockedGroupToast: typeof AnyViewClass;
|
||||
BlockedToast: typeof AnyViewClass;
|
||||
CannotMixImageAndNonImageAttachmentsToast: typeof AnyViewClass;
|
||||
CaptchaSolvedToast: typeof AnyViewClass;
|
||||
CaptchaFailedToast: typeof AnyViewClass;
|
||||
CannotStartGroupCallToast: typeof AnyViewClass;
|
||||
ConversationArchivedToast: typeof AnyViewClass;
|
||||
ConversationUnarchivedToast: typeof AnyViewClass;
|
||||
ConversationMarkedUnreadToast: typeof AnyViewClass;
|
||||
DangerousFileTypeToast: typeof AnyViewClass;
|
||||
DecryptionErrorToast: typeof AnyViewClass;
|
||||
ExpiredToast: typeof AnyViewClass;
|
||||
FileSavedToast: typeof AnyViewClass;
|
||||
FileSizeToast: typeof AnyViewClass;
|
||||
FoundButNotLoadedToast: typeof AnyViewClass;
|
||||
GroupLinkCopiedToast: typeof AnyViewClass;
|
||||
InvalidConversationToast: typeof AnyViewClass;
|
||||
LeftGroupToast: typeof AnyViewClass;
|
||||
MaxAttachmentsToast: typeof AnyViewClass;
|
||||
MessageBodyTooLongToast: typeof AnyViewClass;
|
||||
OneNonImageAtATimeToast: typeof AnyViewClass;
|
||||
OriginalNoLongerAvailableToast: typeof AnyViewClass;
|
||||
OriginalNotFoundToast: typeof AnyViewClass;
|
||||
PinnedConversationsFullToast: typeof AnyViewClass;
|
||||
ReactionFailedToast: typeof AnyViewClass;
|
||||
DeleteForEveryoneFailedToast: typeof AnyViewClass;
|
||||
TapToViewExpiredIncomingToast: typeof AnyViewClass;
|
||||
TapToViewExpiredOutgoingToast: typeof AnyViewClass;
|
||||
TimerConflictToast: typeof AnyViewClass;
|
||||
UnableToLoadToast: typeof AnyViewClass;
|
||||
VoiceNoteLimit: typeof AnyViewClass;
|
||||
VoiceNoteMustBeOnlyAttachmentToast: typeof AnyViewClass;
|
||||
|
||||
ClearDataView: typeof AnyViewClass;
|
||||
ConversationLoadingScreen: typeof AnyViewClass;
|
||||
GroupMemberList: typeof AnyViewClass;
|
||||
|
@ -669,6 +633,5 @@ export type WhisperType = {
|
|||
RecorderView: typeof AnyViewClass;
|
||||
SafetyNumberChangeDialogView: typeof AnyViewClass;
|
||||
StandaloneRegistrationView: typeof AnyViewClass;
|
||||
ToastView: typeof AnyViewClass;
|
||||
View: typeof AnyViewClass;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue