From 2cbe07b3737803c909e5391d2b2f2b3de417d6b1 Mon Sep 17 00:00:00 2001 From: Dick Choi Date: Sun, 14 Aug 2016 01:34:32 +0900 Subject: [PATCH] Finder --- browser/finder/FinderDetail.js | 44 -- browser/finder/FinderInput.js | 16 - browser/finder/FinderList.js | 71 --- browser/finder/FinderMain.styl | 78 +++ browser/finder/NoteDetail.js | 198 ++++++++ browser/finder/NoteDetail.styl | 93 ++++ browser/finder/NoteItem.js | 86 ++++ browser/finder/NoteItem.styl | 86 ++++ browser/finder/NoteList.js | 89 ++++ browser/finder/StorageSection.js | 72 +++ browser/finder/StorageSection.styl | 59 +++ browser/finder/actions.js | 39 -- browser/finder/index.js | 447 ++++++++++-------- browser/finder/ipcClient.js | 97 ++++ browser/finder/reducer.js | 47 -- browser/finder/store.js | 77 +++ browser/main/Main.js | 1 + browser/main/SideNav/StorageItem.styl | 2 +- browser/main/StatusBar/StatusBar.styl | 1 - browser/main/StatusBar/index.js | 16 +- browser/main/index.js | 33 +- browser/main/lib/ConfigManager.js | 10 +- browser/main/lib/ipc.js | 138 ++++++ browser/main/lib/notify.js | 11 + .../main/modals/PreferencesModal/ConfigTab.js | 1 - lib/finder-app.js | 6 +- lib/finder-window.js | 112 +---- lib/finder.html | 9 +- lib/hotkey.js | 14 +- lib/main-app.js | 195 ++------ lib/main-menu.js | 89 ++-- lib/main-window.js | 5 + package.json | 2 + webpack-skeleton.js | 3 +- 34 files changed, 1482 insertions(+), 765 deletions(-) delete mode 100644 browser/finder/FinderDetail.js delete mode 100644 browser/finder/FinderInput.js delete mode 100644 browser/finder/FinderList.js create mode 100644 browser/finder/FinderMain.styl create mode 100644 browser/finder/NoteDetail.js create mode 100644 browser/finder/NoteDetail.styl create mode 100644 browser/finder/NoteItem.js create mode 100644 browser/finder/NoteItem.styl create mode 100644 browser/finder/NoteList.js create mode 100644 browser/finder/StorageSection.js create mode 100644 browser/finder/StorageSection.styl delete mode 100644 browser/finder/actions.js create mode 100644 browser/finder/ipcClient.js delete mode 100644 browser/finder/reducer.js create mode 100644 browser/finder/store.js create mode 100644 browser/main/lib/ipc.js create mode 100644 browser/main/lib/notify.js diff --git a/browser/finder/FinderDetail.js b/browser/finder/FinderDetail.js deleted file mode 100644 index 5e4cfc3f..00000000 --- a/browser/finder/FinderDetail.js +++ /dev/null @@ -1,44 +0,0 @@ -import React, { PropTypes } from 'react' -import CodeEditor from 'browser/components/CodeEditor' -import MarkdownPreview from 'browser/components/MarkdownPreview' -import ModeIcon from 'browser/components/ModeIcon' - -export default class FinderDetail extends React.Component { - render () { - let { activeArticle } = this.props - - if (activeArticle != null) { - return ( -
-
-
- {activeArticle.title} -
-
- -
-
-
- {activeArticle.mode === 'markdown' - ? - : - } -
-
- ) - } - return ( -
-
Nothing selected
-
- ) - } -} - -FinderDetail.propTypes = { - activeArticle: PropTypes.shape(), - saveToClipboard: PropTypes.func -} diff --git a/browser/finder/FinderInput.js b/browser/finder/FinderInput.js deleted file mode 100644 index d23fa98d..00000000 --- a/browser/finder/FinderInput.js +++ /dev/null @@ -1,16 +0,0 @@ -import React, { PropTypes } from 'react' - -export default class FinderInput extends React.Component { - render () { - return ( -
- -
- ) - } -} - -FinderInput.propTypes = { - handleSearchChange: PropTypes.func, - value: PropTypes.string -} diff --git a/browser/finder/FinderList.js b/browser/finder/FinderList.js deleted file mode 100644 index d9f48827..00000000 --- a/browser/finder/FinderList.js +++ /dev/null @@ -1,71 +0,0 @@ -import React, { PropTypes } from 'react' -import ReactDOM from 'react-dom' -import ModeIcon from 'browser/components/ModeIcon' -import { selectArticle } from './actions' - -export default class FinderList extends React.Component { - componentDidUpdate () { - var index = this.props.articles.indexOf(this.props.activeArticle) - var el = ReactDOM.findDOMNode(this) - var li = el.querySelectorAll('li')[index] - - if (li == null) { - return - } - - var overflowBelow = el.clientHeight + el.scrollTop < li.offsetTop + li.clientHeight - if (overflowBelow) { - el.scrollTop = li.offsetTop + li.clientHeight - el.clientHeight - } - var overflowAbove = el.scrollTop > li.offsetTop - if (overflowAbove) { - el.scrollTop = li.offsetTop - } - } - - handleArticleClick (article) { - return (e) => { - let { dispatch } = this.props - dispatch(selectArticle(article.key)) - } - } - - render () { - let articleElements = this.props.articles.map(function (article) { - if (article == null) { - return ( -
  • -
    Undefined
    -
    -
  • - ) - } - - var isActive = this.props.activeArticle != null && (article.key === this.props.activeArticle.key) - return ( -
  • -
    - {article.title}
    -
    -
  • - ) - }.bind(this)) - - return ( -
    -
      - {articleElements} -
    -
    - ) - } -} - -FinderList.propTypes = { - articles: PropTypes.array, - activeArticle: PropTypes.shape({ - type: PropTypes.string, - key: PropTypes.string - }), - dispatch: PropTypes.func -} diff --git a/browser/finder/FinderMain.styl b/browser/finder/FinderMain.styl new file mode 100644 index 00000000..44d8ef3a --- /dev/null +++ b/browser/finder/FinderMain.styl @@ -0,0 +1,78 @@ +$search-height = 50px +$nav-width = 175px +$list-width = 250px + +.root + absolute top left right bottom + +.search + height $search-height + padding 10px + box-sizing border-box + border-bottom $ui-border + text-align center + +.search-input + height 30px + width 100% + margin 0 auto + font-size 18px + border none + outline none + text-align center +.result + absolute left right bottom + top $search-height + +.result-nav + user-select none + absolute left top bottom + width $nav-width + background-color $ui-backgroundColor +.result-nav-filter + margin-bottom 5px +.result-nav-filter-option + height 25px + line-height 25px + padding 0 10px + label + cursor pointer + +.result-nav-menu + navButtonColor() + height 40px + padding 0 10px + font-size 14px + width 100% + outline none + text-align left + line-height 40px + box-sizing border-box + cursor pointer + +.result-nav-menu--active + @extend .result-nav-menu + background-color $ui-button--active-backgroundColor + color $ui-button--active-color + &:hover + background-color $ui-button--active-backgroundColor + +.result-nav-storageList + absolute bottom left right + top 80px + 50px + 10px + overflow-y auto + +.result-list + user-select none + absolute top bottom + left $nav-width + width $list-width + border-width 0 1px + border-style solid + border-color $ui-borderColor + box-sizing border-box + overflow-y auto + +.result-detail + absolute top bottom right + left $nav-width + $list-width diff --git a/browser/finder/NoteDetail.js b/browser/finder/NoteDetail.js new file mode 100644 index 00000000..d339265b --- /dev/null +++ b/browser/finder/NoteDetail.js @@ -0,0 +1,198 @@ +import React, { PropTypes } from 'react' +import CSSModules from 'browser/lib/CSSModules' +import styles from './NoteDetail.styl' +import MarkdownPreview from 'browser/components/MarkdownPreview' +import MarkdownEditor from 'browser/components/MarkdownEditor' +import CodeEditor from 'browser/components/CodeEditor' +import modes from 'browser/lib/modes' + +const electron = require('electron') +const { clipboard } = electron +const path = require('path') + +function notify (title, options) { + if (process.platform === 'win32') { + options.icon = path.join('file://', global.__dirname, '../../resources/app.png') + } + return new window.Notification(title, options) +} + +class NoteDetail extends React.Component { + constructor (props) { + super(props) + + this.state = { + snippetIndex: 0 + } + } + + componentWillReceiveProps (nextProps) { + if (nextProps.note !== this.props.note) { + this.setState({ + snippetIndex: 0 + }, () => { + if (nextProps.note.type === 'SNIPPET_NOTE') { + nextProps.note.snippets.forEach((snippet, index) => { + this.refs['code-' + index].reload() + }) + } + }) + } + } + + selectPriorSnippet () { + let { note } = this.props + if (note.type === 'SNIPPET_NOTE' && note.snippets.length > 1) { + this.setState({ + snippetIndex: (this.state.snippetIndex + note.snippets.length - 1) % note.snippets.length + }) + } + } + + selectNextSnippet () { + let { note } = this.props + if (note.type === 'SNIPPET_NOTE' && note.snippets.length > 1) { + this.setState({ + snippetIndex: (this.state.snippetIndex + 1) % note.snippets.length + }) + } + } + + saveToClipboard () { + let { note } = this.props + + if (note.type === 'MARKDOWN_NOTE') { + clipboard.writeText(note.content) + } else { + clipboard.writeText(note.snippets[this.state.snippetIndex].content) + } + + notify('Saved to Clipboard!', { + body: 'Paste it wherever you want!', + silent: true + }) + } + + handleTabButtonClick (e, index) { + this.setState({ + snippetIndex: index + }) + } + + render () { + let { note, config } = this.props + if (note == null) { + return ( +
    + +
    + ) + } + + let editorFontSize = parseInt(config.editor.fontSize, 10) + if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14 + let editorIndentSize = parseInt(config.editor.indentSize, 10) + if (!(editorFontSize > 0 && editorFontSize < 132)) editorIndentSize = 4 + + if (note.type === 'SNIPPET_NOTE') { + let tabList = note.snippets.map((snippet, index) => { + let isActive = this.state.snippetIndex === index + return
    + +
    + }) + let viewList = note.snippets.map((snippet, index) => { + let isActive = this.state.snippetIndex === index + let mode = snippet.mode === 'text' + ? null + : modes.filter((mode) => mode.name === snippet.mode)[0] + + return
    +
    + + +
    + {snippet.mode === 'markdown' + ? + : + } +
    + }) + + return ( +
    +
    +