diff --git a/ts/components/session/SessionToast.tsx b/ts/components/session/SessionToast.tsx
index ad7c6a162..241398d64 100644
--- a/ts/components/session/SessionToast.tsx
+++ b/ts/components/session/SessionToast.tsx
@@ -1,12 +1,8 @@
import React from 'react';
-import classNames from 'classnames';
-import {
- SessionIcon,
- SessionIconButton,
- SessionIconSize,
- SessionIconType,
-} from './icon/';
+import { SessionIcon, SessionIconSize, SessionIconType } from './icon/';
+import { Flex } from './Flex';
+import styled from 'styled-components';
export enum SessionToastType {
Info = 'info',
@@ -15,70 +11,80 @@ export enum SessionToastType {
Error = 'error',
}
-interface Props {
+type Props = {
title: string;
id?: string;
type?: SessionToastType;
icon?: SessionIconType;
description?: string;
- closeToast: any;
-}
+ closeToast?: any;
+};
-export class SessionToast extends React.PureComponent
{
- constructor(props: any) {
- super(props);
- }
+const TitleDiv = styled.div`
+ font-size: ${props => props.theme.common.fonts.md};
+ line-height: ${props => props.theme.common.fonts.md};
+ font-family: ${props => props.theme.common.fonts.sessionFontDefault};
+ color: ${props => props.theme.colors.textColor};
+ text-overflow: ellipsis;
+`;
- public render() {
- const { title, description, type, icon } = this.props;
+const DescriptionDiv = styled.div`
+ font-size: ${props => props.theme.common.fonts.sm};
+ color: ${props => props.theme.colors.textColorSubtle};
+ text-overflow: ellipsis;
+ font-family: ${props => props.theme.common.fonts.sessionFontDefault};
+ padding-bottom: ${props => props.theme.common.fonts.xs};
+ padding-top: ${props => props.theme.common.fonts.xs};
+`;
- const toastType = type ? type : SessionToastType.Info;
- const toastDesc = description ? description : '';
- const toastIconSize = toastDesc
- ? SessionIconSize.Huge
- : SessionIconSize.Medium;
+const IconDiv = styled.div`
+ flex-shrink: 0;
+ padding-inline-end: ${props => props.theme.common.margins.xs};
+`;
- // Set a custom icon or allow the theme to define the icon
- let toastIcon = icon || undefined;
- if (!toastIcon) {
- switch (type) {
- case SessionToastType.Info:
- toastIcon = SessionIconType.Info;
- break;
- case SessionToastType.Success:
- toastIcon = SessionIconType.Check;
- break;
- case SessionToastType.Error:
- toastIcon = SessionIconType.Error;
- break;
- case SessionToastType.Warning:
- toastIcon = SessionIconType.Warning;
- break;
- default:
- toastIcon = SessionIconType.Info;
- }
- }
+export const SessionToast = (props: Props) => {
+ const { title, description, type, icon } = props;
- return (
-
-
-
-
-
-
-
{title}
-
{toastDesc}
-
-
+ const toastDesc = description ? description : '';
+ const toastIconSize = toastDesc
+ ? SessionIconSize.Huge
+ : SessionIconSize.Medium;
-
-
-
-
- );
+ // Set a custom icon or allow the theme to define the icon
+ let toastIcon = icon || undefined;
+ if (!toastIcon) {
+ switch (type) {
+ case SessionToastType.Info:
+ toastIcon = SessionIconType.Info;
+ break;
+ case SessionToastType.Success:
+ toastIcon = SessionIconType.Check;
+ break;
+ case SessionToastType.Error:
+ toastIcon = SessionIconType.Error;
+ break;
+ case SessionToastType.Warning:
+ toastIcon = SessionIconType.Warning;
+ break;
+ default:
+ toastIcon = SessionIconType.Info;
+ }
}
-}
+
+ return (
+
+
+
+
+
+ {title}
+ {toastDesc && {toastDesc}}
+
+
+ );
+};
diff --git a/ts/components/session/SessionToastContainer.tsx b/ts/components/session/SessionToastContainer.tsx
new file mode 100644
index 000000000..d41976fb0
--- /dev/null
+++ b/ts/components/session/SessionToastContainer.tsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import { Slide, ToastContainer, ToastContainerProps } from 'react-toastify';
+import styled from 'styled-components';
+
+const SessionToastContainerPrivate = () => {
+ return (
+
+ );
+};
+
+const WrappedToastContainer = ({
+ className,
+ ...rest
+}: ToastContainerProps & { className?: string }) => (
+
+
+
+);
+
+// tslint:disable-next-line: no-default-export
+export const SessionToastContainer = styled(SessionToastContainerPrivate).attrs(
+ {
+ // custom props
+ }
+)`
+ .Toastify__toast-container {
+ }
+ .Toastify__toast {
+ }
+ .Toastify__toast--error {
+ }
+ .Toastify__toast--warning {
+ }
+ .Toastify__toast--success {
+ }
+ .Toastify__toast-body {
+ }
+ .Toastify__progress-bar {
+ }
+`;
diff --git a/ts/components/session/conversation/SessionConversation.tsx b/ts/components/session/conversation/SessionConversation.tsx
index 5abed9c8c..5857978ae 100644
--- a/ts/components/session/conversation/SessionConversation.tsx
+++ b/ts/components/session/conversation/SessionConversation.tsx
@@ -223,7 +223,8 @@ export class SessionConversation extends React.Component {
const conversationModel = window.ConversationController.getOrThrow(
conversationKey
);
- const isRss = conversation.isRss;
+
+ const { isRss } = conversation;
// TODO VINCE: OPTIMISE FOR NEW SENDING???
const sendMessageFn = conversationModel.sendMessage.bind(conversationModel);
diff --git a/ts/components/session/settings/SessionSettings.tsx b/ts/components/session/settings/SessionSettings.tsx
index 418496997..896cdd2cb 100644
--- a/ts/components/session/settings/SessionSettings.tsx
+++ b/ts/components/session/settings/SessionSettings.tsx
@@ -10,6 +10,8 @@ import {
import { BlockedNumberController, UserUtil } from '../../../util';
import { MultiDeviceProtocol } from '../../../session/protocols';
import { PubKey } from '../../../session/types';
+import { SessionToast, SessionToastType } from '../SessionToast';
+import { toast } from 'react-toastify';
import { ToastUtils } from '../../../session/utils';
export enum SessionSettingCategory {
@@ -609,10 +611,7 @@ export class SettingsView extends React.Component {
await BlockedNumberController.unblock(blockedNumber);
this.forceUpdate();
}
- ToastUtils.push({
- title: window.i18n('unblocked'),
- id: 'unblocked',
- });
+ ToastUtils.pushToastSuccess('unblocked', window.i18n('unblocked'));
},
hidden: false,
onClick: undefined,
diff --git a/ts/receiver/dataMessage.ts b/ts/receiver/dataMessage.ts
index 37ade63e9..a0b07fa12 100644
--- a/ts/receiver/dataMessage.ts
+++ b/ts/receiver/dataMessage.ts
@@ -608,7 +608,7 @@ export async function handleMessageEvent(event: MessageEvent): Promise {
SESSION_RESTORE,
} = SignalService.DataMessage.Flags;
- // eslint-disable-next-line no-bitwise
+ // tslint:disable-next-line: no-bitwise
const isProfileUpdate = Boolean(message.flags & PROFILE_KEY_UPDATE);
if (isProfileUpdate) {
@@ -682,7 +682,7 @@ export async function handleMessageEvent(event: MessageEvent): Promise {
// =========== Process flags =============
- // eslint-disable-next-line no-bitwise
+ // tslint:disable-next-line: no-bitwise
if (message.flags & SESSION_RESTORE) {
// Show that the session reset is "in progress" even though we had a valid session
msg.set({ endSessionType: 'ongoing' });
diff --git a/ts/session/utils/Toast.ts b/ts/session/utils/Toast.ts
deleted file mode 100644
index 5f03f1e3c..000000000
--- a/ts/session/utils/Toast.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-export function push(options: {
- title: string;
- id?: string;
- description?: string;
- type?: 'success' | 'info' | 'warning' | 'error';
- icon?: string;
- shouldFade?: boolean;
-}) {
- window.pushToast(options);
-}
-
-export function pushLoadAttachmentFailure() {
- window.pushToast({
- title: window.i18n('unableToLoadAttachment'),
- type: 'error',
- id: 'unableToLoadAttachment',
- });
-}
-
-export function pushDangerousFileError() {
- window.pushToast({
- title: window.i18n('dangerousFileType'),
- type: 'error',
- id: 'dangerousFileType',
- });
-}
-
-export function pushFileSizeError(limit: number, units: string) {
- window.pushToast({
- title: window.i18n('fileSizeWarning'),
- description: `Max size: ${limit} ${units}`,
- type: 'error',
- id: 'fileSizeWarning',
- });
-}
-
-export function pushMultipleNonImageError() {
- window.pushToast({
- title: window.i18n('cannotMixImageAndNonImageAttachments'),
- type: 'error',
- id: 'cannotMixImageAndNonImageAttachments',
- });
-}
-
-export function pushCannotMixError() {
- window.pushToast({
- title: window.i18n('oneNonImageAtATimeToast'),
- type: 'error',
- id: 'oneNonImageAtATimeToast',
- });
-}
-
-export function pushMaximumAttachmentsError() {
- window.pushToast({
- title: window.i18n('maximumAttachments'),
- type: 'error',
- id: 'maximumAttachments',
- });
-}
-
-export function pushMessageBodyTooLong() {
- window.pushToast({
- title: window.i18n('messageBodyTooLong'),
- type: 'error',
- id: 'messageBodyTooLong',
- });
-}
-
-export function pushMessageBodyMissing() {
- window.pushToast({
- title: window.i18n('messageBodyMissing'),
- type: 'error',
- id: 'messageBodyMissing',
- });
-}
-
-export function pushCopiedToClipBoard() {
- window.pushToast({
- title: window.i18n('copiedToClipboard'),
- type: 'success',
- id: 'copiedToClipboard',
- });
-}
-
-export function pushForceUnlinked() {
- window.pushToast({
- title: window.i18n('successUnlinked'),
- type: 'info',
- id: 'successUnlinked',
- });
-}
-
-export function pushSpellCheckDirty() {
- window.pushToast({
- title: window.i18n('spellCheckDirty'),
- type: 'info',
- id: 'spellCheckDirty',
- });
-}
-
-export function pushAlreadyMemberOpenGroup() {
- window.pushToast({
- title: window.i18n('publicChatExists'),
- type: 'info',
- id: 'alreadyMemberPublicChat',
- });
-}
-
-export function pushUserBanSuccess() {
- window.pushToast({
- title: window.i18n('userBanned'),
- type: 'success',
- id: 'userBanned',
- });
-}
-
-export function pushUserBanFailure() {
- window.pushToast({
- title: window.i18n('userBanFailed'),
- type: 'error',
- id: 'userBanFailed',
- });
-}
-
-export function pushMessageDeleteForbidden() {
- window.pushToast({
- title: window.i18n('messageDeletionForbidden'),
- type: 'error',
- id: 'messageDeletionForbidden',
- });
-}
-
-export function pushAudioPermissionNeeded() {
- window.pushToast({
- id: 'audioPermissionNeeded',
- title: window.i18n('audioPermissionNeededTitle'),
- description: window.i18n('audioPermissionNeeded'),
- type: 'info',
- });
-}
-
-export function pushOriginalNotFound() {
- window.pushToast({
- id: 'originalMessageNotFound',
- title: window.i18n('originalMessageNotFound'),
- type: 'error',
- });
-}
-
-export function pushOriginalNoLongerAvailable() {
- window.pushToast({
- id: 'originalMessageNotAvailable',
- title: window.i18n('originalMessageNotAvailable'),
- type: 'error',
- });
-}
-
-export function pushFoundButNotLoaded() {
- window.pushToast({
- id: 'messageFoundButNotLoaded',
- title: window.i18n('messageFoundButNotLoaded'),
- type: 'error',
- });
-}
diff --git a/ts/session/utils/Toast.tsx b/ts/session/utils/Toast.tsx
new file mode 100644
index 000000000..2ed0c8ff3
--- /dev/null
+++ b/ts/session/utils/Toast.tsx
@@ -0,0 +1,214 @@
+import React from 'react';
+import { toast } from 'react-toastify';
+import { SessionIconType } from '../../components/session/icon';
+import {
+ SessionToast,
+ SessionToastType,
+} from '../../components/session/SessionToast';
+
+// if you push a toast manually with toast...() be sure to set the type attribute of the SessionToast component
+export function pushToastError(
+ id: string,
+ title: string,
+ description?: string
+) {
+ toast.error(
+ ,
+ { toastId: id }
+ );
+}
+
+export function pushToastWarning(
+ id: string,
+ title: string,
+ description?: string
+) {
+ toast.warning(
+ ,
+ { toastId: id }
+ );
+}
+
+export function pushToastInfo(id: string, title: string, description?: string) {
+ toast.info(
+ ,
+ { toastId: id }
+ );
+}
+
+export function pushToastSuccess(
+ id: string,
+ title: string,
+ description?: string,
+ icon?: SessionIconType
+) {
+ toast.success(
+ ,
+ { toastId: id }
+ );
+}
+
+export function pushLoadAttachmentFailure() {
+ pushToastError(
+ 'unableToLoadAttachment',
+ window.i18n('unableToLoadAttachment')
+ );
+}
+
+export function pushDangerousFileError() {
+ pushToastError('dangerousFileType', window.i18n('dangerousFileType'));
+}
+
+export function pushFileSizeError(limit: number, units: string) {
+ pushToastError(
+ 'fileSizeWarning',
+ window.i18n('fileSizeWarning'),
+ `Max size: ${limit} ${units}`
+ );
+}
+
+export function pushMultipleNonImageError() {
+ pushToastError(
+ 'cannotMixImageAndNonImageAttachments',
+ window.i18n('cannotMixImageAndNonImageAttachments')
+ );
+}
+
+export function pushCannotMixError() {
+ pushToastError(
+ 'oneNonImageAtATimeToast',
+ window.i18n('oneNonImageAtATimeToast')
+ );
+}
+
+export function pushMaximumAttachmentsError() {
+ pushToastError('maximumAttachments', window.i18n('maximumAttachments'));
+}
+
+export function pushMessageBodyTooLong() {
+ pushToastError('messageBodyTooLong', window.i18n('messageBodyTooLong'));
+}
+
+export function pushMessageBodyMissing() {
+ pushToastError('messageBodyMissing', window.i18n('messageBodyMissing'));
+}
+
+export function pushCopiedToClipBoard() {
+ pushToastInfo('copiedToClipboard', window.i18n('copiedToClipboard'));
+}
+
+export function pushForceUnlinked() {
+ pushToastInfo('successUnlinked', window.i18n('successUnlinked'));
+}
+
+export function pushSpellCheckDirty() {
+ pushToastInfo('spellCheckDirty', window.i18n('spellCheckDirty'));
+}
+
+export function pushAlreadyMemberOpenGroup() {
+ pushToastInfo('publicChatExists', window.i18n('publicChatExists'));
+}
+
+export function pushUserBanSuccess() {
+ pushToastSuccess('userBanned', window.i18n('userBanned'));
+}
+
+export function pushUserBanFailure() {
+ pushToastError('userBanFailed', window.i18n('userBanFailed'));
+}
+
+export function pushMessageDeleteForbidden() {
+ pushToastError(
+ 'messageDeletionForbidden',
+ window.i18n('messageDeletionForbidden')
+ );
+}
+
+export function pushAudioPermissionNeeded() {
+ pushToastInfo(
+ 'audioPermissionNeeded',
+ window.i18n('audioPermissionNeededTitle'),
+ window.i18n('audioPermissionNeeded')
+ );
+}
+
+export function pushOriginalNotFound() {
+ pushToastError(
+ 'originalMessageNotFound',
+ window.i18n('originalMessageNotFound')
+ );
+}
+
+export function pushOriginalNoLongerAvailable() {
+ pushToastError(
+ 'originalMessageNotAvailable',
+ window.i18n('originalMessageNotAvailable')
+ );
+}
+
+export function pushFoundButNotLoaded() {
+ pushToastError(
+ 'messageFoundButNotLoaded',
+ window.i18n('messageFoundButNotLoaded')
+ );
+}
+
+export function pushTooManyMembers() {
+ pushToastError('tooManyMembers', window.i18n('closedGroupMaxSize'));
+}
+
+export function pushPairingRequestReceived(alreadyLinked: boolean) {
+ const title = alreadyLinked
+ ? window.i18n('devicePairingRequestReceivedLimitTitle')
+ : window.i18n('devicePairingRequestReceivedNoListenerTitle');
+
+ const description = alreadyLinked
+ ? window.i18n(
+ 'devicePairingRequestReceivedLimitDescription',
+ window.CONSTANTS.MAX_LINKED_DEVICES
+ )
+ : window.i18n('devicePairingRequestReceivedNoListenerDescription');
+
+ if (alreadyLinked) {
+ toast.info(
+ ,
+ {
+ toastId: 'pairingRequestReceived',
+ autoClose: false,
+ }
+ );
+ } else {
+ toast.warning(
+ ,
+ {
+ toastId: 'pairingRequestReceived',
+ autoClose: false,
+ }
+ );
+ }
+}
diff --git a/ts/state/ducks/SessionTheme.tsx b/ts/state/ducks/SessionTheme.tsx
index 38a6816be..4313ae643 100644
--- a/ts/state/ducks/SessionTheme.tsx
+++ b/ts/state/ducks/SessionTheme.tsx
@@ -18,6 +18,11 @@ const common = {
sessionFontDefault: 'Public Sans',
sessionFontAccent: 'Loor',
sessionFontMono: 'SpaceMono',
+ xs: '11px',
+ sm: '13px',
+ md: '15px',
+ lg: '18px',
+ xl: '24px',
},
margins: {
xs: '5px',
diff --git a/ts/styled.d.ts b/ts/styled.d.ts
index 25d59d72c..b8e5b60c1 100644
--- a/ts/styled.d.ts
+++ b/ts/styled.d.ts
@@ -7,6 +7,11 @@ declare module 'styled-components' {
sessionFontDefault: string;
sessionFontAccent: string;
sessionFontMono: string;
+ xs: string;
+ sm: string;
+ md: string;
+ lg: string;
+ xl: string;
};
margins: {
xs: string;
diff --git a/ts/window.d.ts b/ts/window.d.ts
index 45c0fcc1c..a5ee275ec 100644
--- a/ts/window.d.ts
+++ b/ts/window.d.ts
@@ -47,7 +47,6 @@ declare global {
deleteAccount: any;
displayNameRegex: any;
friends: any;
- generateID: any;
getAccountManager: any;
getConversations: any;
getFriendsFromContacts: any;
@@ -75,7 +74,6 @@ declare global {
mnemonic: RecoveryPhraseUtil;
onLogin: any;
passwordUtil: any;
- pushToast: any;
resetDatabase: any;
restart: any;
seedNodeList: any;
diff --git a/yarn.lock b/yarn.lock
index b98cbf2f0..219b0520b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -126,6 +126,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.8.7":
+ version "7.12.5"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
+ integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
"@babel/template@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
@@ -3217,6 +3224,14 @@ dom-align@^1.7.0:
dependencies:
"@babel/runtime" "^7.1.2"
+dom-helpers@^5.0.1:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
+ integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
+ dependencies:
+ "@babel/runtime" "^7.8.7"
+ csstype "^3.0.2"
+
dom-walk@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
@@ -8864,6 +8879,25 @@ react-styleguidist@7.0.1:
webpack-dev-server "^2.11.2"
webpack-merge "^4.1.2"
+react-toastify@^6.0.9:
+ version "6.0.9"
+ resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-6.0.9.tgz#2a65e5ad9e05f3ee47664cbc69441498b9d694ce"
+ integrity sha512-StHXv+4kezHUnPyoILlvygSptQ79bxVuvKcC05yXP0FlqQgPA1ue+80BqxZZiCw2jWDGiY2MHyqBfFKf5YzZbA==
+ dependencies:
+ classnames "^2.2.6"
+ prop-types "^15.7.2"
+ react-transition-group "^4.4.1"
+
+react-transition-group@^4.4.1:
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
+ integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ dom-helpers "^5.0.1"
+ loose-envify "^1.4.0"
+ prop-types "^15.6.2"
+
react-virtualized@9.21.0:
version "9.21.0"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.21.0.tgz#8267c40ffb48db35b242a36dea85edcf280a6506"