1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-11-06 09:19:22 +02:00

Desktop: UI update (#3586)

This commit is contained in:
Laurent
2020-09-15 14:01:07 +01:00
committed by GitHub
parent bdedf69439
commit 056285deda
138 changed files with 4620 additions and 2308 deletions

View File

@@ -292,8 +292,8 @@ class BaseApplication {
notes = await Tag.notes(parentId, options);
} else if (parentType === BaseModel.TYPE_SEARCH) {
const search = BaseModel.byId(state.searches, parentId);
notes = await SearchEngineUtils.notesForQuery(search.query_pattern, { fuzzy: search.fuzzy });
const parsedQuery = await SearchEngine.instance().parseQuery(search.query_pattern, search.fuzzy);
notes = await SearchEngineUtils.notesForQuery(search.query_pattern);
const parsedQuery = await SearchEngine.instance().parseQuery(search.query_pattern);
highlightedWords = SearchEngine.instance().allParsedQueryTerms(parsedQuery);
} else if (parentType === BaseModel.TYPE_SMART_FILTER) {
notes = await Note.previews(parentId, options);

View File

@@ -4,7 +4,8 @@ const { _ } = require('lib/locale');
export const declaration:CommandDeclaration = {
name: 'historyBackward',
label: () => _('Back'),
iconName: 'fa-arrow-left',
// iconName: 'fa-arrow-left',
iconName: 'icon-back',
};
interface Props {

View File

@@ -4,7 +4,7 @@ const { _ } = require('lib/locale');
export const declaration:CommandDeclaration = {
name: 'historyForward',
label: () => _('Forward'),
iconName: 'fa-arrow-right',
iconName: 'icon-forward',
};
interface Props {

View File

@@ -10,7 +10,7 @@ class ModalDialog extends React.Component {
}
styles() {
const themeId = this.props.theme;
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
if (this.styles_[themeId]) return this.styles_[themeId];

View File

@@ -63,7 +63,7 @@ class AppNavComponent extends Component {
this.previousRouteName_ = route.routeName;
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const style = { flex: 1, backgroundColor: theme.backgroundColor };
@@ -81,7 +81,7 @@ class AppNavComponent extends Component {
const AppNav = connect(state => {
return {
route: state.route,
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(AppNavComponent);

View File

@@ -44,7 +44,7 @@ class NoteBodyViewer extends Component {
this.forceUpdate_ = false;
const note = this.props.note;
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const bodyToRender = note ? note.body : '';

View File

@@ -22,9 +22,9 @@ class NoteItemComponent extends Component {
}
styles() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
this.styles_ = {};
const styles = {
@@ -62,8 +62,8 @@ class NoteItemComponent extends Component {
styles.selectionWrapperSelected = Object.assign({}, styles.selectionWrapper);
styles.selectionWrapperSelected.backgroundColor = theme.selectedColor;
this.styles_[this.props.theme] = StyleSheet.create(styles);
return this.styles_[this.props.theme];
this.styles_[this.props.themeId] = StyleSheet.create(styles);
return this.styles_[this.props.themeId];
}
async todoCheckbox_change(checked) {
@@ -107,7 +107,7 @@ class NoteItemComponent extends Component {
const note = this.props.note ? this.props.note : {};
const isTodo = !!Number(note.is_todo);
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
// IOS: display: none crashes the app
const checkboxStyle = !isTodo ? { display: 'none' } : { color: theme.color };
@@ -145,7 +145,7 @@ class NoteItemComponent extends Component {
const NoteItem = connect(state => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
noteSelectionEnabled: state.noteSelectionEnabled,
selectedNoteIds: state.selectedNoteIds,
};

View File

@@ -22,7 +22,7 @@ class NoteListComponent extends Component {
}
styles() {
const themeId = this.props.theme;
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
if (this.styles_[themeId]) return this.styles_[themeId];
@@ -114,7 +114,7 @@ const NoteList = connect(state => {
items: state.notes,
folders: state.folders,
notesSource: state.notesSource,
theme: state.settings.theme,
themeId: state.settings.theme,
noteSelectionEnabled: state.noteSelectionEnabled,
};
})(NoteListComponent);

View File

@@ -532,7 +532,7 @@ const ScreenHeader = connect(state => {
historyCanGoBack: state.historyCanGoBack,
locale: state.settings.locale,
folders: state.folders,
theme: state.settings.theme,
themeId: state.settings.theme,
noteSelectionEnabled: state.noteSelectionEnabled,
selectedNoteIds: state.selectedNoteIds,
showMissingMasterKeyMessage: state.notLoadedMasterKeys.length && state.masterKeys.length,

View File

@@ -116,7 +116,7 @@ class NoteTagsDialogComponent extends React.Component {
}
styles() {
const themeId = this.props.theme;
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
if (this.styles_[themeId]) return this.styles_[themeId];
@@ -155,7 +155,7 @@ class NoteTagsDialogComponent extends React.Component {
}
render() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const dialogContent = (
<View style={{ flex: 1 }}>
@@ -175,13 +175,13 @@ class NoteTagsDialogComponent extends React.Component {
</View>
);
return <ModalDialog theme={this.props.theme} ContentComponent={dialogContent} title={_('Type new tags or select from list')} onOkPress={this.okButton_press} onCancelPress={this.cancelButton_press} buttonBarEnabled={!this.state.savingTags} />;
return <ModalDialog themeId={this.props.themeId} ContentComponent={dialogContent} title={_('Type new tags or select from list')} onOkPress={this.okButton_press} onCancelPress={this.cancelButton_press} buttonBarEnabled={!this.state.savingTags} />;
}
}
const NoteTagsDialog = connect(state => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
tags: state.tags,
noteId: state.selectedNoteIds.length ? state.selectedNoteIds[0] : null,
};

View File

@@ -1,6 +1,6 @@
import * as React from 'react';
import { View, Text, ScrollView } from 'react-native';
import useSyncTargetUpgrade from 'lib/services/synchronizer/gui/useSyncTargetUpgrade';
const { View, Text, ScrollView } = require('react-native');
const { connect } = require('react-redux');
const { themeStyle } = require('lib/components/global-style.js');
@@ -10,7 +10,7 @@ const { _ } = require('lib/locale.js');
function UpgradeSyncTargetScreen(props:any) {
const upgradeResult = useSyncTargetUpgrade();
const theme = themeStyle(props.theme);
const theme = themeStyle(props.themeId);
const lineStyle = { ...theme.normalText, marginBottom: 20 };
const stackTraceStyle = { ...theme.normalText, flexWrap: 'nowrap', fontSize: theme.fontSize * 0.5, color: theme.colorFaded };
@@ -67,6 +67,6 @@ function UpgradeSyncTargetScreen(props:any) {
export default connect((state:any) => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(UpgradeSyncTargetScreen);

View File

@@ -154,7 +154,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
}
styles() {
const themeId = this.props.theme;
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
if (this.styles_[themeId]) return this.styles_[themeId];
@@ -249,7 +249,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
}
renderHeader(key, title) {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
return (
<View key={key} style={this.styles().headerWrapperStyle}>
<Text style={theme.headerStyle}>{title}</Text>
@@ -327,7 +327,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
}
settingToComponent(key, value) {
const themeId = this.props.theme;
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
const output = null;
@@ -429,7 +429,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
render() {
const settings = this.state.settings;
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const settingComps = shared.settingsToComponents2(this, 'mobile', settings);
@@ -545,7 +545,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
);
return (
<View style={this.rootStyle(this.props.theme).root}>
<View style={this.rootStyle(this.props.themeId).root}>
<ScreenHeader title={_('Configuration')} showSaveButton={true} showSearchButton={false} showSideMenuButton={false} saveButtonDisabled={!this.state.changedSettingKeys.length} onSaveButtonPress={this.saveButton_press} />
<ScrollView>{settingComps}</ScrollView>
</View>
@@ -556,7 +556,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
const ConfigScreen = connect(state => {
return {
settings: state.settings,
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(ConfigScreenComponent);

View File

@@ -24,7 +24,7 @@ class DropboxLoginScreenComponent extends BaseScreenComponent {
}
styles() {
const themeId = this.props.theme;
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
if (this.styles_[themeId]) return this.styles_[themeId];
@@ -48,7 +48,7 @@ class DropboxLoginScreenComponent extends BaseScreenComponent {
}
render() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
return (
<View style={this.styles().screen}>
@@ -83,7 +83,7 @@ class DropboxLoginScreenComponent extends BaseScreenComponent {
const DropboxLoginScreen = connect(state => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(DropboxLoginScreenComponent);

View File

@@ -57,7 +57,7 @@ class EncryptionConfigScreenComponent extends BaseScreenComponent {
}
styles() {
const themeId = this.props.theme;
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
if (this.styles_[themeId]) return this.styles_[themeId];
@@ -97,7 +97,7 @@ class EncryptionConfigScreenComponent extends BaseScreenComponent {
}
renderMasterKey(num, mk) {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const onSaveClick = () => {
return shared.onSavePasswordClick(this, mk);
@@ -129,7 +129,7 @@ class EncryptionConfigScreenComponent extends BaseScreenComponent {
}
passwordPromptComponent() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const onEnableClick = async () => {
try {
@@ -194,7 +194,7 @@ class EncryptionConfigScreenComponent extends BaseScreenComponent {
}
render() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const masterKeys = this.props.masterKeys;
const decryptedItemsInfo = this.props.encryptionEnabled ? <Text style={this.styles().normalText}>{shared.decryptedStatText(this)}</Text> : null;
@@ -260,7 +260,7 @@ class EncryptionConfigScreenComponent extends BaseScreenComponent {
) : null;
return (
<View style={this.rootStyle(this.props.theme).root}>
<View style={this.rootStyle(this.props.themeId).root}>
<ScreenHeader title={_('Encryption Config')} />
<ScrollView style={this.styles().container}>
{
@@ -297,7 +297,7 @@ class EncryptionConfigScreenComponent extends BaseScreenComponent {
const EncryptionConfigScreen = connect(state => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
masterKeys: state.masterKeys,
passwords: state.settings['encryption.passwordCache'],
encryptionEnabled: state.settings['encryption.enabled'],

View File

@@ -25,9 +25,9 @@ class FolderScreenComponent extends BaseScreenComponent {
}
styles() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
this.styles_ = {};
const styles = {
@@ -38,8 +38,8 @@ class FolderScreenComponent extends BaseScreenComponent {
},
};
this.styles_[this.props.theme] = StyleSheet.create(styles);
return this.styles_[this.props.theme];
this.styles_[this.props.themeId] = StyleSheet.create(styles);
return this.styles_[this.props.themeId];
}
UNSAFE_componentWillMount() {
@@ -102,10 +102,10 @@ class FolderScreenComponent extends BaseScreenComponent {
render() {
const saveButtonDisabled = !this.isModified();
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
return (
<View style={this.rootStyle(this.props.theme).root}>
<View style={this.rootStyle(this.props.themeId).root}>
<ScreenHeader title={_('Edit notebook')} showSaveButton={true} saveButtonDisabled={saveButtonDisabled} onSaveButtonPress={() => this.saveFolderButton_press()} showSideMenuButton={false} showSearchButton={false} />
<TextInput placeholder={_('Enter notebook title')} placeholderTextColor={theme.colorFaded} underlineColorAndroid={theme.dividerColor} selectionColor={theme.textSelectionColor} keyboardAppearance={theme.keyboardAppearance} style={this.styles().textInput} autoFocus={true} value={this.state.folder.title} onChangeText={text => this.title_changeText(text)} />
<dialogs.DialogBox
@@ -121,7 +121,7 @@ class FolderScreenComponent extends BaseScreenComponent {
const FolderScreen = connect(state => {
return {
folderId: state.selectedFolderId,
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(FolderScreenComponent);

View File

@@ -26,9 +26,9 @@ class LogScreenComponent extends BaseScreenComponent {
}
styles() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
this.styles_ = {};
const styles = {
@@ -56,8 +56,8 @@ class LogScreenComponent extends BaseScreenComponent {
styles.rowTextWarn = Object.assign({}, styles.rowText);
styles.rowTextWarn.color = theme.colorWarn;
this.styles_[this.props.theme] = StyleSheet.create(styles);
return this.styles_[this.props.theme];
this.styles_[this.props.themeId] = StyleSheet.create(styles);
return this.styles_[this.props.themeId];
}
UNSAFE_componentWillMount() {
@@ -96,7 +96,7 @@ class LogScreenComponent extends BaseScreenComponent {
// `enableEmptySections` is to fix this warning: https://github.com/FaridSafi/react-native-gifted-listview/issues/39
return (
<View style={this.rootStyle(this.props.theme).root}>
<View style={this.rootStyle(this.props.themeId).root}>
<ScreenHeader title={_('Log')} />
<FlatList
data={this.state.logEntries}
@@ -128,7 +128,7 @@ class LogScreenComponent extends BaseScreenComponent {
const LogScreen = connect(state => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(LogScreenComponent);

View File

@@ -257,7 +257,7 @@ class NoteScreenComponent extends BaseScreenComponent {
}
styles() {
const themeId = this.props.theme;
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
const cacheKey = [themeId, this.state.titleTextInputHeight, this.state.HACK_webviewLoadingState].join('_');
@@ -957,12 +957,12 @@ class NoteScreenComponent extends BaseScreenComponent {
);
}
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const note = this.state.note;
const isTodo = !!Number(note.is_todo);
if (this.state.showCamera) {
return <CameraView theme={this.props.theme} style={{ flex: 1 }} onPhoto={this.cameraView_onPhoto} onCancel={this.cameraView_onCancel} />;
return <CameraView themeId={this.props.themeId} style={{ flex: 1 }} onPhoto={this.cameraView_onPhoto} onCancel={this.cameraView_onCancel} />;
}
let bodyComponent = null;
@@ -992,7 +992,7 @@ class NoteScreenComponent extends BaseScreenComponent {
note={note}
noteResources={this.state.noteResources}
highlightedKeywords={keywords}
theme={this.props.theme}
themeId={this.props.themeId}
noteHash={this.props.noteHash}
onCheckboxChange={newBody => {
onCheckboxChange(newBody);
@@ -1049,7 +1049,7 @@ class NoteScreenComponent extends BaseScreenComponent {
note: note,
noteResources: this.state.noteResources,
highlightedKeywords: keywords,
theme: this.props.theme,
themeId: this.props.themeId,
noteHash: this.props.noteHash,
onCheckboxChange: newBody => {
onCheckboxChange(newBody);
@@ -1153,7 +1153,7 @@ class NoteScreenComponent extends BaseScreenComponent {
const noteTagDialog = !this.state.noteTagDialogShown ? null : <NoteTagsDialog onCloseRequested={this.noteTagDialog_closeRequested} />;
return (
<View style={this.rootStyle(this.props.theme).root}>
<View style={this.rootStyle(this.props.themeId).root}>
<ScreenHeader
folderPickerOptions={this.folderPickerOptions()}
menuOptions={this.menuOptions()}
@@ -1193,7 +1193,7 @@ const NoteScreen = connect(state => {
itemType: state.selectedItemType,
folders: state.folders,
searchQuery: state.searchQuery,
theme: state.settings.theme,
themeId: state.settings.theme,
editorFont: [state.settings['style.editor.fontFamily']],
ftsEnabled: state.settings['db.ftsEnabled'],
sharedData: state.sharedData,

View File

@@ -81,7 +81,7 @@ class NotesScreenComponent extends BaseScreenComponent {
styles() {
if (!this.styles_) this.styles_ = {};
const themeId = this.props.theme;
const themeId = this.props.themeId;
const cacheKey = themeId;
if (this.styles_[cacheKey]) return this.styles_[cacheKey];
@@ -207,7 +207,7 @@ class NotesScreenComponent extends BaseScreenComponent {
render() {
const parent = this.parentItem();
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const rootStyle = {
flex: 1,
@@ -263,7 +263,7 @@ const NotesScreen = connect(state => {
notesSource: state.notesSource,
uncompletedTodosOnTop: state.settings.uncompletedTodosOnTop,
showCompletedTodos: state.settings.showCompletedTodos,
theme: state.settings.theme,
themeId: state.settings.theme,
noteSelectionEnabled: state.noteSelectionEnabled,
notesOrder: stateUtils.notesOrder(state.settings),
};

View File

@@ -23,7 +23,7 @@ class OneDriveLoginScreenComponent extends BaseScreenComponent {
}
styles() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
return {
screen: {
flex: 1,
@@ -129,7 +129,7 @@ class OneDriveLoginScreenComponent extends BaseScreenComponent {
const OneDriveLoginScreen = connect((state) => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(OneDriveLoginScreenComponent);

View File

@@ -30,9 +30,9 @@ class SearchScreenComponent extends BaseScreenComponent {
}
styles() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
this.styles_ = {};
const styles = {
@@ -58,8 +58,8 @@ class SearchScreenComponent extends BaseScreenComponent {
styles.clearIcon.paddingRight = theme.marginRight;
styles.clearIcon.backgroundColor = theme.backgroundColor;
this.styles_[this.props.theme] = StyleSheet.create(styles);
return this.styles_[this.props.theme];
this.styles_[this.props.themeId] = StyleSheet.create(styles);
return this.styles_[this.props.themeId];
}
componentDidMount() {
@@ -144,7 +144,7 @@ class SearchScreenComponent extends BaseScreenComponent {
render() {
if (!this.isMounted_) return null;
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const rootStyle = {
flex: 1,
@@ -203,7 +203,7 @@ class SearchScreenComponent extends BaseScreenComponent {
const SearchScreen = connect(state => {
return {
query: state.searchQuery,
theme: state.settings.theme,
themeId: state.settings.theme,
settings: state.settings,
noteSelectionEnabled: state.noteSelectionEnabled,
};

View File

@@ -32,7 +32,7 @@ class StatusScreenComponent extends BaseScreenComponent {
}
styles() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
return {
body: {
flex: 1,
@@ -42,7 +42,7 @@ class StatusScreenComponent extends BaseScreenComponent {
}
render() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const renderBody = report => {
const baseStyle = {
@@ -138,7 +138,7 @@ class StatusScreenComponent extends BaseScreenComponent {
const body = renderBody(this.state.report);
return (
<View style={this.rootStyle(this.props.theme).root}>
<View style={this.rootStyle(this.props.themeId).root}>
<ScreenHeader title={_('Status')} />
<View style={this.styles().body}>{body}</View>
<Button title={_('Refresh')} onPress={() => this.resfreshScreen()} />
@@ -149,7 +149,7 @@ class StatusScreenComponent extends BaseScreenComponent {
const StatusScreen = connect(state => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(StatusScreenComponent);

View File

@@ -28,7 +28,7 @@ class TagsScreenComponent extends BaseScreenComponent {
styles() {
if (this.styles_) return this.styles_;
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
this.styles_ = StyleSheet.create({
listItem: {
@@ -89,7 +89,7 @@ class TagsScreenComponent extends BaseScreenComponent {
}
render() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const rootStyle = {
flex: 1,
@@ -107,7 +107,7 @@ class TagsScreenComponent extends BaseScreenComponent {
const TagsScreen = connect(state => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(TagsScreenComponent);

View File

@@ -15,9 +15,9 @@ class SideMenuContentNoteComponent extends Component {
}
styles() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
this.styles_ = {};
const styles = {
@@ -45,12 +45,12 @@ class SideMenuContentNoteComponent extends Component {
styles.sideButton = Object.assign({}, styles.button, { flex: 0 });
styles.sideButtonDisabled = Object.assign({}, styles.sideButton, { opacity: 0.6 });
this.styles_[this.props.theme] = StyleSheet.create(styles);
return this.styles_[this.props.theme];
this.styles_[this.props.themeId] = StyleSheet.create(styles);
return this.styles_[this.props.themeId];
}
renderDivider(key) {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
return <View style={{ marginTop: 15, marginBottom: 15, flex: -1, borderBottomWidth: 1, borderBottomColor: theme.dividerColor }} key={key}></View>;
}
@@ -72,7 +72,7 @@ class SideMenuContentNoteComponent extends Component {
}
render() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const items = [];
@@ -109,7 +109,7 @@ class SideMenuContentNoteComponent extends Component {
const SideMenuContentNote = connect(state => {
return {
theme: state.settings.theme,
themeId: state.settings.theme,
};
})(SideMenuContentNoteComponent);

View File

@@ -35,9 +35,9 @@ class SideMenuContentComponent extends Component {
}
styles() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
this.styles_ = {};
const styles = {
@@ -85,8 +85,8 @@ class SideMenuContentComponent extends Component {
styles.sideButtonSelected = Object.assign({}, styles.sideButton, { backgroundColor: theme.selectedColor });
styles.sideButtonText = Object.assign({}, styles.buttonText);
this.styles_[this.props.theme] = StyleSheet.create(styles);
return this.styles_[this.props.theme];
this.styles_[this.props.themeId] = StyleSheet.create(styles);
return this.styles_[this.props.themeId];
}
componentDidUpdate(prevProps) {
@@ -220,7 +220,7 @@ class SideMenuContentComponent extends Component {
}
renderFolderItem(folder, selected, hasChildren, depth) {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const folderButtonStyle = {
flex: 1,
@@ -298,12 +298,12 @@ class SideMenuContentComponent extends Component {
}
makeDivider(key) {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
return <View style={{ marginTop: 15, marginBottom: 15, flex: -1, borderBottomWidth: 1, borderBottomColor: theme.dividerColor }} key={key}></View>;
}
renderBottomPanel() {
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
const items = [];
@@ -351,7 +351,7 @@ class SideMenuContentComponent extends Component {
render() {
let items = [];
const theme = themeStyle(this.props.theme);
const theme = themeStyle(this.props.themeId);
// HACK: inner height of ScrollView doesn't appear to be calculated correctly when
// using padding. So instead creating blank elements for padding bottom and top.
@@ -398,7 +398,7 @@ const SideMenuContent = connect(state => {
selectedTagId: state.selectedTagId,
notesParentType: state.notesParentType,
locale: state.settings.locale,
theme: state.settings.theme,
themeId: state.settings.theme,
// Don't do the opacity animation as it means re-rendering the list multiple times
// opacity: state.sideMenuOpenPercent,
collapsedFolderIds: state.collapsedFolderIds,

View File

@@ -1267,14 +1267,14 @@ class Setting extends BaseModel {
}
static sectionNameToIcon(name) {
if (name === 'general') return 'fas fa-sliders-h';
if (name === 'sync') return 'fas fa-sync-alt';
if (name === 'appearance') return 'fas fa-pencil-alt';
if (name === 'note') return 'far fa-file-alt';
if (name === 'plugins') return 'fas fa-puzzle-piece';
if (name === 'application') return 'fas fa-cog';
if (name === 'revisionService') return 'fas fa-history';
if (name === 'encryption') return 'fas fa-key';
if (name === 'general') return 'icon-general';
if (name === 'sync') return 'icon-sync';
if (name === 'appearance') return 'icon-appearance';
if (name === 'note') return 'icon-note';
if (name === 'plugins') return 'icon-plugins';
if (name === 'application') return 'icon-application';
if (name === 'revisionService') return 'icon-note-history';
if (name === 'encryption') return 'icon-encryption';
if (name === 'server') return 'far fa-hand-scissors';
if (name === 'keymap') return 'fa fa-keyboard';
return name;

View File

@@ -790,13 +790,17 @@ const reducer = (state = defaultState, action) => {
break;
case 'TAG_SELECT':
newState.selectedTagId = action.id;
if (!action.id) {
newState.notesParentType = defaultNotesParentType(state, 'Tag');
} else {
newState.notesParentType = 'Tag';
if (state.selectedTagId !== action.id) {
newState = Object.assign({}, state);
newState.selectedTagId = action.id;
if (!action.id) {
newState.notesParentType = defaultNotesParentType(state, 'Tag');
} else {
newState.notesParentType = 'Tag';
}
newState.selectedNoteIds = [];
}
newState.selectedNoteIds = [];
break;
case 'TAG_UPDATE_ONE':

View File

@@ -39,6 +39,15 @@ export interface Command {
runtime?: CommandRuntime,
}
export interface ToolbarButtonInfo {
name: string,
tooltip: string,
iconName: string,
enabled: boolean,
onClick():void,
title: string,
}
interface Commands {
[key:string]: Command;
}
@@ -260,6 +269,12 @@ export default class CommandService extends BaseService {
return command.runtime.title(command.runtime.props);
}
iconName(commandName:string):string {
const command = this.commandByName(commandName);
if (!command) throw new Error(`No such command: ${commandName}`);
return command.declaration.iconName;
}
label(commandName:string, fullLabel:boolean = false):string {
const command = this.commandByName(commandName);
if (!command) throw new Error(`Command: ${commandName} is not declared`);
@@ -281,10 +296,11 @@ export default class CommandService extends BaseService {
return {};
}
commandToToolbarButton(commandName:string, executeArgs:any = null) {
commandToToolbarButton(commandName:string, executeArgs:any = null):ToolbarButtonInfo {
const command = this.commandByName(commandName, { runtimeMustBeRegistered: true });
return {
name: commandName,
tooltip: this.label(commandName),
iconName: command.declaration.iconName,
enabled: this.isEnabled(commandName),

View File

@@ -81,7 +81,7 @@ class SearchEngine {
);
}
if (!noteIds.length && (Setting.value('db.fuzzySearchEnabled') == 1)) {
if (!noteIds.length && (Setting.value('db.fuzzySearchEnabled') === 1)) {
// On the last loop
queries.push({ sql: 'INSERT INTO notes_spellfix(word,rank) SELECT term, documents FROM search_aux WHERE col=\'*\'' });
}
@@ -433,7 +433,9 @@ class SearchEngine {
return await Promise.all(fuzzyMatches);
}
async parseQuery(query, fuzzy = false) {
async parseQuery(query, fuzzy = null) {
if (fuzzy === null) fuzzy = Setting.value('db.fuzzySearchEnabled') === 1;
const trimQuotes = (str) => str.startsWith('"') ? str.substr(1, str.length - 2) : str;
let allTerms = [];
@@ -610,7 +612,7 @@ class SearchEngine {
if (!Setting.value('db.ftsEnabled') || ['ja', 'zh', 'ko', 'th'].indexOf(st) >= 0) {
return SearchEngine.SEARCH_TYPE_BASIC;
} else if ((Setting.value('db.fuzzySearchEnabled') === 1) && options.fuzzy) {
} else if (options.fuzzy) {
return SearchEngine.SEARCH_TYPE_FTS_FUZZY;
} else {
return SearchEngine.SEARCH_TYPE_FTS;
@@ -621,6 +623,7 @@ class SearchEngine {
async search(searchString, options = null) {
options = Object.assign({}, {
searchType: SearchEngine.SEARCH_TYPE_AUTO,
fuzzy: Setting.value('db.fuzzySearchEnabled') === 1,
}, options);
searchString = this.normalizeText_(searchString);
@@ -641,10 +644,10 @@ class SearchEngine {
// when searching.
// https://github.com/laurent22/joplin/issues/1075#issuecomment-459258856
const parsedQuery = await this.parseQuery(searchString, options.fuzzy);
const parsedQuery = await this.parseQuery(searchString, searchType === SearchEngine.SEARCH_TYPE_FTS_FUZZY);
try {
const { query, params } = (searchType === SearchEngine.SEARCH_TYPE_FTS_FUZZY) ? queryBuilder(parsedQuery.allTerms, true) : queryBuilder(parsedQuery.allTerms, false);
const { query, params } = queryBuilder(parsedQuery.allTerms, searchType === SearchEngine.SEARCH_TYPE_FTS_FUZZY);
const rows = await this.db().selectAll(query, params);
this.processResults_(rows, parsedQuery);
if (searchType === SearchEngine.SEARCH_TYPE_FTS_FUZZY && !parsedQuery.any) {

View File

@@ -11,7 +11,7 @@ class SearchEngineUtils {
searchType = SearchEngine.SEARCH_TYPE_BASIC;
}
const results = await SearchEngine.instance().search(query, { searchType, fuzzy: options.fuzzy });
const results = await SearchEngine.instance().search(query, { searchType });
const noteIds = results.map(n => n.id);
// We need at least the note ID to be able to sort them below so if not

View File

@@ -1,18 +1,29 @@
import { Theme } from './themes/type';
import theme_light from './themes/light';
import theme_dark from './themes/dark';
import theme_dracula from './themes/dracula';
import theme_solarizedLight from './themes/solarizedLight';
import theme_solarizedDark from './themes/solarizedDark';
import theme_nord from './themes/nord';
import theme_aritimDark from './themes/aritimDark';
import theme_oledDark from './themes/oledDark';
const Setting = require('lib/models/Setting.js');
const Color = require('color');
const themes = {
[Setting.THEME_LIGHT]: require('./themes/light'),
[Setting.THEME_DARK]: require('./themes/dark'),
[Setting.THEME_DRACULA]: require('./themes/dracula'),
[Setting.THEME_SOLARIZED_LIGHT]: require('./themes/solarizedLight'),
[Setting.THEME_SOLARIZED_DARK]: require('./themes/solarizedDark'),
[Setting.THEME_NORD]: require('./themes/nord'),
[Setting.THEME_ARITIM_DARK]: require('./themes/aritimDark'),
[Setting.THEME_OLED_DARK]: require('./themes/oledDark'),
const themes:any = {
[Setting.THEME_LIGHT]: theme_light,
[Setting.THEME_DARK]: theme_dark,
[Setting.THEME_DRACULA]: theme_dracula,
[Setting.THEME_SOLARIZED_LIGHT]: theme_solarizedLight,
[Setting.THEME_SOLARIZED_DARK]: theme_solarizedDark,
[Setting.THEME_NORD]: theme_nord,
[Setting.THEME_ARITIM_DARK]: theme_aritimDark,
[Setting.THEME_OLED_DARK]: theme_oledDark,
};
function themeById(themeId) {
function themeById(themeId:string) {
if (!themes[themeId]) throw new Error(`Invalid theme ID: ${themeId}`);
const output = Object.assign({}, themes[themeId]);
@@ -33,8 +44,8 @@ function themeById(themeId) {
// globalStyle should be used for properties that do not change across themes
// i.e. should not be used for colors
const globalStyle = {
fontFamily: 'sans-serif',
const globalStyle:any = {
fontFamily: 'Roboto',// 'sans-serif',
margin: 15, // No text and no interactive component should be within this margin
itemMarginTop: 10,
itemMarginBottom: 10,
@@ -44,10 +55,12 @@ const globalStyle = {
editorFontSize: 12,
textAreaLineHeight: 17,
lineHeight: '1.6em',
headerHeight: 35,
headerButtonHPadding: 6,
toolbarHeight: 35,
toolbarHeight: 26,
toolbarPadding: 6,
appearance: 'light',
mainPadding: 12,
topRowHeight: 50,
};
globalStyle.marginRight = globalStyle.margin;
@@ -94,28 +107,125 @@ globalStyle.buttonStyle = {
paddingRight: 12,
paddingTop: 6,
paddingBottom: 6,
boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
// boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
fontSize: globalStyle.fontSize,
borderRadius: 4,
};
function addExtraStyles(style) {
function addMissingProperties(theme:Theme) {
// if (!('backgroundColor3' in theme)) theme.backgroundColor3 = theme.backgroundColor;
// if (!('color3' in theme)) theme.color3 = theme.color;
// if (!('selectionBackgroundColor3' in theme)) {
// if (theme.appearance === 'dark') {
// theme.selectionBackgroundColor3 = '#ffffff77';
// } else {
// theme.selectionBackgroundColor3 = '#00000077';
// }
// }
// if (!('backgroundColorHover3' in theme)) theme.backgroundColorHover3 = Color(theme.selectionBackgroundColor3).alpha(0.5).rgb();
// if (!('selectionBorderColor3' in theme)) theme.selectionBorderColor3 = theme.backgroundColor3;
// TODO: pick base theme based on appearence
// const lightTheme = themes[Setting.THEME_LIGHT];
// for (const n in lightTheme) {
// if (!(n in theme)) theme[n] = lightTheme[n];
// }
return theme;
}
function addExtraStyles(style:any) {
style.selectedDividerColor = Color(style.dividerColor).darken(0.2).hex();
style.iconColor = Color(style.color).alpha(0.8);
style.colorFaded2 = Color(style.color2).alpha(0.5).rgb();
style.colorHover2 = Color(style.color2).alpha(0.7).rgb();
style.colorActive2 = Color(style.color2).alpha(0.9).rgb();
style.backgroundColorHoverDim3 = Color(style.backgroundColorHover3).alpha(0.3).rgb();
style.backgroundColorActive3 = Color(style.backgroundColorHover3).alpha(0.5).rgb();
const bgColor4 = style.backgroundColor4;
style.backgroundColorHover2 = Color(style.selectedColor2).alpha(0.4).rgb();
style.backgroundColorHover4 = Color(style.backgroundColorHover3).alpha(0.3).rgb();
style.backgroundColorActive4 = Color(style.backgroundColorHover3).alpha(0.8).rgb();
style.borderColor4 = Color(style.color).alpha(0.3);
style.backgroundColor4 = bgColor4;
style.color5 = bgColor4;
style.backgroundColor5 = style.color4;
style.backgroundColorHover5 = Color(style.backgroundColor5).darken(0.2).hex();
style.backgroundColorActive5 = Color(style.backgroundColor5).darken(0.4).hex();
style.configScreenPadding = style.mainPadding * 2;
style.icon = Object.assign({},
style.icon,
{ color: style.color }
);
style.lineInput = Object.assign({},
style.lineInput,
{
color: style.color,
backgroundColor: style.backgroundColor,
}
);
style.headerStyle = Object.assign({},
style.headerStyle,
{
color: style.color,
backgroundColor: style.backgroundColor,
}
);
style.inputStyle = Object.assign({},
style.inputStyle,
{
color: style.color,
backgroundColor: style.backgroundColor,
borderColor: style.dividerColor,
}
);
style.containerStyle = Object.assign({},
style.containerStyle,
{
color: style.color,
backgroundColor: style.backgroundColor,
}
);
style.buttonStyle = Object.assign({},
style.buttonStyle,
{
color: style.color4,
backgroundColor: style.backgroundColor4,
borderColor: style.borderColor4,
userSelect: 'none',
cursor: 'pointer',
}
);
style.tagStyle = {
fontSize: style.fontSize,
fontFamily: style.fontFamily,
paddingTop: 3,
paddingBottom: 3,
paddingRight: 8,
paddingLeft: 8,
backgroundColor: style.raisedBackgroundColor,
color: style.raisedColor,
paddingTop: 4,
paddingBottom: 4,
paddingRight: 10,
paddingLeft: 10,
backgroundColor: style.backgroundColor3,
color: style.color3,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginRight: 5,
marginRight: 8,
borderRadius: 100,
};
style.toolbarStyle = {
@@ -142,6 +252,10 @@ function addExtraStyles(style) {
color: style.color,
};
style.clickableTextStyle = Object.assign({}, style.textStyle, {
userSelect: 'none',
});
style.textStyle2 = Object.assign({}, style.textStyle,
{ color: style.color2 }
);
@@ -248,9 +362,9 @@ function addExtraStyles(style) {
return style;
}
const themeCache_ = {};
const themeCache_:any = {};
function themeStyle(theme) {
function themeStyle(theme:any) {
if (!theme) throw new Error('Theme must be specified');
const zoomRatio = 1; // Setting.value('style.zoom') / 100;
@@ -262,81 +376,29 @@ function themeStyle(theme) {
// Font size are not theme specific, but they must be referenced
// and computed here to allow them to respond to settings changes
// without the need to restart
const fontSizes = {
const fontSizes:any = {
fontSize: Math.round(12 * zoomRatio),
toolbarIconSize: 16,
editorFontSize: editorFontSize,
textAreaLineHeight: Math.round(globalStyle.textAreaLineHeight * editorFontSize / 12),
};
fontSizes.noteViewerFontSize = Math.round(fontSizes.fontSize * 1.25);
let output = {};
let output:any = {};
output.zoomRatio = zoomRatio;
// All theme are based on the light style, and just override the
// relevant properties
output = Object.assign({}, globalStyle, fontSizes, themes[Setting.THEME_LIGHT], themes[theme]);
// Note: All the theme specific things should go in addExtraStyles
// so that their definition is not split between here and the
// beginning of the file. At least new styles should go in
// addExtraStyles.
output.icon = Object.assign({},
output.icon,
{ color: output.color }
);
output.lineInput = Object.assign({},
output.lineInput,
{
color: output.color,
backgroundColor: output.backgroundColor,
}
);
output.headerStyle = Object.assign({},
output.headerStyle,
{
color: output.color,
backgroundColor: output.backgroundColor,
}
);
output.inputStyle = Object.assign({},
output.inputStyle,
{
color: output.color,
backgroundColor: output.backgroundColor,
borderColor: output.dividerColor,
}
);
output.containerStyle = Object.assign({},
output.containerStyle,
{
color: output.color,
backgroundColor: output.backgroundColor,
}
);
output.buttonStyle = Object.assign({},
output.buttonStyle,
{
color: output.color,
backgroundColor: output.backgroundColor,
borderColor: output.dividerColor,
userSelect: 'none',
}
);
output = Object.assign({}, globalStyle, fontSizes, themes[theme]);
output = addMissingProperties(output);
output = addExtraStyles(output);
themeCache_[cacheKey] = output;
return themeCache_[cacheKey];
}
const cachedStyles_ = {
const cachedStyles_:any = {
themeId: null,
styles: {},
};
@@ -344,7 +406,7 @@ const cachedStyles_ = {
// cacheKey must be a globally unique key, and must change whenever
// the dependencies of the style change. If the style depends only
// on the theme, a static string can be provided as a cache key.
function buildStyle(cacheKey, themeId, callback) {
function buildStyle(cacheKey:any, themeId:string, callback:Function) {
cacheKey = Array.isArray(cacheKey) ? cacheKey.join('_') : cacheKey;
// We clear the cache whenever switching themes

View File

@@ -1,5 +1,8 @@
const aritimStyle = {
appearance: 'dark',
import { Theme } from './type';
import theme_dark from './dark';
const theme:Theme = {
...theme_dark,
backgroundColor: '#10151a', // Main background color
backgroundColorTransparent: 'rgba(16, 21, 26, 0.9)', //
@@ -34,4 +37,4 @@ const aritimStyle = {
highlightedColor: '#d3dae3',
};
module.exports = aritimStyle;
export default theme;

View File

@@ -1,37 +0,0 @@
const darkStyle = {
appearance: 'dark',
backgroundColor: '#1D2024',
backgroundColorTransparent: 'rgba(255,255,255,0.9)',
oddBackgroundColor: '#dddddd',
color: '#dddddd',
colorError: 'red',
colorWarn: '#9A5B00',
colorFaded: '#999999', // For less important text
colorBright: '#ffffff', // For important text
dividerColor: '#555555',
selectedColor: '#333333',
urlColor: 'rgb(166,166,255)',
backgroundColor2: '#181A1D',
color2: '#ffffff',
selectedColor2: '#013F74',
colorError2: '#ff6c6c',
raisedBackgroundColor: '#474747',
raisedColor: '#ffffff',
warningBackgroundColor: '#CC6600',
codeColor: '#ffffff',
tableBackgroundColor: 'rgb(40, 41, 42)',
codeBackgroundColor: 'rgb(47, 48, 49)',
codeBorderColor: 'rgb(70, 70, 70)',
codeMirrorTheme: 'material-darker',
codeThemeCss: 'atom-one-dark-reasonable.css',
highlightedColor: '#0066C7',
};
module.exports = darkStyle;

View File

@@ -0,0 +1,55 @@
import { Theme, ThemeAppearance } from './type';
// This is the default dark theme in Joplin
const theme:Theme = {
appearance: ThemeAppearance.Dark,
// Color scheme "1" is the basic one, like used to display the note
// content. It's basically dark gray text on white background
backgroundColor: '#1D2024',
backgroundColorTransparent: 'rgba(255,255,255,0.9)',
oddBackgroundColor: '#dddddd',
color: '#dddddd',
colorError: 'red',
colorWarn: '#9A5B00',
colorFaded: '#999999', // For less important text
colorBright: '#ffffff', // For important text
dividerColor: '#555555',
selectedColor: '#616161',
urlColor: 'rgb(166,166,255)',
// Color scheme "2" is used for the sidebar. It's white text over
// dark blue background.
backgroundColor2: '#181A1D',
color2: '#ffffff',
selectedColor2: '#013F74',
colorError2: '#ff6c6c',
// Color scheme "3" is used for the config screens for example/
// It's dark text over gray background.
backgroundColor3: '#2E3138',
backgroundColorHover3: '#4E4E4E',
color3: '#dddddd',
// Color scheme "4" is used for secondary-style buttons. It makes a white
// button with blue text.
backgroundColor4: '#1D2024',
color4: '#789FE9',
raisedBackgroundColor: '#474747',
raisedColor: '#ffffff',
searchMarkerBackgroundColor: '#F7D26E',
searchMarkerColor: 'black',
warningBackgroundColor: '#CC6600',
tableBackgroundColor: 'rgb(40, 41, 42)',
codeBackgroundColor: 'rgb(47, 48, 49)',
codeBorderColor: 'rgb(70, 70, 70)',
codeColor: '#ffffff',
codeMirrorTheme: 'material-darker',
codeThemeCss: 'atom-one-dark-reasonable.css',
};
export default theme;

View File

@@ -1,5 +1,8 @@
const draculaStyle = {
appearance: 'dark',
import { Theme } from './type';
import theme_dark from './dark';
const theme:Theme = {
...theme_dark,
backgroundColor: '#282a36',
backgroundColorTransparent: 'rgba(40, 42, 54, 0.9)',
@@ -32,4 +35,4 @@ const draculaStyle = {
codeThemeCss: 'atom-one-dark-reasonable.css',
};
module.exports = draculaStyle;
export default theme;

View File

@@ -1,38 +0,0 @@
// This is the default theme in Joplin
const lightStyle = {
appearance: 'light',
backgroundColor: '#ffffff',
backgroundColorTransparent: 'rgba(255,255,255,0.9)',
oddBackgroundColor: '#dddddd',
color: '#555555', // For regular text
colorError: 'red',
colorWarn: '#9A5B00',
colorFaded: '#777777', // For less important text
colorBright: '#000000', // For important text
dividerColor: '#dddddd',
selectedColor: '#e5e5e5',
urlColor: '#155BDA',
backgroundColor2: '#162B3D',
color2: '#f5f5f5',
selectedColor2: '#0269C2',
colorError2: '#ff6c6c',
raisedBackgroundColor: '#e5e5e5',
raisedColor: '#222222',
searchMarkerBackgroundColor: '#F7D26E',
searchMarkerColor: 'black',
warningBackgroundColor: '#FFD08D',
tableBackgroundColor: 'rgb(247, 247, 247)',
codeBackgroundColor: 'rgb(243, 243, 243)',
codeBorderColor: 'rgb(220, 220, 220)',
codeColor: 'rgb(0,0,0)',
codeMirrorTheme: 'default',
codeThemeCss: 'atom-one-light.css',
};
module.exports = lightStyle;

View File

@@ -0,0 +1,55 @@
import { Theme, ThemeAppearance } from './type';
// This is the default theme in Joplin
const theme:Theme = {
appearance: ThemeAppearance.Light,
// Color scheme "1" is the basic one, like used to display the note
// content. It's basically dark gray text on white background
backgroundColor: '#ffffff',
backgroundColorTransparent: 'rgba(255,255,255,0.9)',
oddBackgroundColor: '#dddddd',
color: '#32373F', // For regular text
colorError: 'red',
colorWarn: '#9A5B00',
colorFaded: '#7C8B9E', // For less important text
colorBright: '#000000', // For important text
dividerColor: '#dddddd',
selectedColor: '#e5e5e5',
urlColor: '#155BDA',
// Color scheme "2" is used for the sidebar. It's white text over
// dark blue background.
backgroundColor2: '#313640',
color2: '#ffffff',
selectedColor2: '#131313',
colorError2: '#ff6c6c',
// Color scheme "3" is used for the config screens for example/
// It's dark text over gray background.
backgroundColor3: '#F4F5F6',
backgroundColorHover3: '#CBDAF1',
color3: '#738598',
// Color scheme "4" is used for secondary-style buttons. It makes a white
// button with blue text.
backgroundColor4: '#ffffff',
color4: '#2D6BDC',
raisedBackgroundColor: '#e5e5e5',
raisedColor: '#222222',
searchMarkerBackgroundColor: '#F7D26E',
searchMarkerColor: 'black',
warningBackgroundColor: '#FFD08D',
tableBackgroundColor: 'rgb(247, 247, 247)',
codeBackgroundColor: 'rgb(243, 243, 243)',
codeBorderColor: 'rgb(220, 220, 220)',
codeColor: 'rgb(0,0,0)',
codeMirrorTheme: 'default',
codeThemeCss: 'atom-one-light.css',
};
export default theme;

View File

@@ -1,3 +1,6 @@
import { Theme } from './type';
import theme_dark from './dark';
const nord = ['#2e3440', '#3b4252', '#434c5e', '#4c566a', '#d8dee9', '#e5e9f0', '#eceff4', '#8fbcbb', '#88c0d0', '#81a1c1', '#5e81ac', '#bf616a', '#d08770', '#ebcb8b', '#a3be8c', '#b48ead'];
// DOCUMENTATION of Nord as of Oct 3
@@ -44,8 +47,8 @@ const nord = ['#2e3440', '#3b4252', '#434c5e', '#4c566a', '#d8dee9', '#e5e9f0',
// Used for numbers.
// 2e3440 === rbga(46, 52, 64, 1)
const nordStyle = {
appearance: 'dark',
const theme:Theme = {
...theme_dark,
backgroundColor: nord[0],
backgroundColorTransparent: 'rgba(46, 52, 64, 0.9)',
@@ -78,4 +81,4 @@ const nordStyle = {
codeThemeCss: 'atom-one-dark-reasonable.css',
};
module.exports = nordStyle;
export default theme;

View File

@@ -1,7 +1,8 @@
const darkBase = require('./dark');
import { Theme } from './type';
import theme_dark from './dark';
module.exports = Object.assign({}, darkBase, {
appearance: 'dark',
const theme:Theme = {
...theme_dark,
backgroundColor: '#000000',
color: '#dddddd',
colorFaded: '#777777',
@@ -11,10 +12,11 @@ module.exports = Object.assign({}, darkBase, {
codeColor: '#ffffff',
raisedBackgroundColor: '#0F2051',
raisedColor: '#788BC3',
raisedHighlightedColor: '#ffffff',
tableBackgroundColor: 'rgb(0, 0, 0)',
codeBackgroundColor: 'rgb(47, 48, 49)',
codeBorderColor: 'rgb(70, 70, 70)',
codeThemeCss: 'atom-one-dark-reasonable.css',
colorBright: 'rgb(220,220,220)',
});
};
export default theme;

View File

@@ -1,5 +1,8 @@
const solarizedDarkStyle = {
appearance: 'dark',
import { Theme } from './type';
import theme_dark from './dark';
const theme:Theme = {
...theme_dark,
backgroundColor: '#002b36',
backgroundColorTransparent: 'rgba(0, 43, 54, 0.9)',
@@ -32,4 +35,4 @@ const solarizedDarkStyle = {
codeThemeCss: 'atom-one-dark-reasonable.css',
};
module.exports = solarizedDarkStyle;
export default theme;

View File

@@ -1,5 +1,8 @@
const solarizedLightStyle = {
appearance: 'light',
import { Theme } from './type';
import theme_light from './light';
const theme:Theme = {
...theme_light,
backgroundColor: '#fdf6e3',
backgroundColorTransparent: 'rgba(253, 246, 227, 0.9)',
@@ -32,4 +35,4 @@ const solarizedLightStyle = {
codeThemeCss: 'atom-one-light.css',
};
module.exports = solarizedLightStyle;
export default theme;

View File

@@ -0,0 +1,57 @@
export enum ThemeAppearance {
Light = 'light',
Dark = 'dark',
}
export interface Theme {
appearance: ThemeAppearance,
// Color scheme "1" is the basic one, like used to display the note
// content. It's basically dark gray text on white background
backgroundColor: string,
backgroundColorTransparent: string,
oddBackgroundColor: string,
color: string, // For regular text
colorError: string,
colorWarn: string,
colorFaded: string, // For less important text
colorBright: string, // For important text
dividerColor: string,
selectedColor: string,
urlColor: string,
// Color scheme "2" is used for the sidebar. It's white text over
// dark blue background.
backgroundColor2: string,
color2: string,
selectedColor2: string,
colorError2: string,
// Color scheme "3" is used for the config screens for example/
// It's dark text over gray background.
backgroundColor3: string,
backgroundColorHover3: string,
color3: string,
// Color scheme "4" is used for secondary-style buttons. It makes a white
// button with blue text.
backgroundColor4: string,
color4: string,
raisedBackgroundColor: string,
raisedColor: string,
searchMarkerBackgroundColor: string,
searchMarkerColor: string,
warningBackgroundColor: string,
tableBackgroundColor: string,
codeBackgroundColor: string,
codeBorderColor: string,
codeColor: string,
codeMirrorTheme: string,
codeThemeCss: string,
highlightedColor?: string,
}

View File

@@ -727,11 +727,8 @@ class AppComponent extends React.Component {
}
render() {
if (this.props.appState != 'ready') {
return this.renderStartupScreen();
}
const theme = themeStyle(this.props.theme);
if (this.props.appState != 'ready') return this.renderStartupScreen();
const theme = themeStyle(this.props.themeId);
let sideMenuContent = null;
let menuPosition = 'left';
@@ -799,7 +796,7 @@ const mapStateToProps = (state) => {
noteSelectionEnabled: state.noteSelectionEnabled,
selectedFolderId: state.selectedFolderId,
routeName: state.route.routeName,
theme: state.settings.theme,
themeId: state.settings.theme,
noteSideMenuOptions: state.noteSideMenuOptions,
};
};