this.handleNoteClick(note.uniqueKey)(e)}
+ key={note.storage + '-' + note.key}
+ onClick={(e) => this.handleNoteClick(note.storage + '-' + note.key)(e)}
>
diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js
index 37bf994a..3e541413 100644
--- a/browser/main/SideNav/index.js
+++ b/browser/main/SideNav/index.js
@@ -36,12 +36,13 @@ class SideNav extends React.Component {
}
render () {
- let { storages, location, config } = this.props
+ let { data, location, config } = this.props
let isFolded = config.isSideNavFolded
let isHomeActive = location.pathname.match(/^\/home$/)
let isStarredActive = location.pathname.match(/^\/starred$/)
- let storageList = storages.map((storage) => {
+
+ let storageList = data.storageMap.map((storage, key) => {
return {
dispatch({
- type: 'CREATE_NOTE',
+ type: 'UPDATE_NOTE',
note: note
})
hashHistory.push({
pathname: location.pathname,
- query: {key: note.uniqueKey}
+ query: {key: note.storage + '-' + note.key}
})
ee.emit('detail:focus')
this.props.close()
})
}
+
handleMarkdownNoteButtonKeyDown (e) {
if (e.keyCode === 9) {
e.preventDefault()
@@ -50,8 +53,11 @@ class NewNoteModal extends React.Component {
handleSnippetNoteButtonClick (e) {
let { storage, folder, dispatch, location } = this.props
+
dataApi
- .createSnippetNote(storage, folder, {
+ .createNote(storage, {
+ type: 'SNIPPET_NOTE',
+ folder: folder,
title: '',
description: '',
snippets: [{
@@ -62,12 +68,12 @@ class NewNoteModal extends React.Component {
})
.then((note) => {
dispatch({
- type: 'CREATE_NOTE',
+ type: 'UPDATE_NOTE',
note: note
})
hashHistory.push({
pathname: location.pathname,
- query: {key: note.uniqueKey}
+ query: {key: note.storage + '-' + note.key}
})
ee.emit('detail:focus')
this.props.close()
diff --git a/browser/main/store.js b/browser/main/store.js
index b1c2e68b..b93a64d8 100644
--- a/browser/main/store.js
+++ b/browser/main/store.js
@@ -1,94 +1,270 @@
import { combineReducers, createStore } from 'redux'
import { routerReducer } from 'react-router-redux'
import ConfigManager from 'browser/main/lib/ConfigManager'
+import { Map, Set } from 'browser/lib/Mutable'
+import _ from 'lodash'
-function storages (state = [], action) {
- console.info('REDUX >> ', action)
- switch (action.type) {
- case 'INIT_ALL':
- return action.storages
- case 'ADD_STORAGE':
- {
- let storages = state.slice()
-
- 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
- }
+function defaultDataMap () {
+ return {
+ storageMap: new Map(),
+ noteMap: new Map(),
+ starredSet: new Set(),
+ storeageNoteMap: new Map(),
+ folderNoteMap: new Map(),
+ tagNoteMap: new Map()
}
- return state
}
-function notes (state = [], action) {
+function data (state = defaultDataMap(), action) {
switch (action.type) {
case 'INIT_ALL':
- return action.notes
- 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)
+ state = defaultDataMap()
- return notes
- }
- case 'REMOVE_FOLDER':
- {
- let notes = state.slice()
- notes = notes
- .filter((note) => note.storage !== action.storage.key || note.folder !== action.key)
+ action.storages.forEach((storage) => {
+ state.storageMap.set(storage.key, storage)
+ })
- return notes
- }
- case 'CREATE_NOTE':
- {
- let notes = state.slice()
- notes.push(action.note)
- 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)
+ }
+
+ let storageNoteList = state.storeageNoteMap.get(note.storage)
+ if (storageNoteList == null) {
+ storageNoteList = new Set(storageNoteList)
+ 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':
{
- let notes = state.slice()
- notes = notes.filter((note) => note.key !== action.note.key || note.folder !== action.note.folder || note.storage !== action.note.storage)
- notes.push(action.note)
- return notes
+ let note = action.note
+ 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.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':
{
- let notes = state.slice()
- notes = notes.filter((note) => note.key !== action.note.key || note.folder !== action.note.folder || note.storage !== action.note.storage)
- notes.push(action.newNote)
- return notes
+ let originNote = action.originNote
+ let originKey = originNote.storage + '-' + originNote.key
+ let note = action.note
+ 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)
+ }
+
+ // 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 'REMOVE_NOTE':
+ 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 notes
+
+ return state
}
}
return state
@@ -116,8 +292,7 @@ function config (state = defaultConfig, action) {
}
let reducer = combineReducers({
- storages,
- notes,
+ data,
config,
routing: routerReducer
})