From bd06fa781ed44830085c4b517c875901d620beb1 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Thu, 27 Jul 2017 18:25:42 +0100 Subject: [PATCH] Fixed note sorting and changed colour of header --- CliClient/app/command-edit.js | 3 ++ CliClient/app/command-use.js | 4 --- CliClient/locales/en_GB.po | 4 +++ CliClient/locales/fr_FR.po | 6 ++-- CliClient/locales/joplin.pot | 4 +++ CliClient/package.json | 2 +- ReactNativeClient/android/app/build.gradle | 4 +-- .../lib/components/global-style.js | 4 +++ .../lib/components/screen-header.js | 16 +++++---- .../lib/components/side-menu-content.js | 7 +--- ReactNativeClient/lib/models/note.js | 35 ++++++++++++++----- ReactNativeClient/lib/registry.js | 10 +++--- ReactNativeClient/root.js | 2 +- 13 files changed, 64 insertions(+), 37 deletions(-) diff --git a/CliClient/app/command-edit.js b/CliClient/app/command-edit.js index 0464eaaa7..ec5589ecb 100644 --- a/CliClient/app/command-edit.js +++ b/CliClient/app/command-edit.js @@ -2,6 +2,7 @@ import fs from 'fs-extra'; import { BaseCommand } from './base-command.js'; import { app } from './app.js'; import { _ } from 'lib/locale.js'; +import { vorpalUtils } from './vorpal-utils.js'; import { Folder } from 'lib/models/folder.js'; import { Note } from 'lib/models/note.js'; import { Setting } from 'lib/models/setting.js'; @@ -46,6 +47,8 @@ class Command extends BaseCommand { let note = await app().loadItem(BaseModel.TYPE_NOTE, title); if (!note) { + let ok = await vorpalUtils.cmdPromptConfirm(this, _('Note does not exist: "%s". Create it?', title)) + if (!ok) return; newNote = await Note.save({ title: title, parent_id: app().currentFolder().id }); note = await Note.load(newNote.id); } diff --git a/CliClient/app/command-use.js b/CliClient/app/command-use.js index 94c8da3cb..813bbc2fe 100644 --- a/CliClient/app/command-use.js +++ b/CliClient/app/command-use.js @@ -15,10 +15,6 @@ class Command extends BaseCommand { return _('Switches to [notebook] - all further operations will happen within this notebook.'); } - aliases() { - return ['cd']; - } - autocomplete() { return { data: autocompleteFolders }; } diff --git a/CliClient/locales/en_GB.po b/CliClient/locales/en_GB.po index 97d762043..e4c08a1c3 100644 --- a/CliClient/locales/en_GB.po +++ b/CliClient/locales/en_GB.po @@ -94,6 +94,10 @@ msgstr "" msgid "No active notebook." msgstr "" +#, javascript-format +msgid "Note does not exist: \"%s\". Create it?" +msgstr "" + msgid "Starting to edit note. Close the editor to get back to the prompt." msgstr "" diff --git a/CliClient/locales/fr_FR.po b/CliClient/locales/fr_FR.po index d994e4c87..8e20c1b12 100644 --- a/CliClient/locales/fr_FR.po +++ b/CliClient/locales/fr_FR.po @@ -14,8 +14,6 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.0.3\n" -"POT-Creation-Date: \n" -"PO-Revision-Date: \n" msgid "No notebook selected." msgstr "Aucun carnet n'est sélectionné." @@ -105,6 +103,10 @@ msgstr "" msgid "No active notebook." msgstr "Aucun carnet actif." +#, fuzzy, javascript-format +msgid "Note does not exist: \"%s\". Create it?" +msgstr "Ce carnet n'existe pas : \"%s\". Le créer ?" + msgid "Starting to edit note. Close the editor to get back to the prompt." msgstr "" "Edition de la note en cours. Fermez l'éditeur de texte pour retourner à " diff --git a/CliClient/locales/joplin.pot b/CliClient/locales/joplin.pot index 97d762043..e4c08a1c3 100644 --- a/CliClient/locales/joplin.pot +++ b/CliClient/locales/joplin.pot @@ -94,6 +94,10 @@ msgstr "" msgid "No active notebook." msgstr "" +#, javascript-format +msgid "Note does not exist: \"%s\". Create it?" +msgstr "" + msgid "Starting to edit note. Close the editor to get back to the prompt." msgstr "" diff --git a/CliClient/package.json b/CliClient/package.json index 216396f37..7fdc6fc7a 100644 --- a/CliClient/package.json +++ b/CliClient/package.json @@ -7,7 +7,7 @@ "url": "https://github.com/laurent22/joplin" }, "url": "git://github.com/laurent22/joplin.git", - "version": "0.8.65", + "version": "0.8.68", "bin": { "joplin": "./main_launcher.js" }, diff --git a/ReactNativeClient/android/app/build.gradle b/ReactNativeClient/android/app/build.gradle index 50ae7929c..abf1fc39f 100644 --- a/ReactNativeClient/android/app/build.gradle +++ b/ReactNativeClient/android/app/build.gradle @@ -90,8 +90,8 @@ android { applicationId "net.cozic.joplin" minSdkVersion 16 targetSdkVersion 22 - versionCode 33 - versionName "0.9.20" + versionCode 34 + versionName "0.9.21" ndk { abiFilters "armeabi-v7a", "x86" } diff --git a/ReactNativeClient/lib/components/global-style.js b/ReactNativeClient/lib/components/global-style.js index 0c591c9ee..c621af161 100644 --- a/ReactNativeClient/lib/components/global-style.js +++ b/ReactNativeClient/lib/components/global-style.js @@ -8,6 +8,10 @@ const globalStyle = { selectedColor: '#e5e5e5', disabledOpacity: 0.3, + raisedBackgroundColor: "#0072D5", + raisedColor: "#003363", + raisedHighlightedColor: "#ffffff", + // For WebView - must correspond to the properties above htmlFontSize: '14px', htmlColor: 'black', // Note: CSS in WebView component only seem to work if the colour is written in full letters (so no hexadecimal) diff --git a/ReactNativeClient/lib/components/screen-header.js b/ReactNativeClient/lib/components/screen-header.js index 309eac911..fdfd5e10c 100644 --- a/ReactNativeClient/lib/components/screen-header.js +++ b/ReactNativeClient/lib/components/screen-header.js @@ -16,7 +16,7 @@ let styleObject = { flexDirection: 'row', paddingTop: 10, paddingBottom: 10, - backgroundColor: globalStyle.backgroundColor, + backgroundColor: globalStyle.raisedBackgroundColor, alignItems: 'center', shadowColor: '#000000', elevation: 5, @@ -24,7 +24,7 @@ let styleObject = { folderPicker: { height: 30, flex:1, - color: globalStyle.color, + color: globalStyle.raisedHighlightedColor, // Note: cannot set backgroundStyle as that would remove the arrow in the component }, divider: { @@ -35,14 +35,14 @@ let styleObject = { sideMenuButton: { flex: 1, alignItems: 'center', - backgroundColor: globalStyle.backgroundColor, + backgroundColor: globalStyle.raisedBackgroundColor, paddingLeft: globalStyle.marginLeft, paddingRight: 5, marginRight: 2, }, iconButton: { flex: 1, - backgroundColor: globalStyle.backgroundColor, + backgroundColor: globalStyle.raisedBackgroundColor, paddingLeft: 15, paddingRight: 15, }, @@ -70,11 +70,11 @@ let styleObject = { contextMenuTrigger: { fontSize: 25, paddingRight: globalStyle.marginRight, - color: globalStyle.color, + color: globalStyle.raisedColor, fontWeight: 'bold', }, contextMenu: { - backgroundColor: globalStyle.backgroundColor, + backgroundColor: globalStyle.raisedBackgroundColor, }, contextMenuItem: { backgroundColor: globalStyle.backgroundColor, @@ -91,13 +91,15 @@ let styleObject = { titleText: { flex: 1, marginLeft: 0, - color: globalStyle.color, + color: globalStyle.raisedHighlightedColor, + fontWeight: 'bold', } }; styleObject.topIcon = Object.assign({}, globalStyle.icon); styleObject.topIcon.flex = 1; styleObject.topIcon.textAlignVertical = 'center'; +styleObject.topIcon.color = globalStyle.raisedColor; styleObject.backButton = Object.assign({}, styleObject.iconButton); styleObject.backButton.marginRight = 1; diff --git a/ReactNativeClient/lib/components/side-menu-content.js b/ReactNativeClient/lib/components/side-menu-content.js index 6ec51f59f..eb4912f48 100644 --- a/ReactNativeClient/lib/components/side-menu-content.js +++ b/ReactNativeClient/lib/components/side-menu-content.js @@ -167,12 +167,6 @@ class SideMenuContentComponent extends Component { return } - // onLayout(event) { - // const newWidth = event.nativeEvent.layout.width; - // if (this.state.width == newWidth) return; - // this.setState({ width: newWidth }); - // } - render() { let items = []; @@ -202,6 +196,7 @@ class SideMenuContentComponent extends Component { if (items.length) items.push(this.makeDivider('divider_2')); let lines = Synchronizer.reportToLines(this.props.syncReport); + while (lines.length < 10) lines.push(''); // Add blank lines so that height of report text is fixed and doesn't affect scrolling const syncReportText = lines.join("\n"); items.push(this.synchronizeButton(this.props.syncStarted ? 'cancel' : 'sync')); diff --git a/ReactNativeClient/lib/models/note.js b/ReactNativeClient/lib/models/note.js index 2b1677a23..63a33b8cd 100644 --- a/ReactNativeClient/lib/models/note.js +++ b/ReactNativeClient/lib/models/note.js @@ -43,7 +43,7 @@ class Note extends BaseItem { static geolocationUrl(note) { if (!('latitude' in note) || !('longitude' in note)) throw new Error('Latitude or longitude is missing'); - if (!note.latitude && !note.longitude) throw new Error(_('This note does not have geolocation information.')); + if (!Number(note.latitude) && !Number(note.longitude)) throw new Error(_('This note does not have geolocation information.')); return sprintf('https://www.openstreetmap.org/?lat=%s&lon=%s&zoom=20', note.latitude, note.longitude) } @@ -63,14 +63,28 @@ class Note extends BaseItem { return output; } - // static sortNotes(notes, order) { - // return notes.sort((a, b) => { - // // let r = -1; - // // if (a[order.orderBy] < b[order.orderBy]) r = +1; - // // if (order.orderByDir == 'ASC') r = -r; - // // return r; - // }); - // } + static sortNotes(notes, orders, uncompletedTodosOnTop) { + const noteOnTop = (note) => { + return uncompletedTodosOnTop && note.is_todo && !note.todo_completed; + } + + return notes.sort((a, b) => { + if (noteOnTop(a) && !noteOnTop(b)) return -1; + if (!noteOnTop(a) && noteOnTop(b)) return +1; + + let r = 0; + + for (let i = 0; i < orders.length; i++) { + const order = orders[i]; + if (a[order.by] < b[order.by]) r = +1; + if (a[order.by] > b[order.by]) r = -1; + if (order.dir == 'ASC') r = -r; + if (r) break; + } + + return r; + }); + } static previewFields() { return ['id', 'title', 'body', 'is_todo', 'todo_completed', 'parent_id', 'updated_time']; @@ -96,6 +110,9 @@ class Note extends BaseItem { } static async previews(parentId, options = null) { + // Note: ordering logic must be duplicated in sortNotes, which + // is used to sort already loaded notes. + if (!options) options = {}; if (!options.order) options.order = { by: 'updated_time', dir: 'DESC' }; if (!options.conditions) options.conditions = []; diff --git a/ReactNativeClient/lib/registry.js b/ReactNativeClient/lib/registry.js index 00cb74e45..a63138e5e 100644 --- a/ReactNativeClient/lib/registry.js +++ b/ReactNativeClient/lib/registry.js @@ -159,14 +159,14 @@ reg.syncStarted = async () => { } reg.setupRecurrentSync = () => { - if (this.recurrentSyncId_) { - PoorManIntervals.clearInterval(this.recurrentSyncId_); - this.recurrentSyncId_ = null; + if (reg.recurrentSyncId_) { + PoorManIntervals.clearInterval(reg.recurrentSyncId_); + reg.recurrentSyncId_ = null; } - console.info('Setting up recurrent sync with interval ' + Setting.value('sync.interval')); + reg.logger().debug('Setting up recurrent sync with interval ' + Setting.value('sync.interval')); - this.recurrentSyncId_ = PoorManIntervals.setInterval(() => { + reg.recurrentSyncId_ = PoorManIntervals.setInterval(() => { reg.logger().info('Running background sync on timer...'); reg.scheduleSync(0); }, 1000 * Setting.value('sync.interval')); diff --git a/ReactNativeClient/root.js b/ReactNativeClient/root.js index 565aa84c9..d0a65541f 100644 --- a/ReactNativeClient/root.js +++ b/ReactNativeClient/root.js @@ -245,7 +245,7 @@ const reducer = (state = defaultState, action) => { if (!found && ('parent_id' in modNote) && modNote.parent_id == state.selectedFolderId) newNotes.push(modNote); - //newNotes = Note.sortNotes(newNotes, state.notesOrder); + newNotes = Note.sortNotes(newNotes, state.notesOrder, newState.settings.uncompletedTodosOnTop); newState = Object.assign({}, state); newState.notes = newNotes; break;