diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js
index 7694f1e7..df6ce3ea 100755
--- a/browser/main/Detail/MarkdownNoteDetail.js
+++ b/browser/main/Detail/MarkdownNoteDetail.js
@@ -19,6 +19,7 @@ import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
import ConfigManager from 'browser/main/lib/ConfigManager'
import TrashButton from './TrashButton'
import FullscreenButton from './FullscreenButton'
+import RestoreButton from './RestoreButton'
import PermanentDeleteButton from './PermanentDeleteButton'
import InfoButton from './InfoButton'
import ToggleModeButton from './ToggleModeButton'
@@ -321,10 +322,7 @@ class MarkdownNoteDetail extends React.Component {
const trashTopBar =
- this.handleUndoButtonClick(e)}
- />
+ this.handleUndoButtonClick(e)} />
this.handleTrashButtonClick(e)} />
diff --git a/browser/main/Detail/RestoreButton.js b/browser/main/Detail/RestoreButton.js
new file mode 100644
index 00000000..0f9c992e
--- /dev/null
+++ b/browser/main/Detail/RestoreButton.js
@@ -0,0 +1,21 @@
+import PropTypes from 'prop-types'
+import React from 'react'
+import CSSModules from 'browser/lib/CSSModules'
+import styles from './RestoreButton.styl'
+
+const RestoreButton = ({
+ onClick
+}) => (
+
+)
+
+RestoreButton.propTypes = {
+ onClick: PropTypes.func.isRequired
+}
+
+export default CSSModules(RestoreButton, styles)
diff --git a/browser/main/Detail/RestoreButton.styl b/browser/main/Detail/RestoreButton.styl
new file mode 100644
index 00000000..58ce745d
--- /dev/null
+++ b/browser/main/Detail/RestoreButton.styl
@@ -0,0 +1,22 @@
+.control-restoreButton
+ top 115px
+ topBarButtonRight()
+ &:hover .tooltip
+ opacity 1
+
+.tooltip
+ tooltip()
+ position absolute
+ pointer-events none
+ top 50px
+ left 25px
+ z-index 200
+ padding 5px
+ line-height normal
+ border-radius 2px
+ opacity 0
+ transition 0.1s
+
+body[data-theme="dark"]
+ .control-restoreButton
+ topBarButtonDark()
diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js
index 791b490e..dbef37ca 100644
--- a/browser/main/Detail/SnippetNoteDetail.js
+++ b/browser/main/Detail/SnippetNoteDetail.js
@@ -20,6 +20,7 @@ import _ from 'lodash'
import { findNoteTitle } from 'browser/lib/findNoteTitle'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
import TrashButton from './TrashButton'
+import RestoreButton from './RestoreButton'
import PermanentDeleteButton from './PermanentDeleteButton'
import InfoButton from './InfoButton'
import InfoPanel from './InfoPanel'
@@ -589,10 +590,7 @@ class SnippetNoteDetail extends React.Component {
const trashTopBar =
- this.handleUndoButtonClick(e)}
- />
+ this.handleUndoButtonClick(e)} />
this.handleTrashButtonClick(e)} />
diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js
index cb71ac07..345dfe0d 100644
--- a/browser/main/NoteList/index.js
+++ b/browser/main/NoteList/index.js
@@ -66,6 +66,7 @@ class NoteList extends React.Component {
this.deleteNote = this.deleteNote.bind(this)
this.focusNote = this.focusNote.bind(this)
this.pinToTop = this.pinToTop.bind(this)
+ this.restoreNote = this.restoreNote.bind(this)
// TODO: not Selected noteKeys but SelectedNote(for reusing)
this.state = {
@@ -453,6 +454,7 @@ class NoteList extends React.Component {
const pinLabel = note.isPinned ? 'Remove pin' : 'Pin to Top'
const deleteLabel = 'Delete Note'
const cloneNote = 'Clone Note'
+ const restoreNote = 'Restore Note'
const menu = new Menu()
if (!location.pathname.match(/\/starred|\/trash/)) {
@@ -461,6 +463,14 @@ class NoteList extends React.Component {
click: this.pinToTop
}))
}
+
+ if (location.pathname.match(/\/trash/)) {
+ menu.append(new MenuItem({
+ label: restoreNote,
+ click: this.restoreNote
+ }))
+ }
+
menu.append(new MenuItem({
label: deleteLabel,
click: this.deleteNote
@@ -472,28 +482,50 @@ class NoteList extends React.Component {
menu.popup()
}
- pinToTop () {
+ updateSelectedNotes (updateFunc, cleanSelection = true) {
const { selectedNoteKeys } = this.state
const { dispatch } = this.props
const notes = this.notes.map((note) => Object.assign({}, note))
const selectedNotes = findNotesByKeys(notes, selectedNoteKeys)
+ if (!_.isFunction(updateFunc)) {
+ console.warn('Update function is not defined. No update will happen')
+ updateFunc = (note) => { return note }
+ }
+
Promise.all(
- selectedNotes.map((note) => {
- note.isPinned = !note.isPinned
- return dataApi
- .updateNote(note.storage, note.key, note)
- })
- )
- .then((updatedNotes) => {
- updatedNotes.forEach((note) => {
- dispatch({
- type: 'UPDATE_NOTE',
- note
+ selectedNotes.map((note) => {
+ note = updateFunc(note)
+ return dataApi
+ .updateNote(note.storage, note.key, note)
})
- })
+ )
+ .then((updatedNotes) => {
+ updatedNotes.forEach((note) => {
+ dispatch({
+ type: 'UPDATE_NOTE',
+ note
+ })
+ })
+ })
+
+ if (cleanSelection) {
+ this.selectNextNote()
+ }
+ }
+
+ pinToTop () {
+ this.updateSelectedNotes((note) => {
+ note.isPinned = !note.isPinned
+ return note
+ })
+ }
+
+ restoreNote () {
+ this.updateSelectedNotes((note) => {
+ note.isTrashed = false
+ return note
})
- this.setState({ selectedNoteKeys: [] })
}
deleteNote () {