import PropTypes from 'prop-types' import React from 'react' import ReactDOM from 'react-dom' import { connect, Provider } from 'react-redux' import _ from 'lodash' import store from './store' import CSSModules from 'browser/lib/CSSModules' import styles from './FinderMain.styl' import StorageSection from './StorageSection' import NoteList from './NoteList' import NoteDetail from './NoteDetail' import SideNavFilter from 'browser/components/SideNavFilter' import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig' require('!!style!css!stylus?sourceMap!../main/global.styl') require('../lib/customMeta') require('./ipcClient.js') const electron = require('electron') const { remote } = electron const { Menu } = remote function hideFinder () { const finderWindow = remote.getCurrentWindow() if (global.process.platform === 'win32') { finderWindow.blur() finderWindow.hide() } if (global.process.platform === 'darwin') { Menu.sendActionToFirstResponder('hide:') } remote.getCurrentWindow().hide() } require('!!style!css!stylus?sourceMap!../styles/finder/index.styl') class FinderMain extends React.Component { constructor (props) { super(props) this.state = { search: '', index: 0, filter: { includeSnippet: true, includeMarkdown: false, type: 'ALL', storage: null, folder: null } } this.focusHandler = (e) => this.handleWindowFocus(e) this.blurHandler = (e) => this.handleWindowBlur(e) } componentDidMount () { this.refs.search.focus() window.addEventListener('focus', this.focusHandler) window.addEventListener('blur', this.blurHandler) } componentWillUnmount () { window.removeEventListener('focus', this.focusHandler) window.removeEventListener('blur', this.blurHandler) } handleWindowFocus (e) { this.refs.search.focus() } handleWindowBlur (e) { this.setState({ search: '' }) } handleKeyDown (e) { this.refs.search.focus() if (e.keyCode === 9) { if (e.shiftKey) { this.refs.detail.selectPriorSnippet() } else { this.refs.detail.selectNextSnippet() } e.preventDefault() } if (e.keyCode === 38) { this.selectPrevious() e.preventDefault() } if (e.keyCode === 40) { this.selectNext() e.preventDefault() } if (e.keyCode === 13) { this.refs.detail.saveToClipboard() AwsMobileAnalyticsConfig.recordDynamicCustomEvent('COPY_FINDER') hideFinder() e.preventDefault() } if (e.keyCode === 27) { hideFinder() e.preventDefault() } if (e.keyCode === 91 || e.metaKey) { return } } handleSearchChange (e) { this.setState({ search: e.target.value, index: 0 }) } selectArticle (article) { this.setState({currentArticle: article}) } selectPrevious () { if (this.state.index > 0) { this.setState({ index: this.state.index - 1 }) } } selectNext () { if (this.state.index < this.noteCount - 1) { this.setState({ index: this.state.index + 1 }) } } handleOnlySnippetCheckboxChange (e) { const { filter } = this.state filter.includeSnippet = e.target.checked this.setState({ filter: filter, index: 0 }, () => { this.refs.search.focus() }) } handleOnlyMarkdownCheckboxChange (e) { const { filter } = this.state filter.includeMarkdown = e.target.checked this.refs.list.resetScroll() this.setState({ filter: filter, index: 0 }, () => { this.refs.search.focus() }) } handleAllNotesButtonClick (e) { const { filter } = this.state filter.type = 'ALL' this.refs.list.resetScroll() this.setState({ filter, index: 0 }, () => { this.refs.search.focus() }) } handleStarredButtonClick (e) { const { filter } = this.state filter.type = 'STARRED' this.refs.list.resetScroll() this.setState({ filter, index: 0 }, () => { this.refs.search.focus() }) } handleStorageButtonClick (e, storage) { const { filter } = this.state filter.type = 'STORAGE' filter.storage = storage this.refs.list.resetScroll() this.setState({ filter, index: 0 }, () => { this.refs.search.focus() }) } handleFolderButtonClick (e, storage, folder) { const { filter } = this.state filter.type = 'FOLDER' filter.storage = storage filter.folder = folder this.refs.list.resetScroll() this.setState({ filter, index: 0 }, () => { this.refs.search.focus() }) } handleNoteClick (e, index) { this.setState({ index }, () => { this.refs.search.focus() }) } render () { const { data, config } = this.props const { filter, search } = this.state const storageList = [] for (const key in data.storageMap) { const storage = data.storageMap[key] const item = ( this.handleStorageButtonClick(e, storage)} handleFolderButtonClick={(e, storage, folder) => this.handleFolderButtonClick(e, storage, folder)} /> ) storageList.push(item) } let notes = [] let noteIds switch (filter.type) { case 'STORAGE': noteIds = data.storageNoteMap[filter.storage] break case 'FOLDER': noteIds = data.folderNoteMap[filter.storage + '-' + filter.folder] break case 'STARRED': noteIds = data.starredSet } if (noteIds != null) { noteIds.forEach((id) => { notes.push(data.noteMap[id]) }) } else { for (const key in data.noteMap) { notes.push(data.noteMap[key]) } } if (!filter.includeSnippet && filter.includeMarkdown) { notes = notes.filter((note) => note.type === 'MARKDOWN_NOTE') } else if (filter.includeSnippet && !filter.includeMarkdown) { notes = notes.filter((note) => note.type === 'SNIPPET_NOTE') } if (search.trim().length > 0) { const needle = new RegExp(_.escapeRegExp(search.trim()), 'i') notes = notes.filter((note) => note.title.match(needle)) } notes = notes .sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)) const activeNote = notes[this.state.index] this.noteCount = notes.length return (
this.handleKeyDown(e)} >
this.handleSearchChange(e)} />
this.handleAllNotesButtonClick(e)} isStarredActive={filter.type === 'STARRED'} handleStarredButtonClick={(e) => this.handleStarredButtonClick(e)} />
{storageList}
this.handleNoteClick(e, _index)} />
) } } FinderMain.propTypes = { dispatch: PropTypes.func } var Finder = connect((x) => x)(CSSModules(FinderMain, styles)) function refreshData () { // let data = dataStore.getData(true) } ReactDOM.render(( ), document.getElementById('content'), function () { refreshData() })