1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 09:46:22 +00:00

feat: add shiftkey multiselect notes and delete

This commit is contained in:
voidSatisfaction
2017-11-05 18:11:08 +09:00
parent 1f8acc3afc
commit 2d0e14c1cc

View File

@@ -15,6 +15,7 @@ import markdown from 'browser/lib/markdown'
import { findNoteTitle } from 'browser/lib/findNoteTitle'
import stripgtags from 'striptags'
import store from 'browser/main/store'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
const { remote } = require('electron')
const { Menu, MenuItem, dialog } = remote
@@ -50,8 +51,12 @@ class NoteList extends React.Component {
}
this.importFromFileHandler = this.importFromFile.bind(this)
this.jumpNoteByHash = this.jumpNoteByHashHandler.bind(this)
this.handleNoteListKeyUp = this.handleNoteListKeyUp.bind(this)
this.deleteNote = this.deleteNote.bind(this)
this.state = {
shiftKeyDown: false,
selectedNoteIds: []
}
this.contextNotes = []
@@ -197,6 +202,10 @@ class NoteList extends React.Component {
}
handleNoteListKeyDown (e) {
if (e.shiftKey) {
this.setState({ shiftKeyDown: true })
}
if (e.metaKey || e.ctrlKey) return true
if (e.keyCode === 65 && !e.shiftKey) {
@@ -225,6 +234,12 @@ class NoteList extends React.Component {
}
}
handleNoteListKeyUp (e) {
if (!e.shiftKey) {
this.setState({ shiftKeyDown: false })
}
}
getNotes () {
let { data, params, location } = this.props
let { router } = this.context
@@ -302,13 +317,28 @@ class NoteList extends React.Component {
handleNoteClick (e, uniqueKey) {
let { router } = this.context
let { location } = this.props
let { shiftKeyDown, selectedNoteIds } = this.state
router.push({
pathname: location.pathname,
query: {
key: uniqueKey
}
})
if (shiftKeyDown && !selectedNoteIds.includes(uniqueKey)) {
selectedNoteIds.push(uniqueKey)
this.setState({
selectedNoteIds
})
} else if (shiftKeyDown) {
this.setState({
selectedNoteIds: [...selectedNoteIds].filter((item) => item !== uniqueKey)
})
} else {
this.setState({
selectedNoteIds: [uniqueKey]
})
router.push({
pathname: location.pathname,
query: {
key: uniqueKey
}
})
}
}
handleSortByChange (e) {
@@ -358,11 +388,16 @@ class NoteList extends React.Component {
handleNoteContextMenu (e, uniqueKey) {
const { location } = this.props
const { selectedNoteIds } = this.state
const note = this.notes.find((note) => {
const noteKey = `${note.storage}-${note.key}`
return noteKey === uniqueKey
})
if (selectedNoteIds.length === 0) {
this.handleNoteClick(e, uniqueKey)
}
const pinLabel = note.isPinned ? 'Remove pin' : 'Pin to Top'
const deleteLabel = 'Delete Note'
@@ -375,7 +410,7 @@ class NoteList extends React.Component {
}
menu.append(new MenuItem({
label: deleteLabel,
click: (e) => this.deleteNote(e, uniqueKey)
click: this.deleteNote
}))
menu.popup()
}
@@ -403,9 +438,68 @@ class NoteList extends React.Component {
})
}
deleteNote (e, uniqueKey) {
this.handleNoteClick(e, uniqueKey)
ee.emit('detail:delete')
deleteNote () {
const { dispatch } = this.props
const { selectedNoteIds } = this.state
// not to change objects of this.notes
const notes = this.notes.map((note) => Object.assign({}, note))
const selectedNotes = notes.filter((note) => selectedNoteIds.includes(`${note.storage}-${note.key}`))
const firstNote = selectedNotes[0]
if (firstNote.isTrashed) {
const noteExp = selectedNotes.length > 1 ? 'notes' : 'note'
const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Confirm note deletion',
detail: `This will permanently remove ${selectedNotes.length} ${noteExp}.`,
buttons: ['Confirm', 'Cancel']
})
if (dialogueButtonIndex === 1) return
Promise.all(
selectedNoteIds.map((uniqueKey) => {
const storageKey = uniqueKey.split('-')[0]
const noteKey = uniqueKey.split('-')[1]
return dataApi
.deleteNote(storageKey, noteKey)
})
)
.then((data) => {
data.forEach((item) => {
dispatch({
type: 'DELETE_NOTE',
storageKey: item.storageKey,
noteKey: item.noteKey
})
})
})
.catch((err) => {
console.error('Cannot Delete note: ' + err)
})
console.log('Notes were all deleted')
} else {
Promise.all(
selectedNotes.map((note) => {
note.isTrashed = true
return dataApi
.updateNote(note.storage, note.key, note)
})
)
.then((newNotes) => {
newNotes.forEach((newNote) => {
dispatch({
type: 'UPDATE_NOTE',
note: newNote
})
})
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('EDIT_NOTE')
console.log('Notes went to trash')
})
.catch((err) => {
console.error('Notes could not go to trash: ' + err)
})
}
this.setState({ selectedNoteIds: [] })
}
importFromFile () {
@@ -475,6 +569,7 @@ class NoteList extends React.Component {
render () {
let { location, notes, config, dispatch } = this.props
let { selectedNoteIds } = this.state
let sortFunc = config.sortBy === 'CREATED_AT'
? sortByCreatedAt
: config.sortBy === 'ALPHABETICAL'
@@ -495,7 +590,8 @@ class NoteList extends React.Component {
}
const isDefault = config.listStyle === 'DEFAULT'
const isActive = location.query.key === note.storage + '-' + note.key
const uniqueKey = note.storage + '-' + note.key
const isActive = selectedNoteIds.includes(uniqueKey)
const dateDisplay = moment(
config.sortBy === 'CREATED_AT'
? note.createdAt : note.updatedAt
@@ -570,6 +666,7 @@ class NoteList extends React.Component {
ref='list'
tabIndex='-1'
onKeyDown={(e) => this.handleNoteListKeyDown(e)}
onKeyUp={this.handleNoteListKeyUp}
>
{noteList}
</div>