feat(preferences): error reporting segment (#652)

* feat(preferences): error reporting segment

* feat(preferences): move error reporting to general pane
This commit is contained in:
Gorjan Petrovski 2021-09-28 18:08:27 +02:00 committed by GitHub
parent b312df41a6
commit 3867f625f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 117 additions and 20 deletions

View file

@ -1,14 +1,14 @@
import { RoundIconButton } from '@/components/RoundIconButton';
import { TitleBar, Title } from '@/components/TitleBar';
import { FunctionComponent } from 'preact';
import { AccountPreferences, HelpAndFeedback, Security } from './panes';
import { AccountPreferences, General, HelpAndFeedback, Security } from './panes';
import { observer } from 'mobx-react-lite';
import { PreferencesMenu } from './PreferencesMenu';
import { PreferencesMenuView } from './PreferencesMenuView';
import { WebApplication } from '@/ui_models/application';
import { MfaProps } from './panes/two-factor-auth/MfaProps';
import { AppState } from '@/ui_models/app_state';
import { useCallback, useEffect } from 'preact/hooks';
import { useEffect } from 'preact/hooks';
interface PreferencesProps extends MfaProps {
application: WebApplication;
@ -21,7 +21,7 @@ const PaneSelector: FunctionComponent<
> = observer((props) => {
switch (props.menu.selectedPaneId) {
case 'general':
return null;
return <General appState={props.appState} application={props.application} />
case 'account':
return (
<AccountPreferences

View file

@ -7,18 +7,18 @@ const HorizontalLine: FunctionComponent<{ index: number; length: number }> = ({
}) => (index < length - 1 ? <HorizontalSeparator classes="my-4" /> : null);
export const PreferencesGroup: FunctionComponent = ({ children }) => (
<div className="bg-default border-1 border-solid rounded border-gray-300 px-6 py-6 flex flex-col">
<div className="bg-default border-1 border-solid rounded border-gray-300 px-6 py-6 flex flex-col mb-3">
{Array.isArray(children)
? children
.filter(
(child) => child != undefined && child !== '' && child !== false
)
.map((child, i, arr) => (
<>
{child}
<HorizontalLine index={i} length={arr.length} />
</>
))
.filter(
(child) => child != undefined && child !== '' && child !== false
)
.map((child, i, arr) => (
<>
{child}
<HorizontalLine index={i} length={arr.length} />
</>
))
: children}
</div>
);

View file

@ -7,12 +7,6 @@ export const PreferencesPane: FunctionComponent = ({ children }) => (
{children != undefined && Array.isArray(children)
? children
.filter((child) => child != undefined)
.map((child) => (
<>
{child}
<div className="min-h-3" />
</>
))
: children}
</div>
</div>

View file

@ -0,0 +1,16 @@
import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state';
import { FunctionComponent } from 'preact';
import { PreferencesPane } from '../components';
import { ErrorReporting } from './general-segments';
interface GeneralProps {
appState: AppState;
application: WebApplication;
}
export const General: FunctionComponent<GeneralProps> = (props) => (
<PreferencesPane>
<ErrorReporting appState={props.appState} />
</PreferencesPane>
);

View file

@ -0,0 +1,86 @@
import { useState } from 'preact/hooks';
import { storage, StorageKey } from '@Services/localStorage';
import { disableErrorReporting, enableErrorReporting, errorReportingId } from '@Services/errorReporting';
import { alertDialog } from '@Services/alertService';
import { observer } from 'mobx-react-lite';
import { AppState } from '@/ui_models/app_state';
import { FunctionComponent } from 'preact';
import { PreferencesGroup, PreferencesSegment, Title, Text } from '@/preferences/components';
import { Switch } from '@/components/Switch';
type Props = {
appState: AppState;
}
export const ErrorReporting: FunctionComponent<Props> = observer(({ appState }: Props) => {
const [isErrorReportingEnabled] = useState(() => storage.get(StorageKey.DisableErrorReporting) === false);
const [errorReportingIdValue] = useState(() => errorReportingId());
const toggleErrorReportingEnabled = () => {
if (isErrorReportingEnabled) {
disableErrorReporting();
} else {
enableErrorReporting();
}
if (!appState.sync.inProgress) {
window.location.reload();
}
};
const openErrorReportingDialog = () => {
alertDialog({
title: 'Data sent during automatic error reporting',
text: `
We use <a target="_blank" rel="noreferrer" href="https://www.bugsnag.com/">Bugsnag</a>
to automatically report errors that occur while the app is running. See
<a target="_blank" rel="noreferrer" href="https://docs.bugsnag.com/platforms/javascript/#sending-diagnostic-data">
this article, paragraph 'Browser' under 'Sending diagnostic data',
</a>
to see what data is included in error reports.
<br><br>
Error reports never include IP addresses and are fully
anonymized. We use error reports to be alerted when something in our
code is causing unexpected errors and crashes in your application
experience.
`
});
};
return (
<PreferencesGroup>
<PreferencesSegment>
<div className="flex flex-row items-center">
<div className="flex-grow flex flex-col">
<Title>Error Reporting</Title>
<Text>
Help us improve Standard Notes by automatically submitting
anonymized error reports.
</Text>
</div>
<div className="flex flex-col justify-center items-center min-w-15">
<Switch onChange={toggleErrorReportingEnabled} checked={isErrorReportingEnabled} />
</div>
</div>
<div className="min-h-2" />
{errorReportingIdValue && (
<>
<Text>
Your random identifier is <span className="font-bold">{errorReportingIdValue}</span>
</Text>
<Text>
Disabling error reporting will remove that identifier from your
local storage, and a new identifier will be created should you
decide to enable error reporting again in the future.
</Text>
</>
)}
<Text>
<a className="cursor-pointer" onClick={openErrorReportingDialog}>What data is being sent?</a>
</Text>
</PreferencesSegment>
</PreferencesGroup>
);
});

View file

@ -0,0 +1 @@
export * from './ErrorReporting';

View file

@ -1,3 +1,4 @@
export * from './HelpFeedback';
export * from './Security';
export * from './AccountPreferences';
export * from './General';

View file

@ -6,7 +6,6 @@ import { ApplicationEvent } from '@standardnotes/snjs';
import { isSameDay } from '@/utils';
import { PreferencesGroup, PreferencesSegment, Title, Text } from '@/preferences/components';
import { Button } from '@/components/Button';
import { Switch } from '@/components/Switch';
type Props = {
application: WebApplication;