diff --git a/browser/lib/Repository.js b/browser/lib/Repository.js index 40077966..3a72ec0c 100644 --- a/browser/lib/Repository.js +++ b/browser/lib/Repository.js @@ -3,6 +3,7 @@ const fs = require('fs') const path = require('path') const CSON = require('season') const _ = require('lodash') +const consts = require('browser/lib/consts') let repositories = [] @@ -19,10 +20,10 @@ let repositories = [] * .then(() => repo.load()) * * // Update Cached - * repo.updateCache({name: 'renamed'}) + * repo.saveCache({name: 'renamed'}) * * // Update JSON - * repo.updateJSON({author: 'Other user'}) + * repo.saveJSON({author: 'Other user'}) * * // Remove repository * repo.unmount() @@ -142,6 +143,7 @@ class Repository { return Promise.all([resolveDataDirectory, resolveBoostrepoJSON]) .then((data) => { this.json = data[1] + return true }) } @@ -167,6 +169,7 @@ class Repository { return Promise.all(notes) .then((notes) => { this.notes = notes + return true }) } @@ -178,10 +181,11 @@ class Repository { return this.getData() }) - .catch(function handleError (err) { + .catch((err) => { this.status = 'ERROR' this.error = err - return err + console.error(err) + return this }) } @@ -253,14 +257,23 @@ class Repository { * @return {Promise} all data of a repository */ getData () { - if (this.status !== 'READY') { + function carbonCopy (obj) { + return JSON.parse(JSON.stringify(obj)) + } + if (this.status === 'IDLE') { return this.load() } - return Promise.resolve(Object.assign({}, this.json, this.cached, { + if (this.status === 'ERROR') { + return Promise.resolve(carbonCopy(Object.assign({}, this.json, this.cached, { + status: this.status + }))) + } + + return Promise.resolve(carbonCopy(Object.assign({}, this.json, this.cached, { status: this.status, notes: this.notes - })) + }))) } /** @@ -287,11 +300,13 @@ class Repository { */ saveJSON (newJSON) { let jsonPath = path.join(this.cached.path, 'boostrepo.json') - Object.assign(this.json, newJSON) + if (_.isObject(newJSON)) { + Object.assign(this.json, newJSON) + } - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { CSON - .writeFile(jsonPath, this.json, function (err) { + .writeFile(jsonPath, this.json, (err) => { if (err != null) return reject(err) resolve(this.json) }) @@ -316,9 +331,9 @@ class Repository { newFolder = _.pick(newFolder, ['color', 'name']) if (!_.isString(newFolder.name) || newFolder.name.trim().length === 0) newFolder.name = 'unnamed' - else newFolder.name = newFolder.trim() + else newFolder.name = newFolder.name.trim() - if (!_.isString(newFolder.color)) newFolder.color = '' + if (!_.isString(newFolder.color)) newFolder.color = this.constructor.randomColor() newFolder.key = keygen() while (_.findIndex(folders, {key: newFolder.key}) > -1) { @@ -327,7 +342,7 @@ class Repository { folders.push(newFolder) - return this.updateJSON(this.json) + return this.saveJSON(this.json) .then(() => newFolder) } @@ -451,6 +466,10 @@ class Repository { return Promise.resolve(this.notes) } + /** + * Static Methods + */ + static generateDefaultJSON (override) { return Object.assign({ name: 'unnamed', @@ -458,7 +477,7 @@ class Repository { folders: [{ key: keygen(), name: 'general', - color: 'green' + color: this.randomColor() }] }, override) } @@ -474,21 +493,28 @@ class Repository { * @return {Promise} resolving parsed data */ static resolveJSON (targetPath, defaultOverrides) { - return new Promise(function checkIfExists (resolve, reject) { - // If JSON doesn't exist, make a new one. - if (CSON.resolve(targetPath) == null) { - let newRepoJSON = this.constructor.generateDefaultJSON(defaultOverrides) - CSON.writeFile(targetPath, newRepoJSON, function (err) { + return (new Promise((resolve, reject) => { + let writeNew = () => { + let newRepoJSON = this.generateDefaultJSON(defaultOverrides) + CSON.writeFile(targetPath, newRepoJSON, (err) => { if (err != null) return reject(err) resolve(newRepoJSON) }) + } + // If JSON doesn't exist, make a new one. + if (CSON.resolve(targetPath) == null) { + writeNew() } else { - CSON.readFile(targetPath, function (err, obj) { + CSON.readFile(targetPath, (err, obj) => { if (err != null) return reject(err) - resolve(obj) + if (obj == null) { + writeNew() + } else { + resolve(obj) + } }) } - }) + })) } /** @@ -553,7 +579,6 @@ class Repository { throw new Error('Data is corrupted. it must be an array.') } } catch (err) { - console.log(err) data = [] this.saveAllCached(data) } @@ -582,6 +607,10 @@ class Repository { let repository = _.find(repositories, {cached: {key: repoKey}}) return Promise.resolve(repository) } + + static randomColor () { + return consts.FOLDER_COLORS[Math.floor(Math.random() * consts.FOLDER_COLORS.length)] + } } export default Repository diff --git a/browser/lib/consts.js b/browser/lib/consts.js new file mode 100644 index 00000000..de75eaf1 --- /dev/null +++ b/browser/lib/consts.js @@ -0,0 +1,14 @@ +const consts = { + FOLDER_COLORS: [ + '#3460C7', + '#2BA5F7', + '#FF8E00', + '#E8D252', + '#3FD941', + '#1FAD85', + '#E10051', + '#B013A4' + ] +} + +module.exports = consts diff --git a/browser/main/HomePage/SideNav/RepositorySection.js b/browser/main/HomePage/SideNav/RepositorySection.js index 9b66ea40..04f77e81 100644 --- a/browser/main/HomePage/SideNav/RepositorySection.js +++ b/browser/main/HomePage/SideNav/RepositorySection.js @@ -9,10 +9,28 @@ const Menu = remote.Menu const MenuItem = remote.MenuItem class RepositorySection extends React.Component { + constructor (props) { + super(props) + + this.state = { + isOpen: true, + isCreatingFolder: false, + isSaving: false, + newFolder: { + name: '' + } + } + } + + getRepository () { + let { repository } = this.props + return Repository.find(repository.key) + } + handleUnlinkButtonClick () { let { dispatch, repository } = this.props - Repository.find(repository.key) + this.getRepository() .then((repositoryInstance) => { return repositoryInstance.unmount() }) @@ -25,16 +43,16 @@ class RepositorySection extends React.Component { } handleToggleButtonClick (e) { - + this.setState({ + isOpen: !this.state.isOpen + }) } handleContextButtonClick (e) { var menu = new Menu() menu.append(new MenuItem({ - label: 'New Note' - })) - menu.append(new MenuItem({ - label: 'New Folder' + label: 'New Folder', + click: () => this.handleNewFolderButtonClick() })) menu.append(new MenuItem({ type: 'separator' })) menu.append(new MenuItem({ @@ -45,17 +63,62 @@ class RepositorySection extends React.Component { menu.popup(remote.getCurrentWindow()) } + handleNewFolderButtonClick (e) { + this.setState({ + isCreatingFolder: true, + newFolder: { + name: 'New Folder' + } + }, () => { + this.refs.nameInput.select() + this.refs.nameInput.focus() + }) + } + + handleNewFolderFormChange (e) { + let newFolder = this.state.newFolder + newFolder.name = this.refs.nameInput.value + + this.setState({ + newFolder + }) + } + + handleNameInputBlur (e) { + let { dispatch, repository } = this.props + + this.getRepository() + .then((repositoryInstance) => { + return repositoryInstance.addFolder({ + name: this.state.newFolder.name + }) + }) + .then((folder) => { + console.log(folder) + dispatch({ + type: 'ADD_FOLDER', + key: repository.key, + folder: folder + }) + + this.setState({ + isCreatingFolder: false, + isSaving: false + }) + }) + } + render () { let { repository } = this.props let folderElements = repository.folders.map((folder) => { return (