1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-14 10:16:26 +00:00
INIT_ALL, NOTE_MOVE, NOTE_UPDATE(create/update) done
This commit is contained in:
Dick Choi
2016-08-30 02:33:28 +09:00
parent ba374e08ff
commit aefb84df3b
13 changed files with 449 additions and 152 deletions

View File

@@ -34,7 +34,7 @@ class NoteItem extends React.Component {
? 'root--active' ? 'root--active'
: 'root' : 'root'
} }
key={note.uniqueKey} key={note.storage + '-' + note.key}
onClick={(e) => this.handleClick(e)} onClick={(e) => this.handleClick(e)}
> >
<div styleName='border'/> <div styleName='border'/>

View File

@@ -64,7 +64,7 @@ class NoteList extends React.Component {
return ( return (
<NoteItem <NoteItem
note={note} note={note}
key={`${note.storage}-${note.folder}-${note.key}`} key={`${note.storage}-${note.key}`}
storage={storage} storage={storage}
folder={folder} folder={folder}
isActive={index === _index} isActive={index === _index}

87
browser/lib/Mutable.js Normal file
View File

@@ -0,0 +1,87 @@
class MutableMap {
constructor (iterable) {
this._map = new Map(iterable)
}
get (...args) {
return this._map.get(...args)
}
set (...args) {
return this._map.set(...args)
}
delete (...args) {
return this._map.delete(...args)
}
has (...args) {
return this._map.has(...args)
}
clear (...args) {
return this._map.clear(...args)
}
forEach (...args) {
return this._map.forEach(...args)
}
[Symbol.iterator] () {
return this._map[Symbol.iterator]()
}
map (cb) {
let result = []
for (let [key, value] of this._map) {
result.push(cb(value, key))
}
return result
}
}
class MutableSet {
constructor (iterable) {
if (iterable instanceof MutableSet) {
this._set = new Set(iterable._set)
} else {
this._set = new Set(iterable)
}
}
add (...args) {
return this._set.add(...args)
}
delete (...args) {
return this._set.delete(...args)
}
forEach (...args) {
return this._map.forEach(...args)
}
[Symbol.iterator] () {
return this._set[Symbol.iterator]()
}
map (cb) {
let result = []
this._set.forEach(function (value, key) {
result.push(cb(value, key))
})
return result
}
toJS () {
return Array.from(this._set)
}
}
const Mutable = {
Map: MutableMap,
Set: MutableSet
}
module.exports = Mutable

View File

@@ -184,12 +184,12 @@ class FolderSelect extends React.Component {
} }
render () { render () {
let { className, storages, value } = this.props let { className, data, value } = this.props
let splitted = value.split('-') let splitted = value.split('-')
let storageKey = splitted.shift() let storageKey = splitted.shift()
let folderKey = splitted.shift() let folderKey = splitted.shift()
let options = [] let options = []
storages.forEach((storage, index) => { data.storageMap.forEach((storage, index) => {
storage.folders.forEach((folder) => { storage.folders.forEach((folder) => {
options.push({ options.push({
storage: storage, storage: storage,

View File

@@ -35,6 +35,7 @@ class MarkdownNoteDetail extends React.Component {
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
if (nextProps.note.key !== this.props.note.key && !this.isMovingNote) { if (nextProps.note.key !== this.props.note.key && !this.isMovingNote) {
if (this.saveQueue != null) this.saveNow()
this.setState({ this.setState({
note: Object.assign({}, nextProps.note), note: Object.assign({}, nextProps.note),
isDeleting: false isDeleting: false
@@ -45,6 +46,10 @@ class MarkdownNoteDetail extends React.Component {
} }
} }
componentWillUnmount () {
if (this.saveQueue != null) this.saveNow()
}
findTitle (value) { findTitle (value) {
let splitted = value.split('\n') let splitted = value.split('\n')
let title = null let title = null
@@ -91,15 +96,23 @@ class MarkdownNoteDetail extends React.Component {
save () { save () {
clearTimeout(this.saveQueue) clearTimeout(this.saveQueue)
this.saveQueue = setTimeout(() => { this.saveQueue = setTimeout(() => {
this.saveNow()
}, 1000)
}
saveNow () {
let { note, dispatch } = this.props let { note, dispatch } = this.props
dispatch({ clearTimeout(this.saveQueue)
type: 'UPDATE_NOTE', this.saveQueue = null
note: this.state.note
})
dataApi dataApi
.updateNote(note.storage, note.folder, note.key, this.state.note) .updateNote(note.storage, note.key, this.state.note)
}, 1000) .then((note) => {
dispatch({
type: 'UPDATE_NOTE',
note: note
})
})
} }
handleFolderChange (e) { handleFolderChange (e) {
@@ -110,7 +123,7 @@ class MarkdownNoteDetail extends React.Component {
let newFolderKey = splitted.shift() let newFolderKey = splitted.shift()
dataApi dataApi
.moveNote(note.storage, note.folder, note.key, newStorageKey, newFolderKey) .moveNote(note.storage, note.key, newStorageKey, newFolderKey)
.then((newNote) => { .then((newNote) => {
this.setState({ this.setState({
isMovingNote: true, isMovingNote: true,
@@ -119,13 +132,13 @@ class MarkdownNoteDetail extends React.Component {
let { dispatch, location } = this.props let { dispatch, location } = this.props
dispatch({ dispatch({
type: 'MOVE_NOTE', type: 'MOVE_NOTE',
note: note, originNote: note,
newNote: newNote note: newNote
}) })
hashHistory.replace({ hashHistory.replace({
pathname: location.pathname, pathname: location.pathname,
query: { query: {
key: newNote.uniqueKey key: newNote.storage + '-' + newNote.key
} }
}) })
this.setState({ this.setState({
@@ -210,7 +223,7 @@ class MarkdownNoteDetail extends React.Component {
} }
render () { render () {
let { storages, config } = this.props let { data, config } = this.props
let { note } = this.state let { note } = this.state
return ( return (
@@ -243,7 +256,7 @@ class MarkdownNoteDetail extends React.Component {
<FolderSelect styleName='info-left-top-folderSelect' <FolderSelect styleName='info-left-top-folderSelect'
value={this.state.note.storage + '-' + this.state.note.folder} value={this.state.note.storage + '-' + this.state.note.folder}
ref='folder' ref='folder'
storages={storages} data={data}
onChange={(e) => this.handleFolderChange(e)} onChange={(e) => this.handleFolderChange(e)}
/> />
</div> </div>

View File

@@ -48,6 +48,7 @@ class SnippetNoteDetail extends React.Component {
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
if (nextProps.note.key !== this.props.note.key) { if (nextProps.note.key !== this.props.note.key) {
if (this.saveQueue != null) this.saveNow()
let nextNote = Object.assign({ let nextNote = Object.assign({
description: '' description: ''
}, nextProps.note, { }, nextProps.note, {
@@ -67,6 +68,10 @@ class SnippetNoteDetail extends React.Component {
} }
} }
componentWillUnmount () {
if (this.saveQueue != null) this.saveNow()
}
findTitle (value) { findTitle (value) {
let splitted = value.split('\n') let splitted = value.split('\n')
let title = null let title = null
@@ -113,15 +118,23 @@ class SnippetNoteDetail extends React.Component {
save () { save () {
clearTimeout(this.saveQueue) clearTimeout(this.saveQueue)
this.saveQueue = setTimeout(() => { this.saveQueue = setTimeout(() => {
this.saveNow()
}, 1000)
}
saveNow () {
let { note, dispatch } = this.props let { note, dispatch } = this.props
dispatch({ clearTimeout(this.saveQueue)
type: 'UPDATE_NOTE', this.saveQueue = null
note: this.state.note
})
dataApi dataApi
.updateNote(note.storage, note.folder, note.key, this.state.note) .updateNote(note.storage, note.key, this.state.note)
}, 1000) .then((note) => {
dispatch({
type: 'UPDATE_NOTE',
note: note
})
})
} }
handleFolderChange (e) { handleFolderChange (e) {
@@ -132,7 +145,7 @@ class SnippetNoteDetail extends React.Component {
let newFolderKey = splitted.shift() let newFolderKey = splitted.shift()
dataApi dataApi
.moveNote(note.storage, note.folder, note.key, newStorageKey, newFolderKey) .moveNote(note.storage, note.key, newStorageKey, newFolderKey)
.then((newNote) => { .then((newNote) => {
this.setState({ this.setState({
isMovingNote: true, isMovingNote: true,
@@ -141,13 +154,13 @@ class SnippetNoteDetail extends React.Component {
let { dispatch, location } = this.props let { dispatch, location } = this.props
dispatch({ dispatch({
type: 'MOVE_NOTE', type: 'MOVE_NOTE',
note: note, originNote: note,
newNote: newNote note: newNote
}) })
hashHistory.replace({ hashHistory.replace({
pathname: location.pathname, pathname: location.pathname,
query: { query: {
key: newNote.uniqueKey key: newNote.storage + '-' + newNote.key
} }
}) })
this.setState({ this.setState({
@@ -321,7 +334,7 @@ class SnippetNoteDetail extends React.Component {
} }
render () { render () {
let { storages, config } = this.props let { data, config } = this.props
let { note } = this.state let { note } = this.state
let editorFontSize = parseInt(config.editor.fontSize, 10) let editorFontSize = parseInt(config.editor.fontSize, 10)
@@ -434,7 +447,7 @@ class SnippetNoteDetail extends React.Component {
<FolderSelect styleName='info-left-top-folderSelect' <FolderSelect styleName='info-left-top-folderSelect'
value={this.state.note.storage + '-' + this.state.note.folder} value={this.state.note.storage + '-' + this.state.note.folder}
ref='folder' ref='folder'
storages={storages} data={data}
onChange={(e) => this.handleFolderChange(e)} onChange={(e) => this.handleFolderChange(e)}
/> />
</div> </div>

View File

@@ -31,19 +31,14 @@ class Detail extends React.Component {
} }
render () { render () {
let { location, notes, config } = this.props let { location, data, config } = this.props
let note = null let note = null
if (location.query.key != null) { if (location.query.key != null) {
let splitted = location.query.key.split('-') let splitted = location.query.key.split('-')
let storageKey = splitted.shift() let storageKey = splitted.shift()
let folderKey = splitted.shift()
let noteKey = splitted.shift() let noteKey = splitted.shift()
note = _.find(notes, { note = data.noteMap.get(storageKey + '-' + noteKey)
storage: storageKey,
folder: folderKey,
key: noteKey
})
} }
if (note == null) { if (note == null) {
@@ -67,7 +62,7 @@ class Detail extends React.Component {
ref='root' ref='root'
{..._.pick(this.props, [ {..._.pick(this.props, [
'dispatch', 'dispatch',
'storages', 'data',
'style', 'style',
'ignorePreviewPointerEvents', 'ignorePreviewPointerEvents',
'location' 'location'
@@ -83,7 +78,7 @@ class Detail extends React.Component {
ref='root' ref='root'
{..._.pick(this.props, [ {..._.pick(this.props, [
'dispatch', 'dispatch',
'storages', 'data',
'style', 'style',
'ignorePreviewPointerEvents', 'ignorePreviewPointerEvents',
'location' 'location'
@@ -95,7 +90,6 @@ class Detail extends React.Component {
Detail.propTypes = { Detail.propTypes = {
dispatch: PropTypes.func, dispatch: PropTypes.func,
storages: PropTypes.array,
style: PropTypes.shape({ style: PropTypes.shape({
left: PropTypes.number left: PropTypes.number
}), }),

View File

@@ -101,7 +101,7 @@ class Main extends React.Component {
<SideNav <SideNav
{..._.pick(this.props, [ {..._.pick(this.props, [
'dispatch', 'dispatch',
'storages', 'data',
'config', 'config',
'location' 'location'
])} ])}
@@ -112,9 +112,8 @@ class Main extends React.Component {
<TopBar style={{width: this.state.listWidth}} <TopBar style={{width: this.state.listWidth}}
{..._.pick(this.props, [ {..._.pick(this.props, [
'dispatch', 'dispatch',
'storages',
'config', 'config',
'notes', 'data',
'params', 'params',
'location' 'location'
])} ])}
@@ -122,8 +121,7 @@ class Main extends React.Component {
<NoteList style={{width: this.state.listWidth}} <NoteList style={{width: this.state.listWidth}}
{..._.pick(this.props, [ {..._.pick(this.props, [
'dispatch', 'dispatch',
'storages', 'data',
'notes',
'config', 'config',
'params', 'params',
'location' 'location'
@@ -140,8 +138,7 @@ class Main extends React.Component {
style={{left: this.state.listWidth + 1}} style={{left: this.state.listWidth + 1}}
{..._.pick(this.props, [ {..._.pick(this.props, [
'dispatch', 'dispatch',
'storages', 'data',
'notes',
'config', 'config',
'params', 'params',
'location' 'location'
@@ -159,7 +156,7 @@ class Main extends React.Component {
Main.propTypes = { Main.propTypes = {
dispatch: PropTypes.func, dispatch: PropTypes.func,
repositories: PropTypes.array data: PropTypes.shape({}).isRequired
} }
export default connect((x) => x)(CSSModules(Main, styles)) export default connect((x) => x)(CSSModules(Main, styles))

View File

@@ -43,7 +43,7 @@ class NoteList extends React.Component {
router.replace({ router.replace({
pathname: location.pathname, pathname: location.pathname,
query: { query: {
key: this.notes[0].uniqueKey key: this.notes[0].storage + '-' + this.notes[0].key
} }
}) })
return return
@@ -52,7 +52,7 @@ class NoteList extends React.Component {
// Auto scroll // Auto scroll
if (_.isString(location.query.key)) { if (_.isString(location.query.key)) {
let targetIndex = _.findIndex(this.notes, (note) => { let targetIndex = _.findIndex(this.notes, (note) => {
return note.uniqueKey === location.query.key return note != null && note.storage + '-' + note.key === location.query.key
}) })
if (targetIndex > -1) { if (targetIndex > -1) {
let list = this.refs.root let list = this.refs.root
@@ -153,30 +153,33 @@ class NoteList extends React.Component {
} }
getNotes () { getNotes () {
let { storages, notes, params, location } = this.props let { data, params, location } = this.props
if (location.pathname.match(/\/home/)) { if (location.pathname.match(/\/home/)) {
return notes return data.noteMap.map((note) => note)
} }
if (location.pathname.match(/\/starred/)) { if (location.pathname.match(/\/starred/)) {
return notes return data.starredSet.toJS()
.filter((note) => note.isStarred) .map((uniqueKey) => data.noteMap.get(uniqueKey))
} }
let storageKey = params.storageKey let storageKey = params.storageKey
let folderKey = params.folderKey let folderKey = params.folderKey
let storage = _.find(storages, {key: storageKey}) let storage = data.storageMap.get(storageKey)
if (storage == null) return [] if (storage == null) return []
let folder = _.find(storage.folders, {key: folderKey}) let folder = _.find(storage.folders, {key: folderKey})
if (folder == null) { if (folder == null) {
return notes return data.storeageNoteMap
.filter((note) => note.storage === storageKey) .get(storage.key)
.map((uniqueKey) => data.noteMap.get(uniqueKey))
} }
return notes let folderNoteKeyList = data.folderNoteMap
.filter((note) => note.folder === folderKey) .get(storage.key + '-' + folder.key)
return folderNoteKeyList
.map((uniqueKey) => data.noteMap.get(uniqueKey))
} }
handleNoteClick (uniqueKey) { handleNoteClick (uniqueKey) {
@@ -194,13 +197,14 @@ class NoteList extends React.Component {
} }
render () { render () {
let { location, storages, notes } = this.props let { location, data, notes } = this.props
this.notes = notes = this.getNotes() this.notes = notes = this.getNotes()
.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)) .sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt))
let noteList = notes let noteList = notes
.map((note) => { .map((note) => {
let storage = _.find(storages, {key: note.storage}) if (note == null) return null
let storage = data.storageMap.get(note.storage)
let folder = _.find(storage.folders, {key: note.folder}) let folder = _.find(storage.folders, {key: note.folder})
let tagElements = _.isArray(note.tags) let tagElements = _.isArray(note.tags)
? note.tags.map((tag) => { ? note.tags.map((tag) => {
@@ -212,14 +216,14 @@ class NoteList extends React.Component {
) )
}) })
: [] : []
let isActive = location.query.key === note.uniqueKey let isActive = location.query.key === note.storage + '-' + note.key
return ( return (
<div styleName={isActive <div styleName={isActive
? 'item--active' ? 'item--active'
: 'item' : 'item'
} }
key={note.uniqueKey} key={note.storage + '-' + note.key}
onClick={(e) => this.handleNoteClick(note.uniqueKey)(e)} onClick={(e) => this.handleNoteClick(note.storage + '-' + note.key)(e)}
> >
<div styleName='item-border'/> <div styleName='item-border'/>
<div styleName='item-info'> <div styleName='item-info'>

View File

@@ -36,12 +36,13 @@ class SideNav extends React.Component {
} }
render () { render () {
let { storages, location, config } = this.props let { data, location, config } = this.props
let isFolded = config.isSideNavFolded let isFolded = config.isSideNavFolded
let isHomeActive = location.pathname.match(/^\/home$/) let isHomeActive = location.pathname.match(/^\/home$/)
let isStarredActive = location.pathname.match(/^\/starred$/) let isStarredActive = location.pathname.match(/^\/starred$/)
let storageList = storages.map((storage) => {
let storageList = data.storageMap.map((storage, key) => {
return <StorageItem return <StorageItem
key={storage.key} key={storage.key}
storage={storage} storage={storage}

View File

@@ -33,9 +33,16 @@ class TopBar extends React.Component {
} }
handleNewPostButtonClick (e) { handleNewPostButtonClick (e) {
let { storages, params, dispatch, location } = this.props let { data, params, dispatch, location } = this.props
let storage = _.find(storages, {key: params.storageKey}) let storage = data.storageMap.get(params.storageKey)
if (storage == null) storage = storages[0]
// Find first storage
if (storage == null) {
for (let kv of data.storageMap) {
storage = kv[1]
break
}
}
if (storage == null) throw new Error('No storage to create a note') if (storage == null) throw new Error('No storage to create a note')
let folder = _.find(storage.folders, {key: params.folderKey}) let folder = _.find(storage.folders, {key: params.folderKey})
if (folder == null) folder = storage.folders[0] if (folder == null) folder = storage.folders[0]

View File

@@ -24,23 +24,26 @@ class NewNoteModal extends React.Component {
handleMarkdownNoteButtonClick (e) { handleMarkdownNoteButtonClick (e) {
let { storage, folder, dispatch, location } = this.props let { storage, folder, dispatch, location } = this.props
dataApi dataApi
.createMarkdownNote(storage, folder, { .createNote(storage, {
type: 'MARKDOWN_NOTE',
folder: folder,
title: '', title: '',
content: '' content: ''
}) })
.then((note) => { .then((note) => {
dispatch({ dispatch({
type: 'CREATE_NOTE', type: 'UPDATE_NOTE',
note: note note: note
}) })
hashHistory.push({ hashHistory.push({
pathname: location.pathname, pathname: location.pathname,
query: {key: note.uniqueKey} query: {key: note.storage + '-' + note.key}
}) })
ee.emit('detail:focus') ee.emit('detail:focus')
this.props.close() this.props.close()
}) })
} }
handleMarkdownNoteButtonKeyDown (e) { handleMarkdownNoteButtonKeyDown (e) {
if (e.keyCode === 9) { if (e.keyCode === 9) {
e.preventDefault() e.preventDefault()
@@ -50,8 +53,11 @@ class NewNoteModal extends React.Component {
handleSnippetNoteButtonClick (e) { handleSnippetNoteButtonClick (e) {
let { storage, folder, dispatch, location } = this.props let { storage, folder, dispatch, location } = this.props
dataApi dataApi
.createSnippetNote(storage, folder, { .createNote(storage, {
type: 'SNIPPET_NOTE',
folder: folder,
title: '', title: '',
description: '', description: '',
snippets: [{ snippets: [{
@@ -62,12 +68,12 @@ class NewNoteModal extends React.Component {
}) })
.then((note) => { .then((note) => {
dispatch({ dispatch({
type: 'CREATE_NOTE', type: 'UPDATE_NOTE',
note: note note: note
}) })
hashHistory.push({ hashHistory.push({
pathname: location.pathname, pathname: location.pathname,
query: {key: note.uniqueKey} query: {key: note.storage + '-' + note.key}
}) })
ee.emit('detail:focus') ee.emit('detail:focus')
this.props.close() this.props.close()

View File

@@ -1,94 +1,270 @@
import { combineReducers, createStore } from 'redux' import { combineReducers, createStore } from 'redux'
import { routerReducer } from 'react-router-redux' import { routerReducer } from 'react-router-redux'
import ConfigManager from 'browser/main/lib/ConfigManager' import ConfigManager from 'browser/main/lib/ConfigManager'
import { Map, Set } from 'browser/lib/Mutable'
import _ from 'lodash'
function storages (state = [], action) { function defaultDataMap () {
console.info('REDUX >> ', action) return {
switch (action.type) { storageMap: new Map(),
case 'INIT_ALL': noteMap: new Map(),
return action.storages starredSet: new Set(),
case 'ADD_STORAGE': storeageNoteMap: new Map(),
{ folderNoteMap: new Map(),
let storages = state.slice() tagNoteMap: new Map()
storages.push(action.storage)
return storages
} }
case 'ADD_FOLDER':
case 'REMOVE_FOLDER':
case 'UPDATE_STORAGE':
case 'RENAME_STORAGE':
{
let storages = state.slice()
storages = storages
.filter((storage) => storage.key !== action.storage.key)
storages.push(action.storage)
return storages
}
case 'REMOVE_STORAGE':
{
let storages = state.slice()
storages = storages
.filter((storage) => storage.key !== action.key)
return storages
}
}
return state
} }
function notes (state = [], action) { function data (state = defaultDataMap(), action) {
switch (action.type) { switch (action.type) {
case 'INIT_ALL': case 'INIT_ALL':
return action.notes state = defaultDataMap()
case 'ADD_STORAGE':
{
let notes = state.concat(action.notes)
return notes
}
case 'REMOVE_STORAGE':
{
let notes = state.slice()
notes = notes
.filter((note) => note.storage !== action.key)
return notes action.storages.forEach((storage) => {
} state.storageMap.set(storage.key, storage)
case 'REMOVE_FOLDER': })
{
let notes = state.slice()
notes = notes
.filter((note) => note.storage !== action.storage.key || note.folder !== action.key)
return notes action.notes.forEach((note) => {
let uniqueKey = note.storage + '-' + note.key
let folderKey = note.storage + '-' + note.folder
state.noteMap.set(uniqueKey, note)
if (note.isStarred) {
state.starredSet.add(uniqueKey)
} }
case 'CREATE_NOTE':
{ let storageNoteList = state.storeageNoteMap.get(note.storage)
let notes = state.slice() if (storageNoteList == null) {
notes.push(action.note) storageNoteList = new Set(storageNoteList)
return notes state.storeageNoteMap.set(note.storage, storageNoteList)
} }
storageNoteList.add(uniqueKey)
let folderNoteList = state.folderNoteMap.get(folderKey)
if (folderNoteList == null) {
folderNoteList = new Set(folderNoteList)
state.folderNoteMap.set(folderKey, folderNoteList)
}
folderNoteList.add(uniqueKey)
note.tags.forEach((tag) => {
let tagNoteList = state.tagNoteMap.get(tag)
if (tagNoteList == null) {
tagNoteList = new Set(tagNoteList)
state.tagNoteMap.set(tag, tagNoteList)
}
tagNoteList.add(uniqueKey)
})
})
return state
case 'UPDATE_NOTE': case 'UPDATE_NOTE':
{ {
let notes = state.slice() let note = action.note
notes = notes.filter((note) => note.key !== action.note.key || note.folder !== action.note.folder || note.storage !== action.note.storage) let uniqueKey = note.storage + '-' + note.key
notes.push(action.note) let folderKey = note.storage + '-' + note.folder
return notes let oldNote = state.noteMap.get(uniqueKey)
state = Object.assign({}, state)
state.noteMap = new Map(state.noteMap)
state.noteMap.set(uniqueKey, note)
if (oldNote == null || oldNote.isStarred !== note.isStarred) {
state.starredSet = new Set(state.starredSet)
if (note.isStarred) {
state.starredSet.add(uniqueKey)
} else {
state.starredSet.delete(uniqueKey)
}
}
// Update storageNoteMap if oldNote doesn't exist
if (oldNote == null) {
state.storeageNoteMap = new Map(state.storeageNoteMap)
let noteSet = state.storeageNoteMap.get(note.storage)
noteSet = new Set(noteSet)
noteSet.add(uniqueKey)
state.folderNoteMap.set(folderKey, noteSet)
}
// Update foldermap if folder changed or post created
if (oldNote == null || oldNote.folder !== note.folder) {
state.folderNoteMap = new Map(state.folderNoteMap)
let folderNoteList = state.folderNoteMap.get(folderKey)
folderNoteList = new Set(folderNoteList)
folderNoteList.add(uniqueKey)
state.folderNoteMap.set(folderKey, folderNoteList)
if (oldNote != null) {
let oldFolderKey = oldNote.storage + '-' + oldNote.folder
let oldFolderNoteList = state.folderNoteMap.get(oldFolderKey)
oldFolderNoteList = new Set(oldFolderNoteList)
oldFolderNoteList.delete(uniqueKey)
state.folderNoteMap.set(oldFolderKey, oldFolderNoteList)
}
}
if (oldNote != null) {
let discardedTags = _.difference(oldNote.tags, note.tags)
let addedTags = _.difference(note.tags, oldNote.tags)
if (discardedTags.length + addedTags.length > 0) {
state.tagNoteMap = new Map(state.tagNoteMap)
discardedTags.forEach((tag) => {
let tagNoteList = state.tagNoteMap.get(tag)
if (tagNoteList != null) {
tagNoteList = new Set(tagNoteList)
tagNoteList.delete(uniqueKey)
state.tagNoteMap.set(tag, tagNoteList)
}
})
addedTags.forEach((tag) => {
let tagNoteList = state.tagNoteMap.get(tag)
tagNoteList = new Set(tagNoteList)
tagNoteList.add(uniqueKey)
state.tagNoteMap.set(tag, tagNoteList)
})
}
} else {
state.tagNoteMap = new Map(state.tagNoteMap)
note.tags.forEach((tag) => {
let tagNoteList = state.tagNoteMap.get(tag)
if (tagNoteList == null) {
tagNoteList = new Set(tagNoteList)
state.tagNoteMap.set(tag, tagNoteList)
}
tagNoteList.add(uniqueKey)
})
}
return state
} }
case 'MOVE_NOTE': case 'MOVE_NOTE':
{ {
let notes = state.slice() let originNote = action.originNote
notes = notes.filter((note) => note.key !== action.note.key || note.folder !== action.note.folder || note.storage !== action.note.storage) let originKey = originNote.storage + '-' + originNote.key
notes.push(action.newNote) let note = action.note
return notes let uniqueKey = note.storage + '-' + note.key
let folderKey = note.storage + '-' + note.folder
let oldNote = state.noteMap.get(uniqueKey)
state = Object.assign({}, state)
state.noteMap = new Map(state.noteMap)
state.noteMap.delete(originKey)
state.noteMap.set(uniqueKey, note)
// If storage chanced, origin key must be discarded
if (originKey !== uniqueKey) {
console.log('diffrent storage')
// From isStarred
if (originNote.isStarred) {
state.starredSet = new Set(state.starredSet)
state.starredSet.delete(originKey)
} }
case 'REMOVE_NOTE':
// From storageNoteMap
state.storeageNoteMap = new Map(state.storeageNoteMap)
let noteSet = state.storeageNoteMap.get(originNote.storage)
noteSet = new Set(noteSet)
noteSet.delete(originKey)
state.storeageNoteMap.set(originNote.storage, noteSet)
// From folderNoteMap
state.folderNoteMap = new Map(state.folderNoteMap)
let originFolderKey = originNote.storage + '-' + originNote.folder
let originFolderList = state.folderNoteMap.get(originFolderKey)
originFolderList = new Set(originFolderList)
originFolderList.delete(originKey)
state.folderNoteMap.set(originFolderKey, originFolderList)
// From tagMap
if (originNote.tags.length > 0) {
state.tagNoteMap = new Map(state.tagNoteMap)
originNote.tags.forEach((tag) => {
let noteSet = state.tagNoteMap.get(tag)
noteSet = new Set(noteSet)
noteSet.delete(originKey)
state.tagNoteMap.set(tag, noteSet)
})
}
}
if (oldNote == null || oldNote.isStarred !== note.isStarred) {
state.starredSet = new Set(state.starredSet)
if (note.isStarred) {
state.starredSet.add(uniqueKey)
} else {
state.starredSet.delete(uniqueKey)
}
}
// Update storageNoteMap if oldNote doesn't exist
if (oldNote == null) {
state.storeageNoteMap = new Map(state.storeageNoteMap)
let noteSet = state.storeageNoteMap.get(note.storage)
noteSet = new Set(noteSet)
noteSet.add(uniqueKey)
state.folderNoteMap.set(folderKey, noteSet)
}
// Update foldermap if folder changed or post created
if (oldNote == null || oldNote.folder !== note.folder) {
state.folderNoteMap = new Map(state.folderNoteMap)
let folderNoteList = state.folderNoteMap.get(folderKey)
folderNoteList = new Set(folderNoteList)
folderNoteList.add(uniqueKey)
state.folderNoteMap.set(folderKey, folderNoteList)
if (oldNote != null) {
let oldFolderKey = oldNote.storage + '-' + oldNote.folder
let oldFolderNoteList = state.folderNoteMap.get(oldFolderKey)
oldFolderNoteList = new Set(oldFolderNoteList)
oldFolderNoteList.delete(uniqueKey)
state.folderNoteMap.set(oldFolderKey, oldFolderNoteList)
}
}
// Remove from old folder map
if (oldNote != null) {
let discardedTags = _.difference(oldNote.tags, note.tags)
let addedTags = _.difference(note.tags, oldNote.tags)
if (discardedTags.length + addedTags.length > 0) {
state.tagNoteMap = new Map(state.tagNoteMap)
discardedTags.forEach((tag) => {
let tagNoteList = state.tagNoteMap.get(tag)
if (tagNoteList != null) {
tagNoteList = new Set(tagNoteList)
tagNoteList.delete(uniqueKey)
state.tagNoteMap.set(tag, tagNoteList)
}
})
addedTags.forEach((tag) => {
let tagNoteList = state.tagNoteMap.get(tag)
tagNoteList = new Set(tagNoteList)
tagNoteList.add(uniqueKey)
state.tagNoteMap.set(tag, tagNoteList)
})
}
} else {
state.tagNoteMap = new Map(state.tagNoteMap)
note.tags.forEach((tag) => {
let tagNoteList = state.tagNoteMap.get(tag)
if (tagNoteList == null) {
tagNoteList = new Set(tagNoteList)
state.tagNoteMap.set(tag, tagNoteList)
}
tagNoteList.add(uniqueKey)
})
}
return state
}
case 'DELETE_NOTE':
{ {
let notes = state.slice()
notes = notes.filter((note) => note.key !== action.note.key || note.folder !== action.note.folder || note.storage !== action.note.storage) return state
return notes
} }
} }
return state return state
@@ -116,8 +292,7 @@ function config (state = defaultConfig, action) {
} }
let reducer = combineReducers({ let reducer = combineReducers({
storages, data,
notes,
config, config,
routing: routerReducer routing: routerReducer
}) })