From 191f2cacbfd93273084f81987e0269e16d9241b7 Mon Sep 17 00:00:00 2001 From: William Grant Date: Sun, 25 Mar 2018 12:27:04 +0200 Subject: [PATCH 01/46] Show confirmation dialog when deleting notes from the context menu if set in preferences --- browser/main/NoteList/index.js | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index e97f7aef..c3ebd9e0 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -574,22 +574,29 @@ class NoteList extends React.Component { }) } + confirmDeleteNote (selectedNotes) { + const noteExp = selectedNotes.length > 1 ? 'notes' : 'note' + const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), { + type: 'warning', + message: i18n.__('Confirm note deletion'), + detail: `This will permanently remove ${selectedNotes.length} ${noteExp}.`, + buttons: [i18n.__('Confirm'), i18n.__('Cancel')] + }) + + return dialogueButtonIndex === 1 ? false : true + } + deleteNote () { const { dispatch } = this.props const { selectedNoteKeys } = this.state const notes = this.notes.map((note) => Object.assign({}, note)) const selectedNotes = findNotesByKeys(notes, selectedNoteKeys) const firstNote = selectedNotes[0] + const confirmDeletion = this.props.config.ui.confirmDeletion if (firstNote.isTrashed) { - const noteExp = selectedNotes.length > 1 ? 'notes' : 'note' - const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), { - type: 'warning', - message: i18n.__('Confirm note deletion'), - detail: `This will permanently remove ${selectedNotes.length} ${noteExp}.`, - buttons: [i18n.__('Confirm'), i18n.__('Cancel')] - }) - if (dialogueButtonIndex === 1) return + if (!this.confirmDeleteNote(selectedNotes)) return + Promise.all( selectedNotes.map((note) => { return dataApi @@ -610,6 +617,10 @@ class NoteList extends React.Component { }) console.log('Notes were all deleted') } else { + if (confirmDeletion) { + if (!this.confirmDeleteNote(selectedNotes)) return + } + Promise.all( selectedNotes.map((note) => { note.isTrashed = true From a9b75f752e9cdef0aec6d155090fa1626c233b97 Mon Sep 17 00:00:00 2001 From: William Grant Date: Sun, 25 Mar 2018 18:28:02 +0200 Subject: [PATCH 02/46] updated node version in travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c68d1063..36542f3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - 6 + - 7 script: - npm run lint && npm run test - 'if [[ ${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} = "master" ]]; then npm install -g grunt npm@5.2 && grunt pre-build; fi' From 871ab428c295972dfe0e1de1f0efac068a1e642e Mon Sep 17 00:00:00 2001 From: William Grant Date: Sun, 25 Mar 2018 18:42:48 +0200 Subject: [PATCH 03/46] Revert "updated node version in travis.yml" This reverts commit a9b75f752e9cdef0aec6d155090fa1626c233b97. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 36542f3c..c68d1063 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - 7 + - 6 script: - npm run lint && npm run test - 'if [[ ${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} = "master" ]]; then npm install -g grunt npm@5.2 && grunt pre-build; fi' From 56231edc3a7c295d2d11951c93ed982a1a4b5be3 Mon Sep 17 00:00:00 2001 From: William Grant Date: Sun, 25 Mar 2018 18:43:54 +0200 Subject: [PATCH 04/46] fix delete confirmation method --- browser/main/NoteList/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index c3ebd9e0..e5b5403c 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -583,7 +583,7 @@ class NoteList extends React.Component { buttons: [i18n.__('Confirm'), i18n.__('Cancel')] }) - return dialogueButtonIndex === 1 ? false : true + return dialogueButtonIndex != 1 } deleteNote () { From 4f98995fe4fc98f41fd5629d6349511245225324 Mon Sep 17 00:00:00 2001 From: William Grant Date: Sun, 25 Mar 2018 18:47:21 +0200 Subject: [PATCH 05/46] ... that second equals --- browser/main/NoteList/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index e5b5403c..029d9dcd 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -583,7 +583,7 @@ class NoteList extends React.Component { buttons: [i18n.__('Confirm'), i18n.__('Cancel')] }) - return dialogueButtonIndex != 1 + return dialogueButtonIndex !== 1 } deleteNote () { From f0144233f917c36bf13245fcdd58665f92f104df Mon Sep 17 00:00:00 2001 From: William Grant Date: Sun, 25 Mar 2018 23:04:16 +0200 Subject: [PATCH 06/46] Fullscreen shortcut for non macOS is now F11 --- lib/main-menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main-menu.js b/lib/main-menu.js index ddf5ee54..036256f2 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -287,7 +287,7 @@ const window = { }, { label: 'Toggle Full Screen', - accelerator: 'Command+Control+F', + accelerator: process.platform === 'darwin' ? 'Command+Control+F' : 'F11', selector: 'toggleFullScreen:' }, { From ee78e113de148a839754f58acab13f06a6d0a33e Mon Sep 17 00:00:00 2001 From: William Grant Date: Tue, 27 Mar 2018 20:52:58 +0200 Subject: [PATCH 07/46] Moved 'Toggle Fullscreen' to the View label used non-OS specific fullscreen --- lib/main-menu.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/main-menu.js b/lib/main-menu.js index 036256f2..37debc52 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -230,6 +230,13 @@ const view = { BrowserWindow.getFocusedWindow().toggleDevTools() } }, + { + label: 'Toggle Full Screen', + accelerator: macOS ? 'Command+Control+F' : 'F11', + click () { + mainWindow.setFullScreen(!mainWindow.isFullScreen()) + } + }, { type: 'separator' }, @@ -285,11 +292,6 @@ const window = { accelerator: 'Command+M', selector: 'performMiniaturize:' }, - { - label: 'Toggle Full Screen', - accelerator: process.platform === 'darwin' ? 'Command+Control+F' : 'F11', - selector: 'toggleFullScreen:' - }, { label: 'Close', accelerator: 'Command+W', From 9a445e34fd50c381ec29230240b14a55a24a94b4 Mon Sep 17 00:00:00 2001 From: William Grant Date: Tue, 27 Mar 2018 21:06:59 +0200 Subject: [PATCH 08/46] fixed trailing spaces --- lib/main-menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main-menu.js b/lib/main-menu.js index 37debc52..f0830863 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -233,7 +233,7 @@ const view = { { label: 'Toggle Full Screen', accelerator: macOS ? 'Command+Control+F' : 'F11', - click () { + click () { mainWindow.setFullScreen(!mainWindow.isFullScreen()) } }, From e1e3cc7999a8404669e14447c11a61269c58378b Mon Sep 17 00:00:00 2001 From: William Grant Date: Wed, 28 Mar 2018 19:17:40 +0200 Subject: [PATCH 09/46] moved label to a better position --- lib/main-menu.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/main-menu.js b/lib/main-menu.js index f0830863..644491ec 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -230,13 +230,6 @@ const view = { BrowserWindow.getFocusedWindow().toggleDevTools() } }, - { - label: 'Toggle Full Screen', - accelerator: macOS ? 'Command+Control+F' : 'F11', - click () { - mainWindow.setFullScreen(!mainWindow.isFullScreen()) - } - }, { type: 'separator' }, @@ -263,6 +256,16 @@ const view = { click () { mainWindow.webContents.send('top:focus-search') } + }, + { + type: 'separator' + }, + { + label:'Toggle Full Screen', + accelerator: macOS ? 'Command+Control+F' : 'F11', + click () { + mainWindow.setFullScreen(!mainWindow.isFullScreen()) + } } ] } From 11f8cfe0e6aa00dc64bf0ee57ea85ccf9291e127 Mon Sep 17 00:00:00 2001 From: William Grant Date: Wed, 28 Mar 2018 19:21:36 +0200 Subject: [PATCH 10/46] fixed label key-spacing --- lib/main-menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main-menu.js b/lib/main-menu.js index 644491ec..e253fdbf 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -261,7 +261,7 @@ const view = { type: 'separator' }, { - label:'Toggle Full Screen', + label: 'Toggle Full Screen', accelerator: macOS ? 'Command+Control+F' : 'F11', click () { mainWindow.setFullScreen(!mainWindow.isFullScreen()) From b46b9581050914212fcc056a794dd37426214fea Mon Sep 17 00:00:00 2001 From: William Grant Date: Fri, 30 Mar 2018 11:05:20 +0200 Subject: [PATCH 11/46] updated for separate methods for full screen depending on the platform --- lib/main-menu.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/main-menu.js b/lib/main-menu.js index e253fdbf..cb4f1f4a 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -263,9 +263,7 @@ const view = { { label: 'Toggle Full Screen', accelerator: macOS ? 'Command+Control+F' : 'F11', - click () { - mainWindow.setFullScreen(!mainWindow.isFullScreen()) - } + selector: macOS ? 'toggleFullScreen:' : mainWindow.setFullScreen(!mainWindow.isFullScreen()) } ] } From a32cfc8aff3c6336cf136722cc9347b9f4c533c4 Mon Sep 17 00:00:00 2001 From: William Grant Date: Fri, 30 Mar 2018 13:01:18 +0200 Subject: [PATCH 12/46] Revert "updated for separate methods for full screen depending on the platform" This reverts commit b46b9581050914212fcc056a794dd37426214fea. --- lib/main-menu.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/main-menu.js b/lib/main-menu.js index cb4f1f4a..e253fdbf 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -263,7 +263,9 @@ const view = { { label: 'Toggle Full Screen', accelerator: macOS ? 'Command+Control+F' : 'F11', - selector: macOS ? 'toggleFullScreen:' : mainWindow.setFullScreen(!mainWindow.isFullScreen()) + click () { + mainWindow.setFullScreen(!mainWindow.isFullScreen()) + } } ] } From be94edde0f4908755c5520a688013d25bc9d547c Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Tue, 10 Apr 2018 16:26:50 +0900 Subject: [PATCH 13/46] extract confirmDeleteNote function --- browser/lib/confirmDeleteNote.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 browser/lib/confirmDeleteNote.js diff --git a/browser/lib/confirmDeleteNote.js b/browser/lib/confirmDeleteNote.js new file mode 100644 index 00000000..80d1ffc7 --- /dev/null +++ b/browser/lib/confirmDeleteNote.js @@ -0,0 +1,23 @@ +import electron from 'electron' +import i18n from 'browser/lib/i18n' +const { remote } = electron +const { dialog } = remote + +export function confirmDeleteNote (confirmDeletion, permanent) { + if (confirmDeletion || permanent) { + const alertConfig = { + ype: 'warning', + message: i18n.__('Confirm note deletion'), + detail: i18n.__('This will permanently remove this note.'), + buttons: [i18n.__('Confirm'), i18n.__('Cancel')] + } + + const dialogButtonIndex = dialog.showMessageBox( + remote.getCurrentWindow(), alertConfig + ) + + return dialogButtonIndex === 0 + } + + return true +} From ce440351a51766ba5823a5f9f7b9670756f1a126 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Tue, 10 Apr 2018 16:28:05 +0900 Subject: [PATCH 14/46] use extracted confirmDeleteNote function --- browser/main/Detail/MarkdownNoteDetail.js | 10 +++++----- browser/main/Detail/SnippetNoteDetail.js | 10 +++++----- browser/main/Detail/index.js | 2 -- browser/main/NoteList/index.js | 21 ++++----------------- 4 files changed, 14 insertions(+), 29 deletions(-) diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js index 6821bf2f..05883c0e 100755 --- a/browser/main/Detail/MarkdownNoteDetail.js +++ b/browser/main/Detail/MarkdownNoteDetail.js @@ -28,6 +28,7 @@ import InfoPanelTrashed from './InfoPanelTrashed' import { formatDate } from 'browser/lib/date-formatter' import { getTodoPercentageOfCompleted } from 'browser/lib/getTodoStatus' import striptags from 'striptags' +import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote' class MarkdownNoteDetail extends React.Component { constructor (props) { @@ -181,10 +182,10 @@ class MarkdownNoteDetail extends React.Component { handleTrashButtonClick (e) { const { note } = this.state const { isTrashed } = note - const { confirmDeletion } = this.props + const { confirmDeletion } = this.props.config.ui if (isTrashed) { - if (confirmDeletion(true)) { + if (confirmDeleteNote(confirmDeletion, true)) { const {note, dispatch} = this.props dataApi .deleteNote(note.storage, note.key) @@ -201,7 +202,7 @@ class MarkdownNoteDetail extends React.Component { .then(() => ee.emit('list:next')) } } else { - if (confirmDeletion()) { + if (confirmDeleteNote(confirmDeletion, false)) { note.isTrashed = true this.setState({ @@ -437,8 +438,7 @@ MarkdownNoteDetail.propTypes = { style: PropTypes.shape({ left: PropTypes.number }), - ignorePreviewPointerEvents: PropTypes.bool, - confirmDeletion: PropTypes.bool.isRequired + ignorePreviewPointerEvents: PropTypes.bool } export default CSSModules(MarkdownNoteDetail, styles) diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index 620de512..411027d5 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -27,6 +27,7 @@ import InfoPanel from './InfoPanel' import InfoPanelTrashed from './InfoPanelTrashed' import { formatDate } from 'browser/lib/date-formatter' import i18n from 'browser/lib/i18n' +import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote' function pass (name) { switch (name) { @@ -197,10 +198,10 @@ class SnippetNoteDetail extends React.Component { handleTrashButtonClick (e) { const { note } = this.state const { isTrashed } = note - const { confirmDeletion } = this.props + const { confirmDeletion } = this.props.config.ui if (isTrashed) { - if (confirmDeletion(true)) { + if (confirmDeleteNote(confirmDeletion, true)) { const {note, dispatch} = this.props dataApi .deleteNote(note.storage, note.key) @@ -217,7 +218,7 @@ class SnippetNoteDetail extends React.Component { .then(() => ee.emit('list:next')) } } else { - if (confirmDeletion()) { + if (confirmDeleteNote(confirmDeletion, false)) { note.isTrashed = true this.setState({ @@ -883,8 +884,7 @@ SnippetNoteDetail.propTypes = { style: PropTypes.shape({ left: PropTypes.number }), - ignorePreviewPointerEvents: PropTypes.bool, - confirmDeletion: PropTypes.bool.isRequired + ignorePreviewPointerEvents: PropTypes.bool } export default CSSModules(SnippetNoteDetail, styles) diff --git a/browser/main/Detail/index.js b/browser/main/Detail/index.js index df38132c..32d20a32 100644 --- a/browser/main/Detail/index.js +++ b/browser/main/Detail/index.js @@ -82,7 +82,6 @@ class Detail extends React.Component { this.confirmDeletion(permanent)} ref='root' {..._.pick(this.props, [ 'dispatch', @@ -99,7 +98,6 @@ class Detail extends React.Component { this.confirmDeletion(permanent)} ref='root' {..._.pick(this.props, [ 'dispatch', diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index 029d9dcd..2d672664 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -18,6 +18,7 @@ import copy from 'copy-to-clipboard' import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig' import Markdown from '../../lib/markdown' import i18n from 'browser/lib/i18n' +import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote' const { remote } = require('electron') const { Menu, MenuItem, dialog } = remote @@ -574,28 +575,16 @@ class NoteList extends React.Component { }) } - confirmDeleteNote (selectedNotes) { - const noteExp = selectedNotes.length > 1 ? 'notes' : 'note' - const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), { - type: 'warning', - message: i18n.__('Confirm note deletion'), - detail: `This will permanently remove ${selectedNotes.length} ${noteExp}.`, - buttons: [i18n.__('Confirm'), i18n.__('Cancel')] - }) - - return dialogueButtonIndex !== 1 - } - deleteNote () { const { dispatch } = this.props const { selectedNoteKeys } = this.state const notes = this.notes.map((note) => Object.assign({}, note)) const selectedNotes = findNotesByKeys(notes, selectedNoteKeys) const firstNote = selectedNotes[0] - const confirmDeletion = this.props.config.ui.confirmDeletion + const { confirmDeletion } = this.props.config.ui if (firstNote.isTrashed) { - if (!this.confirmDeleteNote(selectedNotes)) return + if (!confirmDeleteNote(confirmDeletion, true)) return Promise.all( selectedNotes.map((note) => { @@ -617,9 +606,7 @@ class NoteList extends React.Component { }) console.log('Notes were all deleted') } else { - if (confirmDeletion) { - if (!this.confirmDeleteNote(selectedNotes)) return - } + if (!confirmDeleteNote(confirmDeletion, false)) return Promise.all( selectedNotes.map((note) => { From eafccc4fc41ce737a6d244ac52d3ac147c08ec00 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Tue, 10 Apr 2018 16:44:04 +0900 Subject: [PATCH 15/46] remove confirmDeletion function --- browser/main/Detail/index.js | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/browser/main/Detail/index.js b/browser/main/Detail/index.js index 32d20a32..7d2b4cba 100644 --- a/browser/main/Detail/index.js +++ b/browser/main/Detail/index.js @@ -33,26 +33,6 @@ class Detail extends React.Component { ee.off('detail:delete', this.deleteHandler) } - confirmDeletion (permanent) { - if (this.props.config.ui.confirmDeletion || permanent) { - const electron = require('electron') - const { remote } = electron - const { dialog } = remote - - const alertConfig = { - type: 'warning', - message: i18n.__('Confirm note deletion'), - detail: i18n.__('This will permanently remove this note.'), - buttons: [i18n.__('Confirm'), i18n.__('Cancel')] - } - - const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), alertConfig) - return dialogueButtonIndex === 0 - } - - return true - } - render () { const { location, data, config } = this.props let note = null From 022915ffc9a7e5cae5e3413f8f3d2baadc6c08b8 Mon Sep 17 00:00:00 2001 From: Frank Kanis Date: Thu, 12 Apr 2018 00:10:22 +0200 Subject: [PATCH 16/46] Fixed change some languages --- browser/lib/i18n.js | 2 +- browser/main/modals/PreferencesModal/UiTab.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/browser/lib/i18n.js b/browser/lib/i18n.js index 0da1dd25..3cb0d049 100644 --- a/browser/lib/i18n.js +++ b/browser/lib/i18n.js @@ -5,7 +5,7 @@ const { app } = remote // load package for localization const i18n = new (require('i18n-2'))({ // setup some locales - other locales default to the first locale - locales: ['en', 'sq', 'zh-CN', 'zh-TW', 'da', 'fr', 'de', 'hu', 'ja', 'ko', 'no', 'pl', 'pt', 'es-ES'], + locales: ['da', 'de', 'en', 'es-ES', 'fr', 'hu', 'ja', 'ko', 'pl', 'pt-BR', 'pt-PT', 'ru', 'sq', 'zh-CN', 'zh-TW' ], extension: '.json', directory: process.env.NODE_ENV === 'production' ? path.join(app.getAppPath(), './locales') diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 748c3914..a092129a 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -194,9 +194,10 @@ class UiTab extends React.Component { - + + - + From cc667ac7384fe8ab98dec668883c338ad427b8d5 Mon Sep 17 00:00:00 2001 From: Frank Kanis Date: Thu, 12 Apr 2018 00:27:20 +0200 Subject: [PATCH 17/46] Added spacing --- browser/lib/i18n.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/lib/i18n.js b/browser/lib/i18n.js index 3cb0d049..f7bd96e9 100644 --- a/browser/lib/i18n.js +++ b/browser/lib/i18n.js @@ -5,7 +5,7 @@ const { app } = remote // load package for localization const i18n = new (require('i18n-2'))({ // setup some locales - other locales default to the first locale - locales: ['da', 'de', 'en', 'es-ES', 'fr', 'hu', 'ja', 'ko', 'pl', 'pt-BR', 'pt-PT', 'ru', 'sq', 'zh-CN', 'zh-TW' ], + locales: [ 'da', 'de', 'en', 'es-ES', 'fr', 'hu', 'ja', 'ko', 'pl', 'pt-BR', 'pt-PT', 'ru', 'sq', 'zh-CN', 'zh-TW' ], extension: '.json', directory: process.env.NODE_ENV === 'production' ? path.join(app.getAppPath(), './locales') From 7aedb59f262a6978b080cf142fd9ac5fa13b468c Mon Sep 17 00:00:00 2001 From: Frank Kanis Date: Thu, 12 Apr 2018 21:20:16 +0200 Subject: [PATCH 18/46] Fixed moving notes with images --- browser/main/lib/dataApi/moveNote.js | 38 +++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/browser/main/lib/dataApi/moveNote.js b/browser/main/lib/dataApi/moveNote.js index 928d331b..31e9d096 100644 --- a/browser/main/lib/dataApi/moveNote.js +++ b/browser/main/lib/dataApi/moveNote.js @@ -68,26 +68,30 @@ function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) { return noteData }) .then(function moveImages (noteData) { - const searchImagesRegex = /!\[.*?]\(\s*?\/:storage\/(.*\.\S*?)\)/gi - let match = searchImagesRegex.exec(noteData.content) + if(oldStorage.path === newStorage.path) { + return noteData + } else { + const searchImagesRegex = /!\[.*?]\(\s*?\/:storage\/(.*\.\S*?)\)/gi + let match = searchImagesRegex.exec(noteData.content) - const moveTasks = [] - while (match != null) { - const [, filename] = match - const oldPath = path.join(oldStorage.path, 'images', filename) - moveTasks.push( - copyImage(oldPath, noteData.storage, false) - .then(() => { - fs.unlinkSync(oldPath) - }) - ) + const moveTasks = [] + while (match != null) { + const [, filename] = match + const oldPath = path.join(oldStorage.path, 'images', filename) + moveTasks.push( + copyImage(oldPath, noteData.storage, false) + .then(() => { + fs.unlinkSync(oldPath) + }) + ) - // find next occurence - match = searchImagesRegex.exec(noteData.content) - } + // find next occurence + match = searchImagesRegex.exec(noteData.content) + } - return Promise.all(moveTasks).then(() => noteData) - }) + return Promise.all(moveTasks).then(() => noteData) + } + }) .then(function writeAndReturn (noteData) { CSON.writeFileSync(path.join(newStorage.path, 'notes', noteData.key + '.cson'), _.omit(noteData, ['key', 'storage'])) return noteData From daea604c607480ac50b04b22427dcf6bc25ad3f7 Mon Sep 17 00:00:00 2001 From: Frank Kanis Date: Thu, 12 Apr 2018 21:51:01 +0200 Subject: [PATCH 19/46] Added spaces --- browser/main/lib/dataApi/moveNote.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/browser/main/lib/dataApi/moveNote.js b/browser/main/lib/dataApi/moveNote.js index 31e9d096..bb17d208 100644 --- a/browser/main/lib/dataApi/moveNote.js +++ b/browser/main/lib/dataApi/moveNote.js @@ -68,7 +68,7 @@ function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) { return noteData }) .then(function moveImages (noteData) { - if(oldStorage.path === newStorage.path) { + if (oldStorage.path === newStorage.path) { return noteData } else { const searchImagesRegex = /!\[.*?]\(\s*?\/:storage\/(.*\.\S*?)\)/gi @@ -90,8 +90,8 @@ function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) { } return Promise.all(moveTasks).then(() => noteData) - } - }) + } + }) .then(function writeAndReturn (noteData) { CSON.writeFileSync(path.join(newStorage.path, 'notes', noteData.key + '.cson'), _.omit(noteData, ['key', 'storage'])) return noteData From a8500150b0bc5e4c0e78cc71a73a15f6db9a35d8 Mon Sep 17 00:00:00 2001 From: Hung Nguyen Date: Sat, 14 Apr 2018 21:43:19 +0700 Subject: [PATCH 20/46] fixed menu popup on alt --- browser/main/index.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/browser/main/index.js b/browser/main/index.js index ae906538..3fa682cd 100644 --- a/browser/main/index.js +++ b/browser/main/index.js @@ -24,6 +24,46 @@ document.addEventListener('dragover', function (e) { e.stopPropagation() }) +// prevent menu from popup when alt pressed +// but still able to toggle menu when only alt is pressed +let isAltPressing = false +let isAltWithMouse = false +let isAltWithOtherKey = false +let isOtherKey = false + +document.addEventListener('keydown', function (e) { + if (e.key === 'Alt') { + isAltPressing = true + if (isOtherKey) { + isAltWithOtherKey = true + } + } else { + if (isAltPressing) { + isAltWithOtherKey = true + } + isOtherKey = true + } +}) + +document.addEventListener('mousedown', function (e) { + if (isAltPressing) { + isAltWithMouse = true + } +}) + +document.addEventListener('keyup', function (e) { + if (e.key === 'Alt') { + if (isAltWithMouse || isAltWithOtherKey) { + console.log(isAltWithMouse, isAltWithOtherKey) + e.preventDefault() + } + isAltWithMouse = false + isAltWithOtherKey = false + isAltPressing = false + isOtherKey = false + } +}) + document.addEventListener('click', function (e) { const className = e.target.className if (!className && typeof (className) !== 'string') return From 4a6b22f5b76eb8f025e98f347c1a6e5dba0baa4f Mon Sep 17 00:00:00 2001 From: Hung Nguyen Date: Sun, 15 Apr 2018 09:18:12 +0700 Subject: [PATCH 21/46] removed console.log used for debuging --- browser/main/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/browser/main/index.js b/browser/main/index.js index 3fa682cd..6e8bdcc5 100644 --- a/browser/main/index.js +++ b/browser/main/index.js @@ -54,7 +54,6 @@ document.addEventListener('mousedown', function (e) { document.addEventListener('keyup', function (e) { if (e.key === 'Alt') { if (isAltWithMouse || isAltWithOtherKey) { - console.log(isAltWithMouse, isAltWithOtherKey) e.preventDefault() } isAltWithMouse = false From 47af3f09fcde27fc3ebe86c31e485249394c3390 Mon Sep 17 00:00:00 2001 From: Hung Nguyen Date: Tue, 17 Apr 2018 09:59:30 +0700 Subject: [PATCH 22/46] Centralized languages into 1 file --- browser/lib/Languages.js | 65 +++++++++++++++++++ browser/lib/i18n.js | 8 ++- browser/main/Main.js | 23 ++----- browser/main/modals/PreferencesModal/UiTab.js | 21 ++---- 4 files changed, 84 insertions(+), 33 deletions(-) create mode 100644 browser/lib/Languages.js diff --git a/browser/lib/Languages.js b/browser/lib/Languages.js new file mode 100644 index 00000000..f5262810 --- /dev/null +++ b/browser/lib/Languages.js @@ -0,0 +1,65 @@ +module.exports = { + languages: [ + { + name: 'Albanian', + locale: 'sq' + }, + { + name: 'Chinese (zh-CN)', + locale: 'zh-CN' + }, + { + name: 'Chinese (zh-TW)', + locale: 'zh-TW' + }, + { + name: 'Danish', + locale: 'da' + }, + { + name: 'English', + locale: 'en' + }, + { + name: 'French', + locale: 'fr' + }, + { + name: 'German', + locale: 'de' + }, + { + name: 'Hungarian', + locale: 'hu' + }, + { + name: 'Japanese', + locale: 'ja' + }, + { + name: 'Korean', + locale: 'ko' + }, + { + name: 'Norwegian', + locale: 'no' + }, + { + name: 'Polish', + locale: 'pl' + }, + { + name: 'Portuguese', + locale: 'pt' + }, + { + name: 'Russian', + locale: 'ru' + }, + { + name: 'Spanish', + locale: 'es-ES' + } + ] +} + diff --git a/browser/lib/i18n.js b/browser/lib/i18n.js index 0da1dd25..ce94dfee 100644 --- a/browser/lib/i18n.js +++ b/browser/lib/i18n.js @@ -1,11 +1,17 @@ const path = require('path') const { remote } = require('electron') const { app } = remote +const { languages } = require('./Languages.js') + +let locales = languages.reduce(function (localeList, locale) { + localeList.push(locale.locale) + return localeList +}, []) // load package for localization const i18n = new (require('i18n-2'))({ // setup some locales - other locales default to the first locale - locales: ['en', 'sq', 'zh-CN', 'zh-TW', 'da', 'fr', 'de', 'hu', 'ja', 'ko', 'no', 'pl', 'pt', 'es-ES'], + locales: locales, extension: '.json', directory: process.env.NODE_ENV === 'production' ? path.join(app.getAppPath(), './locales') diff --git a/browser/main/Main.js b/browser/main/Main.js index 14a56225..1fa5ba2b 100644 --- a/browser/main/Main.js +++ b/browser/main/Main.js @@ -15,6 +15,7 @@ import eventEmitter from 'browser/main/lib/eventEmitter' import { hashHistory } from 'react-router' import store from 'browser/main/store' import i18n from 'browser/lib/i18n' +import { languages } from 'browser/lib/Languages' const path = require('path') const electron = require('electron') const { remote } = electron @@ -152,24 +153,12 @@ class Main extends React.Component { document.body.setAttribute('data-theme', 'default') } - const supportedLanguages = [ - 'sq', - 'zh-CN', - 'zh-TW', - 'da', - 'fr', - 'de', - 'hu', - 'ja', - 'ko', - 'no', - 'pl', - 'pt', - 'ru', - 'es-ES' - ] + let locales = languages.reduce(function (localeList, locale) { + localeList.push(locale.locale) + return localeList + }, []) - if (supportedLanguages.indexOf(config.ui.language) !== -1) { + if (locales.indexOf(config.ui.language) !== -1) { i18n.setLocale(config.ui.language) } else { i18n.setLocale('en') diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 748c3914..189b1064 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -10,6 +10,7 @@ import CodeMirror from 'codemirror' import 'codemirror-mode-elixir' import _ from 'lodash' import i18n from 'browser/lib/i18n' +import { languages } from 'browser/lib/Languages' const OSX = global.process.platform === 'darwin' @@ -182,21 +183,11 @@ class UiTab extends React.Component { onChange={(e) => this.handleUIChange(e)} ref='uiLanguage' > - - - - - - - - - - - - - - - + { + languages.map((language) => { + return () + }) + } From 2994420160314feb4147659d2abe654d7a0c45a7 Mon Sep 17 00:00:00 2001 From: Hung Nguyen Date: Tue, 17 Apr 2018 20:47:13 +0700 Subject: [PATCH 23/46] Fixed image not displaying after paste --- browser/components/CodeEditor.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 872e9ad7..809957da 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -331,9 +331,14 @@ export default class CodeEditor extends React.Component { const imageDir = path.join(storagePath, 'images') if (!fs.existsSync(imageDir)) fs.mkdirSync(imageDir) const imagePath = path.join(imageDir, `${imageName}.png`) - fs.writeFile(imagePath, binaryData, 'binary') - const imageMd = `![${imageName}](${path.join('/:storage', `${imageName}.png`)})` - this.insertImageMd(imageMd) + fs.writeFile(imagePath, binaryData, 'binary', (error) => { + if (error) { + throw error + } else { + const imageMd = `![${imageName}](${path.join('/:storage', `${imageName}.png`)})` + this.insertImageMd(imageMd) + } + }) } } else if (this.props.fetchUrlTitle && isURL(pastedTxt) && !isInLinkTag(editor)) { this.handlePasteUrl(e, editor, pastedTxt) From 1d4f1764fcb8b9dfe0379f02406bbeebc20dff08 Mon Sep 17 00:00:00 2001 From: William Grant Date: Tue, 17 Apr 2018 18:22:54 +0200 Subject: [PATCH 24/46] Changed top:focus-search shortcut --- browser/main/NoteList/index.js | 4 ++-- lib/main-menu.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index e97f7aef..c4da6358 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -281,8 +281,8 @@ class NoteList extends React.Component { ee.emit('detail:focus') } - // F or S key - if (e.keyCode === 70 || e.keyCode === 83) { + // L or S key + if (e.keyCode === 76 || e.keyCode === 83) { e.preventDefault() ee.emit('top:focus-search') } diff --git a/lib/main-menu.js b/lib/main-menu.js index e253fdbf..e1e2a83a 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -252,7 +252,7 @@ const view = { }, { label: 'Focus Search', - accelerator: 'Control+S', + accelerator: 'CommandOrControl+Shift+L', click () { mainWindow.webContents.send('top:focus-search') } @@ -275,7 +275,7 @@ let editorFocused // Define extra shortcut keys mainWindow.webContents.on('before-input-event', (event, input) => { // Synonyms for Search (Find) - if (input.control && input.key === 'f' && input.type === 'keyDown') { + if (input.control && input.key === 'l' && input.type === 'keyDown') { if (!editorFocused) { mainWindow.webContents.send('top:focus-search') event.preventDefault() From 813b433f4dc67ccdbdc13d63ae9543a2c0dd8bde Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 17 Apr 2018 18:07:27 -0300 Subject: [PATCH 25/46] Fix small typo --- locales/es-ES.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/es-ES.json b/locales/es-ES.json index ea20641b..d533579c 100644 --- a/locales/es-ES.json +++ b/locales/es-ES.json @@ -87,7 +87,7 @@ "Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote es utilizado en alrededor de 200 países y regiones diferentes por una increíble comunidad de desarrolladores.", "To continue supporting this growth, and to satisfy community expectations,": "Para continuar apoyando este crecimiento y satisfacer las expectativas de la comunidad,", "we would like to invest more time and resources in this project.": "nos gustaría invertir más tiempo y recursos en este proyecto.", - "If you like this project and see its potential, you can help by supporting us on OpenCollective!": "Si te gusta este proyecto y ves potencial en él, ¡puedes ayudar apoyándonos en OpenCollective!", + "If you like this project and see its potential, you can help by supporting us on OpenCollective!": "Si te gusta este proyecto y ves su potencial, ¡puedes ayudar apoyándonos en OpenCollective!", "Thanks,": "Gracias,", "Boostnote maintainers": "Equipo de Boostnote", "Support via OpenCollective": "Contribuir vía OpenCollective", @@ -149,5 +149,5 @@ "Sanitization": "Saneamiento", "Only allow secure html tags (recommended)": "Solo permitir etiquetas html seguras (recomendado)", "Allow styles": "Permitir estilos", - "Allow dangerous html tags": "Permitir etiques html peligrosas" + "Allow dangerous html tags": "Permitir etiquetas html peligrosas" } From 3d0af2d8ca91b4f16950b76d0973cb8ff3c71df7 Mon Sep 17 00:00:00 2001 From: "K.Kimura" Date: Wed, 18 Apr 2018 13:20:20 +0900 Subject: [PATCH 26/46] locales/ja.json translated in Japanese --- locales/ja.json | 274 ++++++++++++++++++++++++------------------------ 1 file changed, 137 insertions(+), 137 deletions(-) diff --git a/locales/ja.json b/locales/ja.json index 51f975d9..19609ffa 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -1,153 +1,153 @@ { - "Notes": "Notes", - "Tags": "Tags", - "Preferences": "Preferences", - "Make a note": "Make a note", + "Notes": "ノート", + "Tags": "タグ", + "Preferences": "設定", + "Make a note": "ノート作成", "Ctrl": "Ctrl", "Ctrl(^)": "Ctrl", - "to create a new note": "to create a new note", - "Toggle Mode": "Toggle Mode", - "Trash": "Trash", - "MODIFICATION DATE": "MODIFICATION DATE", - "Words": "Words", - "Letters": "Letters", - "STORAGE": "STORAGE", - "FOLDER": "FOLDER", - "CREATION DATE": "CREATION DATE", - "NOTE LINK": "NOTE LINK", + "to create a new note": "ノートを新規に作成", + "Toggle Mode": "モード切替", + "Trash": "ゴミ箱", + "MODIFICATION DATE": "修正日", + "Words": "ワード", + "Letters": "文字", + "STORAGE": "ストレージ", + "FOLDER": "フォルダ", + "CREATION DATE": "作成日", + "NOTE LINK": "リンク", ".md": ".md", ".txt": ".txt", ".html": ".html", - "Print": "Print", - "Your preferences for Boostnote": "Your preferences for Boostnote", - "Storages": "Storages", - "Add Storage Location": "Add Storage Location", - "Add Folder": "Add Folder", - "Open Storage folder": "Open Storage folder", - "Unlink": "Unlink", - "Edit": "Edit", - "Delete": "Delete", - "Interface": "Interface", - "Interface Theme": "Interface Theme", - "Default": "Default", - "White": "White", - "Solarized Dark": "Solarized Dark", - "Dark": "Dark", - "Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes", - "Editor Theme": "Editor Theme", - "Editor Font Size": "Editor Font Size", - "Editor Font Family": "Editor Font Family", - "Editor Indent Style": "Editor Indent Style", - "Spaces": "Spaces", - "Tabs": "Tabs", - "Switch to Preview": "Switch to Preview", - "When Editor Blurred": "When Editor Blurred", - "When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click", - "On Right Click": "On Right Click", - "Editor Keymap": "Editor Keymap", - "default": "default", + "Print": "印刷", + "Your preferences for Boostnote": "Boostnoteの個人設定", + "Storages": "ストレージ", + "Add Storage Location": "ストレージロケーションを追加", + "Add Folder": "フォルダを追加", + "Open Storage folder": "ストレージフォルダを開く", + "Unlink": "リンク解除", + "Edit": "編集", + "Delete": "削除", + "Interface": "インターフェース", + "Interface Theme": "インターフェーステーマ", + "Default": "デフォルト", + "White": "白", + "Solarized Dark": "明灰", + "Dark": "暗灰", + "Show a confirmation dialog when deleting notes": "ノートを削除する時に確認ダイアログを表示する", + "Editor Theme": "エディタのテーマ", + "Editor Font Size": "エディタのフォントサイズ", + "Editor Font Family": "エディタのフォント", + "Editor Indent Style": "エディタのインデント方法", + "Spaces": "スペース", + "Tabs": "タブ", + "Switch to Preview": "プレビューへ移動", + "When Editor Blurred": "エディタがフォーカスを失った時", + "When Editor Blurred, Edit On Double Click": "エディタがフォーカスを失った時、ダブルクリックで編集", + "On Right Click": "右クリック", + "Editor Keymap": "エディタのキーマップ", + "default": "デフォルト", "vim": "vim", "emacs": "emacs", - "⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap", - "Show line numbers in the editor": "Show line numbers in the editor", - "Allow editor to scroll past the last line": "Allow editor to scroll past the last line", + "⚠️ Please restart boostnote after you change the keymap": "⚠️ Plキーマップ変更後は Boostnote を再起動してください", + "Show line numbers in the editor": "エディタ内に行番号を表示", + "Allow editor to scroll past the last line": "エディタが最終行以降にスクロールできるようにする", "Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor", - "Preview": "Preview", - "Preview Font Size": "Preview Font Size", - "Preview Font Family": "Preview Font Family", - "Code block Theme": "Code block Theme", - "Allow preview to scroll past the last line": "Allow preview to scroll past the last line", - "Show line numbers for preview code blocks": "Show line numbers for preview code blocks", - "LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter", - "LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter", - "LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter", - "LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter", - "Community": "Community", - "Subscribe to Newsletter": "Subscribe to Newsletter", + "Preview": "プレビュー", + "Preview Font Size": "プレビュー時フォントサイズ", + "Preview Font Family": "プレビュー時フォント", + "Code block Theme": "コードブロックのテーマ", + "Allow preview to scroll past the last line": "プレビュー時に最終行以降にスクロールできるようにする", + "Show line numbers for preview code blocks": "プレビュー時のコードブロック内に行番号を表示する", + "LaTeX Inline Open Delimiter": "LaTeX 開始デリミタ(インライン)Inline Open Delimiter", + "LaTeX Inline Close Delimiter": "LaTeX 終了デリミタ(インライン)", + "LaTeX Block Open Delimiter": "LaTeX 開始デリミタ(ブロック)", + "LaTeX Block Close Delimiter": "LaTeX 終了デリミタ(ブロック)", + "Community": "コミュニティ", + "Subscribe to Newsletter": "ニュースレターを購読する", "GitHub": "GitHub", - "Blog": "Blog", - "Facebook Group": "Facebook Group", + "Blog": "ブログ", + "Facebook Group": "Facebook グループ", "Twitter": "Twitter", - "About": "About", + "About": "について", "Boostnote": "Boostnote", - "An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.", - "Website": "Website", - "Development": "Development", - " : Development configurations for Boostnote.": " : Development configurations for Boostnote.", + "An open source note-taking app made for programmers just like you.": "あなたのようなプログラマー向けのオープンソースメモ書きアプリケーション", + "Website": "ウェブサイト", + "Development": "開発", + " : Development configurations for Boostnote.": " : Boostnote の開発構成", "Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO", - "License: GPL v3": "License: GPL v3", - "Analytics": "Analytics", - "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.", - "You can see how it works on ": "You can see how it works on ", - "You can choose to enable or disable this option.": "You can choose to enable or disable this option.", - "Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote", - "Crowdfunding": "Crowdfunding", + "License: GPL v3": "ライセンス: GPL v3", + "Analytics": "解析", + "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote はアプリケーションの機能向上だけを目的に匿名データを収集します。ノートの内容を含めた個人の情報は一切収集しません。", + "You can see how it works on ": "どのように動くかをこちらで確認できます ", + "You can choose to enable or disable this option.": "このオプションは有効/無効を選択できます。", + "Enable analytics to help improve Boostnote": "Boostnote の機能向上のための解析機能を有効にする", + "Crowdfunding": "クラウドファンディング", "Dear everyone,": "Dear everyone,", - "Thank you for using Boostnote!": "Thank you for using Boostnote!", - "Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.", - "To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,", - "we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.", - "If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!", - "Thanks,": "Thanks,", - "Boostnote maintainers": "Boostnote maintainers", - "Support via OpenCollective": "Support via OpenCollective", - "Language": "Language", - "English": "English", - "German": "German", - "French": "French", - "Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying", - "All Notes": "All Notes", - "Starred": "Starred", - "Are you sure to ": "Are you sure to ", - " delete": " delete", - "this folder?": "this folder?", - "Confirm": "Confirm", - "Cancel": "Cancel", - "Markdown Note": "Markdown Note", - "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.", - "Snippet Note": "Snippet Note", - "This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.", - "Tab to switch format": "Tab to switch format", - "Updated": "Updated", - "Created": "Created", - "Alphabetically": "Alphabetically", - "Default View": "Default View", - "Compressed View": "Compressed View", - "Search": "Search", - "Blog Type": "Blog Type", - "Blog Address": "Blog Address", - "Save": "Save", - "Auth": "Auth", - "Authentication Method": "Authentication Method", + "Thank you for using Boostnote!": "Boostnote を利用いただき、ありがとうございます!", + "Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote はおよそ 200 の国と地域において、開発者コミュニティを中心に利用されています。", + "To continue supporting this growth, and to satisfy community expectations,": "この成長を持続し、またコミュニティからの要望に答えるため、", + "we would like to invest more time and resources in this project.": "私達はこのプロジェクトにより多くの時間とリソースを投資したいと考えています。", + "If you like this project and see its potential, you can help by supporting us on OpenCollective!": "もしあなたがこのプロジェクトとそのポテンシャルを気に入っていただけたのであれば、OpenCollective を通じて支援いただくことができます!", + "Thanks,": "ありがとうございます。", + "Boostnote maintainers": "Boostnote メンテナンスチーム", + "Support via OpenCollective": "OpenCollective を通じて支援します", + "Language": "言語", + "English": "英語", + "German": "ドイツ語", + "French": "フランス語", + "Show \"Saved to Clipboard\" notification when copying": "クリップボードコピー時に \"クリップボードに保存\" 通知を表示する", + "All Notes": "すべてのノート", + "Starred": "スター付き", + "Are you sure to ": "本当に ", + " delete": "このフォルダを", + "this folder?": "削除しますか?", + "Confirm": "確認", + "Cancel": "キャンセル", + "Markdown Note": "マークダウン", + "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "このフォーマットはテキスト文書を作成することを目的としています。チェックリストや比較的長いコード、LaTeX にも向いています。", + "Snippet Note": "スニペット", + "This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "このフォーマットは短いコードスニペットを作成することを目的としています。複数のコードスニペットを1つのグループにまとめて1つのノートとして扱うことも可能です。", + "Tab to switch format": "フォーマット切り替えタブ", + "Updated": "更新日時", + "Created": "作成日時", + "Alphabetically": "アルファベット順", + "Default View": "デフォルトビュー", + "Compressed View": "圧縮ビュー", + "Search": "検索", + "Blog Type": "ブログの種類", + "Blog Address": "ブログのアドレス", + "Save": "保存", + "Auth": "認証", + "Authentication Method": "認証方法", "JWT": "JWT", - "USER": "USER", - "Token": "Token", - "Storage": "Storage", - "Hotkeys": "Hotkeys", - "Show/Hide Boostnote": "Show/Hide Boostnote", - "Restore": "Restore", - "Permanent Delete": "Permanent Delete", - "Confirm note deletion": "Confirm note deletion", - "This will permanently remove this note.": "This will permanently remove this note.", - "Successfully applied!": "Successfully applied!", - "Albanian": "Albanian", - "Chinese (zh-CN)": "Chinese (zh-CN)", - "Chinese (zh-TW)": "Chinese (zh-TW)", - "Danish": "Danish", - "Japanese": "Japanese", - "Korean": "Korean", - "Norwegian": "Norwegian", - "Polish": "Polish", - "Portuguese": "Portuguese", - "Spanish": "Spanish", - "You have to save!": "You have to save!", - "Russian": "Russian", - "Command(⌘)": "Command(⌘)", - "Editor Rulers": "Editor Rulers", - "Enable": "Enable", - "Disable": "Disable", - "Sanitization": "Sanitization", - "Only allow secure html tags (recommended)": "Only allow secure html tags (recommended)", - "Allow styles": "Allow styles", - "Allow dangerous html tags": "Allow dangerous html tags" + "USER": "ユーザー", + "Token": "トークン", + "Storage": "ストレージ", + "Hotkeys": "ホットキー", + "Show/Hide Boostnote": "Boostnote の表示/非表示", + "Restore": "リストア", + "Permanent Delete": "永久に削除", + "Confirm note deletion": "ノート削除確認", + "This will permanently remove this note.": "本当にこのノートを削除します。", + "Successfully applied!": "成功しました!", + "Albanian": "アルバニア語", + "Chinese (zh-CN)": "簡体字中国語 (zh-CN)", + "Chinese (zh-TW)": "繁体字中国語 (zh-TW)", + "Danish": "デンマーク語", + "Japanese": "日本語", + "Korean": "韓国語", + "Norwegian": "ノルウェー語", + "Polish": "ポーランド語", + "Portuguese": "ポルトガル語", + "Spanish": "スペイン語", + "You have to save!": "保存してください!", + "Russian": "ロシア語", + "Command(⌘)": "コマンド(⌘)", + "Editor Rulers": "罫線", + "Enable": "有効", + "Disable": "無効", + "Sanitization": "サニタイズ", + "Only allow secure html tags (recommended)": "安全なHTMLタグのみ利用を許可する(推奨)", + "Allow styles": "スタイルを許可する", + "Allow dangerous html tags": "安全でないHTMLタグの利用を許可する" } From 8ccf6cb8a36361aee85c3c700f5761a106f2a3d9 Mon Sep 17 00:00:00 2001 From: Brent Hughes Date: Wed, 18 Apr 2018 10:55:01 -0500 Subject: [PATCH 27/46] Updated tag note count to float to the right like the storage list --- browser/components/TagListItem.js | 2 +- browser/components/TagListItem.styl | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/browser/components/TagListItem.js b/browser/components/TagListItem.js index ebef7df4..4346ac21 100644 --- a/browser/components/TagListItem.js +++ b/browser/components/TagListItem.js @@ -16,7 +16,7 @@ const TagListItem = ({name, handleClickTagListItem, isActive, count}) => ( ) diff --git a/browser/components/TagListItem.styl b/browser/components/TagListItem.styl index b35b30cf..513d112a 100644 --- a/browser/components/TagListItem.styl +++ b/browser/components/TagListItem.styl @@ -49,7 +49,10 @@ text-overflow ellipsis .tagList-item-count - padding 0 3px + float right + line-height 26px + padding-right 15px + font-size 13px body[data-theme="white"] .tagList-item From 88de66a31f1339413f6b599d5a595d9fa179ca05 Mon Sep 17 00:00:00 2001 From: Hung Nguyen Date: Thu, 19 Apr 2018 19:17:10 +0700 Subject: [PATCH 28/46] fix the same error when drop image --- browser/main/lib/dataApi/copyImage.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/browser/main/lib/dataApi/copyImage.js b/browser/main/lib/dataApi/copyImage.js index 6a79b8b7..2664dea6 100644 --- a/browser/main/lib/dataApi/copyImage.js +++ b/browser/main/lib/dataApi/copyImage.js @@ -21,8 +21,12 @@ function copyImage (filePath, storageKey, rename = true) { const imageDir = path.join(targetStorage.path, 'images') if (!fs.existsSync(imageDir)) fs.mkdirSync(imageDir) const outputImage = fs.createWriteStream(path.join(imageDir, basename)) + outputImage.on('error', reject) + inputImage.on('error', reject) + inputImage.on('end', () => { + resolve(basename) + }) inputImage.pipe(outputImage) - resolve(basename) } catch (e) { return reject(e) } From e91b7fb0820fba88720d0085472914e92103314e Mon Sep 17 00:00:00 2001 From: Davide Fiorito Date: Thu, 19 Apr 2018 17:54:14 +0200 Subject: [PATCH 29/46] Italian translation --- locales/it.json | 156 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 locales/it.json diff --git a/locales/it.json b/locales/it.json new file mode 100644 index 00000000..bfb09691 --- /dev/null +++ b/locales/it.json @@ -0,0 +1,156 @@ +{ + "Notes": "Note", + "Tags": "Tags", + "Preferences": "Preferenze", + "Make a note": "Crea una nota", + "Ctrl": "Ctrl", + "Ctrl(^)": "Ctrl", + "to create a new note": "per creare una nuova nota", + "Toggle Mode": "Cambia Modalità", + "Trash": "Cestino", + "MODIFICATION DATE": "DATA DI MODIFICA", + "Words": "Parole", + "Letters": "Lettere", + "STORAGE": "POSIZIONE", + "FOLDER": "CARTELLA", + "CREATION DATE": "DATA DI CREAZIONE", + "NOTE LINK": "LINK NOTA", + ".md": ".md", + ".txt": ".txt", + ".html": ".html", + "Print": "Stampa", + "Your preferences for Boostnote": "Le tue preferenze per Boostnote", + "Storages": "Posizioni", + "Add Storage Location": "Aggiungi posizione", + "Add Folder": "Aggiungi cartella", + "Open Storage folder": "Apri cartella di memoria", + "Unlink": "Scollega", + "Edit": "Modifica", + "Delete": "Elimina", + "Interface": "Interfaccia", + "Interface Theme": "Tema interfaccia", + "Default": "Default", + "White": "White", + "Solarized Dark": "Solarized Dark", + "Dark": "Dark", + "Show a confirmation dialog when deleting notes": "Mostra finestra di conferma quando elimini delle note", + "Editor Theme": "Tema dell'Editor", + "Editor Font Size": "Dimensione font dell'editor", + "Editor Font Family": "Famiglia del font dell'editor", + "Editor Indent Style": "Stile di indentazione dell'editor", + "Spaces": "Spazi", + "Tabs": "Tabs", + "Switch to Preview": "Passa all'anteprima", + "When Editor Blurred": "Quando l'editor è sfocato", + "When Editor Blurred, Edit On Double Click": "Quando l'Editor è sfocato, Modifica facendo doppio click", + "On Right Click": "Cliccando con il tasto destro", + "Editor Keymap": "keymapping dell'editor", + "default": "default", + "vim": "vim", + "emacs": "emacs", + "⚠️ Please restart boostnote after you change the keymap": "⚠️ Riavvia Boostnote dopo aver cambiato il keymapping", + "Show line numbers in the editor": "Mostra numero di linea nell'editor", + "Allow editor to scroll past the last line": "Consenti scrolling oltre l'ultima linea nell'editor", + "Bring in web page title when pasting URL on editor": "Mostra il titolo della pagina web quando incolli un URL nell'editor", + "Preview": "Anteprima", + "Preview Font Size": "Dimensione font nell'anteprima", + "Preview Font Family": "Famiglia del font dell'anteprima", + "Code block Theme": "Tema blocco di codice", + "Allow preview to scroll past the last line": "Consenti scrolling oltre l'ultima linea", + "Show line numbers for preview code blocks": "Mostra numero di linea per i blocchi di codice nell'Anteprima", + "LaTeX Inline Open Delimiter": "Delimitatore inline per apertura LaTex", + "LaTeX Inline Close Delimiter": "Delimitatore inline per chiusura LaTex", + "LaTeX Block Open Delimiter": "Delimitatore apertura LaTex", + "LaTeX Block Close Delimiter": "Delimitatore chiusura LaTex", + "Community": "Community", + "Subscribe to Newsletter": "Iscriviti alla Newsletter", + "GitHub": "GitHub", + "Blog": "Blog", + "Facebook Group": "Gruppo Facebook", + "Twitter": "Twitter", + "About": "About", + "Boostnote": "Boostnote", + "An open source note-taking app made for programmers just like you.": "Un'app open-source per prendere appunti, fatta per sviluppatori come te.", + "Website": "Sito Web", + "Development": "Sviluppo", + " : Development configurations for Boostnote.": " : Configurazioni di sviluppo per Boostnote.", + "Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO", + "License: GPL v3": "Licenza: GPL v3", + "Analytics": "Statistiche", + "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote raccoglie dati anonimi al solo scopo di migliorare l'applicazione, e non raccoglie nessuna informazione personale rigurado il contenuto delle note.", + "You can see how it works on ": "Ypuoi vedere come su ", + "You can choose to enable or disable this option.": "Puoi scegliere se attivare o disattivare questa opzione.", + "Enable analytics to help improve Boostnote": "Attiva raccolta dati per aiutare a migliorare Boostnote", + "Crowdfunding": "Crowdfunding", + "Dear everyone,": "Cari utenti,", + "Thank you for using Boostnote!": "Grazie per stare utilizzando Boostnote!", + "Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote è usato in circa 200 Paesi da una fantastica community di sviluppatori.", + "To continue supporting this growth, and to satisfy community expectations,": "Per continuare a supportarne la crescita, e per soddisfare le aspettative della comunità,", + "we would like to invest more time and resources in this project.": "ci piacerebbe investire più tempo e risorse in questo progetto.", + "If you like this project and see its potential, you can help by supporting us on OpenCollective!": "Se ti piace questo progetto e ci vedi del potenziale, puoi aiutarci dandodci supporto su OpenCollective!", + "Thanks,": "Grazie,", + "Boostnote maintainers": "I mantainers di Boostnote", + "Support via OpenCollective": "Supporta su OpenCollective", + "Language": "Lingua", + "English": "Inglese", + "German": "Tedesco", + "French": "Francese", + "Show \"Saved to Clipboard\" notification when copying": "Mostra la notifica \"Salvato negli Appunti\" quando copi:", + "All Notes": "Tutte le note", + "Starred": "Contribuite", + "Are you sure to ": "Sei sicuro di ", + " delete": " eliminare", + "this folder?": "questa cartella?", + "Confirm": "Conferma", + "Cancel": "Cancella", + "Markdown Note": "Nota in Markdown", + "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "Questo formato è per creare documenti di testo. Sono disponibili checklist, blocchi di codice and blocchi in Latex", + "Snippet Note": "Nota Snippet", + "This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "Questo formato è per creare snippets. Più snippet possono essere raccolti in un'unica nota.", + "Tab to switch format": "Premi Tab per cambiare formato", + "Updated": "Aggiornato", + "Created": "Creato", + "Alphabetically": "Ordine alfabetico", + "Counter": "Contatore", + "Default View": "Visione di default", + "Compressed View": "Visione compressa", + "Search": "Cerca", + "Blog Type": "Tipo di blog", + "Blog Address": "Indirizzo del blog", + "Save": "Salva", + "Auth": "Autorizzazione", + "Authentication Method": "Metodo di autenticazione", + "JWT": "JWT", + "USER": "USER", + "Token": "Token", + "Storage": "Storage", + "Hotkeys": "Hotkeys", + "Show/Hide Boostnote": "Mostra/Nascondi Boostnote", + "Restore": "Ripristina", + "Permanent Delete": "Elimina permanentemente", + "Confirm note deletion": "Conferma eliiminazione della nota", + "This will permanently remove this note.": "Questo eliminerà permanentemente questa nota.", + "Successfully applied!": "Applicato con successo!", + "Albanian": "Albanese", + "Chinese (zh-CN)": "Cinese (zh-CN)", + "Chinese (zh-TW)": "Cinese (zh-TW)", + "Danish": "Danese", + "Japanese": "Giapponese", + "Korean": "Koreano", + "Norwegian": "Novergese", + "Polish": "Polacco", + "Portuguese": "Portoghese", + "Spanish": "Spagnolo", + "You have to save!": "Devi salvare!", + "UserName": "UserName", + "Password": "Password", + "Russian": "Russo", + "Command(⌘)": "Comando(⌘)", + "Editor Rulers": "Regole dell'editor", + "Enable": "Abilita", + "Disable": "Disabilia", + "Sanitization": "Bonifica", + "Only allow secure html tags (recommended)": "Consenti solo tag HTML sicuri (raccomandato)", + "Allow styles": "Consenti stili", + "Allow dangerous html tags": "Consenti tag HTML pericolosi" +}" From e692432242ba7f9fb635947d4c37778bbf35a867 Mon Sep 17 00:00:00 2001 From: Kazz Yokomizo Date: Sat, 21 Apr 2018 15:55:54 +0900 Subject: [PATCH 30/46] Remake slack url --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index b5d02729..928bedc9 100644 --- a/readme.md +++ b/readme.md @@ -25,7 +25,7 @@ Boostnote is an open source project. It's an independent project with its ongoin ## Community - [Facebook Group](https://www.facebook.com/groups/boostnote/) - [Twitter](https://twitter.com/boostnoteapp) -- [Slack Group](https://join.slack.com/t/boostnote-group/shared_invite/enQtMzI3NTIxMTQzMTQzLTUyYWZmZWM1YzcwYzQ5OWQ5YzA3Y2M2NzUzNmIwNzYzMjg5NmQyOGJlNzcyZDJhMGY0ZDc0ZjdlZDFhMDdiMWE) +- [Slack Group](https://join.slack.com/t/boostnote-group/shared_invite/enQtMzUxODgwMTc2MDg3LTgwZjA2Zjg3NjFlMzczNTVjNGMzZTk0MmIyNmE3ZjEwYTNhMTA0Y2Y4NDNlNWU4YjZlNmJiNGZhNDViOTA1ZjM) - [Blog](https://boostlog.io/tags/boostnote) - [Reddit](https://www.reddit.com/r/Boostnote/) From a4782f066332ebad8c9178d3a24c0ee47cea0b14 Mon Sep 17 00:00:00 2001 From: Mahdi Kalhor Date: Sat, 21 Apr 2018 19:15:10 +0430 Subject: [PATCH 31/46] Add fa.json for persian(farsi) language. --- locales/fa.json | 156 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 locales/fa.json diff --git a/locales/fa.json b/locales/fa.json new file mode 100644 index 00000000..d6bacd0a --- /dev/null +++ b/locales/fa.json @@ -0,0 +1,156 @@ +{ + "Notes": "یادداشت ها", + "Tags": "تگ ها", + "Preferences": "تنظیمات", + "Make a note": "یک یادداشت بنویس", + "Ctrl": "Ctrl", + "Ctrl(^)": "Ctrl", + "to create a new note": "برای ساخت یک یادداشت", + "Toggle Mode": "تغییر حالت نمایش", + "Trash": "سطل آشغال", + "MODIFICATION DATE": "تاریخ تغییر", + "Words": "کلمات", + "Letters": "حروف", + "STORAGE": "ذخیره سازی", + "FOLDER": "پوشه", + "CREATION DATE": "تاریخ ایجاد", + "NOTE LINK": "لینک یادداشت", + ".md": ".md", + ".txt": ".txt", + ".html": ".html", + "Print": "پرینت", + "Your preferences for Boostnote": "تنظیمات شما برای boostnote", + "Storages": "ذخیره سازی", + "Add Storage Location": "افزودن محل ذخیره سازی", + "Add Folder": "ساخت پوشه", + "Open Storage folder": "بازکردن پوشه ذخیره سازی", + "Unlink": "حذف لینک", + "Edit": "ویرایش", + "Delete": "حذف", + "Interface": "رابط کاربری", + "Interface Theme": "تم رابط کاربری", + "Default": "پیش فرض", + "White": "روشن", + "Solarized Dark": "سولارایز", + "Dark": "تاریک", + "Show a confirmation dialog when deleting notes": "هنگام حذف یادداشت ها یک پیام تایید نمایش بده.", + "Editor Theme": "تم ویرایشگر", + "Editor Font Size": "اندازه فونت ویرایشگر", + "Editor Font Family": "فونت ویرایشگر", + "Editor Indent Style": "حالت فاصله گذاری ویرایشگر", + "Spaces": "Spaces", + "Tabs": "Tabs", + "Switch to Preview": "دیدن پیش نمایش", + "When Editor Blurred": "وقتی ویرایشگر از حالت ویرایش خارج شد ", + "When Editor Blurred, Edit On Double Click": "وقتی ویرایشگر از حالت ویرایش خارج شد و با دبل کلیک ویرایش کنید.", + "On Right Click": "راست کلیک", + "Editor Keymap": "ویرایشگر Keymap", + "default": "پیش فرض", + "vim": "vim", + "emacs": "emacs", + "⚠️ Please restart boostnote after you change the keymap": "⚠️ برنامه را دوباره راه اندازی کنید keymap لطفا بعد از تغییر", + "Show line numbers in the editor": "شماره خطوط در ویرایشگر را نمایش بده.", + "Allow editor to scroll past the last line": "اجازه بده ویرایشگر بعد از آخرین خط اسکرول کند.", + "Bring in web page title when pasting URL on editor": "هنگامی که آدرس اینترنتی در ویرایشگر اضافه شد عنوان آنرا نمایش بده", + "Preview": "پیش نمایش", + "Preview Font Size": "اندازه فونتِ پیش نمایش", + "Preview Font Family": " فونتِ پیش نمایش", + "Code block Theme": "تم بخش کد", + "Allow preview to scroll past the last line": "اجازه بده پیش نمایش بعد از آخرین خط اسکرول کند.", + "Show line numbers for preview code blocks": "شماره خطوط در پیش نمایش را نمایش بده.", + "LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter", + "LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter", + "LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter", + "LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter", + "Community": "کامینیتی", + "Subscribe to Newsletter": "اشتراک در خبرنامه", + "GitHub": "گیت هاب", + "Blog": "بلاگ", + "Facebook Group": "گروه فیسبوک", + "Twitter": "توییتر", + "About": "درباره", + "Boostnote": "Boostnote", + "An open source note-taking app made for programmers just like you.": "یک دفترچه یادداشت متن باز ساخته شده برای برنامه نویسانی مثل تو.", + "Website": "وبسایت", + "Development": "توسعه", + " : Development configurations for Boostnote.": " : پیکربندی توسعه برای Boostnote.", + "Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO", + "License: GPL v3": "لایسنس: GPL v3", + "Analytics": "تجزیه و تحلیل", + "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Bosstnote اطلاعات ناشناس را برای بهبود عملکرد برنامه جمع آوری می‌کند.اطلاعات شخصی شما مثل محتوای یادداشت ها هرگز برای هیچ هدفی جمع آوری نمی‌شوند", + "You can see how it works on ": "میتوانید ببینید چگونه کار میکند. ", + "You can choose to enable or disable this option.": "میتوانید این گزینه را فعال یا غیرفعال کنید.", + "Enable analytics to help improve Boostnote":".تجزیه تحلیل داده ها را برای کمک به بهبود برنامه فعال کن", + "Crowdfunding": "جمع سپاری (سرمایه گذاری جمعی )", + "Dear everyone,": "عزیز جان,", + "Thank you for using Boostnote!": "از شما بخاطر استفاده از boostnote ممنونیم!", + "Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "در ۲۰۰ کشور مختلف دنیا مورد توسط جمعی از برنامه نویسان بی نظیر مورد استفاده قرار میگیرد. Boostnote", + "To continue supporting this growth, and to satisfy community expectations,": "برای حمایت از این رشد ، و برآورده شدن انتظارات کامینیتی,", + "we would like to invest more time and resources in this project.": "ما می خواهیم زمان و منابع بیشتری را در این پروژه سرمایه گذاری کنیم.", + "If you like this project and see its potential, you can help by supporting us on OpenCollective!": "اگر این پروژه را دوست دارید و پتانسیلی در آن می‌بینید، میتوانید مارا در اوپن‌ کالکتیو حمایت کنید.", + "Thanks,": "با تشکر,", + "Boostnote maintainers": "Boostnote نگهدارندگان", + "Support via OpenCollective": "حمایت کنید OpenCollective از طریق", + "Language": "زبان", + "English": "انگلیسی", + "German": "آلمانی", + "French": "فرانسوی", + "Show \"Saved to Clipboard\" notification when copying": "نمایش \"ذخیره در کلیپ‌بورد\" اطلاع رسانی هنگام کپی کردن", + "All Notes": "همه یادداشت ها", + "Starred": "ستاره دار", + "Are you sure to ": " مطمئن هستید که", + " delete": "حذف ", + "this folder?": "این پوشه ؟", + "Confirm": "تایید", + "Cancel": "انصراف", + "Markdown Note": "Markdown یادداشتِ", + "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "این قالب برای ساخت سند های متنی است. چک لیست ها و تکه کد ها و بلاک های لاتکس قابل استفاده اند.", + "Snippet Note": "Snippet یادداشتِ", + "This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "این قالب برای ساخت تکه کد هاست. چند تکه کد میتوانند تبدیل به یک یادداشت شوند.", + "Tab to switch format": "را بزنید Tab برای تغییر فرمت", + "Updated": "بروزرسانی شد", + "Created": "ایجاد شد", + "Alphabetically": "بر اساس حروف الفبا", + "Counter": "شمارشگر", + "Default View": "نمایش پیش‌فرض", + "Compressed View": "نمایش فشرده", + "Search": "جستجو", + "Blog Type": "نوع وبلاگ", + "Blog Address": "آدرس وبلاگ", + "Save": "ذخیره", + "Auth": "هویت", + "Authentication Method": "متد احراز هویت", + "JWT": "JWT", + "USER": "کاربر", + "Token": "توکن", + "Storage": "ذخیره سازی", + "Hotkeys": "کلید های میانبر", + "Show/Hide Boostnote": "Boostnote نمایش/پنهان کردن", + "Restore": "بازگرداندن به حالت اول", + "Permanent Delete": "حذف بدون بازگشت", + "Confirm note deletion": ".حذف یادداشت را تایید کنید", + "This will permanently remove this note.": ".این کار یادداشت را بطور دائمی حذف خواهد کرد", + "Successfully applied!": "!با موفقیت اجرا شد", + "Albanian": "آلبانی", + "Chinese (zh-CN)": "چینی (zh-CN)", + "Chinese (zh-TW)": "چینی (zh-TW)", + "Danish": "دانمارکی", + "Japanese": "ژاپنی", + "Korean": "کره ای", + "Norwegian": "نروژی", + "Polish": "لهستانی", + "Portuguese": "پرتغالی", + "Spanish": "اسپانیایی", + "You have to save!": "!باید ذخیره کنید", + "UserName": "نام کاربری", + "Password": "رمز عبور", + "Russian": "روسی", + "Command(⌘)": "Command(⌘)", + "Editor Rulers": "Editor Rulers", + "Enable": "فعال", + "Disable": "غیرفعال", + "Sanitization": "پاکسازی کردن", + "Only allow secure html tags (recommended)": "(فقط تگ های امن اچ تی ام ال مجاز اند.(پیشنهاد میشود", + "Allow styles": "حالت های مجاز", + "Allow dangerous html tags": "تگ های خطرناک اچ‌ تی ام ال مجاز اند" +} \ No newline at end of file From d2129ffac664ec2cdd99eabd23eaa54ab965fd5e Mon Sep 17 00:00:00 2001 From: Mahdi Kalhor Date: Sat, 21 Apr 2018 19:20:14 +0430 Subject: [PATCH 32/46] edit some errors in translations. --- locales/fa.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/fa.json b/locales/fa.json index d6bacd0a..e0aa1978 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -58,10 +58,10 @@ "Code block Theme": "تم بخش کد", "Allow preview to scroll past the last line": "اجازه بده پیش نمایش بعد از آخرین خط اسکرول کند.", "Show line numbers for preview code blocks": "شماره خطوط در پیش نمایش را نمایش بده.", - "LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter", - "LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter", - "LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter", - "LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter", + "LaTeX Inline Open Delimiter": "جداکننده آغازین لاتکس خطی", + "LaTeX Inline Close Delimiter": "جداکننده پایانی لاتکس خطی", + "LaTeX Block Open Delimiter": "جداکننده آغازین بلوک لاتکس ", + "LaTeX Block Close Delimiter": "جداکننده آغازین بلوک لاتکس ", "Community": "کامینیتی", "Subscribe to Newsletter": "اشتراک در خبرنامه", "GitHub": "گیت هاب", @@ -82,7 +82,7 @@ "You can choose to enable or disable this option.": "میتوانید این گزینه را فعال یا غیرفعال کنید.", "Enable analytics to help improve Boostnote":".تجزیه تحلیل داده ها را برای کمک به بهبود برنامه فعال کن", "Crowdfunding": "جمع سپاری (سرمایه گذاری جمعی )", - "Dear everyone,": "عزیز جان,", + "Dear everyone,": "عزیزان,", "Thank you for using Boostnote!": "از شما بخاطر استفاده از boostnote ممنونیم!", "Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "در ۲۰۰ کشور مختلف دنیا مورد توسط جمعی از برنامه نویسان بی نظیر مورد استفاده قرار میگیرد. Boostnote", "To continue supporting this growth, and to satisfy community expectations,": "برای حمایت از این رشد ، و برآورده شدن انتظارات کامینیتی,", From 6ec2124a9c9ea8f1c32b2d41ee57427d2838bb03 Mon Sep 17 00:00:00 2001 From: Chen Shenghan Date: Tue, 24 Apr 2018 02:51:58 +1200 Subject: [PATCH 33/46] Fix #1797: In preview window, open external link in external browser. --- browser/components/MarkdownPreview.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 6e6bb9ec..33e0fa8f 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -523,6 +523,15 @@ export default class MarkdownPreview extends React.Component { } handlelinkClick (e) { + e.preventDefault() + e.stopPropagation() + + const href = e.target.href + if (href.match(/^http/i)) { + shell.openExternal(href) + return + } + const noteHash = e.target.href.split('/').pop() // this will match the new uuid v4 hash and the old hash // e.g. From a82a79e25c62d91965a0f8a9b41e69a228be1006 Mon Sep 17 00:00:00 2001 From: Ralph Chung Date: Wed, 18 Apr 2018 16:24:51 +0800 Subject: [PATCH 34/46] Edit the localization file of zh-TW I've edited the zh-TW.json based on the original version. The use of words in this document is more in keeping with the habits of how Taiwanese use Chinese. --- locales/zh-TW.json | 150 ++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 06f40608..bc60cfcc 100755 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -1,135 +1,135 @@ { "Notes": "筆記", "Tags": "標籤", - "Preferences": "首選項", - "Make a note": "新建筆記", + "Preferences": "偏好設定", + "Make a note": "做點筆記", "Ctrl": "Ctrl", "Ctrl(^)": "Ctrl", - "to create a new note": "新建筆記", + "to create a new note": "新增筆記", "Toggle Mode": "切換模式", "Trash": "廢紙簍", - "MODIFICATION DATE": "更改時間", - "Words": "單詞", + "MODIFICATION DATE": "修改時間", + "Words": "單字", "Letters": "字數", - "STORAGE": "本地儲存", + "STORAGE": "本機儲存空間", "FOLDER": "資料夾", - "CREATION DATE": "創建時間", - "NOTE LINK": "筆記鏈接", + "CREATION DATE": "建立時間", + "NOTE LINK": "筆記連結", ".md": ".md", ".txt": ".txt", ".html": ".html", "Print": "列印", - "Your preferences for Boostnote": "個性設置", - "Storages": "本地儲存", - "Add Storage Location": "添加一個本地儲存位置", - "Add Folder": "新建資料夾", - "Open Storage folder": "打開一個本地儲存位置", - "Unlink": "取消鏈接", + "Your preferences for Boostnote": "Boostnote 偏好設定", + "Storages": "本機儲存空間", + "Add Storage Location": "新增一個本機儲存位置", + "Add Folder": "新增資料夾", + "Open Storage folder": "開啟儲存資料夾", + "Unlink": "解除連結", "Edit": "編輯", "Delete": "刪除", "Interface": "界面", "Interface Theme": "主題", - "Default": "默認", + "Default": "預設", "White": "White", "Solarized Dark": "Solarized Dark", "Dark": "Dark", - "Show a confirmation dialog when deleting notes": "刪除筆記的時候,顯示確認框", + "Show a confirmation dialog when deleting notes": "刪除筆記的時候,顯示確認對話框", "Editor Theme": "編輯器主題", "Editor Font Size": "編輯器字型大小", "Editor Font Family": "編輯器字體", - "Editor Indent Style": "縮進風格", + "Editor Indent Style": "縮排風格", "Spaces": "空格", "Tabs": "Tabs", - "Switch to Preview": "快速切換到預覽界面", - "When Editor Blurred": "當編輯器失去焦點的時候,切換到預覽界面", - "When Editor Blurred, Edit On Double Click": "當編輯器失去焦點的時候預覽,雙擊切換到編輯界面", - "On Right Click": "右鍵點擊切換兩個界面", + "Switch to Preview": "切回預覽頁面的時機", + "When Editor Blurred": "當編輯器失去焦點時", + "When Editor Blurred, Edit On Double Click": "當編輯器失去焦點時,雙擊切換到編輯畫面", + "On Right Click": "點擊右鍵切換兩個頁面", "Editor Keymap": "編輯器 Keymap", - "default": "默認", + "default": "預設", "vim": "vim", "emacs": "emacs", - "⚠️ Please restart boostnote after you change the keymap": "⚠️ 設置好快捷鍵後,記得重啟设置好快捷键后,记得重启boostnote", + "⚠️ Please restart boostnote after you change the keymap": "⚠️ 請重新開啟 Boostnote 以完成設定。", "Show line numbers in the editor": "在編輯器中顯示行號", - "Allow editor to scroll past the last line": "允許編輯器滾動到最後一行", - "Bring in web page title when pasting URL on editor": "粘貼網頁鏈接的時候,顯示為網頁標題", - "Preview": "預覽器", - "Preview Font Size": "預覽器字型大小", - "Preview Font Family": "預覽器字體", - "Code block Theme": "代碼塊主題", - "Allow preview to scroll past the last line": "允許預覽器滾動到最後一行", - "Show line numbers for preview code blocks": "在預覽器中顯示行號", - "LaTeX Inline Open Delimiter": "LaTeX 單行開頭分隔符", - "LaTeX Inline Close Delimiter": "LaTeX 單行結尾分隔符", - "LaTeX Block Open Delimiter": "LaTeX 多行開頭分隔符", - "LaTeX Block Close Delimiter": "LaTeX 多行結尾分隔符", - "Community": "社區", + "Allow editor to scroll past the last line": "允許編輯器捲軸捲動超過最後一行", + "Bring in web page title when pasting URL on editor": "在編輯器貼上網址的時候,自動加上網頁標題", + "Preview": "預覽頁面", + "Preview Font Size": "預覽頁面字型大小", + "Preview Font Family": "預覽頁面字體", + "Code block Theme": "程式碼區塊主題", + "Allow preview to scroll past the last line": "允許預覽頁面捲軸捲動超過最後一行", + "Show line numbers for preview code blocks": "在預覽頁面的程式碼區塊中顯示行號", + "LaTeX Inline Open Delimiter": "LaTeX 單行開頭符號", + "LaTeX Inline Close Delimiter": "LaTeX 單行結尾符號", + "LaTeX Block Open Delimiter": "LaTeX 多行開頭符號", + "LaTeX Block Close Delimiter": "LaTeX 多行結尾符號", + "Community": "社群", "Subscribe to Newsletter": "訂閱郵件", "GitHub": "GitHub", "Blog": "部落格", - "Facebook Group": "Facebook Group", + "Facebook Group": "Facebook 社團", "Twitter": "Twitter", "About": "關於", "Boostnote": "Boostnote", - "An open source note-taking app made for programmers just like you.": "一款專門為程式員朋友量身打造的開源筆記", + "An open source note-taking app made for programmers just like you.": "一款專門為程式設計師朋友量身打造的開源筆記軟體", "Website": "官網", "Development": "開發", - " : Development configurations for Boostnote.": " : Boostnote的開發配置", + " : Development configurations for Boostnote.": " : Boostnote 的開發組態", "Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO", "License: GPL v3": "License: GPL v3", "Analytics": "分析", - "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote 收集匿名數據只為了提升軟體使用體驗,絕對不收集任何個人信息(包括筆記內容)", - "You can see how it works on ": "你可以看看它的源碼是如何運作的 ", - "You can choose to enable or disable this option.": "你可以選擇開啟或不開啟這個功能", - "Enable analytics to help improve Boostnote": "允許對數據進行分析,幫助我們改進Boostnote", - "Crowdfunding": "眾籌", + "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote 收集匿名資料單純只為了提升軟體使用體驗,絕對不收集任何個人資料(包括筆記內容)", + "You can see how it works on ": "你可以看看它的程式碼是如何運作 ", + "You can choose to enable or disable this option.": "你可以選擇啟用或禁用這項功能", + "Enable analytics to help improve Boostnote": "允許數據分析以協助我們改進 Boostnote", + "Crowdfunding": "群眾募資", "Dear everyone,": "親愛的用戶:", - "Thank you for using Boostnote!": "謝謝你使用Boostnote!", - "Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "大約有200個不同的國家和地區的優秀開發者們都在使用Boostnote!", - "To continue supporting this growth, and to satisfy community expectations,": "為了繼續支持這種發展,和滿足社區的期待,", + "Thank you for using Boostnote!": "謝謝你使用 Boostnote!", + "Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "大約有 200 個不同的國家和地區的優秀開發者們都在使用 Boostnote!", + "To continue supporting this growth, and to satisfy community expectations,": "為了繼續支持這種發展,和滿足社群的期待,", "we would like to invest more time and resources in this project.": "我們非常願意投入更多的時間和資源到這個專案中。", - "If you like this project and see its potential, you can help by supporting us on OpenCollective!": "如果你喜歡這款軟體並且看好它的潛力, 請在OpenCollective上支持我們!", + "If you like this project and see its potential, you can help by supporting us on OpenCollective!": "如果你喜歡這款軟體並且看好它的潛力, 請在 OpenCollective 上支持我們!", "Thanks,": "十分感謝!", - "Boostnote maintainers": "Boostnote的維護人員", - "Support via OpenCollective": "在OpenCollective上支持我們", + "Boostnote maintainers": "Boostnote 的維護人員", + "Support via OpenCollective": "在 OpenCollective 上支持我們", "Language": "語言", "English": "English", "German": "German", "French": "French", - "Show \"Saved to Clipboard\" notification when copying": "複製的時候,顯示 \"已複製\" 提示", + "Show \"Saved to Clipboard\" notification when copying": "複製的時候,顯示 \"已複製到剪貼簿\" 的通知", "All Notes": "所有筆記", - "Starred": "星標收藏", + "Starred": "星號收藏", "Are you sure to ": "你確定要 ", " delete": " 刪除", "this folder?": "這個資料夾嗎?", "Confirm": "確認", "Cancel": "取消", - "Markdown Note": "Markdown筆記", - "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "創建文檔,清單,代碼塊甚至是Latex格式文檔", - "Snippet Note": "代碼筆記", - "This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "創建代碼片段,支持多種語法代碼片段", - "Tab to switch format": "使用Tab鍵切換格式", - "Updated": "更新時間", - "Created": "創建時間", - "Alphabetically": "A~Z排序", - "Default View": "默認視圖", - "Compressed View": "列表視圖", - "Search": "搜索", + "Markdown Note": "Markdown 筆記", + "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "建立文件、清單,也可以使用程式碼區塊甚至是 Latex 區塊。", + "Snippet Note": "程式碼片段筆記", + "This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "建立程式碼區塊片段。數個程式碼區塊可以合在同一個筆記裡。", + "Tab to switch format": "使用 Tab 鍵切換格式", + "Updated": "依更新時間排序", + "Created": "依建立時間排序", + "Alphabetically": "依字母排序", + "Default View": "預設顯示", + "Compressed View": "緊密顯示", + "Search": "搜尋", "Blog Type": "部落格類型", - "Blog Address": "部落格地址", - "Save": "保存", + "Blog Address": "部落格網址", + "Save": "儲存", "Auth": "Auth", "Authentication Method": "認證方法", "JWT": "JWT", "USER": "USER", "Token": "Token", - "Storage": "本地儲存", + "Storage": "本機儲存空間", "Hotkeys": "快捷鍵", "Show/Hide Boostnote": "顯示/隱藏 Boostnote", - "Restore": "恢復", + "Restore": "還原", "Permanent Delete": "永久刪除", "Confirm note deletion": "確認刪除筆記", - "This will permanently remove this note.": "永久地刪除這條筆記", - "Successfully applied!": "設置成功", + "This will permanently remove this note.": "這將會永久地刪除這條筆記", + "Successfully applied!": "設定成功", "Albanian": "Albanian", "Chinese (zh-CN)": "简体中文", "Chinese (zh-TW)": "繁體中文", @@ -142,11 +142,11 @@ "Spanish": "Spanish", "You have to save!": "你必須儲存一下!", "Russian": "Russian", - "Editor Rulers": "Editor Rulers", - "Enable": "開啟", - "Disable": "關閉", - "Sanitization": "代碼處理", - "Only allow secure html tags (recommended)": "只允許安全的html標籤(推薦)", + "Editor Rulers": "編輯器中顯示垂直尺規", + "Enable": "啟用", + "Disable": "禁用", + "Sanitization": "過濾 HTML 程式碼", + "Only allow secure html tags (recommended)": "只允許安全的 HTML 標籤 (建議)", "Allow styles": "允許樣式", - "Allow dangerous html tags": "允許危險的html標籤" + "Allow dangerous html tags": "允許危險的 HTML 標籤" } From 4a55f78a48cae32b3414f646d5469b5d9d2c039d Mon Sep 17 00:00:00 2001 From: yosmoc Date: Mon, 23 Apr 2018 21:08:10 +0200 Subject: [PATCH 35/46] fix deprecation warning moment.updateLocale will properly replace properties on an existing locale. --- browser/main/NoteList/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index e413c647..dedad209 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -916,7 +916,7 @@ class NoteList extends React.Component { if (note.isTrashed !== true || location.pathname === '/trashed') return true }) - moment.locale('en', { + moment.updateLocale('en', { relativeTime: { future: 'in %s', past: '%s ago', From d76db726c4fc656ebb2a1e5ecb5845fc03adc173 Mon Sep 17 00:00:00 2001 From: Hung Nguyen Date: Tue, 24 Apr 2018 18:06:10 +0700 Subject: [PATCH 36/46] refactored code according to review --- browser/lib/Languages.js | 134 ++++++++++-------- browser/lib/i18n.js | 9 +- browser/main/Main.js | 9 +- browser/main/modals/PreferencesModal/UiTab.js | 6 +- 4 files changed, 78 insertions(+), 80 deletions(-) diff --git a/browser/lib/Languages.js b/browser/lib/Languages.js index f5262810..09a1614e 100644 --- a/browser/lib/Languages.js +++ b/browser/lib/Languages.js @@ -1,65 +1,75 @@ +const languages = [ + { + name: 'Albanian', + locale: 'sq' + }, + { + name: 'Chinese (zh-CN)', + locale: 'zh-CN' + }, + { + name: 'Chinese (zh-TW)', + locale: 'zh-TW' + }, + { + name: 'Danish', + locale: 'da' + }, + { + name: 'English', + locale: 'en' + }, + { + name: 'French', + locale: 'fr' + }, + { + name: 'German', + locale: 'de' + }, + { + name: 'Hungarian', + locale: 'hu' + }, + { + name: 'Japanese', + locale: 'ja' + }, + { + name: 'Korean', + locale: 'ko' + }, + { + name: 'Norwegian', + locale: 'no' + }, + { + name: 'Polish', + locale: 'pl' + }, + { + name: 'Portuguese', + locale: 'pt' + }, + { + name: 'Russian', + locale: 'ru' + }, + { + name: 'Spanish', + locale: 'es-ES' + } +] + module.exports = { - languages: [ - { - name: 'Albanian', - locale: 'sq' - }, - { - name: 'Chinese (zh-CN)', - locale: 'zh-CN' - }, - { - name: 'Chinese (zh-TW)', - locale: 'zh-TW' - }, - { - name: 'Danish', - locale: 'da' - }, - { - name: 'English', - locale: 'en' - }, - { - name: 'French', - locale: 'fr' - }, - { - name: 'German', - locale: 'de' - }, - { - name: 'Hungarian', - locale: 'hu' - }, - { - name: 'Japanese', - locale: 'ja' - }, - { - name: 'Korean', - locale: 'ko' - }, - { - name: 'Norwegian', - locale: 'no' - }, - { - name: 'Polish', - locale: 'pl' - }, - { - name: 'Portuguese', - locale: 'pt' - }, - { - name: 'Russian', - locale: 'ru' - }, - { - name: 'Spanish', - locale: 'es-ES' - } - ] + getLocales () { + return languages.reduce(function (localeList, locale) { + localeList.push(locale.locale) + return localeList + }, []) + }, + getLanguages () { + return languages + } } diff --git a/browser/lib/i18n.js b/browser/lib/i18n.js index ce94dfee..e12e2aa6 100644 --- a/browser/lib/i18n.js +++ b/browser/lib/i18n.js @@ -1,17 +1,12 @@ const path = require('path') const { remote } = require('electron') const { app } = remote -const { languages } = require('./Languages.js') - -let locales = languages.reduce(function (localeList, locale) { - localeList.push(locale.locale) - return localeList -}, []) +const { getLocales } = require('./Languages.js') // load package for localization const i18n = new (require('i18n-2'))({ // setup some locales - other locales default to the first locale - locales: locales, + locales: getLocales(), extension: '.json', directory: process.env.NODE_ENV === 'production' ? path.join(app.getAppPath(), './locales') diff --git a/browser/main/Main.js b/browser/main/Main.js index 1fa5ba2b..9f1c06e7 100644 --- a/browser/main/Main.js +++ b/browser/main/Main.js @@ -15,7 +15,7 @@ import eventEmitter from 'browser/main/lib/eventEmitter' import { hashHistory } from 'react-router' import store from 'browser/main/store' import i18n from 'browser/lib/i18n' -import { languages } from 'browser/lib/Languages' +import { getLocales } from 'browser/lib/Languages' const path = require('path') const electron = require('electron') const { remote } = electron @@ -153,12 +153,7 @@ class Main extends React.Component { document.body.setAttribute('data-theme', 'default') } - let locales = languages.reduce(function (localeList, locale) { - localeList.push(locale.locale) - return localeList - }, []) - - if (locales.indexOf(config.ui.language) !== -1) { + if (getLocales().indexOf(config.ui.language) !== -1) { i18n.setLocale(config.ui.language) } else { i18n.setLocale('en') diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 189b1064..9c74255d 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -10,7 +10,7 @@ import CodeMirror from 'codemirror' import 'codemirror-mode-elixir' import _ from 'lodash' import i18n from 'browser/lib/i18n' -import { languages } from 'browser/lib/Languages' +import { getLanguages } from 'browser/lib/Languages' const OSX = global.process.platform === 'darwin' @@ -184,9 +184,7 @@ class UiTab extends React.Component { ref='uiLanguage' > { - languages.map((language) => { - return () - }) + getLanguages().map((language) => ) } From fbb8b4687b51f22cab9f8e4975f801579a5e9b29 Mon Sep 17 00:00:00 2001 From: Frank Kanis Date: Wed, 25 Apr 2018 17:53:18 +0200 Subject: [PATCH 37/46] Reduced nests --- browser/main/lib/dataApi/moveNote.js | 36 +++++++++++++--------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/browser/main/lib/dataApi/moveNote.js b/browser/main/lib/dataApi/moveNote.js index bb17d208..1441a77e 100644 --- a/browser/main/lib/dataApi/moveNote.js +++ b/browser/main/lib/dataApi/moveNote.js @@ -68,29 +68,27 @@ function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) { return noteData }) .then(function moveImages (noteData) { - if (oldStorage.path === newStorage.path) { - return noteData - } else { - const searchImagesRegex = /!\[.*?]\(\s*?\/:storage\/(.*\.\S*?)\)/gi - let match = searchImagesRegex.exec(noteData.content) + if (oldStorage.path === newStorage.path) return noteData - const moveTasks = [] - while (match != null) { - const [, filename] = match - const oldPath = path.join(oldStorage.path, 'images', filename) - moveTasks.push( - copyImage(oldPath, noteData.storage, false) - .then(() => { - fs.unlinkSync(oldPath) - }) - ) + const searchImagesRegex = /!\[.*?]\(\s*?\/:storage\/(.*\.\S*?)\)/gi + let match = searchImagesRegex.exec(noteData.content) - // find next occurence - match = searchImagesRegex.exec(noteData.content) - } + const moveTasks = [] + while (match != null) { + const [, filename] = match + const oldPath = path.join(oldStorage.path, 'images', filename) + moveTasks.push( + copyImage(oldPath, noteData.storage, false) + .then(() => { + fs.unlinkSync(oldPath) + }) + ) - return Promise.all(moveTasks).then(() => noteData) + // find next occurence + match = searchImagesRegex.exec(noteData.content) } + + return Promise.all(moveTasks).then(() => noteData) }) .then(function writeAndReturn (noteData) { CSON.writeFileSync(path.join(newStorage.path, 'notes', noteData.key + '.cson'), _.omit(noteData, ['key', 'storage'])) From 6c542750f4f68ed88726b196dc5871b6a5060806 Mon Sep 17 00:00:00 2001 From: bimlas Date: Mon, 26 Mar 2018 16:48:07 +0200 Subject: [PATCH 38/46] Narrow list of tags to related ones When a tag is selected, the tag list narrows to show only the related ones: all tags associated to the currently visible notes. Clicking on the plus sign near another tag narrows the list again to the tags of notes associated with the firstly AND secondly selected tag. To show every tags again, press the tag icon on the top-left corner of Boostnote. Before: ![screencast](https://i.imgur.com/PwAdhLe.gif) After: ![screencast](https://i.imgur.com/s3JCaFq.gif) NOTE: Tags are joined with `&` character (`#` not works) in `location.pathname` thus it will make the tags with this character unavailable. Any suggestion to pass multiple values via pathname? --- browser/components/TagListItem.js | 19 ++++++---- browser/components/TagListItem.styl | 37 ++++++++++++++------ browser/main/NoteList/index.js | 3 +- browser/main/SideNav/index.js | 54 +++++++++++++++++++++++++---- browser/main/index.js | 3 ++ 5 files changed, 90 insertions(+), 26 deletions(-) diff --git a/browser/components/TagListItem.js b/browser/components/TagListItem.js index 4346ac21..cbac00ce 100644 --- a/browser/components/TagListItem.js +++ b/browser/components/TagListItem.js @@ -12,13 +12,18 @@ import CSSModules from 'browser/lib/CSSModules' * @param {bool} isActive */ -const TagListItem = ({name, handleClickTagListItem, isActive, count}) => ( - +const TagListItem = ({name, handleClickTagListItem, handleClickNarrowToTag, isActive, count}) => ( +
+ + +
) TagListItem.propTypes = { diff --git a/browser/components/TagListItem.styl b/browser/components/TagListItem.styl index 513d112a..4c5c7379 100644 --- a/browser/components/TagListItem.styl +++ b/browser/components/TagListItem.styl @@ -1,10 +1,10 @@ -.tagList-item +.tagList-itemContainer display flex - width 100% + +.tagList-item, .tagList-itemNarrow height 26px background-color transparent color $ui-inactive-text-color - padding 0 margin-bottom 5px text-align left border none @@ -20,12 +20,18 @@ color $ui-button-default-color background-color $ui-button-default--active-backgroundColor -.tagList-item-active - background-color $ui-button-default--active-backgroundColor +.tagList-item display flex + flex 1 width 100% - height 26px padding 0 + +.tagList-itemNarrow + padding 0 4px + +.tagList-item-active, .tagList-itemNarrow-active + background-color $ui-button-default--active-backgroundColor + height 26px margin-bottom 5px text-align left border none @@ -36,10 +42,19 @@ background-color alpha($ui-button-default--active-backgroundColor, 60%) transition 0.2s +.tagList-item-active + display flex + flex 1 + width 100% + padding 0 + +.tagList-itemNarrow-active + padding 0 4px + .tagList-item-name display block flex 1 - padding 0 15px + padding 0 8px 0 4px height 26px line-height 26px border-width 0 0 0 2px @@ -55,7 +70,7 @@ font-size 13px body[data-theme="white"] - .tagList-item + .tagList-item, .tagList-itemNarrow color $ui-inactive-text-color &:hover color $ui-text-color @@ -64,7 +79,7 @@ body[data-theme="white"] color $ui-text-color background-color $ui-button--active-backgroundColor - .tagList-item-active + .tagList-item-active, .tagList-itemNarrow-active background-color $ui-button--active-backgroundColor color $ui-text-color &:hover @@ -73,7 +88,7 @@ body[data-theme="white"] color $ui-text-color body[data-theme="dark"] - .tagList-item + .tagList-item, .tagList-itemNarrow color $ui-dark-inactive-text-color &:hover color $ui-dark-text-color @@ -82,7 +97,7 @@ body[data-theme="dark"] color $ui-dark-text-color background-color $ui-dark-button--active-backgroundColor - .tagList-item-active + .tagList-item-active, .tagList-itemNarrow-active background-color $ui-dark-button--active-backgroundColor color $ui-dark-text-color &:active diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index dedad209..867457ca 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -343,10 +343,11 @@ class NoteList extends React.Component { } if (location.pathname.match(/\/tags/)) { + const listOfTags = params.tagname.split('&') return data.noteMap.map(note => { return note }).filter(note => { - return note.tags.includes(params.tagname) + return listOfTags.every((tag) => note.tags.includes(tag)) }) } diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js index f8a65013..a9f9f0da 100644 --- a/browser/main/SideNav/index.js +++ b/browser/main/SideNav/index.js @@ -91,7 +91,7 @@ class SideNav extends React.Component { let component // TagsMode is not selected - if (!location.pathname.match('/tags') && !location.pathname.match('/alltags')) { + if (!location.pathname.match('/tags') && !location.pathname.match('/alltags') && !location.pathname.match('/narrowToTag')) { component = (
({name, size: tag.size})), - ['name'] - ) + const relatedTags = this.getRelatedTags(this.getActiveTags(location.pathname), data.noteMap) + let tagList = _.sortBy(data.tagNoteMap.map((tag, name) => { + return { name, size: tag.size } + }), ['name']).filter(tag => { + return (relatedTags.size === 0) ? true : relatedTags.has(tag.name) + }) if (config.sortTagsBy === 'COUNTER') { tagList = _.sortBy(tagList, item => (0 - item.size)) } @@ -158,6 +160,7 @@ class SideNav extends React.Component { { + return {key: note.key, tags: note.tags} + }).filter((note) => { + return activeTags.every((tag) => note.tags.includes(tag)) + }) + let relatedTags = new Set() + relatedNotes.forEach(note => { + note.tags.map(tag => { + relatedTags.add(tag) + }) + }) + return relatedTags + } + getTagActive (path, tag) { + const pathTag = this.getActiveTags(path) + return pathTag.includes(tag) + } + + getActiveTags (path) { const pathSegments = path.split('/') - const pathTag = pathSegments[pathSegments.length - 1] - return pathTag === tag + const tags = pathSegments[pathSegments.length - 1] + if (tags === 'alltags') { + return [] + } + return tags.split('&') } handleClickTagListItem (name) { @@ -192,6 +218,20 @@ class SideNav extends React.Component { }) } + handleClickNarrowToTag (name) { + const { router } = this.context + const { location } = this.props + let listOfTags = this.getActiveTags(location.pathname) + if (listOfTags.includes(name)) { + listOfTags = listOfTags.filter(function (currentTag) { + return name !== currentTag + }) + } else { + listOfTags.push(name) + } + router.push(`/tags/${listOfTags.join('&')}`) + } + emptyTrash (entries) { const { dispatch } = this.props const deletionPromises = entries.map((note) => { diff --git a/browser/main/index.js b/browser/main/index.js index 6e8bdcc5..02bf7125 100644 --- a/browser/main/index.js +++ b/browser/main/index.js @@ -112,6 +112,9 @@ ReactDOM.render(( + + + From 68c0f210ccb76a2c12e58120a68d64b9278a663c Mon Sep 17 00:00:00 2001 From: bimlas Date: Sat, 7 Apr 2018 15:43:06 +0200 Subject: [PATCH 39/46] Separate active tags by ` ` instead of `&` Using `&` to separate tags in path (like `/tags/currently&selected&tags`) may interfer with tags including `&` character (like `black&white`). Since ` ` is replaced with `_` when adding tag to notes, it's ideal separator because it's guaranteed that tags are not including this character. --- browser/main/NoteList/index.js | 2 +- browser/main/SideNav/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index 867457ca..def289fb 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -343,7 +343,7 @@ class NoteList extends React.Component { } if (location.pathname.match(/\/tags/)) { - const listOfTags = params.tagname.split('&') + const listOfTags = params.tagname.split(' ') return data.noteMap.map(note => { return note }).filter(note => { diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js index a9f9f0da..b4c1d322 100644 --- a/browser/main/SideNav/index.js +++ b/browser/main/SideNav/index.js @@ -196,7 +196,7 @@ class SideNav extends React.Component { if (tags === 'alltags') { return [] } - return tags.split('&') + return tags.split(' ') } handleClickTagListItem (name) { @@ -229,7 +229,7 @@ class SideNav extends React.Component { } else { listOfTags.push(name) } - router.push(`/tags/${listOfTags.join('&')}`) + router.push(`/tags/${listOfTags.join(' ')}`) } emptyTrash (entries) { From 61ed47dda04edebb276d0df2fa9645502bd47b89 Mon Sep 17 00:00:00 2001 From: bimlas Date: Tue, 10 Apr 2018 14:13:58 +0200 Subject: [PATCH 40/46] Don't narrow list, add plus sign only for related tags It's easier to understand by most of the users. Later I like to add a setting to enable narrowing of tag list to show only the related ones. --- browser/components/TagListItem.js | 11 +++++++---- browser/main/SideNav/index.js | 10 ++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/browser/components/TagListItem.js b/browser/components/TagListItem.js index cbac00ce..196a5a23 100644 --- a/browser/components/TagListItem.js +++ b/browser/components/TagListItem.js @@ -12,11 +12,14 @@ import CSSModules from 'browser/lib/CSSModules' * @param {bool} isActive */ -const TagListItem = ({name, handleClickTagListItem, handleClickNarrowToTag, isActive, count}) => ( +const TagListItem = ({name, handleClickTagListItem, handleClickNarrowToTag, isActive, isRelated, count}) => (
- + {isRelated + ? + :
+ } - :
+ + + :
}
+
+ +
{ global.process.platform === 'win32' ?
From 24b004bb2d37ccc5d10e9b1ee01bbdb27ac59e18 Mon Sep 17 00:00:00 2001 From: bimlas Date: Wed, 11 Apr 2018 11:45:16 +0200 Subject: [PATCH 44/46] Remove obsolete route path --- browser/main/SideNav/index.js | 2 +- browser/main/index.js | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js index 7af6bb81..6b53478e 100644 --- a/browser/main/SideNav/index.js +++ b/browser/main/SideNav/index.js @@ -91,7 +91,7 @@ class SideNav extends React.Component { let component // TagsMode is not selected - if (!location.pathname.match('/tags') && !location.pathname.match('/alltags') && !location.pathname.match('/narrowToTag')) { + if (!location.pathname.match('/tags') && !location.pathname.match('/alltags')) { component = (
- - - From c4ec69a43f3ae1d791398bba205ff9f60316ff8d Mon Sep 17 00:00:00 2001 From: bimlas Date: Wed, 11 Apr 2018 15:00:45 +0200 Subject: [PATCH 45/46] Add tests --- .../TagListItem.snapshot.test.js.snap | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap b/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap index 0805edcd..0521ca0e 100644 --- a/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap +++ b/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap @@ -1,19 +1,26 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`TagListItem renders correctly 1`] = ` - + +
`; From 2ee99518535c5449b6138f3e4686ded74600bb36 Mon Sep 17 00:00:00 2001 From: yosmoc Date: Thu, 26 Apr 2018 22:29:26 +0200 Subject: [PATCH 46/46] Empty trash menu working in sidebar folded --- browser/components/SideNavFilter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/components/SideNavFilter.js b/browser/components/SideNavFilter.js index 06cfc19a..3a259ce7 100644 --- a/browser/components/SideNavFilter.js +++ b/browser/components/SideNavFilter.js @@ -51,7 +51,7 @@ const SideNavFilter = ({