1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-26 16:11:45 +00:00

Merge branch 'master' into fix-search-issue-unicode

# Conflicts:
#	browser/main/TopBar/index.js
#	yarn.lock
This commit is contained in:
AWolf81
2019-05-29 07:42:20 +02:00
35 changed files with 856 additions and 278 deletions

View File

@@ -1015,15 +1015,19 @@ export default class MarkdownPreview extends React.Component {
e.preventDefault()
e.stopPropagation()
const href = e.target.getAttribute('href')
const linkHash = href.split('/').pop()
const rawHref = e.target.getAttribute('href')
const parser = document.createElement('a')
parser.href = e.target.getAttribute('href')
const { href, hash } = parser
const linkHash = hash === '' ? rawHref : hash // needed because we're having special link formats that are removed by parser e.g. :line:10
if (!href) return
if (!rawHref) return // not checked href because parser will create file://... string for [empty link]()
const regexNoteInternalLink = /main.html#(.+)/
if (regexNoteInternalLink.test(linkHash)) {
const targetId = mdurl.encode(linkHash.match(regexNoteInternalLink)[1])
const targetElement = this.refs.root.contentWindow.document.getElementById(
const regexNoteInternalLink = /.*[main.\w]*.html#/
if (regexNoteInternalLink.test(href)) {
const targetId = mdurl.encode(linkHash)
const targetElement = this.refs.root.contentWindow.document.querySelector(
targetId
)

View File

@@ -1,5 +1,5 @@
import CSSModules from 'react-css-modules'
export default function (component, styles) {
return CSSModules(component, styles, {errorWhenNotFound: false})
return CSSModules(component, styles, {handleNotFoundStyleName: 'log'})
}

View File

@@ -1,7 +1,8 @@
import { hashHistory } from 'react-router'
import dataApi from 'browser/main/lib/dataApi'
import ee from 'browser/main/lib/eventEmitter'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
import queryString from 'query-string'
import { push } from 'connected-react-router'
export function createMarkdownNote (storage, folder, dispatch, location, params, config) {
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_MARKDOWN')
@@ -28,10 +29,10 @@ export function createMarkdownNote (storage, folder, dispatch, location, params,
note: note
})
hashHistory.push({
dispatch(push({
pathname: location.pathname,
query: { key: noteHash }
})
search: queryString.stringify({ key: noteHash })
}))
ee.emit('list:jump', noteHash)
ee.emit('detail:focus')
})
@@ -70,10 +71,10 @@ export function createSnippetNote (storage, folder, dispatch, location, params,
type: 'UPDATE_NOTE',
note: note
})
hashHistory.push({
dispatch(push({
pathname: location.pathname,
query: { key: noteHash }
})
search: queryString.stringify({ key: noteHash })
}))
ee.emit('list:jump', noteHash)
ee.emit('detail:focus')
})

View File

@@ -9,7 +9,6 @@ import StarButton from './StarButton'
import TagSelect from './TagSelect'
import FolderSelect from './FolderSelect'
import dataApi from 'browser/main/lib/dataApi'
import { hashHistory } from 'react-router'
import ee from 'browser/main/lib/eventEmitter'
import markdown from 'browser/lib/markdownTextHelper'
import StatusBar from '../StatusBar'
@@ -30,6 +29,8 @@ import { getTodoPercentageOfCompleted } from 'browser/lib/getTodoStatus'
import striptags from 'striptags'
import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote'
import markdownToc from 'browser/lib/markdown-toc-generator'
import queryString from 'query-string'
import { replace } from 'connected-react-router'
class MarkdownNoteDetail extends React.Component {
constructor (props) {
@@ -147,6 +148,7 @@ class MarkdownNoteDetail extends React.Component {
}
handleFolderChange (e) {
const { dispatch } = this.props
const { note } = this.state
const value = this.refs.folder.value
const splitted = value.split('-')
@@ -166,12 +168,12 @@ class MarkdownNoteDetail extends React.Component {
originNote: note,
note: newNote
})
hashHistory.replace({
dispatch(replace({
pathname: location.pathname,
query: {
search: queryString.stringify({
key: newNote.key
}
})
})
}))
this.setState({
isMovingNote: false
})
@@ -498,7 +500,7 @@ class MarkdownNoteDetail extends React.Component {
<InfoPanel
storageName={currentOption.storage.name}
folderName={currentOption.folder.name}
noteLink={`[${note.title}](:note:${location.query.key})`}
noteLink={`[${note.title}](:note:${queryString.parse(location.search).key})`}
updatedAt={formatDate(note.updatedAt)}
createdAt={formatDate(note.createdAt)}
exportAsMd={this.exportAsMd}

View File

@@ -80,4 +80,12 @@ body[data-theme="monokai"]
body[data-theme="dracula"]
.root
border-left 1px solid $ui-dracula-borderColor
background-color $ui-dracula-noteDetail-backgroundColor
background-color $ui-dracula-noteDetail-backgroundColor
div
> button, div
-webkit-user-drag none
user-select none
> img, span
-webkit-user-drag none
user-select none

View File

@@ -8,7 +8,6 @@ import StarButton from './StarButton'
import TagSelect from './TagSelect'
import FolderSelect from './FolderSelect'
import dataApi from 'browser/main/lib/dataApi'
import {hashHistory} from 'react-router'
import ee from 'browser/main/lib/eventEmitter'
import CodeMirror from 'codemirror'
import 'codemirror-mode-elixir'
@@ -18,7 +17,6 @@ import context from 'browser/lib/context'
import ConfigManager from 'browser/main/lib/ConfigManager'
import _ from 'lodash'
import {findNoteTitle} from 'browser/lib/findNoteTitle'
import convertModeName from 'browser/lib/convertModeName'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
import FullscreenButton from './FullscreenButton'
import TrashButton from './TrashButton'
@@ -31,6 +29,8 @@ import { formatDate } from 'browser/lib/date-formatter'
import i18n from 'browser/lib/i18n'
import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote'
import markdownToc from 'browser/lib/markdown-toc-generator'
import queryString from 'query-string'
import { replace } from 'connected-react-router'
const electron = require('electron')
const { remote } = electron
@@ -166,12 +166,12 @@ class SnippetNoteDetail extends React.Component {
originNote: note,
note: newNote
})
hashHistory.replace({
dispatch(replace({
pathname: location.pathname,
query: {
search: queryString.stringify({
key: newNote.key
}
})
})
}))
this.setState({
isMovingNote: false
})
@@ -814,7 +814,7 @@ class SnippetNoteDetail extends React.Component {
<InfoPanel
storageName={currentOption.storage.name}
folderName={currentOption.folder.name}
noteLink={`[${note.title}](:note:${location.query.key})`}
noteLink={`[${note.title}](:note:${queryString.parse(location.search).key})`}
updatedAt={formatDate(note.updatedAt)}
createdAt={formatDate(note.createdAt)}
exportAsMd={this.showWarning}

View File

@@ -10,6 +10,7 @@ import StatusBar from '../StatusBar'
import i18n from 'browser/lib/i18n'
import debounceRender from 'react-debounce-render'
import searchFromNotes from 'browser/lib/search'
import queryString from 'query-string'
const OSX = global.process.platform === 'darwin'
@@ -36,11 +37,11 @@ class Detail extends React.Component {
}
render () {
const { location, data, params, config } = this.props
const { location, data, match: { params }, config } = this.props
const noteKey = location.search !== '' && queryString.parse(location.search).key
let note = null
if (location.query.key != null) {
const noteKey = location.query.key
if (location.search !== '') {
const allNotes = data.noteMap.map(note => note)
const trashedNotes = data.trashedSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
let displayedNotes = allNotes

View File

@@ -0,0 +1,16 @@
import React from 'react'
import { createDevTools } from 'redux-devtools'
import LogMonitor from 'redux-devtools-log-monitor'
import DockMonitor from 'redux-devtools-dock-monitor'
const DevTools = createDevTools(
<DockMonitor
toggleVisibilityKey='ctrl-h'
changePositionKey='ctrl-q'
defaultIsVisible={false}
>
<LogMonitor theme='tomorrow' />
</DockMonitor>
)
export default DevTools

View File

@@ -0,0 +1,8 @@
/* eslint-disable no-undef */
if (process.env.NODE_ENV === 'production') {
// eslint-disable-next-line global-require
module.exports = require('./index.prod').default
} else {
// eslint-disable-next-line global-require
module.exports = require('./index.dev').default
}

View File

@@ -0,0 +1,6 @@
import React from 'react'
const DevTools = () => <div />
DevTools.instrument = () => {}
export default DevTools

View File

@@ -12,11 +12,11 @@ import _ from 'lodash'
import ConfigManager from 'browser/main/lib/ConfigManager'
import mobileAnalytics from 'browser/main/lib/AwsMobileAnalyticsConfig'
import eventEmitter from 'browser/main/lib/eventEmitter'
import { hashHistory } from 'react-router'
import store from 'browser/main/store'
import { store } from 'browser/main/store'
import i18n from 'browser/lib/i18n'
import { getLocales } from 'browser/lib/Languages'
import applyShortcuts from 'browser/main/lib/shortcutManager'
import { push } from 'connected-react-router'
const path = require('path')
const electron = require('electron')
const { remote } = electron
@@ -132,7 +132,7 @@ class Main extends React.Component {
.then(() => data.storage)
})
.then(storage => {
hashHistory.push('/storages/' + storage.key)
store.dispatch(push('/storages/' + storage.key))
})
.catch(err => {
throw err
@@ -311,7 +311,7 @@ class Main extends React.Component {
onMouseUp={e => this.handleMouseUp(e)}
>
<SideNav
{..._.pick(this.props, ['dispatch', 'data', 'config', 'params', 'location'])}
{..._.pick(this.props, ['dispatch', 'data', 'config', 'match', 'location'])}
width={this.state.navWidth}
/>
{!config.isSideNavFolded &&
@@ -341,7 +341,7 @@ class Main extends React.Component {
'dispatch',
'config',
'data',
'params',
'match',
'location'
])}
/>
@@ -351,7 +351,7 @@ class Main extends React.Component {
'dispatch',
'data',
'config',
'params',
'match',
'location'
])}
/>
@@ -373,7 +373,7 @@ class Main extends React.Component {
'dispatch',
'data',
'config',
'params',
'match',
'location'
])}
ignorePreviewPointerEvents={this.state.isRightSliderFocused}

View File

@@ -21,23 +21,20 @@ class NewNoteButton extends React.Component {
this.state = {
}
this.newNoteHandler = () => {
this.handleNewNoteButtonClick()
}
this.handleNewNoteButtonClick = this.handleNewNoteButtonClick.bind(this)
}
componentDidMount () {
eventEmitter.on('top:new-note', this.newNoteHandler)
eventEmitter.on('top:new-note', this.handleNewNoteButtonClick)
}
componentWillUnmount () {
eventEmitter.off('top:new-note', this.newNoteHandler)
eventEmitter.off('top:new-note', this.handleNewNoteButtonClick)
}
handleNewNoteButtonClick (e) {
const { location, params, dispatch, config } = this.props
const { location, dispatch, match: { params }, config } = this.props
const { storage, folder } = this.resolveTargetFolder()
if (config.ui.defaultNote === 'MARKDOWN_NOTE') {
createMarkdownNote(storage.key, folder.key, dispatch, location, params, config)
} else if (config.ui.defaultNote === 'SNIPPET_NOTE') {
@@ -55,9 +52,8 @@ class NewNoteButton extends React.Component {
}
resolveTargetFolder () {
const { data, params } = this.props
const { data, match: { params } } = this.props
let storage = data.storageMap.get(params.storageKey)
// Find first storage
if (storage == null) {
for (const kv of data.storageMap) {
@@ -93,7 +89,7 @@ class NewNoteButton extends React.Component {
>
<div styleName='control'>
<button styleName='control-newNoteButton'
onClick={(e) => this.handleNewNoteButtonClick(e)}>
onClick={this.handleNewNoteButtonClick}>
<img styleName='iconTag' src='../resources/icon/icon-newnote.svg' />
<span styleName='control-newNoteButton-tooltip'>
{i18n.__('Make a note')} {OSX ? '⌘' : i18n.__('Ctrl')} + N

View File

@@ -14,13 +14,14 @@ import NoteItemSimple from 'browser/components/NoteItemSimple'
import searchFromNotes from 'browser/lib/search'
import fs from 'fs'
import path from 'path'
import { hashHistory } from 'react-router'
import { push, replace } from 'connected-react-router'
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'
import context from 'browser/lib/context'
import queryString from 'query-string'
const { remote } = require('electron')
const { dialog } = remote
@@ -145,15 +146,15 @@ class NoteList extends React.Component {
}
componentDidUpdate (prevProps) {
const { location } = this.props
const { dispatch, location } = this.props
const { selectedNoteKeys } = this.state
const visibleNoteKeys = this.notes.map(note => note.key)
const note = this.notes[0]
const prevKey = prevProps.location.query.key
const visibleNoteKeys = this.notes && this.notes.map(note => note.key)
const note = this.notes && this.notes[0]
const key = location.search && queryString.parse(location.search).key
const prevKey = prevProps.location.search && queryString.parse(prevProps.location.search).key
const noteKey = visibleNoteKeys.includes(prevKey) ? prevKey : note && note.key
if (note && location.query.key == null) {
const { router } = this.context
if (note && location.search === '') {
if (!location.pathname.match(/\/searched/)) this.contextNotes = this.getContextNotes()
// A visible note is an active note
@@ -163,17 +164,17 @@ class NoteList extends React.Component {
ee.emit('list:moved')
}
router.replace({
dispatch(replace({ // was passed with context - we can use connected router here
pathname: location.pathname,
query: {
search: queryString.stringify({
key: noteKey
}
})
})
}))
return
}
// Auto scroll
if (_.isString(location.query.key) && prevProps.location.query.key === location.query.key) {
if (_.isString(key) && prevKey === key) {
const targetIndex = this.getTargetIndex()
if (targetIndex > -1) {
const list = this.refs.list
@@ -194,18 +195,18 @@ class NoteList extends React.Component {
}
focusNote (selectedNoteKeys, noteKey, pathname) {
const { router } = this.context
const { dispatch } = this.props
this.setState({
selectedNoteKeys
})
router.push({
dispatch(push({
pathname,
query: {
search: queryString.stringify({
key: noteKey
}
})
})
}))
}
getNoteKeyFromTargetIndex (targetIndex) {
@@ -348,8 +349,7 @@ class NoteList extends React.Component {
}
getNotes () {
const { data, params, location } = this.props
const { data, match: { params }, location } = this.props
if (location.pathname.match(/\/home/) || location.pathname.match(/alltags/)) {
const allNotes = data.noteMap.map((note) => note)
this.contextNotes = allNotes
@@ -390,7 +390,7 @@ class NoteList extends React.Component {
// get notes in the current folder
getContextNotes () {
const { data, params } = this.props
const { data, match: { params } } = this.props
const storageKey = params.storageKey
const folderKey = params.folderKey
const storage = data.storageMap.get(storageKey)
@@ -430,8 +430,7 @@ class NoteList extends React.Component {
}
handleNoteClick (e, uniqueKey) {
const { router } = this.context
const { location } = this.props
const { dispatch, location } = this.props
let { selectedNoteKeys, prevShiftNoteIndex } = this.state
const { ctrlKeyDown, shiftKeyDown } = this.state
const hasSelectedNoteKey = selectedNoteKeys.length > 0
@@ -482,16 +481,16 @@ class NoteList extends React.Component {
prevShiftNoteIndex
})
router.push({
dispatch(push({
pathname: location.pathname,
query: {
search: queryString.stringify({
key: uniqueKey
}
})
})
}))
}
handleSortByChange (e) {
const { dispatch, params: { folderKey } } = this.props
const { dispatch, match: { params: { folderKey } } } = this.props
const config = {
[folderKey]: { sortBy: e.target.value }
@@ -764,10 +763,10 @@ class NoteList extends React.Component {
selectedNoteKeys: [note.key]
})
hashHistory.push({
dispatch(push({
pathname: location.pathname,
query: {key: note.key}
})
search: queryString.stringify({key: note.key})
}))
})
}
@@ -777,13 +776,13 @@ class NoteList extends React.Component {
}
navigate (sender, pathname) {
const { router } = this.context
router.push({
const { dispatch } = this.props
dispatch(push({
pathname,
query: {
search: queryString.stringify({
// key: noteKey
}
})
})
}))
}
save (note) {
@@ -947,10 +946,10 @@ class NoteList extends React.Component {
type: 'UPDATE_NOTE',
note: note
})
hashHistory.push({
dispatch(push({
pathname: location.pathname,
query: {key: getNoteKey(note)}
})
search: queryString.stringify({key: getNoteKey(note)})
}))
})
})
})
@@ -960,14 +959,15 @@ class NoteList extends React.Component {
getTargetIndex () {
const { location } = this.props
const key = queryString.parse(location.search).key
const targetIndex = _.findIndex(this.notes, (note) => {
return getNoteKey(note) === location.query.key
return getNoteKey(note) === key
})
return targetIndex
}
resolveTargetFolder () {
const { data, params } = this.props
const { data, match: { params } } = this.props
let storage = data.storageMap.get(params.storageKey)
// Find first storage
@@ -1015,7 +1015,7 @@ class NoteList extends React.Component {
}
render () {
const { location, config, params: { folderKey } } = this.props
const { location, config, match: { params: { folderKey } } } = this.props
let { notes } = this.props
const { selectedNoteKeys } = this.state
const sortBy = _.get(config, [folderKey, 'sortBy'], config.sortBy.default)

View File

@@ -2,7 +2,6 @@ import PropTypes from 'prop-types'
import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './StorageItem.styl'
import { hashHistory } from 'react-router'
import modal from 'browser/main/lib/modal'
import CreateFolderModal from 'browser/main/modals/CreateFolderModal'
import RenameFolderModal from 'browser/main/modals/RenameFolderModal'
@@ -12,6 +11,7 @@ import _ from 'lodash'
import { SortableElement } from 'react-sortable-hoc'
import i18n from 'browser/lib/i18n'
import context from 'browser/lib/context'
import { push } from 'connected-react-router'
const { remote } = require('electron')
const { dialog } = remote
@@ -134,14 +134,14 @@ class StorageItem extends React.Component {
}
handleHeaderInfoClick (e) {
const { storage } = this.props
hashHistory.push('/storages/' + storage.key)
const { storage, dispatch } = this.props
dispatch(push('/storages/' + storage.key))
}
handleFolderButtonClick (folderKey) {
return (e) => {
const { storage } = this.props
hashHistory.push('/storages/' + storage.key + '/folders/' + folderKey)
const { storage, dispatch } = this.props
dispatch(push('/storages/' + storage.key + '/folders/' + folderKey))
}
}

View File

@@ -1,5 +1,6 @@
import PropTypes from 'prop-types'
import React from 'react'
import { push } from 'connected-react-router'
import CSSModules from 'browser/lib/CSSModules'
import dataApi from 'browser/main/lib/dataApi'
import styles from './SideNav.styl'
@@ -62,7 +63,7 @@ class SideNav extends React.Component {
})
if (selectedButton === 0) {
const { data, dispatch, location, params } = this.props
const { data, dispatch, location, match: { params } } = this.props
const notes = data.noteMap
.map(note => note)
@@ -92,7 +93,7 @@ class SideNav extends React.Component {
if (index !== -1) {
tags.splice(index, 1)
this.context.router.push(`/tags/${tags.map(tag => encodeURIComponent(tag)).join(' ')}`)
dispatch(push(`/tags/${tags.map(tag => encodeURIComponent(tag)).join(' ')}`))
}
}
})
@@ -104,13 +105,13 @@ class SideNav extends React.Component {
}
handleHomeButtonClick (e) {
const { router } = this.context
router.push('/home')
const { dispatch } = this.props
dispatch(push('/home'))
}
handleStarredButtonClick (e) {
const { router } = this.context
router.push('/starred')
const { dispatch } = this.props
dispatch(push('/starred'))
}
handleTagContextMenu (e, tag) {
@@ -190,18 +191,18 @@ class SideNav extends React.Component {
}
handleTrashedButtonClick (e) {
const { router } = this.context
router.push('/trashed')
const { dispatch } = this.props
dispatch(push('/trashed'))
}
handleSwitchFoldersButtonClick () {
const { router } = this.context
router.push('/home')
const { dispatch } = this.props
dispatch(push('/home'))
}
handleSwitchTagsButtonClick () {
const { router } = this.context
router.push('/alltags')
const { dispatch } = this.props
dispatch(push('/alltags'))
}
onSortEnd (storage) {
@@ -348,8 +349,8 @@ class SideNav extends React.Component {
}
handleClickTagListItem (name) {
const { router } = this.context
router.push(`/tags/${encodeURIComponent(name)}`)
const { dispatch } = this.props
dispatch(push(`/tags/${encodeURIComponent(name)}`))
}
handleSortTagsByChange (e) {
@@ -367,8 +368,7 @@ class SideNav extends React.Component {
}
handleClickNarrowToTag (tag) {
const { router } = this.context
const { location } = this.props
const { dispatch, location } = this.props
const listOfTags = this.getActiveTags(location.pathname)
const indexOfTag = listOfTags.indexOf(tag)
if (indexOfTag > -1) {
@@ -376,7 +376,7 @@ class SideNav extends React.Component {
} else {
listOfTags.push(tag)
}
router.push(`/tags/${encodeURIComponent(listOfTags.join(' '))}`)
dispatch(push(`/tags/${encodeURIComponent(listOfTags.join(' '))}`))
}
emptyTrash (entries) {

View File

@@ -8,6 +8,7 @@ import NewNoteButton from 'browser/main/NewNoteButton'
import i18n from 'browser/lib/i18n'
import debounce from 'lodash/debounce'
import CInput from 'react-composition-input'
import { push } from 'connected-react-router'
class TopBar extends React.Component {
constructor (props) {
@@ -19,6 +20,8 @@ class TopBar extends React.Component {
isSearching: false
}
const { dispatch } = this.props
this.focusSearchHandler = () => {
this.handleOnSearchFocus()
}
@@ -31,7 +34,7 @@ class TopBar extends React.Component {
this.handleSearchClearButton = this.handleSearchClearButton.bind(this)
this.debouncedUpdateKeyword = debounce((keyword) => {
this.context.router.push(`/searched/${encodeURIComponent(keyword)}`)
dispatch(push(`/searched/${encodeURIComponent(keyword)}`))
this.setState({
search: keyword
})
@@ -42,8 +45,8 @@ class TopBar extends React.Component {
}
componentDidMount () {
const { params } = this.props
const searchWord = params.searchword
const { match: { params } } = this.props
const searchWord = params && params.searchword
if (searchWord !== undefined) {
this.setState({
search: searchWord,
@@ -60,13 +63,13 @@ class TopBar extends React.Component {
}
handleSearchClearButton (e) {
const { router } = this.context
const { dispatch } = this.props
this.setState({
search: '',
isSearching: false
})
this.refs.search.childNodes[0].blur
router.push('/searched')
dispatch(push('/searched'))
e.preventDefault()
}
@@ -173,8 +176,8 @@ class TopBar extends React.Component {
'dispatch',
'data',
'config',
'params',
'location'
'location',
'match'
])}
/>}
</div>

View File

@@ -1,11 +1,13 @@
import { Provider } from 'react-redux'
import Main from './Main'
import store from './store'
import React from 'react'
import { store, history } from './store'
import React, { Fragment } from 'react'
import ReactDOM from 'react-dom'
require('!!style!css!stylus?sourceMap!./global.styl')
import { Router, Route, IndexRoute, IndexRedirect, hashHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
import { Route, Switch, Redirect } from 'react-router-dom'
import { ConnectedRouter } from 'connected-react-router'
import DevTools from './DevTools'
require('./lib/ipcClient')
require('../lib/customMeta')
import i18n from 'browser/lib/i18n'
@@ -77,7 +79,6 @@ document.addEventListener('click', function (e) {
})
const el = document.getElementById('content')
const history = syncHistoryWithStore(hashHistory, store)
function notify (...args) {
return new window.Notification(...args)
@@ -98,29 +99,24 @@ function updateApp () {
ReactDOM.render((
<Provider store={store}>
<Router history={history}>
<Route path='/' component={Main}>
<IndexRedirect to='/home' />
<Route path='home' />
<Route path='starred' />
<Route path='searched'>
<Route path=':searchword' />
</Route>
<Route path='trashed' />
<Route path='alltags' />
<Route path='tags'>
<IndexRedirect to='/alltags' />
<Route path=':tagname' />
</Route>
<Route path='storages'>
<IndexRedirect to='/home' />
<Route path=':storageKey'>
<IndexRoute />
<Route path='folders/:folderKey' />
</Route>
</Route>
</Route>
</Router>
<ConnectedRouter history={history}>
<Fragment>
<Switch>
<Redirect path='/' to='/home' exact />
<Route path='/(home|alltags|starred|trashed)' component={Main} />
<Route path='/searched' component={Main} exact />
<Route path='/searched/:searchword' component={Main} />
<Redirect path='/tags' to='/alltags' exact />
<Route path='/tags/:tagname' component={Main} />
{/* storages */}
<Redirect path='/storages' to='/home' exact />
<Route path='/storages/:storageKey' component={Main} exact />
<Route path='/storages/:storageKey/folders/:folderKey' component={Main} />
</Switch>
<DevTools />
</Fragment>
</ConnectedRouter>
</Provider>
), el, function () {
const loadingCover = document.getElementById('loadingCover')

View File

@@ -1,7 +1,7 @@
import React from 'react'
import { Provider } from 'react-redux'
import ReactDOM from 'react-dom'
import store from '../store'
import { store } from '../store'
class ModalBase extends React.Component {
constructor (props) {

View File

@@ -3,7 +3,7 @@ import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './CreateFolderModal.styl'
import dataApi from 'browser/main/lib/dataApi'
import store from 'browser/main/store'
import { store } from 'browser/main/store'
import consts from 'browser/lib/consts'
import ModalEscButton from 'browser/components/ModalEscButton'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'

View File

@@ -4,6 +4,7 @@ import styles from './NewNoteModal.styl'
import ModalEscButton from 'browser/components/ModalEscButton'
import i18n from 'browser/lib/i18n'
import { createMarkdownNote, createSnippetNote } from 'browser/lib/newNote'
import queryString from 'query-string'
class NewNoteModal extends React.Component {
constructor (props) {
@@ -21,7 +22,8 @@ class NewNoteModal extends React.Component {
}
handleMarkdownNoteButtonClick (e) {
const { storage, folder, dispatch, location, params, config } = this.props
const { storage, folder, dispatch, location, config } = this.props
const params = location.search !== '' && queryString.parse(location.search)
if (!this.lock) {
this.lock = true
createMarkdownNote(storage, folder, dispatch, location, params, config).then(() => {
@@ -38,7 +40,8 @@ class NewNoteModal extends React.Component {
}
handleSnippetNoteButtonClick (e) {
const { storage, folder, dispatch, location, params, config } = this.props
const { storage, folder, dispatch, location, config } = this.props
const params = location.search !== '' && queryString.parse(location.search)
if (!this.lock) {
this.lock = true
createSnippetNote(storage, folder, dispatch, location, params, config).then(() => {

View File

@@ -2,7 +2,7 @@ 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 { store } from 'browser/main/store'
import PropTypes from 'prop-types'
import _ from 'lodash'
import i18n from 'browser/lib/i18n'

View File

@@ -4,7 +4,7 @@ import CSSModules from 'browser/lib/CSSModules'
import ReactDOM from 'react-dom'
import styles from './FolderItem.styl'
import dataApi from 'browser/main/lib/dataApi'
import store from 'browser/main/store'
import { store } from 'browser/main/store'
import { SketchPicker } from 'react-color'
import { SortableElement, SortableHandle } from 'react-sortable-hoc'
import i18n from 'browser/lib/i18n'

View File

@@ -3,7 +3,7 @@ import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
import dataApi from 'browser/main/lib/dataApi'
import styles from './FolderList.styl'
import store from 'browser/main/store'
import { store } from 'browser/main/store'
import FolderItem from './FolderItem'
import { SortableContainer } from 'react-sortable-hoc'
import i18n from 'browser/lib/i18n'

View File

@@ -3,7 +3,7 @@ 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 { store } from 'browser/main/store'
import _ from 'lodash'
import i18n from 'browser/lib/i18n'

View File

@@ -2,7 +2,7 @@ import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './InfoTab.styl'
import ConfigManager from 'browser/main/lib/ConfigManager'
import store from 'browser/main/store'
import { store } from 'browser/main/store'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
import _ from 'lodash'
import i18n from 'browser/lib/i18n'

View File

@@ -4,7 +4,7 @@ import CSSModules from 'browser/lib/CSSModules'
import styles from './StorageItem.styl'
import consts from 'browser/lib/consts'
import dataApi from 'browser/main/lib/dataApi'
import store from 'browser/main/store'
import { store } from 'browser/main/store'
import FolderList from './FolderList'
import i18n from 'browser/lib/i18n'

View File

@@ -3,7 +3,7 @@ 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 { store } from 'browser/main/store'
import consts from 'browser/lib/consts'
import ReactCodeMirror from 'react-codemirror'
import CodeMirror from 'codemirror'

View File

@@ -3,7 +3,7 @@ import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './RenameFolderModal.styl'
import dataApi from 'browser/main/lib/dataApi'
import store from 'browser/main/store'
import { store } from 'browser/main/store'
import ModalEscButton from 'browser/components/ModalEscButton'
import i18n from 'browser/lib/i18n'

View File

@@ -1,8 +1,10 @@
import { combineReducers, createStore } from 'redux'
import { routerReducer } from 'react-router-redux'
import { combineReducers, createStore, compose, applyMiddleware } from 'redux'
import { connectRouter, routerMiddleware } from 'connected-react-router'
import { createHashHistory as createHistory } from 'history'
import ConfigManager from 'browser/main/lib/ConfigManager'
import { Map, Set } from 'browser/lib/Mutable'
import _ from 'lodash'
import DevTools from './DevTools'
function defaultDataMap () {
return {
@@ -465,13 +467,16 @@ function getOrInitItem (target, key) {
return results
}
const history = createHistory()
const reducer = combineReducers({
data,
config,
status,
routing: routerReducer
router: connectRouter(history)
})
const store = createStore(reducer)
const store = createStore(reducer, undefined, compose(
applyMiddleware(routerMiddleware(history)), DevTools.instrument()))
export default store
export { store, history }