diff --git a/browser/components/NoteItem.js b/browser/components/NoteItem.js
index 9f49fb28..ce209471 100644
--- a/browser/components/NoteItem.js
+++ b/browser/components/NoteItem.js
@@ -72,6 +72,9 @@ const NoteItem = ({ isActive, note, dateDisplay, handleNoteClick, handleNoteCont
{note.isStarred
? : ''
}
+ {note.isPinned
+ ? : ''
+ }
{note.type === 'MARKDOWN_NOTE'
?
: ''
@@ -101,6 +104,7 @@ NoteItem.propTypes = {
isTrashed: PropTypes.bool.isRequired
}),
handleNoteClick: PropTypes.func.isRequired,
+ handleNoteContextMenu: PropTypes.func.isRequired,
handleDragStart: PropTypes.func.isRequired,
handleDragEnd: PropTypes.func.isRequired
}
diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js
index 6f3860eb..8fad912c 100644
--- a/browser/main/NoteList/index.js
+++ b/browser/main/NoteList/index.js
@@ -14,6 +14,7 @@ import { hashHistory } from 'react-router'
import markdown from 'browser/lib/markdown'
import { findNoteTitle } from 'browser/lib/findNoteTitle'
import stripgtags from 'striptags'
+import store from 'browser/main/store'
const { remote } = require('electron')
const { Menu, MenuItem, dialog } = remote
@@ -283,6 +284,21 @@ class NoteList extends React.Component {
return folderNoteKeyList.map((uniqueKey) => data.noteMap.get(uniqueKey))
}
+ sortByPinn (unorderedNotes) {
+ const { data, params } = this.props
+ let storageKey = params.storageKey
+ let folderKey = params.folderKey
+ let storage = data.storageMap.get(storageKey)
+ if (storage == null) return []
+
+ let folder = _.find(storage.folders, {key: folderKey})
+ const pinnedNotes = unorderedNotes.filter((el) => {
+ return folder.pinnedNotes && folder.pinnedNotes.includes(el.key)
+ })
+
+ return pinnedNotes.concat(unorderedNotes)
+ }
+
handleNoteClick (e, uniqueKey) {
let { router } = this.context
let { location } = this.props
@@ -413,6 +429,56 @@ class NoteList extends React.Component {
})
}
+ handleNoteContextMenu (e, uniqueKey) {
+ let menu = new Menu()
+ menu.append(new MenuItem({
+ label: 'Pin to Top',
+ click: (e) => this.handlePinToTop(e, uniqueKey)
+ }))
+ menu.popup()
+ }
+
+ handlePinToTop (e, uniqueKey) {
+ const { data, location } = this.props
+ let splitted = location.pathname.split('/')
+ const storageKey = splitted[2]
+ const folderKey = splitted[4]
+
+ const currentStorage = data.storageMap.get(storageKey)
+ const currentFolder = _.find(currentStorage.folders, {key: folderKey})
+
+ dataApi
+ .updateFolder(storageKey, folderKey, {
+ color: currentFolder.color,
+ name: currentFolder.name,
+ pinnedNote: uniqueKey.split('-').pop()
+ })
+ .then((data) => {
+ store.dispatch({
+ type: 'UPDATE_FOLDER',
+ storage: data.storage
+ })
+ this.setState({
+ status: 'IDLE'
+ })
+ })
+
+ let targetIndex = _.findIndex(this.notes, (note) => {
+ return note != null && note.storage + '-' + note.key === location.query.key
+ })
+ let note = this.notes[targetIndex]
+
+ dataApi
+ .updateNote(note.storage, note.key, note)
+ .then((note) => {
+ note.isPinned = true
+ store.dispatch({
+ type: 'UPDATE_NOTE',
+ note: note
+ })
+ })
+ }
+
render () {
let { location, notes, config, dispatch } = this.props
let sortFunc = config.sortBy === 'CREATED_AT'
@@ -420,8 +486,8 @@ class NoteList extends React.Component {
: config.sortBy === 'ALPHABETICAL'
? sortByAlphabetical
: sortByUpdatedAt
- this.notes = notes = this.getNotes()
- .sort(sortFunc)
+ const sortedNotes = this.getNotes().sort(sortFunc)
+ this.notes = notes = this.sortByPinn(sortedNotes)
.filter((note) => {
// this is for the trash box
if (note.isTrashed !== true || location.pathname === '/trashed') return true
@@ -450,6 +516,7 @@ class NoteList extends React.Component {
key={key}
handleNoteContextMenu={this.handleNoteContextMenu.bind(this)}
handleNoteClick={this.handleNoteClick.bind(this)}
+ handleNoteContextMenu={this.handleNoteContextMenu.bind(this)}
handleDragStart={this.handleDragStart.bind(this)}
/>
)
@@ -526,4 +593,4 @@ NoteList.propTypes = {
})
}
-export default CSSModules(NoteList, styles)
+
diff --git a/browser/main/lib/dataApi/createFolder.js b/browser/main/lib/dataApi/createFolder.js
index 9357e17c..69c27d38 100644
--- a/browser/main/lib/dataApi/createFolder.js
+++ b/browser/main/lib/dataApi/createFolder.js
@@ -44,7 +44,8 @@ function createFolder (storageKey, input) {
let newFolder = {
key,
color: input.color,
- name: input.name
+ name: input.name,
+ pinnedNotes: []
}
storage.folders.push(newFolder)
diff --git a/browser/main/lib/dataApi/updateFolder.js b/browser/main/lib/dataApi/updateFolder.js
index e128a2d3..414e32b6 100644
--- a/browser/main/lib/dataApi/updateFolder.js
+++ b/browser/main/lib/dataApi/updateFolder.js
@@ -44,6 +44,12 @@ function updateFolder (storageKey, folderKey, input) {
if (targetFolder == null) throw new Error('Target folder doesn\'t exist.')
targetFolder.name = input.name
targetFolder.color = input.color
+ // For compativility
+ if (targetFolder.pinnedNotes) {
+ targetFolder.pinnedNotes.push(input.pinnedNote)
+ } else {
+ targetFolder.pinnedNotes = [input.pinnedNote]
+ }
CSON.writeFileSync(path.join(storage.path, 'boostnote.json'), _.pick(storage, ['folders', 'version']))
diff --git a/browser/main/lib/dataApi/updateNote.js b/browser/main/lib/dataApi/updateNote.js
index 4bf5ca29..e6bc7b55 100644
--- a/browser/main/lib/dataApi/updateNote.js
+++ b/browser/main/lib/dataApi/updateNote.js
@@ -104,6 +104,7 @@ function updateNote (storageKey, noteKey, input) {
noteData.isStarred = false
noteData.isTrashed = false
noteData.tags = []
+ noteData.isPinned = false
}
if (noteData.type === 'SNIPPET_NOTE') {