Bugfix Batch

* Animations disabled on remote events, closing note still triggers animation for local user
* Created save icons to fix display on mobile
* Hidden URLs are hidden until note is deleted or URL is removed from note
* Tags search all categories, but probably not trash
* Back to all notes button clears search
* Deleted Notes are removed from search index
This commit is contained in:
Max G 2020-05-19 03:38:43 +00:00
parent 5096e74a60
commit 543ecf0f2d
8 changed files with 58 additions and 45 deletions

View File

@ -54,8 +54,6 @@
</div> </div>
<div class="menu-bottom-half"> <div class="menu-bottom-half">
<div class="edit-divide"></div>
<div class="edit-button" v-on:click="undoCustom()" data-tooltip="Undo" data-position="bottom center" data-inverted> <div class="edit-button" v-on:click="undoCustom()" data-tooltip="Undo" data-position="bottom center" data-inverted>
<i class="undo icon"></i> <i class="undo icon"></i>
@ -101,13 +99,16 @@
<i class="folder icon"></i> <i class="folder icon"></i>
</div> </div>
<span>{{ statusText }}</span> <div class="edit-button">
<i class="icons">
<i class="grey save outline icon"></i>
<i v-if="statusText == 'saved'" class="green small bottom left corner check icon"></i>
<i v-if="statusText == 'saving'" class="small bottom left corner double angle up icon"></i>
</i>
</div>
</div> </div>
<!-- <span :data-tooltip="`Created: ${$helpers.timeAgo(created)}`">
Edited: {{ $helpers.timeAgo(updated) }}
</span> -->
</div> </div>
<div class="bottom-edit-menu"></div> <div class="bottom-edit-menu"></div>
@ -265,7 +266,7 @@
updated: '', updated: '',
shareUsername: null, shareUsername: null,
diffNoteText: '', diffNoteText: '',
statusText: 'Saved.', statusText: 'saved',
lastNoteHash: null, lastNoteHash: null,
saveDebounce: null, //Prevent save from being called numerous times quickly saveDebounce: null, //Prevent save from being called numerous times quickly
updated: 'Never', updated: 'Never',
@ -1035,7 +1036,7 @@
}, },
onKeyup(){ onKeyup(){
this.statusText = 'Modded' this.statusText = 'modified'
// this.diffText() // this.diffText()
@ -1063,7 +1064,7 @@
const currentNoteText = this.getText() const currentNoteText = this.getText()
const currentHash = this.hashString( currentNoteText ) const currentHash = this.hashString( currentNoteText )
if( this.lastNoteHash == currentHash){ if( this.lastNoteHash == currentHash){
this.statusText = 'Saved.' this.statusText = 'saved'
return resolve(true) return resolve(true)
} }
@ -1084,9 +1085,9 @@
// console.log('Save Hash', currentHash) // console.log('Save Hash', currentHash)
this.statusText = 'Saving' this.statusText = 'saving'
axios.post('/api/note/update', postData).then( response => { axios.post('/api/note/update', postData).then( response => {
this.statusText = 'Saved.' this.statusText = 'saved'
this.updated = Math.round((+new Date)/1000) this.updated = Math.round((+new Date)/1000)
this.modified = true this.modified = true
@ -1298,7 +1299,7 @@
background-color: var(--menu-accent); background-color: var(--menu-accent);
height: 15px; height: 15px;
width: 1px; width: 1px;
margin: 0 3px; margin: 0 1px;
padding: 0; padding: 0;
} }
@media only screen and (max-width: 740px) { @media only screen and (max-width: 740px) {

View File

@ -187,8 +187,8 @@
<!-- set --> <!-- set -->
<div class="middle aligned centered row"> <div class="middle aligned centered row">
<div class="six wide right aligned column"> <div class="six wide right aligned column">
<h2>Search your data</h2> <h2>Secure Search</h2>
<h3>Type in a word and find that same word but somewhere else</h3> <h3>Keyword search using an encrypted search index helps you find what you need without compromising security</h3>
</div> </div>
<div class="six wide column"> <div class="six wide column">
<img loading="lazy" width="100%" src="/api/static/assets/marketing/solution.svg" alt="Hypercube of Solutions"> <img loading="lazy" width="100%" src="/api/static/assets/marketing/solution.svg" alt="Hypercube of Solutions">

View File

@ -218,7 +218,8 @@
'sent': ['paper plane outline', 'Shared Notes'], 'sent': ['paper plane outline', 'Shared Notes'],
'notes': ['file','Notes'], 'notes': ['file','Notes'],
'highlights': ['paragraph', 'Found In Text'], 'highlights': ['paragraph', 'Found In Text'],
'trashed': ['poop', 'Trashed Notes'] 'trashed': ['poop', 'Trashed Notes'],
'tagged': ['tag', 'Tagged'],
}, },
noteSections: { noteSections: {
pinned: [], pinned: [],
@ -227,7 +228,8 @@
sent:[], sent:[],
notes: [], notes: [],
highlights: [], highlights: [],
trashed: [] trashed: [],
tagged:[],
}, },
} }
@ -241,7 +243,7 @@
//Do not update note if its open //Do not update note if its open
if(this.activeNoteId1 != noteId){ if(this.activeNoteId1 != noteId){
this.$store.dispatch('fetchAndUpdateUserTotals') this.$store.dispatch('fetchAndUpdateUserTotals')
this.updateSingleNote(noteId) this.updateSingleNote(noteId, false)
} }
}) })
@ -249,7 +251,7 @@
//Do not update note if its open //Do not update note if its open
if(this.activeNoteId1 != noteId){ if(this.activeNoteId1 != noteId){
this.$store.dispatch('fetchAndUpdateUserTotals') this.$store.dispatch('fetchAndUpdateUserTotals')
this.updateSingleNote(noteId) this.updateSingleNote(noteId, false)
} }
}) })
@ -258,7 +260,7 @@
//Do not update note if its open //Do not update note if its open
if(this.activeNoteId1 != noteId){ if(this.activeNoteId1 != noteId){
this.updateSingleNote(noteId) this.updateSingleNote(noteId, false)
} }
}) })
@ -481,7 +483,7 @@
}, },
// @TODO Don't even trigger this if the note wasn't changed // @TODO Don't even trigger this if the note wasn't changed
updateSingleNote(noteId){ updateSingleNote(noteId, focuseAndAnimate = true){
noteId = parseInt(noteId) noteId = parseInt(noteId)
@ -539,7 +541,7 @@
this.$nextTick( () => { this.$nextTick( () => {
//Trigger close animation on note //Trigger close animation on note
if(this.$refs['note-'+noteId] && this.$refs['note-'+noteId][0]){ if(this.$refs['note-'+noteId] && this.$refs['note-'+noteId][0] && focuseAndAnimate){
this.$refs['note-'+noteId][0].justClosed() this.$refs['note-'+noteId][0].justClosed()
} }
}) })
@ -662,6 +664,11 @@
//Sort notes into defined sections //Sort notes into defined sections
notes.forEach(note => { notes.forEach(note => {
if(this.searchTags.length >= 1){
this.noteSections.tagged.push(note)
return
}
//Only show trashed notes when trashed //Only show trashed notes when trashed
if(this.fastFilters.onlyShowTrashed == 1){ if(this.fastFilters.onlyShowTrashed == 1){
@ -725,7 +732,7 @@
this.fastFilters = {} this.fastFilters = {}
this.updateFastFilters(5) this.updateFastFilters(5)
this.foundAttachments = [] //Remove all attachments this.foundAttachments = [] //Remove all attachments
// this.$bus.$emit('reset_fast_filters') this.$bus.$emit('reset_fast_filters')
//Load initial batch, then tags, then other batch //Load initial batch, then tags, then other batch
this.search(true, this.firstLoadBatchSize) this.search(true, this.firstLoadBatchSize)
@ -733,9 +740,6 @@
//Load a larger batch once first batch has loaded //Load a larger batch once first batch has loaded
return this.search(false, this.batchSize, true) return this.search(false, this.batchSize, true)
}) })
.then( i => {
//Thats how you promise chain
})
}, },
updateFastFilters(index){ updateFastFilters(index){

View File

@ -136,7 +136,7 @@ app.use(function(req, res, next){
// Test Area // Test Area
const printResults = true const printResults = false
let UserTest = require('@models/User') let UserTest = require('@models/User')
let NoteTest = require('@models/Note') let NoteTest = require('@models/Note')
UserTest.keyPairTest('genMan2', '1', printResults) UserTest.keyPairTest('genMan2', '1', printResults)

View File

@ -138,10 +138,7 @@ Attachment.delete = (userId, attachmentId, urlDelete = false) => {
.then((rows, fields) => { .then((rows, fields) => {
noteExists = (rows[0]['exists'] > 0) noteExists = (rows[0][0]['exists'] > 0)
let url = attachment.url let url = attachment.url
const noteId = attachment.note_id const noteId = attachment.note_id
@ -158,18 +155,16 @@ Attachment.delete = (userId, attachmentId, urlDelete = false) => {
if(attachment.attachment_type == 1 && !urlDelete && noteExists){ if(attachment.attachment_type == 1 && !urlDelete && noteExists){
db.promise() db.promise()
.query(`UPDATE attachment SET visible = 0 WHERE id = ?`, [attachmentId]) .query(`UPDATE attachment SET visible = 0 WHERE id = ?`, [attachmentId])
.then((rows, fields) => { }) .then((rows, fields) => resolve(true))
.catch(console.log) .catch(console.log)
return resolve(true) return resolve(true)
} else {
db.promise()
.query(`DELETE FROM attachment WHERE id = ?`, [attachmentId])
.then((rows, fields) => resolve(true))
.catch(console.log)
} }
db.promise()
.query(`DELETE FROM attachment WHERE id = ?`, [attachmentId])
.then((rows, fields) => { })
.catch(console.log)
return resolve(true)
}) })
}) })
} }

View File

@ -299,7 +299,7 @@ Note.reindex = (userId, masterKey, removeId = null) => {
return db.promise().query(` return db.promise().query(`
SELECT note.id, text, salt, encrypted_share_password_key FROM note SELECT note.id, text, salt, encrypted_share_password_key FROM note
JOIN note_raw_text ON note.note_raw_text_id = note_raw_text.id JOIN note_raw_text ON note.note_raw_text_id = note_raw_text.id
WHERE indexed = 0 AND salt IS NOT NULL WHERE indexed = 0 AND salt IS NOT NULL AND trashed = 0
AND user_id = ? LIMIT 100`, [userId]) AND user_id = ? LIMIT 100`, [userId])
}) })
@ -610,7 +610,7 @@ Note.setArchived = (userId, noteId, archivedBoolead) => {
}) })
} }
Note.setTrashed = (userId, noteId, trashedBoolean) => { Note.setTrashed = (userId, noteId, trashedBoolean, masterKey) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const trashed = trashedBoolean ? 1:0 const trashed = trashedBoolean ? 1:0
@ -618,9 +618,18 @@ Note.setTrashed = (userId, noteId, trashedBoolean) => {
//Update other note attributes //Update other note attributes
return db.promise() return db.promise()
.query('UPDATE note JOIN note_raw_text ON note_raw_text_id = note_raw_text.id SET trashed = ?, updated = ? WHERE note.id = ? AND user_id = ?', .query('UPDATE note JOIN note_raw_text ON note_raw_text_id = note_raw_text.id SET trashed = ?, updated = ?, indexed = 0 WHERE note.id = ? AND user_id = ?',
[trashed, now, noteId, userId]) [trashed, now, noteId, userId])
.then((rows, fields) => { .then((rows, fields) => {
const removeFromIndex = []
if(trashed){
//Remove note from index
removeFromIndex.push(noteId)
}
Note.reindex(userId, masterKey, removeFromIndex)
SocketIo.to(userId).emit('note_attribute_modified', noteId) SocketIo.to(userId).emit('note_attribute_modified', noteId)
resolve(true) resolve(true)
}) })
@ -1016,12 +1025,16 @@ Note.search = (userId, searchQuery, searchTags, fastFilters, masterKey) => {
//If tags are passed, use those tags in search //If tags are passed, use those tags in search
if(searchTags.length > 0){ if(searchTags.length > 0){
searchParams.push(searchTags) searchParams.push(searchTags)
noteSearchQuery += ' AND note_tag.tag_id IN (?)' noteSearchQuery += ' AND note_tag.tag_id IN (?) AND note.trashed = 0'
searchAllNotes = true
} }
//Show archived notes, only if fast filter is set, default to not archived //Show archived notes, only if fast filter is set, default to not archived
if(searchAllNotes == false){ if(searchAllNotes == false){
//Default set of filters for all notes
if(fastFilters.notesHome == 1){ if(fastFilters.notesHome == 1){
noteSearchQuery += ' AND note.archived = 0 AND note.trashed = 0 AND note.share_user_id IS NULL' noteSearchQuery += ' AND note.archived = 0 AND note.trashed = 0 AND note.share_user_id IS NULL'
} }

View File

@ -17,7 +17,7 @@ Tag.userTags = (userId, searchQuery, searchTags, fastFilters) => {
FROM tag FROM tag
JOIN note_tag ON tag.id = note_tag.tag_id JOIN note_tag ON tag.id = note_tag.tag_id
JOIN note ON note.id = note_tag.note_id JOIN note ON note.id = note_tag.note_id
WHERE note_tag.user_id = ? WHERE note_tag.user_id = ? AND note.trashed = 0
` `
query += ` GROUP BY tag.id query += ` GROUP BY tag.id

View File

@ -29,7 +29,7 @@ router.post('/get', function (req, res) {
}) })
router.post('/delete', function (req, res) { router.post('/delete', function (req, res) {
Note.delete(userId, req.body.noteId) Note.delete(userId, req.body.noteId, masterKey)
.then( data => res.send(data) ) .then( data => res.send(data) )
}) })
@ -82,7 +82,7 @@ router.post('/setarchived', function (req, res) {
}) })
}) })
router.post('/settrashed', function (req, res) { router.post('/settrashed', function (req, res) {
Note.setTrashed(userId, req.body.noteId, req.body.trashed) Note.setTrashed(userId, req.body.noteId, req.body.trashed, masterKey)
.then( results => { .then( results => {
res.send(results) res.send(results)
}) })