Infinte duration toasts

pull/713/head
Vincent 5 years ago
parent 6ee5d041fb
commit 8074756dc2

@ -395,6 +395,9 @@
"description": "description":
"When there are multiple previously-verified group members with safety number changes, a banner will be shown. The list of contacts with safety number changes is shown, and this text introduces that list." "When there are multiple previously-verified group members with safety number changes, a banner will be shown. The list of contacts with safety number changes is shown, and this text introduces that list."
}, },
"changedSinceVerifiedTitle": {
"message": "Safety Number Changed"
},
"changedSinceVerifiedMultiple": { "changedSinceVerifiedMultiple": {
"message": "message":
"Your safety numbers with multiple group members have changed since you last verified. This could mean that someone is trying to intercept your communication or that they have simply reinstalled Signal.", "Your safety numbers with multiple group members have changed since you last verified. This could mean that someone is trying to intercept your communication or that they have simply reinstalled Signal.",
@ -2024,7 +2027,7 @@
}, },
"banUser": { "banUser": {
"message": "Ban user", "message": "Ban User",
"description": "Ban user from public chat by public key." "description": "Ban user from public chat by public key."
}, },

@ -802,8 +802,6 @@
appView.openConversation(groupId, {}); appView.openConversation(groupId, {});
}; };
window.confirmationDialog = params => { window.confirmationDialog = params => {
const confirmDialog = new Whisper.SessionConfirmView({ const confirmDialog = new Whisper.SessionConfirmView({
el: $('#session-confirm-container'), el: $('#session-confirm-container'),
@ -816,7 +814,7 @@
hideCancel: params.hideCancel || false, hideCancel: params.hideCancel || false,
}); });
confirmDialog.render(); confirmDialog.render();
} };
window.generateID = () => window.generateID = () =>
Math.random() Math.random()
@ -834,6 +832,7 @@
id: options.id || window.generateID(), id: options.id || window.generateID(),
description: options.description || '', description: options.description || '',
type: options.type || '', type: options.type || '',
shouldFade: options.shouldFade,
}; };
// Give all toasts an ID. User may define. // Give all toasts an ID. User may define.

@ -1030,9 +1030,10 @@
}, },
banUser() { banUser() {
window.Whisper.events.trigger('showConfirmationDialog', { window.confirmationDialog({
title: i18n('banUser'),
message: i18n('banUserConfirm'), message: i18n('banUserConfirm'),
onOk: async () => { resolve: async () => {
const source = this.get('source'); const source = this.get('source');
const conversation = this.getConversation(); const conversation = this.getConversation();

@ -61,7 +61,9 @@ const {
const { SessionToast } = require('../../ts/components/session/SessionToast'); const { SessionToast } = require('../../ts/components/session/SessionToast');
const { SessionToggle } = require('../../ts/components/session/SessionToggle'); const { SessionToggle } = require('../../ts/components/session/SessionToggle');
const { SessionModal } = require('../../ts/components/session/SessionModal'); const { SessionModal } = require('../../ts/components/session/SessionModal');
const { SessionConfirm } = require('../../ts/components/session/SessionConfirm'); const {
SessionConfirm,
} = require('../../ts/components/session/SessionConfirm');
const { const {
SessionDropdown, SessionDropdown,
} = require('../../ts/components/session/SessionDropdown'); } = require('../../ts/components/session/SessionDropdown');

@ -1,4 +1,4 @@
/* global $, Whisper, i18n */ /* global $, i18n */
$(document).on('keyup', e => { $(document).on('keyup', e => {
'use strict'; 'use strict';
@ -8,7 +8,7 @@ $(document).on('keyup', e => {
} }
}); });
const dialogParams = { window.confirmationDialog({
title: i18n('audioPermissionNeeded'), title: i18n('audioPermissionNeeded'),
okText: i18n('allowAccess'), okText: i18n('allowAccess'),
resolve: () => { resolve: () => {
@ -18,6 +18,4 @@ const dialogParams = {
window.closePermissionsPopup(); window.closePermissionsPopup();
}, },
onClose: window.closePermissionsPopup, onClose: window.closePermissionsPopup,
}; });
window.confirmationDialog(dialogParams);

@ -1308,7 +1308,7 @@
}, },
forceSend({ contact, message }) { forceSend({ contact, message }) {
const dialog = new Whisper.ConfirmationDialogView({ window.confirmationDialog({
message: i18n('identityKeyErrorOnSend', [ message: i18n('identityKeyErrorOnSend', [
contact.getTitle(), contact.getTitle(),
contact.getTitle(), contact.getTitle(),
@ -1328,11 +1328,7 @@
message.resend(contact.id); message.resend(contact.id);
}, },
}); });
this.$el.prepend(dialog.el);
dialog.focusCancel();
}, },
showSafetyNumber(providedModel) { showSafetyNumber(providedModel) {
@ -1439,14 +1435,11 @@
return; return;
} }
const dialog = new Whisper.ConfirmationDialogView({ window.confirmationDialog({
message: warningMessage, message: warningMessage,
okText: i18n('delete'), okText: i18n('delete'),
resolve: doDelete, resolve: doDelete,
}); });
this.$el.prepend(dialog.el);
dialog.focusCancel();
}, },
deleteMessage(message) { deleteMessage(message) {
@ -1670,7 +1663,8 @@
} }
} }
const dialog = new Whisper.ConfirmationDialogView({ window.confirmationDialog({
title: i18n('changedSinceVerifiedTitle'),
message, message,
okText: i18n('sendAnyway'), okText: i18n('sendAnyway'),
resolve: () => { resolve: () => {
@ -1680,9 +1674,6 @@
this.focusMessageFieldAndClearDisabled(); this.focusMessageFieldAndClearDisabled();
}, },
}); });
this.$el.prepend(dialog.el);
dialog.focusCancel();
}, },
stripQuery(text, cursorPos) { stripQuery(text, cursorPos) {

@ -54,13 +54,12 @@
toast.render(); toast.render();
}, },
showConfirmationDialog({ title, message, onOk, onCancel }) { showConfirmationDialog({ title, message, onOk, onCancel }) {
const dialog = new Whisper.ConfirmationDialogView({ window.confirmationDialog({
title, title,
message, message,
resolve: onOk, resolve: onOk,
reject: onCancel, reject: onCancel,
}); });
this.el.append(dialog.el);
}, },
}); });

@ -61,16 +61,14 @@
onSafetyNumberChanged() { onSafetyNumberChanged() {
this.model.getProfiles().then(this.loadKeys.bind(this)); this.model.getProfiles().then(this.loadKeys.bind(this));
const dialog = new Whisper.ConfirmationDialogView({ window.confirmationDialog({
title: i18n('changedSinceVerifiedTitle'),
message: i18n('changedRightAfterVerify', [ message: i18n('changedRightAfterVerify', [
this.model.getTitle(), this.model.getTitle(),
this.model.getTitle(), this.model.getTitle(),
]), ]),
hideCancel: true, hideCancel: true,
}); });
dialog.$el.insertBefore(this.el);
dialog.focusCancel();
}, },
toggleVerified() { toggleVerified() {
this.$('button.verify').attr('disabled', true); this.$('button.verify').attr('disabled', true);

@ -35,14 +35,14 @@
ok() { ok() {
this.$('.session-confirm-wrapper').remove(); this.$('.session-confirm-wrapper').remove();
if (this.props.resolve){ if (this.props.resolve) {
this.props.resolve() this.props.resolve();
} }
}, },
cancel() { cancel() {
this.$('.session-confirm-wrapper').remove(); this.$('.session-confirm-wrapper').remove();
if (this.props.reject) { if (this.props.reject) {
this.props.reject() this.props.reject();
} }
}, },
onKeyup(event) { onKeyup(event) {
@ -50,6 +50,5 @@
this.cancel(); this.cancel();
} }
}, },
}); });
})(); })();

@ -32,13 +32,18 @@
this.props.id = options.id; this.props.id = options.id;
this.props.description = options.description || ''; this.props.description = options.description || '';
this.props.type = options.type || ''; this.props.type = options.type || '';
this.props.shouldFade = options.shouldFade !== false;
this.toastView.update(this.props); this.toastView.update(this.props);
this.showToast(); this.showToast();
clearTimeout(this.timer); if (this.timer) {
this.timer = setTimeout(this.fadeToast.bind(this), 4000); clearTimeout(this.timer);
}
if (this.props.shouldFade) {
this.timer = setTimeout(this.fadeToast.bind(this), 4000);
}
}, },
showToast() { showToast() {

@ -53,13 +53,12 @@
}, },
confirm(message, okText) { confirm(message, okText) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const dialog = new Whisper.ConfirmationDialogView({ window.confirmationDialog({
message, title: message,
okText, okText,
resolve, resolve,
reject, reject,
}); });
this.$el.append(dialog.el);
}); });
}, },
}, },

@ -11,49 +11,63 @@
}, },
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
"postinstall": "electron-builder install-app-deps && rimraf node_modules/dtrace-provider", "postinstall":
"electron-builder install-app-deps && rimraf node_modules/dtrace-provider",
"start": "electron .", "start": "electron .",
"start-multi": "NODE_APP_INSTANCE=1 electron .", "start-multi": "NODE_APP_INSTANCE=1 electron .",
"start-multi2": "NODE_APP_INSTANCE=2 electron .", "start-multi2": "NODE_APP_INSTANCE=2 electron .",
"start-prod": "NODE_ENV=production NODE_APP_INSTANCE=devprod LOKI_DEV=1 electron .", "start-prod":
"start-prod-multi": "NODE_ENV=production NODE_APP_INSTANCE=devprod1 LOKI_DEV=1 electron .", "NODE_ENV=production NODE_APP_INSTANCE=devprod LOKI_DEV=1 electron .",
"start-prod-multi":
"NODE_ENV=production NODE_APP_INSTANCE=devprod1 LOKI_DEV=1 electron .",
"grunt": "grunt", "grunt": "grunt",
"icon-gen": "electron-icon-maker --input=images/icon_1024.png --output=./build", "icon-gen":
"electron-icon-maker --input=images/icon_1024.png --output=./build",
"generate": "yarn icon-gen && yarn grunt", "generate": "yarn icon-gen && yarn grunt",
"build": "electron-builder --config.extraMetadata.environment=$SIGNAL_ENV", "build": "electron-builder --config.extraMetadata.environment=$SIGNAL_ENV",
"build-release": "export SIGNAL_ENV=production && npm run build -- --config.directories.output=release", "build-release":
"export SIGNAL_ENV=production && npm run build -- --config.directories.output=release",
"sign-release": "node ts/updater/generateSignature.js", "sign-release": "node ts/updater/generateSignature.js",
"build-module-protobuf": "pbjs --target static-module --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "build-module-protobuf":
"clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "pbjs --target static-module --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
"clean-module-protobuf":
"rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
"build-protobuf": "yarn build-module-protobuf", "build-protobuf": "yarn build-module-protobuf",
"clean-protobuf": "yarn clean-module-protobuf", "clean-protobuf": "yarn clean-module-protobuf",
"prepare-beta-build": "node prepare_beta_build.js", "prepare-beta-build": "node prepare_beta_build.js",
"prepare-import-build": "node prepare_import_build.js", "prepare-import-build": "node prepare_import_build.js",
"publish-to-apt": "NAME=$npm_package_name VERSION=$npm_package_version ./aptly.sh", "publish-to-apt":
"NAME=$npm_package_name VERSION=$npm_package_version ./aptly.sh",
"test": "yarn test-node && yarn test-electron", "test": "yarn test-node && yarn test-electron",
"test-view": "NODE_ENV=test yarn run start", "test-view": "NODE_ENV=test yarn run start",
"test-lib-view": "NODE_ENV=test-lib yarn run start", "test-lib-view": "NODE_ENV=test-lib yarn run start",
"test-loki-view": "NODE_ENV=test-loki yarn run start", "test-loki-view": "NODE_ENV=test-loki yarn run start",
"test-electron": "yarn grunt test", "test-electron": "yarn grunt test",
"test-node": "mocha --recursive --exit test/app test/modules ts/test libloki/test/node", "test-node":
"test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test libloki/test/node", "mocha --recursive --exit test/app test/modules ts/test libloki/test/node",
"test-node-coverage-html": "nyc --reporter=lcov --reporter=html mocha --recursive test/app test/modules ts/test libloki/test/node", "test-node-coverage":
"nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test libloki/test/node",
"test-node-coverage-html":
"nyc --reporter=lcov --reporter=html mocha --recursive test/app test/modules ts/test libloki/test/node",
"eslint": "eslint .", "eslint": "eslint .",
"lint": "yarn format --list-different && yarn lint-windows", "lint": "yarn format --list-different && yarn lint-windows",
"dev-lint": "yarn format --list-different; yarn lint-windows", "dev-lint": "yarn format --list-different; yarn lint-windows",
"lint-windows": "yarn eslint && yarn tslint", "lint-windows": "yarn eslint && yarn tslint",
"lint-deps": "node ts/util/lint/linter.js", "lint-deps": "node ts/util/lint/linter.js",
"tslint": "tslint --format stylish --project .", "tslint": "tslint --format stylish --project .",
"format": "prettier --write \"*.{css,js,json,md,scss,ts,tsx}\" \"./**/*.{css,js,json,md,scss,ts,tsx}\"", "format":
"prettier --write \"*.{css,js,json,md,scss,ts,tsx}\" \"./**/*.{css,js,json,md,scss,ts,tsx}\"",
"transpile": "tsc", "transpile": "tsc",
"clean-transpile": "rimraf ts/**/*.js && rimraf ts/*.js", "clean-transpile": "rimraf ts/**/*.js && rimraf ts/*.js",
"open-coverage": "open coverage/lcov-report/index.html", "open-coverage": "open coverage/lcov-report/index.html",
"styleguide": "styleguidist server", "styleguide": "styleguidist server",
"pow-metrics": "node metrics_app.js localhost 9000", "pow-metrics": "node metrics_app.js localhost 9000",
"ready": "yarn clean-transpile && yarn grunt && yarn lint && yarn test-node && yarn test-electron && yarn lint-deps" "ready":
"yarn clean-transpile && yarn grunt && yarn lint && yarn test-node && yarn test-electron && yarn lint-deps"
}, },
"dependencies": { "dependencies": {
"@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#2e28733b61640556b0272a3bfc78b0357daf71e6", "@journeyapps/sqlcipher":
"https://github.com/scottnonnenberg-signal/node-sqlcipher.git#2e28733b61640556b0272a3bfc78b0357daf71e6",
"@sindresorhus/is": "0.8.0", "@sindresorhus/is": "0.8.0",
"@types/dompurify": "^2.0.0", "@types/dompurify": "^2.0.0",
"backbone": "1.3.3", "backbone": "1.3.3",
@ -72,7 +86,8 @@
"emoji-datasource": "4.0.0", "emoji-datasource": "4.0.0",
"emoji-datasource-apple": "4.0.0", "emoji-datasource-apple": "4.0.0",
"emoji-js": "3.4.0", "emoji-js": "3.4.0",
"emoji-panel": "https://github.com/scottnonnenberg-signal/emoji-panel.git#v0.5.5", "emoji-panel":
"https://github.com/scottnonnenberg-signal/emoji-panel.git#v0.5.5",
"filesize": "3.6.1", "filesize": "3.6.1",
"firstline": "1.2.1", "firstline": "1.2.1",
"form-data": "2.3.2", "form-data": "2.3.2",
@ -205,9 +220,7 @@
"artifactName": "${name}-mac-${version}.${ext}", "artifactName": "${name}-mac-${version}.${ext}",
"category": "public.app-category.social-networking", "category": "public.app-category.social-networking",
"icon": "build/icons/mac/icon.icns", "icon": "build/icons/mac/icon.icns",
"target": [ "target": ["dmg"],
"dmg"
],
"bundleVersion": "1", "bundleVersion": "1",
"hardenedRuntime": true, "hardenedRuntime": true,
"gatekeeperAssess": false, "gatekeeperAssess": false,
@ -228,9 +241,7 @@
"url": "https://updates.signal.org/desktop" "url": "https://updates.signal.org/desktop"
} }
], ],
"target": [ "target": ["nsis"]
"nsis"
]
}, },
"nsis": { "nsis": {
"deleteAppDataOnUninstall": true "deleteAppDataOnUninstall": true
@ -241,9 +252,7 @@
"StartupWMClass": "Loki Messenger" "StartupWMClass": "Loki Messenger"
}, },
"asarUnpack": "node_modules/spellchecker/vendor/hunspell_dictionaries", "asarUnpack": "node_modules/spellchecker/vendor/hunspell_dictionaries",
"target": [ "target": ["deb"],
"deb"
],
"icon": "build/icons/png" "icon": "build/icons/png"
}, },
"deb": { "deb": {

@ -739,14 +739,12 @@ label {
margin-left: 75px; margin-left: 75px;
} }
.session-loader { .session-loader {
display: inline-block; display: inline-block;
position: relative; position: relative;
width: 80px; width: 80px;
height: 80px; height: 80px;
div { div {
position: absolute; position: absolute;
top: 33px; top: 33px;

@ -37,7 +37,6 @@ export class AddServerDialog extends React.Component<Props, State> {
this.closeDialog = this.closeDialog.bind(this); this.closeDialog = this.closeDialog.bind(this);
this.onKeyUp = this.onKeyUp.bind(this); this.onKeyUp = this.onKeyUp.bind(this);
} }
public render() { public render() {
@ -77,8 +76,8 @@ export class AddServerDialog extends React.Component<Props, State> {
{this.state.view === 'connecting' ? ( {this.state.view === 'connecting' ? (
<> <>
<div className="session-modal__centered"> <div className="session-modal__centered">
<div className="spacer-lg"></div> <div className="spacer-lg" />
<SessionSpinner/> <SessionSpinner />
<div className="spacer-lg" /> <div className="spacer-lg" />
</div> </div>
@ -108,18 +107,18 @@ export class AddServerDialog extends React.Component<Props, State> {
} }
if (view === 'connecting') { if (view === 'connecting') {
// TODO: Make this not hard coded // TODO: Make this not hard coded
const channelId = 1; const channelId = 1;
const serverUrl = String($('.session-modal #server-url').val()).toLowerCase(); const serverUrl = String(
$('.session-modal #server-url').val()
).toLowerCase();
this.setState({ this.setState({
error: null, error: null,
serverUrl: serverUrl, serverUrl: serverUrl,
}) });
if (serverUrl.length == 0){ if (serverUrl.length == 0) {
this.setState({ this.setState({
error: i18n('noServerUrl'), error: i18n('noServerUrl'),
view: 'default', view: 'default',
@ -134,23 +133,22 @@ export class AddServerDialog extends React.Component<Props, State> {
connecting: true, connecting: true,
}); });
const connectionResult = this.attemptConnection(serverUrl, channelId); const connectionResult = this.attemptConnection(serverUrl, channelId);
// Give 5s maximum for promise to revole. Else, throw error. // Give 5s maximum for promise to revole. Else, throw error.
const max_connection_duration = 5000; const max_connection_duration = 5000;
const connectionTimeout = setTimeout(() => { const connectionTimeout = setTimeout(() => {
if (!this.state.success){ if (!this.state.success) {
this.showView('default'); this.showView('default');
this.setState({
connecting: false,
success: false,
error: i18n('connectToServerFail'),
});
return; this.setState({
} connecting: false,
success: false,
error: i18n('connectToServerFail'),
});
return;
}
}, max_connection_duration); }, max_connection_duration);
connectionResult connectionResult
@ -160,7 +158,7 @@ export class AddServerDialog extends React.Component<Props, State> {
if (this.state.connecting) { if (this.state.connecting) {
this.setState({ this.setState({
success: true, success: true,
}) });
window.pushToast({ window.pushToast({
title: i18n('connectToServerSuccess'), title: i18n('connectToServerSuccess'),
id: 'connectToServerSuccess', id: 'connectToServerSuccess',
@ -169,9 +167,9 @@ export class AddServerDialog extends React.Component<Props, State> {
this.closeDialog(); this.closeDialog();
} }
}) })
.catch((error) => { .catch(error => {
clearTimeout(connectionTimeout); clearTimeout(connectionTimeout);
this.showView('default'); this.showView('default');
this.setState({ this.setState({
connecting: false, connecting: false,
@ -207,7 +205,7 @@ export class AddServerDialog extends React.Component<Props, State> {
private onKeyUp(event: any) { private onKeyUp(event: any) {
switch (event.key) { switch (event.key) {
case 'Enter': case 'Enter':
if (this.state.view == 'default'){ if (this.state.view == 'default') {
this.showView('connecting'); this.showView('connecting');
} }
break; break;
@ -226,18 +224,20 @@ export class AddServerDialog extends React.Component<Props, State> {
private async attemptConnection(serverUrl: string, channelId: number) { private async attemptConnection(serverUrl: string, channelId: number) {
const { i18n } = this.props; const { i18n } = this.props;
const rawServerUrl = serverUrl const rawServerUrl = serverUrl
.replace(/^https?:\/\//i, '') .replace(/^https?:\/\//i, '')
.replace(/[/\\]+$/i, ''); .replace(/[/\\]+$/i, '');
const sslServerUrl = `https://${rawServerUrl}`; const sslServerUrl = `https://${rawServerUrl}`;
const conversationId = `publicChat:${channelId}@${rawServerUrl}`; const conversationId = `publicChat:${channelId}@${rawServerUrl}`;
const conversationExists = window.ConversationController.get(conversationId); const conversationExists = window.ConversationController.get(
conversationId
);
if (conversationExists) { if (conversationExists) {
// We are already a member of this public chat // We are already a member of this public chat
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (false){ if (false) {
resolve(); resolve();
} }
reject(i18n('publicChatExists')); reject(i18n('publicChatExists'));
@ -250,7 +250,7 @@ export class AddServerDialog extends React.Component<Props, State> {
if (!serverAPI) { if (!serverAPI) {
// Url incorrect or server not compatible // Url incorrect or server not compatible
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (false){ if (false) {
resolve(); resolve();
} }
reject(i18n('connectToServerFail')); reject(i18n('connectToServerFail'));

@ -7,8 +7,8 @@ interface Props {
title: string; title: string;
onOk?: any; onOk?: any;
onClose?: any; onClose?: any;
onClickOk: any, onClickOk: any;
onClickClose: any, onClickClose: any;
okText?: string; okText?: string;
cancelText?: string; cancelText?: string;
hideCancel: boolean; hideCancel: boolean;
@ -18,59 +18,43 @@ export class SessionConfirm extends React.Component<Props> {
public static defaultProps = { public static defaultProps = {
title: '', title: '',
hideCancel: false, hideCancel: false,
} };
constructor(props: any) { constructor(props: any) {
super(props); super(props);
} }
public render() { public render() {
const { title, const { title, message, onClickOk, onClickClose, hideCancel } = this.props;
message,
onClickOk,
onClickClose,
hideCancel,
} = this.props;
const okText = this.props.okText || window.i18n('ok'); const okText = this.props.okText || window.i18n('ok');
const cancelText = this.props.cancelText || window.i18n('cancel'); const cancelText = this.props.cancelText || window.i18n('cancel');
const showHeader = !! this.props.title; const showHeader = !!this.props.title;
return ( return (
<SessionModal <SessionModal
title={title} title={title}
onClose={() => null} onClose={() => null}
onOk={() => null} onOk={() => null}
showExitIcon={false} showExitIcon={false}
showHeader={showHeader} showHeader={showHeader}
> >
{ showHeader ? null : ( {showHeader ? null : <div className="spacer-lg" />}
<div className="spacer-lg"></div>
<div className="session-modal__centered">
<span className="text-subtle">{message}</span>
</div>
<div className="spacer-lg" />
<div className="session-modal__button-group">
<SessionButton text={okText} onClick={onClickOk} />
{hideCancel ? null : (
<SessionButton text={cancelText} onClick={onClickClose} />
)} )}
</div>
<div className="session-modal__centered"> </SessionModal>
<span className="text-subtle">
{message}
</span>
</div>
<div className="spacer-lg"></div>
<div className="session-modal__button-group">
<SessionButton
text={okText}
onClick={onClickOk}
/>
{ hideCancel ? null : (
<SessionButton
text={cancelText}
onClick={onClickClose}
/>
)}
</div>
</SessionModal>
); );
} }
} }

@ -19,12 +19,12 @@ interface State {
isVisible: boolean; isVisible: boolean;
} }
export class SessionModal extends React.PureComponent<Props, State> { export class SessionModal extends React.PureComponent<Props, State> {
public static defaultProps = { public static defaultProps = {
showExitIcon: true, showExitIcon: true,
showHeader: true, showHeader: true,
}; };
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.state = { this.state = {
@ -43,7 +43,7 @@ export class SessionModal extends React.PureComponent<Props, State> {
return isVisible ? ( return isVisible ? (
<div className={'session-modal'}> <div className={'session-modal'}>
{ showHeader ? ( {showHeader ? (
<> <>
<div className="session-modal__header"> <div className="session-modal__header">
<div className="session-modal__header__close"> <div className="session-modal__header__close">
@ -53,7 +53,7 @@ export class SessionModal extends React.PureComponent<Props, State> {
iconSize={SessionIconSize.Small} iconSize={SessionIconSize.Small}
onClick={this.close} onClick={this.close}
/> />
) : null } ) : null}
</div> </div>
<div className="session-modal__header__title">{title}</div> <div className="session-modal__header__title">{title}</div>
<div className="session-modal__header__icons"> <div className="session-modal__header__icons">
@ -71,7 +71,7 @@ export class SessionModal extends React.PureComponent<Props, State> {
</div> </div>
</div> </div>
</> </>
) : null } ) : null}
<div className="session-modal__body">{this.props.children}</div> <div className="session-modal__body">{this.props.children}</div>
</div> </div>

@ -1,14 +1,14 @@
import React from 'react'; import React from 'react';
interface Props { interface Props {
loading: boolean; loading: boolean;
} }
export class SessionSpinner extends React.Component<Props> { export class SessionSpinner extends React.Component<Props> {
public static defaultProps = { public static defaultProps = {
loading: true, loading: true,
} };
constructor(props: any) { constructor(props: any) {
super(props); super(props);
} }
@ -17,11 +17,16 @@ export class SessionSpinner extends React.Component<Props> {
const { loading } = this.props; const { loading } = this.props;
return ( return (
<> <>
{ loading ? ( {loading ? (
<div className="session-loader"><div></div><div></div><div></div><div></div></div> <div className="session-loader">
) : null } <div />
</> <div />
<div />
<div />
</div>
) : null}
</>
); );
} }
} }

Loading…
Cancel
Save