From 8d59bd9f71c61aa8be0a87cecd86bb48eb57dbfe Mon Sep 17 00:00:00 2001 From: Nikolay Lopin Date: Sun, 25 Feb 2018 02:42:15 +0300 Subject: [PATCH 1/9] Remove redundant symbol from regexp --- browser/main/lib/dataApi/exportNote.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/lib/dataApi/exportNote.js b/browser/main/lib/dataApi/exportNote.js index 3ed46b92..740baa20 100755 --- a/browser/main/lib/dataApi/exportNote.js +++ b/browser/main/lib/dataApi/exportNote.js @@ -4,7 +4,7 @@ import {findStorage} from 'browser/lib/findStorage' const fs = require('fs') const path = require('path') -const LOCAL_STORED_REGEX = /!\[(.*?)\]\(\s*?\/:storage\/(.*\.\S*?)\)/gi +const LOCAL_STORED_REGEX = /!\[(.*?)]\(\s*?\/:storage\/(.*\.\S*?)\)/gi const IMAGES_FOLDER_NAME = 'images' /** From e5825e898dc0418c04230e6f07526b2507a67b7e Mon Sep 17 00:00:00 2001 From: Nikolay Lopin Date: Sun, 25 Feb 2018 02:45:59 +0300 Subject: [PATCH 2/9] allow to copy images without generating new name --- browser/main/lib/dataApi/copyImage.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/browser/main/lib/dataApi/copyImage.js b/browser/main/lib/dataApi/copyImage.js index ae79f8fb..6a79b8b7 100644 --- a/browser/main/lib/dataApi/copyImage.js +++ b/browser/main/lib/dataApi/copyImage.js @@ -3,19 +3,20 @@ const path = require('path') const { findStorage } = require('browser/lib/findStorage') /** - * @description To copy an image and return the path. + * @description Copy an image and return the path. * @param {String} filePath * @param {String} storageKey - * @return {String} an image path + * @param {Boolean} rename create new filename or leave the old one + * @return {Promise} an image path */ -function copyImage (filePath, storageKey) { +function copyImage (filePath, storageKey, rename = true) { return new Promise((resolve, reject) => { try { const targetStorage = findStorage(storageKey) const inputImage = fs.createReadStream(filePath) const imageExt = path.extname(filePath) - const imageName = Math.random().toString(36).slice(-16) + const imageName = rename ? Math.random().toString(36).slice(-16) : path.basename(filePath, imageExt) const basename = `${imageName}${imageExt}` const imageDir = path.join(targetStorage.path, 'images') if (!fs.existsSync(imageDir)) fs.mkdirSync(imageDir) From 9473a268925938b048fc1595ab0a6e28790b6f75 Mon Sep 17 00:00:00 2001 From: Nikolay Lopin Date: Sun, 25 Feb 2018 02:47:28 +0300 Subject: [PATCH 3/9] Move images between storages together with note 1. Added new step of moving note's images to `moveNote` function 2. Changed behaviour of sidebar navigation after move finished Issue #1578 --- browser/main/SideNav/StorageItem.js | 27 +++++---------------------- browser/main/lib/dataApi/moveNote.js | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/browser/main/SideNav/StorageItem.js b/browser/main/SideNav/StorageItem.js index 5d7e6005..0df7a98e 100644 --- a/browser/main/SideNav/StorageItem.js +++ b/browser/main/SideNav/StorageItem.js @@ -191,33 +191,16 @@ class StorageItem extends React.Component { dropNote (storage, folder, dispatch, location, noteData) { noteData = noteData.filter((note) => folder.key !== note.folder) if (noteData.length === 0) return - const newNoteData = noteData.map((note) => Object.assign({}, note, {storage: storage, folder: folder.key})) Promise.all( - newNoteData.map((note) => dataApi.createNote(storage.key, note)) + noteData.map((note) => dataApi.moveNote(note.storage, note.key, storage.key, folder.key)) ) .then((createdNoteData) => { - createdNoteData.forEach((note) => { + createdNoteData.forEach((newNote) => { dispatch({ - type: 'UPDATE_NOTE', - note: note - }) - }) - }) - .catch((err) => { - console.error(`error on create notes: ${err}`) - }) - .then(() => { - return Promise.all( - noteData.map((note) => dataApi.deleteNote(note.storage, note.key)) - ) - }) - .then((deletedNoteData) => { - deletedNoteData.forEach((note) => { - dispatch({ - type: 'DELETE_NOTE', - storageKey: note.storageKey, - noteKey: note.noteKey + type: 'MOVE_NOTE', + originNote: noteData.find((note) => note.content === newNote.content), + note: newNote }) }) }) diff --git a/browser/main/lib/dataApi/moveNote.js b/browser/main/lib/dataApi/moveNote.js index 4580062e..b37b6ac5 100644 --- a/browser/main/lib/dataApi/moveNote.js +++ b/browser/main/lib/dataApi/moveNote.js @@ -1,10 +1,12 @@ const resolveStorageData = require('./resolveStorageData') const _ = require('lodash') const path = require('path') +const fs = require('fs') const CSON = require('@rokt33r/season') const keygen = require('browser/lib/keygen') const sander = require('sander') const { findStorage } = require('browser/lib/findStorage') +const copyImage = require('./copyImage') function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) { let oldStorage, newStorage @@ -65,6 +67,27 @@ function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) { return noteData }) + .then(function moveImages (noteData) { + 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) + }) + ) + + // 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'])) return noteData From f3f6095d81dec384c5b8b07588b76c1b5eef927b Mon Sep 17 00:00:00 2001 From: lurong Date: Sat, 24 Feb 2018 01:01:54 +0800 Subject: [PATCH 4/9] allow publishing markdown to wordpress --- browser/components/NoteItem.js | 6 +- browser/main/NoteList/index.js | 125 +++++++++++ browser/main/lib/ConfigManager.js | 9 + browser/main/lib/dataApi/updateNote.js | 3 + browser/main/modals/PreferencesModal/Blog.js | 198 ++++++++++++++++++ browser/main/modals/PreferencesModal/index.js | 15 +- 6 files changed, 353 insertions(+), 3 deletions(-) create mode 100644 browser/main/modals/PreferencesModal/Blog.js diff --git a/browser/components/NoteItem.js b/browser/components/NoteItem.js index 2c93dc18..253faa81 100644 --- a/browser/components/NoteItem.js +++ b/browser/components/NoteItem.js @@ -123,7 +123,11 @@ NoteItem.propTypes = { title: PropTypes.string.isrequired, tags: PropTypes.array, isStarred: PropTypes.bool.isRequired, - isTrashed: PropTypes.bool.isRequired + isTrashed: PropTypes.bool.isRequired, + blog: { + blogLink: PropTypes.string, + blogId: PropTypes.number + } }), handleNoteClick: PropTypes.func.isRequired, handleNoteContextMenu: PropTypes.func.isRequired, diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index 8c3e8790..ff90404d 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -13,10 +13,13 @@ import searchFromNotes from 'browser/lib/search' import fs from 'fs' import path from 'path' import { hashHistory } from 'react-router' +import electron from 'electron' import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig' +import markdown from '../../lib/markdown' const { remote } = require('electron') const { Menu, MenuItem, dialog } = remote +const WP_POST_PATH = '/wp/v2/posts' function sortByCreatedAt (a, b) { return new Date(b.createdAt) - new Date(a.createdAt) @@ -458,6 +461,9 @@ class NoteList extends React.Component { const deleteLabel = 'Delete Note' const cloneNote = 'Clone Note' const restoreNote = 'Restore Note' + const publishLabel = 'Publish Blog' + const updateLabel = 'Update Blog' + const openBlogLabel = 'Open Blog' const menu = new Menu() if (!location.pathname.match(/\/starred|\/trash/)) { @@ -482,6 +488,24 @@ class NoteList extends React.Component { label: cloneNote, click: this.cloneNote.bind(this) })) + if (note.type === 'MARKDOWN_NOTE') { + if (note.blog) { + menu.append(new MenuItem({ + label: updateLabel, + click: this.publishMarkdown.bind(this) + })) + menu.append(new MenuItem({ + label: openBlogLabel, + click: () => this.openBlog.bind(this)(note) + })) + } else { + menu.append(new MenuItem({ + label: publishLabel, + click: this.publishMarkdown.bind(this) + })) + } + } + menu.popup() } @@ -630,6 +654,107 @@ class NoteList extends React.Component { }) } + save (note) { + const { dispatch } = this.props + dataApi + .updateNote(note.storage, note.key, note) + .then((note) => { + dispatch({ + type: 'UPDATE_NOTE', + note: note + }) + }) + } + + publishMarkdown () { + if (this.pendingPublish) { + clearTimeout(this.pendingPublish) + } + this.pendingPublish = setTimeout(() => { + this.publishMarkdownNow() + }, 1000) + } + + publishMarkdownNow () { + const {selectedNoteKeys} = this.state + const notes = this.notes.map((note) => Object.assign({}, note)) + const selectedNotes = findNotesByKeys(notes, selectedNoteKeys) + const firstNote = selectedNotes[0] + const config = ConfigManager.get() + let {address, token, authMethod, username, password} = config.blog + if (authMethod === 'USER') { + token = `Basic ${window.btoa(`${username}:${password}`)}` + } else { + token = `Bearer ${token}` + } + var data = { + title: firstNote.title, + content: markdown.render(firstNote.content), + status: 'publish' + } + + let url = '' + let method = '' + if (firstNote.blog) { + url = `${address}${WP_POST_PATH}/${firstNote.blog.blogId}` + method = 'PUT' + } else { + url = `${address}${WP_POST_PATH}` + method = 'POST' + } + // eslint-disable-next-line no-undef + fetch(url, { + method: method, + body: JSON.stringify(data), + headers: { + 'Authorization': token, + 'Content-Type': 'application/json' + } + }).then(res => res.json()) + .then(response => { + firstNote.blog = { + blogLink: response.link, + blogId: response.id + } + this.save(firstNote) + this.confirmPublish(firstNote) + }) + .catch(() => { + this.confirmPublishError() + }) + } + + confirmPublishError () { + const { remote } = electron + const { dialog } = remote + const alertError = { + type: 'warning', + message: 'Publish Failed', + detail: 'Check and update your blog setting and try again.', + buttons: ['Confirm'] + } + dialog.showMessageBox(remote.getCurrentWindow(), alertError) + } + + confirmPublish (note) { + const buttonIndex = dialog.showMessageBox(remote.getCurrentWindow(), { + type: 'warning', + message: 'Publish Succeeded', + detail: `${note.title} is published at ${note.blog.blogLink}`, + buttons: ['Confirm', 'Open Blog'] + }) + + if (buttonIndex === 1) { + this.openBlog(note) + } + } + + openBlog (note) { + const { shell } = electron + console.log(note) + shell.openExternal(note.blog.blogLink) + } + importFromFile () { const options = { filters: [ diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 0c8d6ee9..e7e82a9b 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -49,6 +49,14 @@ export const DEFAULT_CONFIG = { latexBlockOpen: '$$', latexBlockClose: '$$', scrollPastEnd: false + }, + blog: { + type: 'wordpress', // Available value: wordpress, add more types in the future plz + address: 'http://wordpress.com/wp-json', + authMethod: 'JWT', // Available value: JWT, USER + token: '', + username: '', + password: '' } } @@ -151,6 +159,7 @@ function set (updates) { function assignConfigValues (originalConfig, rcConfig) { const config = Object.assign({}, DEFAULT_CONFIG, originalConfig, rcConfig) config.hotkey = Object.assign({}, DEFAULT_CONFIG.hotkey, originalConfig.hotkey, rcConfig.hotkey) + config.blog = Object.assign({}, DEFAULT_CONFIG.blog, originalConfig.blog, rcConfig.blog) config.ui = Object.assign({}, DEFAULT_CONFIG.ui, originalConfig.ui, rcConfig.ui) config.editor = Object.assign({}, DEFAULT_CONFIG.editor, originalConfig.editor, rcConfig.editor) config.preview = Object.assign({}, DEFAULT_CONFIG.preview, originalConfig.preview, rcConfig.preview) diff --git a/browser/main/lib/dataApi/updateNote.js b/browser/main/lib/dataApi/updateNote.js index 2fbd52c2..147fbc06 100644 --- a/browser/main/lib/dataApi/updateNote.js +++ b/browser/main/lib/dataApi/updateNote.js @@ -30,6 +30,9 @@ function validateInput (input) { validatedInput.isPinned = !!input.isPinned } + if (!_.isNil(input.blog)) { + validatedInput.blog = input.blog + } validatedInput.type = input.type switch (input.type) { case 'MARKDOWN_NOTE': diff --git a/browser/main/modals/PreferencesModal/Blog.js b/browser/main/modals/PreferencesModal/Blog.js new file mode 100644 index 00000000..675455f7 --- /dev/null +++ b/browser/main/modals/PreferencesModal/Blog.js @@ -0,0 +1,198 @@ +import React from 'react' +import CSSModules from 'browser/lib/CSSModules' +import styles from './ConfigTab.styl' +import ConfigManager from 'browser/main/lib/ConfigManager' +import store from 'browser/main/store' +import PropTypes from 'prop-types' +import _ from 'lodash' + +const electron = require('electron') +const { shell } = electron +const ipc = electron.ipcRenderer +class Blog extends React.Component { + constructor (props) { + super(props) + + this.state = { + config: props.config, + BlogAlert: null + } + } + + handleLinkClick (e) { + shell.openExternal(e.currentTarget.href) + e.preventDefault() + } + + clearMessage () { + _.debounce(() => { + this.setState({ + BlogAlert: null + }) + }, 2000)() + } + + componentDidMount () { + this.handleSettingDone = () => { + this.setState({BlogAlert: { + type: 'success', + message: 'Successfully applied!' + }}) + } + this.handleSettingError = (err) => { + this.setState({BlogAlert: { + type: 'error', + message: err.message != null ? err.message : 'Error occurs!' + }}) + } + this.oldBlog = this.state.config.blog + ipc.addListener('APP_SETTING_DONE', this.handleSettingDone) + ipc.addListener('APP_SETTING_ERROR', this.handleSettingError) + } + + handleBlogChange (e) { + const { config } = this.state + config.blog = { + password: !_.isNil(this.refs.passwordInput) ? this.refs.passwordInput.value : config.blog.password, + username: !_.isNil(this.refs.usernameInput) ? this.refs.usernameInput.value : config.blog.username, + token: !_.isNil(this.refs.tokenInput) ? this.refs.tokenInput.value : config.blog.token, + authMethod: this.refs.authMethodDropdown.value, + address: this.refs.addressInput.value, + type: this.refs.typeDropdown.value + } + this.setState({ + config + }) + if (_.isEqual(this.oldBlog, config.blog)) { + this.props.haveToSave() + } else { + this.props.haveToSave({ + tab: 'Blog', + type: 'warning', + message: 'You have to save!' + }) + } + } + + handleSaveButtonClick (e) { + const newConfig = { + blog: this.state.config.blog + } + + ConfigManager.set(newConfig) + + store.dispatch({ + type: 'SET_UI', + config: newConfig + }) + this.clearMessage() + this.props.haveToSave() + } + + render () { + const {config, BlogAlert} = this.state + const blogAlertElement = BlogAlert != null + ?

+ {BlogAlert.message} +

+ : null + return ( +
+
+
Blog
+
+
+ Blog Type +
+
+ +
+
+
+
Blog Address
+
+ this.handleBlogChange(e)} + ref='addressInput' + value={config.blog.address} + type='text' + /> +
+
+
+ + {blogAlertElement} +
+
+
Auth
+ +
+
+ Authentication Method +
+
+ +
+
+ { config.blog.authMethod === 'JWT' && +
+
Token
+
+ this.handleBlogChange(e)} + ref='tokenInput' + value={config.blog.token} + type='text' /> +
+
+ } + { config.blog.authMethod === 'USER' && +
+
+
UserName
+
+ this.handleBlogChange(e)} + ref='usernameInput' + value={config.blog.username} + type='text' /> +
+
+
+
Password
+
+ this.handleBlogChange(e)} + ref='passwordInput' + value={config.blog.password} + type='password' /> +
+
+
+ } +
+ ) + } +} + +Blog.propTypes = { + dispatch: PropTypes.func, + haveToSave: PropTypes.func +} + +export default CSSModules(Blog, styles) diff --git a/browser/main/modals/PreferencesModal/index.js b/browser/main/modals/PreferencesModal/index.js index 6cd5badc..09ca9a4e 100644 --- a/browser/main/modals/PreferencesModal/index.js +++ b/browser/main/modals/PreferencesModal/index.js @@ -6,6 +6,7 @@ import UiTab from './UiTab' import InfoTab from './InfoTab' import Crowdfunding from './Crowdfunding' import StoragesTab from './StoragesTab' +import Blog from './Blog' import ModalEscButton from 'browser/components/ModalEscButton' import CSSModules from 'browser/lib/CSSModules' import styles from './PreferencesModal.styl' @@ -19,7 +20,8 @@ class Preferences extends React.Component { this.state = { currentTab: 'STORAGES', UIAlert: '', - HotkeyAlert: '' + HotkeyAlert: '', + BlogAlert: '' } } @@ -75,6 +77,14 @@ class Preferences extends React.Component { return ( ) + case 'BLOG': + return ( + this.setState({BlogAlert: alert})} + /> + ) case 'STORAGES': default: return ( @@ -111,7 +121,8 @@ class Preferences extends React.Component { {target: 'HOTKEY', label: 'Hotkeys', Hotkey: this.state.HotkeyAlert}, {target: 'UI', label: 'Interface', UI: this.state.UIAlert}, {target: 'INFO', label: 'About'}, - {target: 'CROWDFUNDING', label: 'Crowdfunding'} + {target: 'CROWDFUNDING', label: 'Crowdfunding'}, + {target: 'BLOG', label: 'Blog', Blog: this.state.BlogAlert} ] const navButtons = tabs.map((tab) => { From 97600e526b0188ef317195df65f7e60109fd320b Mon Sep 17 00:00:00 2001 From: lurong Date: Sat, 24 Feb 2018 02:51:01 +0800 Subject: [PATCH 5/9] remove the first occurrence of title in content when publishing to WP --- browser/main/NoteList/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index ff90404d..56101b63 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -687,9 +687,10 @@ class NoteList extends React.Component { } else { token = `Bearer ${token}` } + let contentToRender = firstNote.content.replace(`# ${firstNote.title}`, '') var data = { title: firstNote.title, - content: markdown.render(firstNote.content), + content: markdown.render(contentToRender), status: 'publish' } From aef603ed8ce45feba9e19ffffdfd412cc7c85bea Mon Sep 17 00:00:00 2001 From: lurong Date: Sun, 25 Feb 2018 22:50:51 +0800 Subject: [PATCH 6/9] rebase and prefer const in node list --- browser/main/NoteList/index.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index 56101b63..3db88dd1 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -681,13 +681,14 @@ class NoteList extends React.Component { const selectedNotes = findNotesByKeys(notes, selectedNoteKeys) const firstNote = selectedNotes[0] const config = ConfigManager.get() - let {address, token, authMethod, username, password} = config.blog + const {address, token, authMethod, username, password} = config.blog + let authToken = '' if (authMethod === 'USER') { - token = `Basic ${window.btoa(`${username}:${password}`)}` + authToken = `Basic ${window.btoa(`${username}:${password}`)}` } else { - token = `Bearer ${token}` + authToken = `Bearer ${token}` } - let contentToRender = firstNote.content.replace(`# ${firstNote.title}`, '') + const contentToRender = firstNote.content.replace(`# ${firstNote.title}`, '') var data = { title: firstNote.title, content: markdown.render(contentToRender), @@ -708,7 +709,7 @@ class NoteList extends React.Component { method: method, body: JSON.stringify(data), headers: { - 'Authorization': token, + 'Authorization': authToken, 'Content-Type': 'application/json' } }).then(res => res.json()) From 6bcb6398f8cf1a1aa56b74dc028fbae5b0237708 Mon Sep 17 00:00:00 2001 From: Markus Deuerlein Date: Mon, 26 Feb 2018 13:08:03 +0100 Subject: [PATCH 7/9] German translation: minor corrections (#1585) * minor corrections some german improvements and corrections of the translation * update link to docs/de/debug.md * minor corrections * minor corrections * minor corrections * minor corrections * minor corrections --- docs/de/build.md | 2 +- docs/de/debug.md | 22 ++++++++++++++-------- docs/debug.md | 2 +- docs/fr/build.md | 2 +- docs/fr/debug.md | 4 ++-- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/docs/de/build.md b/docs/de/build.md index 44b744ca..3c7c8ac6 100644 --- a/docs/de/build.md +++ b/docs/de/build.md @@ -1,5 +1,5 @@ # Build -Diese Seite ist auch verfügbar in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md), [French](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/build.md) and [German](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md). +Diese Seite ist auch verfügbar in [Japanisch](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Koreanisch](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russisch](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [Vereinfachtem Chinesisch](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md), [Französisch](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/build.md) und [Deutsch](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md). ## Umgebungen * npm: 4.x diff --git a/docs/de/debug.md b/docs/de/debug.md index ee1a734c..6c3de3dc 100644 --- a/docs/de/debug.md +++ b/docs/de/debug.md @@ -1,25 +1,31 @@ # How to debug Boostnote (Electron app) -Diese Seite ist auch verfügbar in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/debug.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/debug.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/debug.md), [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/debug.md), [French](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/debug.md) and [German](https://github.com/BoostIO/Boostnote/blob/add-german-documents/docs/de/debug.md). -Boostnote is eine Electron app, somit basiert sie auf Chromium; Entwickler können die `Developer Tools` verwenden, wie Google Chrome. +Diese Seite ist auch verfügbar in [Japanisch](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/debug.md), [Koreanisch](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/debug.md), [Russisch](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/debug.md), [Vereinfachtem Chinesisch](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/debug.md), [Französisch](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/debug.md) und [Deutsch](https://github.com/BoostIO/Boostnote/blob/master/docs/de/debug.md). + + +Boostnote ist eine Electron App und basiert auf Chromium. + +Zum Entwicklen verwendest du am Besten die `Developer Tools` von Google Chrome verwenden. Diese kannst du ganz einfach im unter dem Menüpunkt `View` mit `Toggle Developer Tools` aktivieren: -Du kannst die `Developer Tools` so einschalten: ![how_to_toggle_devTools](https://cloud.githubusercontent.com/assets/11307908/24343585/162187e2-127c-11e7-9c01-23578db03ecf.png) -Die `Developer Tools` schauen dann ungefähr so aus: +Die Anzeige der `Developer Tools` sieht in etwa so aus: + ![Developer_Tools](https://cloud.githubusercontent.com/assets/11307908/24343545/eff9f3a6-127b-11e7-94cf-cb67bfda634a.png) -Wenn Fehler vorkommen, werden die Fehlermeldungen in der `console` ausgegeben. ## Debugging -Zum Beispiel kannst du mit dem `debugger` Haltepunkte im Code setzen wie hier veranschaulicht: + +Fehlermeldungen werden in der Regel in der `console` ausgegeben, die du über den gleichnamigen Reiter der `Developer Tools` anzeigen lassen kannst. Zum Debuggen kannst du beispielsweise über den `debugger` Haltepunkte im Code setzen. + ![debugger](https://cloud.githubusercontent.com/assets/11307908/24343879/9459efea-127d-11e7-9943-f60bf7f66d4a.png) -Das ist ledigtlich ein Beispiel, du kannst die Art von Debugging verwenden die für dich am besten ist. +Du kannst aber natürlich auch die Art von Debugging verwenden mit der du am besten zurecht kommst. ## Referenz + * [Official document of Google Chrome about debugging](https://developer.chrome.com/devtools) --- -Special thanks: Translated by [gino909](https://github.com/gino909) +Special thanks: Translated by [gino909](https://github.com/gino909), [mdeuerlein](https://github.com/mdeuerlein) diff --git a/docs/debug.md b/docs/debug.md index 30c217a4..78a71137 100644 --- a/docs/debug.md +++ b/docs/debug.md @@ -1,5 +1,5 @@ # How to debug Boostnote (Electron app) -This page is also available in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/debug.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/debug.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/debug.md), [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/debug.md), [French](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/debug.md) and [German](https://github.com/BoostIO/Boostnote/blob/add-german-documents/docs/de/debug.md). +This page is also available in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/debug.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/debug.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/debug.md), [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/debug.md), [French](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/debug.md) and [German](https://github.com/BoostIO/Boostnote/blob/master/docs/de/debug.md). Boostnote is an Electron app so it's based on Chromium; developers can use `Developer Tools` just like Google Chrome. diff --git a/docs/fr/build.md b/docs/fr/build.md index 0d718742..7003de84 100644 --- a/docs/fr/build.md +++ b/docs/fr/build.md @@ -1,5 +1,5 @@ # Build -Cette page est également disponible en [Japonais](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Coréen](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russe](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), et en [Chinois Simplifié](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md). +Cette page est également disponible en [Angalis](https://github.com/BoostIO/Boostnote/blob/master/docs/build.md), [Japonais](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Coréen](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russe](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [Chinois Simplifié](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md) et en [Allemand](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md) ## Environnements * npm: 4.x diff --git a/docs/fr/debug.md b/docs/fr/debug.md index 9395e4f9..f0b1be4b 100644 --- a/docs/fr/debug.md +++ b/docs/fr/debug.md @@ -1,5 +1,5 @@ # Comment débugger Boostnote (Application Electron) -Cette page est également disponible en [Japonais](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/debug.md), [Coréen](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/debug.md), [Russe](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/debug.md), et en [Chinois Simplifié](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/debug.md) +Cette page est également disponible en [Angalis](https://github.com/BoostIO/Boostnote/blob/master/docs/debug.md), [Japonais](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/debug.md), [Coréen](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/debug.md), [Russe](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/debug.md), [Chinois Simplifié](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/debug.md) et en [Allemand](https://github.com/BoostIO/Boostnote/blob/master/docs/de/debug.md) Boostnote est une application Electron donc basée sur Chromium. Il est possible d'utiliser les `Developer Tools` comme dans Google Chrome. @@ -19,4 +19,4 @@ Par exemple, vous pouvez utiliser le `debugger` pour placer un point d'arrêt da C'est une façon comme une autre de faire, vous pouvez trouver une façon de débugger que vous trouverez plus adaptée. ## Références -* [Documentation officiel de Google Chrome sur le debugging](https://developer.chrome.com/devtools) \ No newline at end of file +* [Documentation officiel de Google Chrome sur le debugging](https://developer.chrome.com/devtools) From e5f986a95932ae14a36590bc4dcf22f2acb025f8 Mon Sep 17 00:00:00 2001 From: lijinglue Date: Mon, 26 Feb 2018 21:12:42 +0800 Subject: [PATCH 8/9] checking if return is valid before creating the blog attr in note --- browser/main/NoteList/index.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index 3db88dd1..7075c0ef 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -489,7 +489,7 @@ class NoteList extends React.Component { click: this.cloneNote.bind(this) })) if (note.type === 'MARKDOWN_NOTE') { - if (note.blog) { + if (note.blog && note.blog.blogLink && note.blog.blogId) { menu.append(new MenuItem({ label: updateLabel, click: this.publishMarkdown.bind(this) @@ -697,7 +697,7 @@ class NoteList extends React.Component { let url = '' let method = '' - if (firstNote.blog) { + if (firstNote.blog && firstNote.blog.blogId) { url = `${address}${WP_POST_PATH}/${firstNote.blog.blogId}` method = 'PUT' } else { @@ -714,6 +714,9 @@ class NoteList extends React.Component { } }).then(res => res.json()) .then(response => { + if (_.isNil(response.link) || _.isNil(response.id)) { + return Promise.reject(); + } firstNote.blog = { blogLink: response.link, blogId: response.id @@ -721,7 +724,8 @@ class NoteList extends React.Component { this.save(firstNote) this.confirmPublish(firstNote) }) - .catch(() => { + .catch((error) => { + console.error(error) this.confirmPublishError() }) } @@ -753,7 +757,6 @@ class NoteList extends React.Component { openBlog (note) { const { shell } = electron - console.log(note) shell.openExternal(note.blog.blogLink) } From 7c525ab7a650d565e6a05ec971434e79490be37b Mon Sep 17 00:00:00 2001 From: lurong Date: Mon, 26 Feb 2018 21:27:42 +0800 Subject: [PATCH 9/9] fix lint --- 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 7075c0ef..13cb4400 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -715,7 +715,7 @@ class NoteList extends React.Component { }).then(res => res.json()) .then(response => { if (_.isNil(response.link) || _.isNil(response.id)) { - return Promise.reject(); + return Promise.reject() } firstNote.blog = { blogLink: response.link,