1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-30 10:36:35 +02:00

Merge branch 'tidy_config'

This commit is contained in:
Laurent Cozic 2019-09-11 23:00:03 +01:00
commit 5db7502fe4
21 changed files with 421 additions and 122 deletions

View File

@ -333,7 +333,6 @@ class Application extends BaseApplication {
const importItems = [];
const exportItems = [];
const preferencesItems = [];
const toolsItemsFirst = [];
const templateItems = [];
const ioService = new InteropService();
@ -480,33 +479,6 @@ class Application extends BaseApplication {
},
};
preferencesItems.push({
label: _('General Options'),
accelerator: 'CommandOrControl+,',
click: () => {
this.dispatch({
type: 'NAV_GO',
routeName: 'Config',
});
},
}, {
label: _('Encryption options'),
click: () => {
this.dispatch({
type: 'NAV_GO',
routeName: 'EncryptionConfig',
});
},
}, {
label: _('Web clipper options'),
click: () => {
this.dispatch({
type: 'NAV_GO',
routeName: 'ClipperConfig',
});
},
});
toolsItemsFirst.push(syncStatusItem, {
type: 'separator',
screens: ['Main'],
@ -563,7 +535,17 @@ class Application extends BaseApplication {
},
});
const toolsItems = toolsItemsFirst.concat(preferencesItems);
const toolsItems = toolsItemsFirst.push({
label: _('Options'),
visible: !shim.isMac(),
accelerator: 'CommandOrControl+,',
click: () => {
this.dispatch({
type: 'NAV_GO',
routeName: 'Config',
});
},
});
function _checkForUpdates(ctx) {
bridge().checkForUpdates(false, bridge().window(), ctx.checkForUpdateLoggerPath(), { includePreReleases: Setting.value('autoUpdate.includePreReleases') });
@ -608,7 +590,13 @@ class Application extends BaseApplication {
}, {
label: _('Preferences...'),
visible: shim.isMac() ? true : false,
submenu: preferencesItems,
accelerator: 'CommandOrControl+,',
click: () => {
this.dispatch({
type: 'NAV_GO',
routeName: 'Config',
});
},
}, {
label: _('Check for updates...'),
visible: shim.isMac() ? true : false,

View File

@ -122,6 +122,10 @@ class Bridge {
checkForUpdates(inBackground, window, logFilePath, options);
}
buildDir() {
return this.electronApp().buildDir();
}
}
let bridge_ = null;

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 433.43759 401.99866" height="304.543276757" width="328.360557044" xml:space="preserve" id="svg10" version="1.1"><metadata id="metadata16"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs14"><clipPath id="clipPath26" clipPathUnits="userSpaceOnUse"><path id="path24" d="M 0,792 H 612 V 0 H 0 Z"/></clipPath><clipPath id="clipPath44" clipPathUnits="userSpaceOnUse"><path id="path42" d="M 143.461,245.334 H 468.539 V 420.666 H 143.461 Z"/></clipPath></defs><g transform="matrix(1.3333333,0,0,-1.3333333,-191.2812,729.11065)" id="g18"><g id="g91"><g id="g20"><g id="g22" clip-path="url(#clipPath26)"><g id="g28" transform="translate(143.4609,254.334)"><path d="m 0,0 c 0,-4.971 4.029,-9 9,-9 h 307.078 c 4.971,0 9,4.029 9,9 v 157.331 c 0,4.971 -4.029,9 -9,9 H 9 c -4.971,0 -9,-4.029 -9,-9 z" style="fill:#efeff0;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path30"/></g><path d="m 354.157,522.753 h -96.818 v 24.08 h 96.818 z" style="fill:#abadad;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path32"/><g id="g34" transform="translate(468.5391,372.2559)"><path d="m 0,0 h -325.078 v 126.417 h 90.805 l -0.003,24.08 23.076,24.08 0.008,-48.16 h 96.807 l 0.006,48.16 24.079,-24.08 -0.006,-24.08 H 0 Z" style="fill:#e3e4e5;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path36"/></g></g></g><g id="g38"><g id="g40" clip-path="url(#clipPath44)"><g id="g46" transform="translate(305.6372,413.5986)"><path d="M 0,0 C 0,0 82.026,3.692 125.5,-78.741 H -6.973 c 0,0 -25.017,0.822 -46.346,-29.53 -6.149,-12.716 -12.71,-25.841 -5.329,-51.675 -10.664,18.042 -56.599,98.018 -56.599,98.018 0,0 32.402,58.649 115.247,61.928" style="fill:#e14c40;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path48"/></g><g id="g50" transform="translate(426.8643,204.3018)"><path d="m 0,0 c 0,0 -37.825,-72.871 -130.954,-69.291 11.49,19.885 66.251,114.714 66.251,114.714 0,0 13.222,21.252 -2.387,54.897 -7.936,11.687 -16.02,23.933 -42.087,30.464 C -88.213,130.99 4.009,130.77 4.009,130.77 4.009,130.77 38.589,73.38 0,0" style="fill:#ffd24d;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path52"/></g><g id="g54" transform="translate(184.9966,203.7461)"><path d="M 0,0 C 0,0 -44.197,69.203 5.476,148.06 16.955,128.166 71.687,33.318 71.687,33.318 c 0,0 11.793,-22.075 48.739,-25.381 14.087,1.029 28.732,1.905 47.42,21.21 -10.3,-18.253 -56.609,-98.012 -56.609,-98.012 0,0 -66.989,-1.249 -111.237,68.865" style="fill:#00aa60;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path56"/></g><g id="g58" transform="translate(243.23,273.1113)"><path d="m 0,0 c 0,34.273 27.786,62.063 62.066,62.063 34.278,0 62.061,-27.79 62.061,-62.063 0,-34.283 -27.783,-62.069 -62.061,-62.069 C 27.786,-62.069 0,-34.283 0,0" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path60"/></g><g id="g62" transform="translate(256.6279,273.1113)"><path d="M 0,0 C 0,26.875 21.79,48.665 48.668,48.665 75.539,48.665 97.332,26.875 97.332,0 97.332,-26.879 75.539,-48.668 48.668,-48.668 21.79,-48.668 0,-26.879 0,0" style="fill:#577fc0;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path64"/></g><g id="g66" transform="translate(305.6357,413.5986)"><path d="m 0,0 c 0,0 54.153,2.437 97.777,-40.864 -0.717,0 -148.959,-0.477 -196.584,-0.477 C -81.582,-24.098 -49.965,-1.979 0,0" style="fill:#d6483e;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path68"/></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,44 @@
const React = require('react');
const styleSelector = require('./style/ConfigMenuBar');
const Setting = require('lib/models/Setting');
function ConfigMenuBarButton(props) {
const style = styleSelector(null, props);
const iconStyle = props.selected ? style.buttonIconSelected : style.buttonIcon;
const labelStyle = props.selected ? style.buttonLabelSelected : style.buttonLabel;
return (
<button style={style.button} onClick={props.onClick}>
<i style={iconStyle} className={'fa ' + props.iconName}></i>
<span style={labelStyle}>{props.label}</span>
</button>
);
}
function ConfigMenuBar(props) {
const buttons = [];
const style = styleSelector(null, props);
for (const section of props.sections) {
buttons.push(<ConfigMenuBarButton
selected={props.selection === section.name}
theme={props.theme}
key={section.name}
iconName={Setting.sectionNameToIcon(section.name)}
label={Setting.sectionNameToLabel(section.name)}
onClick={() => { props.onSelectionChange({ section: section });}}
/>);
}
return (
<div style={style.root} className="config-menu-bar">
<div style={style.barButtons}>
{buttons}
</div>
</div>
);
}
module.exports = ConfigMenuBar;

View File

@ -7,6 +7,9 @@ const pathUtils = require('lib/path-utils.js');
const { _ } = require('lib/locale.js');
const SyncTargetRegistry = require('lib/SyncTargetRegistry');
const shared = require('lib/components/shared/config-shared.js');
const ConfigMenuBar = require('./ConfigMenuBar.min.js');
const { EncryptionConfigScreen } = require('./EncryptionConfigScreen.min');
const { ClipperConfigScreen } = require('./ClipperConfigScreen.min');
class ConfigScreenComponent extends React.Component {
constructor() {
@ -14,6 +17,9 @@ class ConfigScreenComponent extends React.Component {
shared.init(this);
this.state.selectedSectionName = 'general';
this.state.screenName = '';
this.checkSyncConfig_ = async () => {
await shared.checkSyncConfig(this, this.state.settings);
};
@ -21,12 +27,57 @@ class ConfigScreenComponent extends React.Component {
this.rowStyle_ = {
marginBottom: 10,
};
this.configMenuBar_selectionChange = this.configMenuBar_selectionChange.bind(this);
}
componentWillMount() {
this.setState({ settings: this.props.settings });
}
componentDidMount() {
if (this.props.defaultSection) {
this.setState({ selectedSectionName: this.props.defaultSection }, () => {
this.switchSection(this.props.defaultSection);
});
}
}
sectionByName(name) {
const sections = shared.settingsSections({ device: 'desktop', settings: this.state.settings });
for (const section of sections) {
if (section.name === name) return section;
}
throw new Error('Invalid section name: ' + name);
}
screenFromName(screenName) {
if (screenName === 'encryption') return <EncryptionConfigScreen theme={this.props.theme}/>;
if (screenName === 'server') return <ClipperConfigScreen theme={this.props.theme}/>;
throw new Error('Invalid screen name: ' + screenName);
}
switchSection(name) {
const section = this.sectionByName(name);
let screenName = '';
if (section.isScreen) {
screenName = section.name;
if (this.hasChanges()) {
const ok = confirm(_('This will open a new screen. Save your current changes?'));
if (ok) shared.saveSettings(this);
}
}
this.setState({ selectedSectionName: section.name, screenName: screenName });
}
configMenuBar_selectionChange(event) {
this.switchSection(event.section.name);
}
keyValueToArray(kv) {
let output = [];
for (let k in kv) {
@ -40,7 +91,7 @@ class ConfigScreenComponent extends React.Component {
return output;
}
sectionToComponent(key, section, settings) {
sectionToComponent(key, section, settings, selected) {
const theme = themeStyle(this.props.theme);
const settingComps = [];
@ -52,15 +103,11 @@ class ConfigScreenComponent extends React.Component {
}
const sectionStyle = {
marginTop: 20,
marginBottom: 20,
};
const headerStyle = Object.assign({}, theme.headerStyle, {
borderBottomWidth: 1,
borderBottomColor: theme.dividerColor,
borderBottomStyle: 'solid',
paddingBottom: '.4em',
});
if (!selected) sectionStyle.display = 'none';
if (section.name === 'general') {
sectionStyle.borderTopWidth = 0;
@ -94,7 +141,6 @@ class ConfigScreenComponent extends React.Component {
return (
<div key={key} style={sectionStyle}>
<h2 style={headerStyle}>{Setting.sectionNameToLabel(section.name)}</h2>
{noteComp}
<div>{settingComps}</div>
</div>
@ -123,6 +169,10 @@ class ConfigScreenComponent extends React.Component {
opacity: 0,
});
const checkboxLabelStyle = Object.assign({}, labelStyle, {
marginLeft: 8,
});
const controlStyle = {
display: 'inline-block',
color: theme.color,
@ -136,6 +186,13 @@ class ConfigScreenComponent extends React.Component {
maxWidth: '70em',
});
const textInputBaseStyle = Object.assign({}, controlStyle, {
border: '1px solid',
padding: '4px 6px',
borderColor: theme.dividerColor,
borderRadius: 4,
});
const updateSettingValue = (key, value) => {
// console.info(key + ' = ' + value);
return shared.updateSettingValue(this, key, value);
@ -161,6 +218,8 @@ class ConfigScreenComponent extends React.Component {
);
}
const selectStyle = Object.assign({}, controlStyle, { height: 22, borderColor: theme.dividerColor });
return (
<div key={key} style={rowStyle}>
<div style={labelStyle}>
@ -168,7 +227,7 @@ class ConfigScreenComponent extends React.Component {
</div>
<select
value={value}
style={controlStyle}
style={selectStyle}
onChange={event => {
updateSettingValue(key, event.target.value);
}}
@ -201,7 +260,7 @@ class ConfigScreenComponent extends React.Component {
onClick={event => {
onCheckboxClick(event);
}}
style={labelStyle}
style={checkboxLabelStyle}
htmlFor={'setting_checkbox_' + key}
>
{md.label()}
@ -211,10 +270,9 @@ class ConfigScreenComponent extends React.Component {
</div>
);
} else if (md.type === Setting.TYPE_STRING) {
const inputStyle = Object.assign({}, controlStyle, {
const inputStyle = Object.assign({}, textInputBaseStyle, {
width: '50%',
minWidth: '20em',
border: '1px solid',
});
const inputType = md.secure === true ? 'password' : 'text';
@ -279,7 +337,7 @@ class ConfigScreenComponent extends React.Component {
}}
value={cmd[0]}
/>
<button onClick={browseButtonClick} style={Object.assign({}, theme.buttonStyle, { marginLeft: 5, minHeight: 20, height: 20 })}>
<button onClick={browseButtonClick} style={Object.assign({}, theme.buttonStyle, { marginLeft: 5 })}>
{_('Browse...')}
</button>
</div>
@ -334,6 +392,8 @@ class ConfigScreenComponent extends React.Component {
const label = [md.label()];
if (md.unitLabel) label.push('(' + md.unitLabel() + ')');
const inputStyle = Object.assign({}, textInputBaseStyle);
return (
<div key={key} style={rowStyle}>
<div style={labelStyle}>
@ -341,7 +401,7 @@ class ConfigScreenComponent extends React.Component {
</div>
<input
type="number"
style={controlStyle}
style={inputStyle}
value={this.state.settings[key]}
onChange={event => {
onNumChange(event);
@ -373,6 +433,10 @@ class ConfigScreenComponent extends React.Component {
this.props.dispatch({ type: 'NAV_BACK' });
}
hasChanges() {
return !!this.state.changedSettingKeys.length;
}
render() {
const theme = themeStyle(this.props.theme);
@ -390,9 +454,9 @@ class ConfigScreenComponent extends React.Component {
let settings = this.state.settings;
const containerStyle = Object.assign({}, theme.containerStyle, { padding: 10, paddingTop: 0 });
const containerStyle = Object.assign({}, theme.containerStyle, { padding: 10, paddingTop: 0, display: 'flex', flex: 1 });
const hasChanges = !!this.state.changedSettingKeys.length;
const hasChanges = this.hasChanges();
const buttonStyle = Object.assign({}, theme.buttonStyle, {
display: 'inline-block',
@ -403,19 +467,33 @@ class ConfigScreenComponent extends React.Component {
opacity: hasChanges ? 1 : theme.disabledOpacity,
});
const settingComps = shared.settingsToComponents2(this, 'desktop', settings);
const settingComps = shared.settingsToComponents2(this, 'desktop', settings, this.state.selectedSectionName);
const buttonBarStyle = {
display: 'flex',
alignItems: 'center',
padding: 15,
borderBottomWidth: 1,
borderBottomStyle: 'solid',
borderBottomColor: theme.dividerColor,
padding: 10,
borderTopWidth: 1,
borderTopStyle: 'solid',
borderTopColor: theme.dividerColor,
};
const screenComp = this.state.screenName ? <div style={{overflow: 'scroll', flex:1}}>{this.screenFromName(this.state.screenName)}</div> : null;
if (screenComp) containerStyle.display = 'none';
const sections = shared.settingsSections({ device: 'desktop', settings });
return (
<div style={style}>
<ConfigMenuBar
selection={this.state.selectedSectionName}
onSelectionChange={this.configMenuBar_selectionChange}
sections={sections}
theme={this.props.theme}
/>
{screenComp}
<div style={containerStyle}>{settingComps}</div>
<div style={buttonBarStyle}>
<button
onClick={() => {
@ -424,28 +502,15 @@ class ConfigScreenComponent extends React.Component {
style={buttonStyle}
>
<i style={theme.buttonIconStyle} className={'fa fa-chevron-left'}></i>
{_('Cancel')}
</button>
<button
disabled={!hasChanges}
onClick={() => {
this.onSaveClick();
}}
style={buttonStyleApprove}
>
{_('OK')}
</button>
<button
disabled={!hasChanges}
onClick={() => {
this.onApplyClick();
}}
style={buttonStyleApprove}
>
{_('Apply')}
{hasChanges && !screenComp ? _('Cancel') : _('Back')}
</button>
{ !screenComp && (
<div>
<button disabled={!hasChanges} onClick={() => { this.onSaveClick(); }} style={buttonStyleApprove}>{_('OK')}</button>
<button disabled={!hasChanges} onClick={() => { this.onApplyClick(); }} style={buttonStyleApprove}>{_('Apply')}</button>
</div>
)}
</div>
<div style={containerStyle}>{settingComps}</div>
</div>
);
}

View File

@ -2,7 +2,6 @@ const React = require('react');
const { connect } = require('react-redux');
const Setting = require('lib/models/Setting');
const EncryptionService = require('lib/services/EncryptionService');
const { Header } = require('./Header.min.js');
const { themeStyle } = require('../theme.js');
const { _ } = require('lib/locale.js');
const { time } = require('lib/time-utils.js');
@ -85,17 +84,13 @@ class EncryptionConfigScreenComponent extends React.Component {
}
render() {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const masterKeys = this.state.masterKeys;
const containerPadding = 10;
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerStyle = Object.assign({}, theme.containerStyle, {
padding: containerPadding,
overflow: 'auto',
height: style.height - theme.headerHeight - containerPadding * 2,
});
const mkComps = [];
@ -200,7 +195,6 @@ class EncryptionConfigScreenComponent extends React.Component {
return (
<div>
<Header style={headerStyle} />
<div style={containerStyle}>
{
<div style={{ backgroundColor: theme.warningBackgroundColor, paddingLeft: 10, paddingRight: 10, paddingTop: 2, paddingBottom: 2 }}>

View File

@ -0,0 +1,45 @@
const React = require('react');
const { bridge } = require('electron').remote.require('./bridge');
const styleSelector = require('./style/ExtensionBadge');
const { _ } = require('lib/locale.js');
function platformAssets(type) {
if (type === 'firefox') {
return {
logoImage: bridge().buildDir() + '/images/firefox-logo.svg',
locationLabel: _('Firefox Extension'),
};
}
if (type === 'chrome') {
return {
logoImage: bridge().buildDir() + '/images/chrome-logo.svg',
locationLabel: _('Chrome Web Store'),
};
}
throw new Error('Invalid type:' + type);
}
function ExtensionBadge(props) {
const style = styleSelector(null, props);
const assets = platformAssets(props.type);
const onClick = () => {
bridge().openExternal(props.url);
};
const rootStyle = props.style ? Object.assign({}, style.root, props.style) : style.root;
return (
<a style={rootStyle} onClick={onClick} href="#">
<img style={style.logo} src={assets.logoImage}/>
<div style={style.labelGroup} >
<div>{_('Get it now:')}</div>
<div style={style.locationLabel}>{assets.locationLabel}</div>
</div>
</a>
);
}
module.exports = ExtensionBadge;

View File

@ -485,7 +485,10 @@ class MainScreenComponent extends React.Component {
const onViewMasterKeysClick = () => {
this.props.dispatch({
type: 'NAV_GO',
routeName: 'EncryptionConfig',
routeName: 'Config',
props: {
defaultSection: 'encryption',
},
});
};

View File

@ -17,10 +17,7 @@ class NavigatorComponent extends Component {
updateWindowTitle(title) {
try {
if (bridge().window())
bridge()
.window()
.setTitle(title);
if (bridge().window()) bridge().window().setTitle(title);
} catch (error) {
console.warn('updateWindowTitle', error);
}

View File

@ -415,10 +415,10 @@ class NoteTextComponent extends React.Component {
}
componentDidUpdate() {
if (Setting.value('env') === 'dev' && this.webviewRef()) {
this.webviewRef().openDevTools();
return;
}
// if (Setting.value('env') === 'dev' && this.webviewRef()) {
// this.webviewRef().openDevTools();
// return;
// }
if (this.webviewRef() && this.props.noteDevToolsVisible !== this.webviewRef().isDevToolsOpened()) {
if (this.props.noteDevToolsVisible) {

View File

@ -11,8 +11,6 @@ const { DropboxLoginScreen } = require('./DropboxLoginScreen.min.js');
const { StatusScreen } = require('./StatusScreen.min.js');
const { ImportScreen } = require('./ImportScreen.min.js');
const { ConfigScreen } = require('./ConfigScreen.min.js');
const { EncryptionConfigScreen } = require('./EncryptionConfigScreen.min.js');
const { ClipperConfigScreen } = require('./ClipperConfigScreen.min.js');
const { Navigator } = require('./Navigator.min.js');
const WelcomeUtils = require('lib/WelcomeUtils');
@ -89,8 +87,6 @@ class RootComponent extends React.Component {
Import: { screen: ImportScreen, title: () => _('Import') },
Config: { screen: ConfigScreen, title: () => _('Options') },
Status: { screen: StatusScreen, title: () => _('Synchronisation Status') },
EncryptionConfig: { screen: EncryptionConfigScreen, title: () => _('Encryption Options') },
ClipperConfig: { screen: ClipperConfigScreen, title: () => _('Clipper Options') },
};
return <Navigator style={navigatorStyle} screens={screens} />;

View File

@ -0,0 +1,55 @@
const { createSelector } = require('reselect');
const { themeStyle } = require('../../theme.js');
const themeSelector = (state, props) => themeStyle(props.theme);
const style = createSelector(
themeSelector,
(theme) => {
const output = {
button: {
fontFamily: theme.fontFamily,
minWidth: 52,
border: 'none',
flexDirection: 'column',
display: 'flex',
alignItems: 'center',
padding: 9,
backgroundColor: theme.backgroundColor,
},
buttonIcon: {
fontSize: 24,
color: theme.colorFaded,
},
buttonLabel: {
display: 'flex',
flex: 1,
alignItems: 'flex-end',
color: theme.colorFaded,
},
root: {
minHeight: 58,
display: 'flex',
borderBottomWidth: 1,
borderBottomStyle: 'solid',
borderBottomColor: theme.dividerColor,
},
barButtons: {
display: 'flex',
flexDirection: 'row',
},
};
output.buttonIconSelected = Object.assign({}, output.buttonIcon, {
color: theme.highlightedColor,
});
output.buttonLabelSelected = Object.assign({}, output.buttonLabel, {
color: theme.color,
});
return output;
}
);
module.exports = style;

View File

@ -0,0 +1,49 @@
const { createSelector } = require('reselect');
const { themeStyle } = require('../../theme.js');
const themeSelector = (state, props) => themeStyle(props.theme);
const style = createSelector(
themeSelector,
(theme) => {
const output = {
root: {
width: 220,
height: 60,
borderRadius: 4,
border: '1px solid',
borderColor: theme.dividerColor,
backgroundColor: theme.backgroundColor,
paddingLeft: 14,
paddingRight: 14,
paddingTop: 8,
paddingBottom: 8,
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'row',
boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
},
logo: {
width: 42,
height: 42,
},
labelGroup: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
marginLeft: 14,
fontFamily: theme.fontFamily,
color: theme.color,
fontSize: theme.fontSize,
},
locationLabel: {
fontSize: theme.fontSize * 1.2,
fontWeight: 'bold',
},
};
return output;
}
);
module.exports = style;

View File

@ -5932,6 +5932,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"reselect": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
"integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA=="
},
"resolve": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz",

View File

@ -24,7 +24,8 @@
"appId": "net.cozic.joplin-desktop",
"npmRebuild": false,
"extraResources": [
"build/icons/*"
"build/icons/*",
"build/images/*"
],
"win": {
"rfc3161TimeStampServer": "http://sha256timestamp.ws.symantec.com/sha256/timestamp",
@ -141,6 +142,7 @@
"read-chunk": "^2.1.0",
"readability-node": "^0.1.0",
"redux": "^3.7.2",
"reselect": "^4.0.0",
"server-destroy": "^1.0.1",
"smalltalk": "^2.5.1",
"sprintf-js": "^1.1.1",

View File

@ -22,6 +22,10 @@ table td, table th {
border: 1px solid #ccc;
}
a {
text-decoration: none;
}
::-webkit-scrollbar {
width: 7px;
height: 7px;
@ -140,3 +144,8 @@ table td, table th {
display: none;
}
}
.config-menu-bar button:focus {
outline: 0 none;
}

View File

@ -65,7 +65,11 @@ globalStyle.buttonStyle = {
maxWidth: 160,
paddingLeft: 12,
paddingRight: 12,
paddingTop: 6,
paddingBottom: 6,
boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
fontSize: globalStyle.fontSize,
borderRadius: 4,
};
const lightStyle = {
@ -140,6 +144,8 @@ const darkStyle = {
editorTheme: 'twilight',
codeThemeCss: 'atom-one-dark-reasonable.css',
highlightedColor: '#0066C7',
};
// Solarized Styles
@ -314,6 +320,11 @@ function addExtraStyles(style) {
style.dropdownList = Object.assign({}, style.inputStyle);
// In general the highlighted color, used to highlight text or icons, should be the same as selectedColor2
// but some times, depending on the theme, it might be too dark or too light, so it can be
// specified directly by the theme too.
if (!style.highlightedColor) style.highlightedColor = style.selectedColor2;
return style;
}

View File

@ -2,6 +2,7 @@ const Setting = require('lib/models/Setting.js');
const SyncTargetRegistry = require('lib/SyncTargetRegistry');
const ObjectUtils = require('lib/ObjectUtils');
const { _ } = require('lib/locale.js');
const { createSelector } = require('reselect');
const shared = {};
@ -79,26 +80,51 @@ shared.settingsToComponents = function(comp, device, settings) {
return settingComps;
};
shared.settingsToComponents2 = function(comp, device, settings) {
const keys = Setting.keys(true, device);
const sectionComps = [];
const metadatas = [];
const deviceSelector = (state) => state.device;
const settingsSelector = (state) => state.settings;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (!Setting.isPublic(key)) continue;
shared.settingsSections = createSelector(
deviceSelector,
settingsSelector,
(device, settings) => {
const keys = Setting.keys(true, device);
const metadatas = [];
const md = Setting.settingMetadata(key);
if (md.show && !md.show(settings)) continue;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (!Setting.isPublic(key)) continue;
metadatas.push(md);
const md = Setting.settingMetadata(key);
if (md.show && !md.show(settings)) continue;
metadatas.push(md);
}
const output = Setting.groupMetadatasBySections(metadatas);
output.push({
name: 'encryption',
metadatas: [],
isScreen: true,
});
output.push({
name: 'server',
metadatas: [],
isScreen: true,
});
return output;
}
);
const sections = Setting.groupMetadatasBySections(metadatas);
shared.settingsToComponents2 = function(comp, device, settings, selectedSectionName = '') {
const sectionComps = [];
const sections = shared.settingsSections({ device, settings });
for (let i = 0; i < sections.length; i++) {
const section = sections[i];
const sectionComp = comp.sectionToComponent(section.name, section, settings);
const sectionComp = comp.sectionToComponent(section.name, section, settings, selectedSectionName === section.name);
if (!sectionComp) continue;
sectionComps.push(sectionComp);
}

View File

@ -811,6 +811,21 @@ class Setting extends BaseModel {
if (name === 'plugins') return _('Plugins');
if (name === 'application') return _('Application');
if (name === 'revisionService') return _('Note History');
if (name === 'encryption') return _('Encryption');
if (name === 'server') return _('Web Clipper');
return name;
}
static sectionNameToIcon(name, platform) {
if (name === 'general') return 'fa-sliders';
if (name === 'sync') return 'fa-refresh';
if (name === 'appearance') return 'fa-pencil';
if (name === 'note') return 'fa-file-text-o';
if (name === 'plugins') return 'fa-puzzle-piece';
if (name === 'application') return 'fa-cog';
if (name === 'revisionService') return 'fa-archive-org';
if (name === 'encryption') return 'fa-key-modern';
if (name === 'server') return 'fa-hand-scissors-o';
return name;
}