* Updated color picker interface

* Updated note status bar
* Added fast filters
* Added pinned and archived notes options
* Added loading indicators to notes and loading of notes
* updated tag edit area
* Updated how search results are displayed
* Fixed bug with opening and closing two notes one after another
* Added mobile detection to global store
* Added a lot of style tweaks and UX tweaks
This commit is contained in:
Max G
2019-09-10 18:10:11 +00:00
parent dd0205a3c1
commit 7b77bd37f3
14 changed files with 620 additions and 131 deletions

View File

@@ -32,13 +32,14 @@ Note.create = (userId, noteText) => {
})
}
Note.update = (userId, noteId, noteText, fancyInput, color) => {
Note.update = (userId, noteId, noteText, fancyInput, color, pinned, archived) => {
return new Promise((resolve, reject) => {
const now = Math.round((+new Date)/1000)
db.promise()
.query('UPDATE note SET text = ?, raw_input = ?, updated = ?, color = ? WHERE id = ? AND user_id = ? LIMIT 1', [noteText, fancyInput, now, color, noteId, userId])
.query('UPDATE note SET text = ?, raw_input = ?, pinned = ?, archived = ?, updated = ?, color = ? WHERE id = ? AND user_id = ? LIMIT 1',
[noteText, fancyInput, pinned, archived, now, color, noteId, userId])
.then((rows, fields) => {
//Process note text and attachment data
@@ -91,9 +92,12 @@ Note.delete = (userId, noteId) => {
Note.get = (userId, noteId) => {
return new Promise((resolve, reject) => {
db.promise()
.query('SELECT text, updated, raw_input, color FROM note WHERE user_id = ? AND id = ? LIMIT 1', [userId,noteId])
.query('SELECT text, updated, raw_input, pinned, archived, color FROM note WHERE user_id = ? AND id = ? LIMIT 1', [userId,noteId])
.then((rows, fields) => {
//Return note data
resolve(rows[0][0])
})
.catch(console.log)
})
@@ -125,18 +129,15 @@ Note.solrQuery = (userId, searchQuery, searchTags) => {
})
}
Note.search = (userId, searchQuery, searchTags) => {
Note.search = (userId, searchQuery, searchTags, fastFilters) => {
return new Promise((resolve, reject) => {
//Define return data objects
let returnData = {
'notes':[],
'tags':[]
}
Note.solrQuery(userId, searchQuery, searchTags).then( solrResult => {
let highlights = solrResult.highlighting
@@ -149,13 +150,20 @@ Note.search = (userId, searchQuery, searchTags) => {
})
}
//No results, return empty data
if(solrNoteIds.length == 0 && searchQuery.length > 0){
resolve(returnData)
}
//Default note lookup gets all notes
let noteSearchQuery = `
SELECT note.id,
SUBSTRING(note.text, 1, 400) as text,
updated, color,
count(distinct note_tag.id) as tag_count,
count(distinct attachment.id) as attachment_count
count(distinct attachment.id) as attachment_count,
note.pinned,
note.archived
FROM note
LEFT JOIN note_tag ON (note.id = note_tag.note_id)
LEFT JOIN attachment ON (note.id = attachment.note_id AND attachment.attachment_type = 1)
@@ -178,8 +186,45 @@ Note.search = (userId, searchQuery, searchTags) => {
noteSearchQuery += ' AND note_tag.tag_id IN (?)'
}
//Toggle archived, show archived if tags are searched
// - archived will show archived in search results
// - onlyArchive will exclude notes that are not archived
if(fastFilters.archived == 1 || searchTags.length > 0 || fastFilters.onlyArchived == 1){
//Do nothing
} else {
noteSearchQuery += ' AND note.archived = 0' //Exclude archived
}
//Finish up note query
noteSearchQuery += ' GROUP BY note.id ORDER BY updated DESC, created DESC, id DESC'
noteSearchQuery += ' GROUP BY note.id'
//Only show notes with Tags
if(fastFilters.withTags == 1){
noteSearchQuery += ' HAVING tag_count > 0'
}
//Only show notes with links
if(fastFilters.withLinks == 1){
noteSearchQuery += ' HAVING attachment_count > 0'
}
//Only show archived notes
if(fastFilters.onlyArchived == 1){
noteSearchQuery += ' HAVING note.archived = 1'
}
//Default Sort, order by last updated
let defaultOrderBy = ' ORDER BY note.pinned DESC, updated DESC, created DESC, opened DESC, id DESC'
//Order by Last Created Date
if(fastFilters.lastCreated == 1){
defaultOrderBy = ' ORDER BY note.pinned DESC, created DESC, updated DESC, opened DESC, id DESC'
}
//Order by last Opened Date
if(fastFilters.lastOpened == 1){
defaultOrderBy = ' ORDER BY note.pinned DESC, opened DESC, updated DESC, created DESC, id DESC'
}
//Append Order by to query
noteSearchQuery += defaultOrderBy
db.promise()
.query(noteSearchQuery, searchParams)

View File

@@ -85,6 +85,13 @@ Tag.add = (tagText) => {
Tag.get = (userId, noteId) => {
return new Promise((resolve, reject) => {
//Update last opened date of note
const now = Math.round((+new Date)/1000)
db.promise()
.query('UPDATE note SET opened = ? WHERE id = ? AND user_id = ? LIMIT 1', [now, noteId, userId])
.then((rows, fields) => {})
db.promise()
.query(`SELECT note_tag.id, tag.text FROM note_tag
JOIN tag ON (tag.id = note_tag.tag_id)
@@ -138,7 +145,7 @@ Tag.suggest = (userId, noteId, tagText) => {
SELECT note_tag.tag_id FROM note_tag WHERE note_tag.note_id = ?
)
GROUP BY text
LIMIT 6;`, [userId, tagText, noteId])
LIMIT 6`, [userId, tagText, noteId])
.then((rows, fields) => {
resolve(rows[0]) //Return new ID
})
@@ -146,7 +153,7 @@ Tag.suggest = (userId, noteId, tagText) => {
})
}
//Suggest note tags - don't suggest tags already on note
//Latest Tags - don't suggest tags already on note
Tag.latest = (userId, noteId) => {
return new Promise((resolve, reject) => {
@@ -160,9 +167,9 @@ Tag.latest = (userId, noteId) => {
)
GROUP BY tag.text, note.updated
ORDER BY note.updated DESC
LIMIT 6;`, [userId, noteId])
LIMIT 8;`, [userId, noteId])
.then((rows, fields) => {
resolve(rows[0]) //Return new ID
resolve(rows[0]) //Return found tags
})
.catch(console.log)
})

View File

@@ -29,12 +29,12 @@ router.post('/create', function (req, res) {
})
router.post('/update', function (req, res) {
Notes.update(userId, req.body.noteId, req.body.text, req.body.fancyInput, req.body.color)
Notes.update(userId, req.body.noteId, req.body.text, req.body.fancyInput, req.body.color, req.body.pinned, req.body.archived)
.then( id => res.send({id}) )
})
router.post('/search', function (req, res) {
Notes.search(userId, req.body.searchQuery, req.body.searchTags)
Notes.search(userId, req.body.searchQuery, req.body.searchTags, req.body.fastFilters)
.then( notesAndTags => res.send(notesAndTags))
})