diff --git a/app/javascript/mastodon/components/error_boundary.js b/app/javascript/mastodon/components/error_boundary.js
index d1ca5bf756..82543e1185 100644
--- a/app/javascript/mastodon/components/error_boundary.js
+++ b/app/javascript/mastodon/components/error_boundary.js
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import illustration from '../../images/elephant_ui_disappointed.svg';
+import { FormattedMessage } from 'react-intl';
+import { version, source_url } from 'mastodon/initial_state';
export default class ErrorBoundary extends React.PureComponent {
@@ -12,26 +13,53 @@ export default class ErrorBoundary extends React.PureComponent {
hasError: false,
stackTrace: undefined,
componentStack: undefined,
- }
+ };
- componentDidCatch(error, info) {
+ componentDidCatch (error, info) {
this.setState({
hasError: true,
stackTrace: error.stack,
componentStack: info && info.componentStack,
+ copied: false,
});
}
+ handleCopyStackTrace = () => {
+ const { stackTrace } = this.state;
+ const textarea = document.createElement('textarea');
+
+ textarea.textContent = stackTrace;
+ textarea.style.position = 'fixed';
+
+ document.body.appendChild(textarea);
+
+ try {
+ textarea.select();
+ document.execCommand('copy');
+ } catch (e) {
+
+ } finally {
+ document.body.removeChild(textarea);
+ }
+
+ this.setState({ copied: true });
+ setTimeout(() => this.setState({ copied: false }), 700);
+ }
+
render() {
- const { hasError } = this.state;
+ const { hasError, copied } = this.state;
if (!hasError) {
return this.props.children;
}
return (
-
-
+
+
+
+
+
Mastodon v{version} · ·
+
);
}
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index fc769a18ff..6ed6b8bcb4 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -160,7 +160,7 @@
"getting_started.heading": "Getting started",
"getting_started.invite": "Invite people",
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
- "getting_started.security": "Security",
+ "getting_started.security": "Account settings",
"getting_started.terms": "Terms of service",
"hashtag.column_header.tag_mode.all": "and {additional}",
"hashtag.column_header.tag_mode.any": "or {additional}",
diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss
index 1f3ef7da2e..2b10b5ad3c 100644
--- a/app/javascript/styles/mastodon/basics.scss
+++ b/app/javascript/styles/mastodon/basics.scss
@@ -135,13 +135,18 @@ button {
.app-holder {
&,
- & > div {
+ & > div,
+ & > noscript {
display: flex;
width: 100%;
align-items: center;
justify-content: center;
outline: 0 !important;
}
+
+ & > noscript {
+ height: 100vh;
+ }
}
.layout-single-column .app-holder {
@@ -157,3 +162,70 @@ button {
height: 100%;
}
}
+
+.error-boundary,
+.app-holder noscript {
+ flex-direction: column;
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 1.7;
+ color: lighten($error-red, 4%);
+ text-align: center;
+
+ & > div {
+ max-width: 500px;
+ }
+
+ p {
+ margin-bottom: .85em;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ a {
+ color: $highlight-text-color;
+
+ &:hover,
+ &:focus,
+ &:active {
+ text-decoration: none;
+ }
+ }
+
+ &__footer {
+ color: $dark-text-color;
+ font-size: 13px;
+
+ a {
+ color: $dark-text-color;
+ }
+ }
+
+ button {
+ display: inline;
+ border: 0;
+ background: transparent;
+ color: $dark-text-color;
+ font: inherit;
+ padding: 0;
+ margin: 0;
+ line-height: inherit;
+ cursor: pointer;
+ outline: 0;
+ transition: color 300ms linear;
+ text-decoration: underline;
+
+ &:hover,
+ &:focus,
+ &:active {
+ text-decoration: none;
+ }
+
+ &.copied {
+ color: $valid-value-color;
+ transition: none;
+ }
+ }
+}