1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-09-16 08:56:40 +02:00

Various bug fixes

This commit is contained in:
Laurent Cozic
2017-08-01 18:53:50 +00:00
parent 88998bbe75
commit 4d61ed1dce
9 changed files with 141 additions and 187 deletions

View File

@@ -78,22 +78,22 @@ function getOptionColWidth(options) {
function getHeader() { function getHeader() {
let output = []; let output = [];
output.push(_('NAME')); output.push('NAME');
output.push(''); output.push('');
output.push(wrap(_('joplin - a note taking and todo app with synchronisation capabilities'), INDENT)); output.push(wrap('joplin - a note taking and todo app with synchronisation capabilities'), INDENT);
output.push(''); output.push('');
output.push(_('DESCRIPTION')); output.push('DESCRIPTION');
output.push(''); output.push('');
let description = []; let description = [];
description.push(_('Joplin is a note taking and todo application, which can handle a large number of notes organised into notebooks.')); description.push('Joplin is a note taking and todo application, which can handle a large number of notes organised into notebooks.');
description.push(_('The notes are searchable, can be copied, tagged and modified with your own text editor.')); description.push('The notes are searchable, can be copied, tagged and modified with your own text editor.');
description.push("\n\n"); description.push("\n\n");
description.push(_('The notes can be synchronised with various target including the file system (for example with a network directory) or with Microsoft OneDrive.')); description.push('The notes can be synchronised with various target including the file system (for example with a network directory) or with Microsoft OneDrive.');
description.push("\n\n"); description.push("\n\n");
description.push(_('Notes exported from Evenotes via .enex files can be imported into Joplin, including the formatted content, resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.).')); description.push('Notes exported from Evenotes via .enex files can be imported into Joplin, including the formatted content, resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.).');
output.push(wrap(description.join(''), INDENT)); output.push(wrap(description.join(''), INDENT));
@@ -103,13 +103,13 @@ function getHeader() {
function getFooter() { function getFooter() {
let output = []; let output = [];
output.push(_('WEBSITE')); output.push('WEBSITE');
output.push(''); output.push('');
output.push(INDENT + 'http://joplin.cozic.net'); output.push(INDENT + 'http://joplin.cozic.net');
output.push(''); output.push('');
output.push(_('LICENSE')); output.push('LICENSE');
output.push(''); output.push('');
let filePath = rootDir + '/LICENSE_' + languageCode(); let filePath = rootDir + '/LICENSE_' + languageCode();
if (!fs.existsSync(filePath)) filePath = rootDir + '/LICENSE'; if (!fs.existsSync(filePath)) filePath = rootDir + '/LICENSE';
@@ -134,7 +134,7 @@ async function main() {
const commandsText = commandBlocks.join("\n\n"); const commandsText = commandBlocks.join("\n\n");
const footerText = getFooter(); const footerText = getFooter();
console.info(headerText + "\n\n" + _('USAGE') + "\n\n" + commandsText + "\n\n" + footerText); console.info(headerText + "\n\n" + 'USAGE' + "\n\n" + commandsText + "\n\n" + footerText);
} }
main().catch((error) => { main().catch((error) => {

View File

@@ -44,45 +44,6 @@ msgstr ""
msgid "No notebook is defined. Create one with `mkbook <notebook>`." msgid "No notebook is defined. Create one with `mkbook <notebook>`."
msgstr "" msgstr ""
msgid "NAME"
msgstr ""
msgid "joplin - a note taking and todo app with synchronisation capabilities"
msgstr ""
msgid "DESCRIPTION"
msgstr ""
msgid ""
"Joplin is a note taking and todo application, which can handle a large "
"number of notes organised into notebooks."
msgstr ""
msgid ""
"The notes are searchable, can be copied, tagged and modified with your own "
"text editor."
msgstr ""
msgid ""
"The notes can be synchronised with various target including the file system "
"(for example with a network directory) or with Microsoft OneDrive."
msgstr ""
msgid ""
"Notes exported from Evenotes via .enex files can be imported into Joplin, "
"including the formatted content, resources (images, attachments, etc.) and "
"complete metadata (geolocation, updated time, created time, etc.)."
msgstr ""
msgid "WEBSITE"
msgstr ""
msgid "LICENSE"
msgstr ""
msgid "USAGE"
msgstr ""
msgid "Displays the given note." msgid "Displays the given note."
msgstr "" msgstr ""
@@ -448,6 +409,15 @@ msgstr ""
msgid "%d hours" msgid "%d hours"
msgstr "" msgstr ""
msgid "Theme"
msgstr ""
msgid "Light"
msgstr ""
msgid "Dark"
msgstr ""
msgid "Sync status (synced items / total items)" msgid "Sync status (synced items / total items)"
msgstr "" msgstr ""

View File

@@ -46,45 +46,6 @@ msgstr "Quitter le logiciel."
msgid "No notebook is defined. Create one with `mkbook <notebook>`." msgid "No notebook is defined. Create one with `mkbook <notebook>`."
msgstr "Aucun carnet n'est défini. Créez-en un avec `mkbook <carnet>`." msgstr "Aucun carnet n'est défini. Créez-en un avec `mkbook <carnet>`."
msgid "NAME"
msgstr "NOM"
msgid "joplin - a note taking and todo app with synchronisation capabilities"
msgstr ""
msgid "DESCRIPTION"
msgstr "DESCRIPTION"
msgid ""
"Joplin is a note taking and todo application, which can handle a large "
"number of notes organised into notebooks."
msgstr ""
msgid ""
"The notes are searchable, can be copied, tagged and modified with your own "
"text editor."
msgstr ""
msgid ""
"The notes can be synchronised with various target including the file system "
"(for example with a network directory) or with Microsoft OneDrive."
msgstr ""
msgid ""
"Notes exported from Evenotes via .enex files can be imported into Joplin, "
"including the formatted content, resources (images, attachments, etc.) and "
"complete metadata (geolocation, updated time, created time, etc.)."
msgstr ""
msgid "WEBSITE"
msgstr "SITE INTERNET"
msgid "LICENSE"
msgstr "LISENSE"
msgid "USAGE"
msgstr "UTILISATION"
msgid "Displays the given note." msgid "Displays the given note."
msgstr "Affiche la note." msgstr "Affiche la note."
@@ -490,6 +451,15 @@ msgstr "%d heure"
msgid "%d hours" msgid "%d hours"
msgstr "%d heures" msgstr "%d heures"
msgid "Theme"
msgstr "Apparence"
msgid "Light"
msgstr "Clair"
msgid "Dark"
msgstr "Sombre"
msgid "Sync status (synced items / total items)" msgid "Sync status (synced items / total items)"
msgstr "Status de la synchronisation (objets synchro. / total)" msgstr "Status de la synchronisation (objets synchro. / total)"
@@ -609,6 +579,21 @@ msgstr ""
msgid "Welcome" msgid "Welcome"
msgstr "Bienvenu" msgstr "Bienvenu"
#~ msgid "NAME"
#~ msgstr "NOM"
#~ msgid "DESCRIPTION"
#~ msgstr "DESCRIPTION"
#~ msgid "WEBSITE"
#~ msgstr "SITE INTERNET"
#~ msgid "LICENSE"
#~ msgstr "LISENSE"
#~ msgid "USAGE"
#~ msgstr "UTILISATION"
#~ msgid "Folder does not exists: \"%s\". Create it?" #~ msgid "Folder does not exists: \"%s\". Create it?"
#~ msgstr "Ce carnet n'existe pas : \"%s\". Le créer ?" #~ msgstr "Ce carnet n'existe pas : \"%s\". Le créer ?"

View File

@@ -44,45 +44,6 @@ msgstr ""
msgid "No notebook is defined. Create one with `mkbook <notebook>`." msgid "No notebook is defined. Create one with `mkbook <notebook>`."
msgstr "" msgstr ""
msgid "NAME"
msgstr ""
msgid "joplin - a note taking and todo app with synchronisation capabilities"
msgstr ""
msgid "DESCRIPTION"
msgstr ""
msgid ""
"Joplin is a note taking and todo application, which can handle a large "
"number of notes organised into notebooks."
msgstr ""
msgid ""
"The notes are searchable, can be copied, tagged and modified with your own "
"text editor."
msgstr ""
msgid ""
"The notes can be synchronised with various target including the file system "
"(for example with a network directory) or with Microsoft OneDrive."
msgstr ""
msgid ""
"Notes exported from Evenotes via .enex files can be imported into Joplin, "
"including the formatted content, resources (images, attachments, etc.) and "
"complete metadata (geolocation, updated time, created time, etc.)."
msgstr ""
msgid "WEBSITE"
msgstr ""
msgid "LICENSE"
msgstr ""
msgid "USAGE"
msgstr ""
msgid "Displays the given note." msgid "Displays the given note."
msgstr "" msgstr ""
@@ -448,6 +409,15 @@ msgstr ""
msgid "%d hours" msgid "%d hours"
msgstr "" msgstr ""
msgid "Theme"
msgstr ""
msgid "Light"
msgstr ""
msgid "Dark"
msgstr ""
msgid "Sync status (synced items / total items)" msgid "Sync status (synced items / total items)"
msgstr "" msgstr ""

View File

@@ -35,6 +35,7 @@ An Android app and a command line interface are currently available. Both can sy
- Search functionality. - Search functionality.
- Geolocation support. - Geolocation support.
- Supports multiple languages. - Supports multiple languages.
- Mobile: Support for dark theme / light theme.
# Localisation # Localisation
@@ -50,7 +51,6 @@ The applications are currently available in English and French. If you would lik
- All clients: End to end encryption. - All clients: End to end encryption.
- All clients: Support for Dropbox synchronisation. - All clients: Support for Dropbox synchronisation.
- Mobile: Compile Windows app? - Mobile: Compile Windows app?
- Mobile: Support for dark theme / light theme.
- Mobile: Link for non-image resources. - Mobile: Link for non-image resources.
- Mobile: Handle tags. - Mobile: Handle tags.
- Mobile: Markdown edition support - Mobile: Markdown edition support

View File

@@ -90,8 +90,8 @@ android {
applicationId "net.cozic.joplin" applicationId "net.cozic.joplin"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 22 targetSdkVersion 22
versionCode 38 versionCode 39
versionName "0.9.25" versionName "0.9.26"
ndk { ndk {
abiFilters "armeabi-v7a", "x86" abiFilters "armeabi-v7a", "x86"
} }

View File

@@ -21,8 +21,10 @@ const globalStyle = {
// For WebView - must correspond to the properties above // For WebView - must correspond to the properties above
htmlFontSize: '20x', htmlFontSize: '20x',
htmlColor: 'black', // Note: CSS in WebView component only seem to work if the colour is written in full letters (so no hexadecimal) htmlColor: 'black', // Note: CSS in WebView component only supports named colors or rgb() notation
htmlBackgroundColor: 'white',
htmlDividerColor: 'Gainsboro', htmlDividerColor: 'Gainsboro',
htmlLinkColor: 'blue',
}; };
globalStyle.marginRight = globalStyle.margin; globalStyle.marginRight = globalStyle.margin;
@@ -50,16 +52,19 @@ function themeStyle(theme) {
if (theme == Setting.THEME_LIGHT) return output; if (theme == Setting.THEME_LIGHT) return output;
output.backgroundColor = '#1D2024'; output.backgroundColor = '#1D2024';
output.color = '#ffffff'; output.color = '#dddddd';
output.colorFaded = '#777777'; output.colorFaded = '#777777';
output.dividerColor = '#555555'; output.dividerColor = '#555555';
output.selectedColor = '#333333'; output.selectedColor = '#333333';
output.htmlColor = 'white';
output.raisedBackgroundColor = "#0F2051"; output.raisedBackgroundColor = "#0F2051";
output.raisedColor = "#788BC3"; output.raisedColor = "#788BC3";
output.raisedHighlightedColor = "#ffffff"; output.raisedHighlightedColor = "#ffffff";
output.htmlColor = 'rgb(220,220,220)';
output.htmlBackgroundColor = 'rgb(29,32,36)';
output.htmlLinkColor = 'rgb(166,166,255)';
themeCache_[theme] = output; themeCache_[theme] = output;
return themeCache_[theme]; return themeCache_[theme];
} }

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { WebView, View } from 'react-native'; import { WebView, View, Linking } from 'react-native';
import { globalStyle } from 'lib/components/global-style.js'; import { globalStyle } from 'lib/components/global-style.js';
import { Resource } from 'lib/models/resource.js'; import { Resource } from 'lib/models/resource.js';
import { shim } from 'lib/shim.js'; import { shim } from 'lib/shim.js';
@@ -59,6 +59,7 @@ class NoteBodyViewer extends Component {
font-size: ` + style.htmlFontSize + `; font-size: ` + style.htmlFontSize + `;
color: ` + style.htmlColor + `; color: ` + style.htmlColor + `;
line-height: 1.5em; line-height: 1.5em;
background-color: ` + style.htmlBackgroundColor + `;
} }
h1 { h1 {
font-size: 1.2em; font-size: 1.2em;
@@ -68,8 +69,8 @@ class NoteBodyViewer extends Component {
font-size: 1em; font-size: 1em;
font-weight: bold; font-weight: bold;
} }
li { a {
color: ` + style.htmlLinkColor + `
} }
ul { ul {
padding-left: 1em; padding-left: 1em;
@@ -134,12 +135,14 @@ class NoteBodyViewer extends Component {
return '[Image: ' + htmlentities(r.title) + '(' + htmlentities(r.mime) + ')]'; return '[Image: ' + htmlentities(r.title) + '(' + htmlentities(r.mime) + ')]';
} }
let html = body ? '<style>' + normalizeCss + "\n" + css + '</style>' + marked(body, { let styleHtml = '<style>' + normalizeCss + "\n" + css + '</style>';
let html = body ? styleHtml + marked(body, {
gfm: true, gfm: true,
breaks: true, breaks: true,
renderer: renderer, renderer: renderer,
sanitize: true, sanitize: true,
}) : ''; }) : styleHtml;
let elementId = 1; let elementId = 1;
while (html.indexOf('°°JOP°') >= 0) { while (html.indexOf('°°JOP°') >= 0) {
@@ -166,7 +169,7 @@ class NoteBodyViewer extends Component {
return ( return (
<View style={style}> <View style={style}>
<WebView <WebView
source={{ html: this.markdownToHtml(note ? note.body : '', globalStyle) }} source={{ html: this.markdownToHtml(note ? note.body : '', this.props.webViewStyle) }}
onMessage={(event) => { onMessage={(event) => {
let msg = event.nativeEvent.data; let msg = event.nativeEvent.data;

View File

@@ -16,50 +16,10 @@ import { reg } from 'lib/registry.js';
import { shim } from 'lib/shim.js'; import { shim } from 'lib/shim.js';
import { BaseScreenComponent } from 'lib/components/base-screen.js'; import { BaseScreenComponent } from 'lib/components/base-screen.js';
import { dialogs } from 'lib/dialogs.js'; import { dialogs } from 'lib/dialogs.js';
import { globalStyle } from 'lib/components/global-style.js'; import { globalStyle, themeStyle } from 'lib/components/global-style.js';
import DialogBox from 'react-native-dialogbox'; import DialogBox from 'react-native-dialogbox';
import { NoteBodyViewer } from 'lib/components/note-body-viewer.js'; import { NoteBodyViewer } from 'lib/components/note-body-viewer.js';
const styleObject = {
titleTextInput: {
flex: 1,
paddingLeft: 0,
color: globalStyle.color,
backgroundColor: globalStyle.backgroundColor,
fontWeight: 'bold',
fontSize: globalStyle.fontSize,
},
bodyTextInput: {
flex: 1,
paddingLeft: globalStyle.marginLeft,
paddingRight: globalStyle.marginRight,
textAlignVertical: 'top',
color: globalStyle.color,
backgroundColor: globalStyle.backgroundColor,
fontSize: globalStyle.fontSize,
},
noteBodyViewer: {
flex: 1,
paddingLeft: globalStyle.marginLeft,
paddingRight: globalStyle.marginRight,
paddingTop: globalStyle.marginTop,
paddingBottom: globalStyle.marginBottom,
},
};
styleObject.titleContainer = {
flex: 0,
flexDirection: 'row',
paddingLeft: globalStyle.marginLeft,
paddingRight: globalStyle.marginRight,
borderBottomColor: globalStyle.dividerColor,
borderBottomWidth: 1,
};
styleObject.titleContainerTodo = Object.assign({}, styleObject.titleContainer);
const styles = StyleSheet.create(styleObject);
class NoteScreenComponent extends BaseScreenComponent { class NoteScreenComponent extends BaseScreenComponent {
static navigationOptions(options) { static navigationOptions(options) {
@@ -82,6 +42,8 @@ class NoteScreenComponent extends BaseScreenComponent {
this.saveButtonHasBeenShown_ = false; this.saveButtonHasBeenShown_ = false;
this.styles_ = {};
// Disabled for now because it doesn't work consistently and proabably interfer with the backHandler // Disabled for now because it doesn't work consistently and proabably interfer with the backHandler
// on root.js. Handling of the back button should be in one single place for this to work well. // on root.js. Handling of the back button should be in one single place for this to work well.
@@ -102,6 +64,55 @@ class NoteScreenComponent extends BaseScreenComponent {
// }; // };
} }
styles() {
const themeId = this.props.theme;
const theme = themeStyle(themeId);
if (this.styles_[themeId]) return this.styles_[themeId];
this.styles_ = {};
let styles = {
// titleTextInput: {
// flex: 1,
// paddingLeft: 0,
// color: theme.color,
// backgroundColor: theme.backgroundColor,
// fontWeight: 'bold',
// fontSize: theme.fontSize,
// },
bodyTextInput: {
flex: 1,
paddingLeft: theme.marginLeft,
paddingRight: theme.marginRight,
textAlignVertical: 'top',
color: theme.color,
backgroundColor: theme.backgroundColor,
fontSize: theme.fontSize,
},
noteBodyViewer: {
flex: 1,
paddingLeft: theme.marginLeft,
paddingRight: theme.marginRight,
paddingTop: theme.marginTop,
paddingBottom: theme.marginBottom,
},
};
styles.titleContainer = {
flex: 0,
flexDirection: 'row',
paddingLeft: theme.marginLeft,
paddingRight: theme.marginRight,
borderBottomColor: theme.dividerColor,
borderBottomWidth: 1,
};
styles.titleContainerTodo = Object.assign({}, styles.titleContainer);
this.styles_[themeId] = StyleSheet.create(styles);
return this.styles_[themeId];
}
isModified() { isModified() {
if (!this.state.note || !this.state.lastSavedNote) return false; if (!this.state.note || !this.state.lastSavedNote) return false;
let diff = BaseModel.diffObjects(this.state.note, this.state.lastSavedNote); let diff = BaseModel.diffObjects(this.state.note, this.state.lastSavedNote);
@@ -294,6 +305,7 @@ class NoteScreenComponent extends BaseScreenComponent {
); );
} }
const theme = themeStyle(this.props.theme);
const note = this.state.note; const note = this.state.note;
const isTodo = !!Number(note.is_todo); const isTodo = !!Number(note.is_todo);
const folder = this.state.folder; const folder = this.state.folder;
@@ -305,14 +317,14 @@ class NoteScreenComponent extends BaseScreenComponent {
this.saveOneProperty('body', newBody); this.saveOneProperty('body', newBody);
}; };
bodyComponent = <NoteBodyViewer style={styles.noteBodyViewer} note={note} onCheckboxChange={(newBody) => { onCheckboxChange(newBody) }}/> bodyComponent = <NoteBodyViewer style={this.styles().noteBodyViewer} webViewStyle={theme} note={note} onCheckboxChange={(newBody) => { onCheckboxChange(newBody) }}/>
} else { } else {
const focusBody = !isNew && !!note.title; const focusBody = !isNew && !!note.title;
bodyComponent = ( bodyComponent = (
<TextInput <TextInput
autoCapitalize="sentences" autoCapitalize="sentences"
autoFocus={focusBody} autoFocus={focusBody}
style={styles.bodyTextInput} style={this.styles().bodyTextInput}
multiline={true} multiline={true}
value={note.body} value={note.body}
onChangeText={(text) => this.body_changeText(text)} onChangeText={(text) => this.body_changeText(text)}
@@ -352,14 +364,22 @@ class NoteScreenComponent extends BaseScreenComponent {
if (showSaveButton) this.saveButtonHasBeenShown_ = true; if (showSaveButton) this.saveButtonHasBeenShown_ = true;
const titleContainerStyle = isTodo ? styles.titleContainerTodo : styles.titleContainer; const titleContainerStyle = isTodo ? this.styles().titleContainerTodo : this.styles().titleContainer;
let titleTextInputStyle = {
flex: 1,
paddingLeft: 0,
color: theme.color,
backgroundColor: theme.backgroundColor,
fontWeight: 'bold',
fontSize: theme.fontSize,
};
const titleTextInputStyle = Object.assign({}, styleObject.titleTextInput);
titleTextInputStyle.height = this.state.titleTextInputHeight; titleTextInputStyle.height = this.state.titleTextInputHeight;
const titleComp = ( const titleComp = (
<View style={titleContainerStyle}> <View style={titleContainerStyle}>
{ isTodo && <Checkbox checked={!!Number(note.todo_completed)} onChange={(checked) => { this.todoCheckbox_change(checked) }} /> } { isTodo && <Checkbox style={{ color: theme.color }} checked={!!Number(note.todo_completed)} onChange={(checked) => { this.todoCheckbox_change(checked) }} /> }
<TextInput <TextInput
onContentSizeChange={(event) => this.titleTextInput_contentSizeChange(event)} onContentSizeChange={(event) => this.titleTextInput_contentSizeChange(event)}
autoFocus={isNew} autoFocus={isNew}
@@ -374,7 +394,7 @@ class NoteScreenComponent extends BaseScreenComponent {
); );
return ( return (
<View style={this.styles().screen}> <View style={this.rootStyle(this.props.theme).root}>
<ScreenHeader <ScreenHeader
titlePicker={{ titlePicker={{
items: titlePickerItems(), items: titlePickerItems(),
@@ -424,6 +444,7 @@ const NoteScreen = connect(
folderId: state.selectedFolderId, folderId: state.selectedFolderId,
itemType: state.selectedItemType, itemType: state.selectedItemType,
folders: state.folders, folders: state.folders,
theme: state.settings.theme,
}; };
} }
)(NoteScreenComponent) )(NoteScreenComponent)