import React, { useState, useEffect, useRef } from 'react';
import { connect } from 'react-redux';
import { Route, Switch, Redirect } from 'react-router-dom';
import { css } from 'glamor';
import * as actions from 'loot-core/src/client/actions';
import Platform from 'loot-core/src/client/platform';
import { send, listen } from 'loot-core/src/platform/client/fetch';
import { numberFormats } from 'loot-core/src/shared/util';
import { Information } from 'loot-design/src/components/alerts';
import {
View,
Text,
Button,
ButtonWithLoading,
AnchorLink
} from 'loot-design/src/components/common';
import { styles, colors } from 'loot-design/src/style';
import ExpandArrow from 'loot-design/src/svg/ExpandArrow';
import useServerVersion from '../hooks/useServerVersion';
let dateFormats = [
{ value: 'MM/dd/yyyy', label: 'MM/DD/YYYY' },
{ value: 'dd/MM/yyyy', label: 'DD/MM/YYYY' },
{ value: 'yyyy-MM-dd', label: 'YYYY-MM-DD' },
{ value: 'MM.dd.yyyy', label: 'MM.DD.YYYY' },
{ value: 'dd.MM.yyyy', label: 'DD.MM.YYYY' }
];
function Title({ name, style }) {
return (
{name}
);
}
function Advanced({ prefs, userData, pushModal, resetSync }) {
let [expanded, setExpanded] = useState(true);
let [resetting, setResetting] = useState(false);
let [resettingCache, setResettingCache] = useState(false);
async function onResetSync() {
setResetting(true);
await resetSync();
setResetting(false);
}
async function onResetCache() {
setResettingCache(true);
await send('reset-budget-cache');
setResettingCache(false);
}
return (
setExpanded(!expanded)}
>
Advanced
{expanded && (
Budget ID: {prefs.id}
Reset budget cache will clear all cached values
for the budget and recalculate the entire budget. All values in
the budget are cached for performance reasons, and if there is a
bug in the cache you won't see correct values. There is no danger
in resetting the cache. Hopefully you never have to do this.
Reset budget cache
Reset sync will remove all local data used to
track changes for syncing, and create a fresh sync id on our
server. This file on other devices will have to be re-downloaded
to use the new sync id. Use this if there is a problem with
syncing and you want to start fresh.
Reset sync
Sync ID: {prefs.groupId || '(none)'}
)}
);
}
function GlobalSettings({
globalPrefs,
userData,
saveGlobalPrefs,
pushModal,
closeBudget
}) {
let [documentDirChanged, setDirChanged] = useState(false);
let dirScrolled = useRef(null);
useEffect(() => {
if (dirScrolled.current) {
dirScrolled.current.scrollTo(10000, 0);
}
}, []);
async function onChooseDocumentDir() {
let res = await window.Actual.openFileDialog({
properties: ['openDirectory']
});
if (res) {
saveGlobalPrefs({ documentDir: res[0] });
setDirChanged(true);
}
}
function onAutoUpdate(e) {
saveGlobalPrefs({ autoUpdate: e.target.checked });
}
function onTrackUsage(e) {
saveGlobalPrefs({ trackUsage: e.target.checked });
}
return (
{!Platform.isBrowser && (
Store files here:
{globalPrefs.documentDir}
)}
{documentDirChanged && (
A restart is required for this change to take effect
)}
Automatically check for updates
By default, Actual will automatically apply new updates as they
are available. Disabling this will avoid updating Actual. You will
need to go to the About menu to manually check for updates.
Send basic usage statistics back to Actual{"'"}s servers
We don{"'"}t track anything specific — only the fact that
you{"'"}ve opened Actual. This helps by giving us important
feedback about how popular new features are.
);
}
function FileSettings({
savePrefs,
prefs,
userData,
localServerURL,
pushModal,
resetSync,
setAppState,
signOut
}) {
function onDateFormat(e) {
let format = e.target.value;
savePrefs({ dateFormat: format });
}
function onNumberFormat(e) {
let format = e.target.value;
savePrefs({ numberFormat: format });
}
function onChangeKey() {
pushModal('create-encryption-key', { recreate: true });
}
async function onExport() {
let data = await send('export-budget');
window.Actual.saveFile(data, `${prefs.id}.zip`, 'Export budget');
}
let dateFormat = prefs.dateFormat || 'MM/dd/yyyy';
let numberFormat = prefs.numberFormat || 'comma-dot';
return (
Date format:{' '}
Number format:{' '}
End-to-end encryption
{prefs.encryptKeyId ? (
Encryption is turned on.
{' '}
Your data is encrypted with a key that only you have before
sending it out to the cloud . Local data remains unencrypted
so if you forget your password you can re-encrypt it.
) : (
Encryption is not enabled. Any data on our servers is still
stored safely and securely, but it's not end-to-end
encrypted which means we have the ability to read it (but we
won't). If you want, you can use a password to encrypt your
data on our servers.
)}
);
}
function SettingsLink({ to, name, style, first, last }) {
return (
{name}
);
}
function Version() {
const version = useServerVersion();
return (
{`App: v${window.Actual.ACTUAL_VERSION} | Server: ${version}`}
);
}
class Settings extends React.Component {
componentDidMount() {
this.unlisten = listen('prefs-updated', () => {
this.props.loadPrefs();
});
this.props.getUserData();
this.props.loadPrefs();
}
componentWillUnmount() {
this.unlisten();
}
render() {
let { prefs, globalPrefs, localServerURL, userData, match } = this.props;
return (
);
}
}
export default connect(
state => ({
prefs: state.prefs.local,
globalPrefs: state.prefs.global,
localServerURL: state.account.localServerURL,
userData: state.user.data
}),
actions
)(Settings);