Compare commits

..

No commits in common. "8d3762e1061929142d25048570eeb98d2d99ebc7" and "8833a213a7880ba7b63dd3682466d5e66dad6c7c" have entirely different histories.

8 changed files with 158 additions and 175 deletions

View File

@ -79,7 +79,7 @@
totals(newVal, oldVal){ totals(newVal, oldVal){
if(oldVal && newVal && newVal[this.numberId] != oldVal[this.numberId]){ if(oldVal && newVal && newVal[this.numberId] != oldVal[this.numberId]){
// console.log('New number ', newVal[this.numberId]) console.log('New number ', newVal[this.numberId])
this.oldNumber = oldVal[this.numberId] this.oldNumber = oldVal[this.numberId]
this.newNumber = newVal[this.numberId] this.newNumber = newVal[this.numberId]
@ -90,6 +90,7 @@
this.animateUp = true this.animateUp = true
} }
setTimeout( () => { setTimeout( () => {
this.animateUp = false this.animateUp = false
this.animateDown = false this.animateDown = false

View File

@ -85,7 +85,7 @@
<!-- Tags --> <!-- Tags -->
<nm-button <nm-button
v-on:click.native="showTagSlideMenu = !showTagSlideMenu; modified = true" v-on:click.native="showTagSlideMenu = !showTagSlideMenu"
icon="tags" icon="tags"
text="Tags" text="Tags"
tip="Tags" tip="Tags"

View File

@ -259,6 +259,8 @@
}, },
removeTag(tagId){ removeTag(tagId){
console.log(tagId)
let postData = { let postData = {
'tagId':tagId, 'tagId':tagId,
'noteId':this.noteId 'noteId':this.noteId

View File

@ -32,7 +32,7 @@
v-html="note.subtext"></div> v-html="note.subtext"></div>
<!-- Display highlights from solr results --> <!-- Display highlights from solr results -->
<div v-if="note.note_highlights.length > 0" class="term-usage"> <div v-if="note.note_highlights.length > 0 && textResults" class="term-usage">
<div <div
class="usage-row" class="usage-row"
v-for="highlight in note.note_highlights" v-for="highlight in note.note_highlights"

View File

@ -28,7 +28,6 @@
<i class="green archive icon"></i>Archived <i class="green archive icon"></i>Archived
<!-- <span>{{ $store.getters.totals['archivedNotes'] }}</span> --> <!-- <span>{{ $store.getters.totals['archivedNotes'] }}</span> -->
</div> </div>
</div> </div>
<div class="eight wide column" v-if="showClear"> <div class="eight wide column" v-if="showClear">
@ -49,7 +48,7 @@
<h2 v-if="fastFilters['onlyArchived'] == 1">Archived Notes</h2> <h2 v-if="fastFilters['onlyArchived'] == 1">Archived Notes</h2>
<h2 v-if="fastFilters['onlyShowSharedNotes'] == 1">Shared Notes</h2> <h2 v-if="fastFilters['onlyShowSharedNotes'] == 1">Shared Notes</h2>
<!-- tags section -->
<div v-if="commonTags.length > 0" class="sixteen wide column"> <div v-if="commonTags.length > 0" class="sixteen wide column">
<h4><i class="green tags icon"></i>Tags</h4> <h4><i class="green tags icon"></i>Tags</h4>
<span v-for="tag in commonTags" @click="toggleTagFilter(tag.id)"> <span v-for="tag in commonTags" @click="toggleTagFilter(tag.id)">
@ -61,35 +60,74 @@
<!-- Note title card display --> <!-- Note title card display -->
<div class="sixteen wide column"> <div class="sixteen wide column">
<h3 v-if="searchTerm.length > 0 && notes.length == 0">No notes found. Check your spelling, try completing the word or using a different phrase.</h3>
<h3 v-if="$store.getters.totals && $store.getters.totals['totalNotes'] == 0"> <h3 v-if="$store.getters.totals && $store.getters.totals['totalNotes'] == 0">
No Notes Yet. Create one when you feel ready. No Notes Yet. Create one when you feel ready.
</h3> </h3>
<!-- <div v-if="working">
<div class="ui active inline loader"></div> Working...
</div> -->
<!-- Go to one wide column, do not do this on mobile interface --> <!-- Go to one wide column, do not do this on mobile interface -->
<div :class="{'one-column':( <div v-if="notes !== null && notes.length > 0"
:class="{'one-column':(
(activeNoteId1 != null || activeNoteId2 != null) && (activeNoteId1 != null || activeNoteId2 != null) &&
!$store.getters.getIsUserOnMobile !$store.getters.getIsUserOnMobile
)}"> )}">
<!-- render each section based on notes in set --> <!-- pinned notes -->
<div v-for="section,index in noteSections" v-if="section.length > 0" class="note-card-section"> <div v-if="containsPinnednotes > 0" class="note-card-section">
<h4><i :class="`green ${sectionData[index][0]} icon`"></i>{{ sectionData[index][1] }}</h4> <!-- ({{containsPinnednotes}}) -->
<h4><i class="green pin icon"></i>Pinned</h4>
<div class="note-card-display-area"> <div class="note-card-display-area">
<note-title-display-card <note-title-display-card
v-for="note in section" v-for="note in notes"
v-if="note.pinned"
:onClick="openNote" :onClick="openNote"
:data="note" :data="note"
:currently-open="(activeNoteId1 == note.id || activeNoteId2 == note.id)" :currently-open="(activeNoteId1 == note.id || activeNoteId2 == note.id)"
:key="note.id + note.color + note.note_highlights.length + note.attachment_highlights.length + ' -' + note.tag_highlights.length + '-' +note.title.length + '-' +note.subtext.length + '-' + note.tag_count + note.updated" :key="note.id + note.color + note.note_highlights.length + note.attachment_highlights.length + ' -' + note.tag_highlights.length + '-' +note.title.length + '-' +note.subtext.length"
/> />
</div> </div>
</div> </div>
<!-- normal notes -->
<div v-if="containsNormalNotes > 0" class="note-card-section">
<!-- ({{containsNormalNotes}}) -->
<h4><i class="green file icon"></i>Notes</h4>
<div class="note-card-display-area">
<note-title-display-card
v-for="note in notes"
v-if="note.note_highlights && !note.pinned"
:onClick="openNote"
:data="note"
:currently-open="(activeNoteId1 == note.id || activeNoteId2 == note.id)"
:key="note.id + note.color + note.note_highlights.length + note.attachment_highlights.length + ' -' + note.tag_highlights.length + '-' +note.title.length + '-' +note.subtext.length"
/>
</div> </div>
</div> </div>
<!-- found in text -->
<div v-if="containsTextResults" class="note-card-section">
<h4><i class="green paragraph icon"></i> Found in Text ({{containsTextResults}})</h4>
<div class="note-card-display-area">
<note-title-display-card
v-for="note in notes"
v-if="note.note_highlights && note.note_highlights.length"
:textResults="true"
:onClick="openNote"
:data="note"
:currently-open="(activeNoteId1 == note.id || activeNoteId2 == note.id)"
:key="note.id + note.color + note.note_highlights.length + note.attachment_highlights.length + ' -' + note.tag_highlights.length + '-' +note.title.length + '-' +note.subtext.length"
/>
</div>
</div>
</div>
</div>
<!-- found attachments --> <!-- found attachments -->
<div class="sixteen wide column" v-if="foundAttachments.length > 0"> <div class="sixteen wide column" v-if="foundAttachments.length > 0">
@ -167,22 +205,14 @@
foundAttachments: [], foundAttachments: [],
sectionData: {
'pinned': ['thumbtack', 'Pinned'],
'archived': ['archive', 'Archived'],
'shared': ['envelope outline', 'Received Notes'],
'sent': ['paper plane outline', 'Shared Notes'],
'notes': ['file','Notes'],
'highlights': ['paragraph', 'Found In Text']
},
noteSections: { noteSections: {
pinned: [], 'pinned': {},
archived: [], 'archived': {},
shared:[], 'recieved': {},
sent:[], 'sent':{},
notes: [], 'notes':{},
highlights: [], 'textMatch':{}
}, }
} }
}, },
@ -201,19 +231,19 @@
} }
}) })
this.$bus.$on('note_deleted', (noteId) => { this.$bus.$on('note_deleted', (noteId) => {
//Remove deleted note from set, its deleted //Remove deleted note from set, its deleted
Object.keys(this.noteSections).forEach( key => { this.notes.forEach( (note, index) => {
this.noteSections[key].forEach( (note, index) => {
if(note.id == noteId){ if(note.id == noteId){
this.noteSections[key].splice(index,1) if(note.pinned == 1){
return this.containsPinnednotes--
} else {
this.containsNormalNotes--
}
this.notes.splice(index, 1)
} }
}) })
}) })
})
this.$bus.$on('update_fast_filters', newFilter => { this.$bus.$on('update_fast_filters', newFilter => {
this.fastFilters = newFilter this.fastFilters = newFilter
//Fast filters always return all the results and tags //Fast filters always return all the results and tags
@ -373,6 +403,8 @@
//Determine percentage down the page //Determine percentage down the page
const percentageDown = Math.round( (bottomOfWindow/offsetHeight)*100 ) const percentageDown = Math.round( (bottomOfWindow/offsetHeight)*100 )
// console.log( percentageDown + '%' )
//If greater than 80 of the way down the page, load the next batch //If greater than 80 of the way down the page, load the next batch
if(percentageDown >= 80){ if(percentageDown >= 80){
@ -411,6 +443,7 @@
//@TODO - set a timeout on this like 2 minutes or just dont do shit and update it via socket.io //@TODO - set a timeout on this like 2 minutes or just dont do shit and update it via socket.io
//If user leaves page then returns to page, reload the first batch //If user leaves page then returns to page, reload the first batch
if(this.lastVisibilityState == 'hidden' && document.visibilityState == 'visible'){ if(this.lastVisibilityState == 'hidden' && document.visibilityState == 'visible'){
// console.log('Welcome back. Reloading a batch')
//Load initial batch, then tags, then other batch //Load initial batch, then tags, then other batch
this.search(false, this.firstLoadBatchSize) this.search(false, this.firstLoadBatchSize)
.then( () => { .then( () => {
@ -441,13 +474,12 @@
let foundNote = false let foundNote = false
if(newNote === undefined){ if(newNote === undefined){
console.log('Note not visible on this page')
return return
} }
//Find Just updated note and modify all its attributes //Go through each note and find the one just updated
Object.keys(this.noteSections).forEach(key => { this.notes.forEach( (note,index) => {
this.noteSections[key].forEach( (note,index) => {
if(note.id == noteId){ if(note.id == noteId){
foundNote = true foundNote = true
@ -459,6 +491,7 @@
//Compare note tags, if they changed, reload tags //Compare note tags, if they changed, reload tags
if(newNote.tag_count != note.tag_count){ if(newNote.tag_count != note.tag_count){
console.log('Tags changed, update those bitches')
this.fetchUserTags() this.fetchUserTags()
} }
@ -467,26 +500,27 @@
note[prop] = newNote[prop] note[prop] = newNote[prop]
}) })
//Remove note from location and push to front this.notes.splice(index, 1)
this.noteSections[key].splice(index, 1) this.notes.unshift(note)
this.noteSections[key].unshift(note)
return
} }
}) })
})
//New notes don't exist in list, push them to the front //This note was not found, update it in list
if(!foundNote){ if(foundNote == false){
this.noteSections.notes.unshift(newNote) if(newNote.pinned == 1){
this.containsPinnednotes++
} else {
this.containsNormalNotes++
}
this.notes.unshift(newNote)
} }
//Trigger section rebuild
this.rebuildNoteCategorise()
}) })
}, },
searchAttachments(){ searchAttachments(){
axios.post('/api/attachment/textsearch', {'searchTerm':this.searchTerm}) axios.post('/api/attachment/textsearch', {'searchTerm':this.searchTerm})
.then(results => { .then(results => {
console.log('Attachment Results')
console.log(results.data)
this.foundAttachments = results.data this.foundAttachments = results.data
}) })
}, },
@ -514,6 +548,10 @@
fastFilters: this.fastFilters, fastFilters: this.fastFilters,
} }
if(showLoading){
this.working = true
}
//Save initial post data on first load //Save initial post data on first load
if(this.initialPostData == null){ if(this.initialPostData == null){
this.initialPostData = JSON.stringify(postData) this.initialPostData = JSON.stringify(postData)
@ -531,8 +569,8 @@
//Perform search - or die //Perform search - or die
this.loadingInProgress = true this.loadingInProgress = true
axios.post('/api/note/search', postData) axios.post('/api/note/search', postData).
.then(response => { then(response => {
//Save the number of notes just loaded //Save the number of notes just loaded
this.batchOffset += response.data.notes.length this.batchOffset += response.data.notes.length
@ -542,62 +580,49 @@
this.commonTags = response.data.tags this.commonTags = response.data.tags
} }
//Either reload all notes with return data or merge return data
if(!mergeExisting){
this.notes = response.data.notes
} else {
this.notes = this.notes.concat(response.data.notes)
}
//Go through each note and see which section to display
let textResultsCount = 0
let pinnedResultsCount = 0
let normalNotesCount = 0
response.data.notes.forEach(note => {
if(note.note_highlights.length > 0){
textResultsCount++
return
}
if(note.pinned == 1){
pinnedResultsCount++
return
}
normalNotesCount++
})
if(!mergeExisting){
this.containsNormalNotes = normalNotesCount
this.containsPinnednotes = pinnedResultsCount
this.containsTextResults = textResultsCount
} else {
this.containsNormalNotes += normalNotesCount
this.containsPinnednotes += pinnedResultsCount
this.containsTextResults += textResultsCount
}
this.working = false
this.loadingInProgress = false this.loadingInProgress = false
this.generateNoteCategories(response.data.notes, mergeExisting)
return resolve(true) return resolve(true)
}) })
}) })
}, },
rebuildNoteCategorise(){
let currentNotes = []
Object.keys(this.noteSections).forEach( key => {
this.noteSections[key].forEach( note => {
currentNotes.push(note)
})
})
this.generateNoteCategories(currentNotes, false)
},
generateNoteCategories(notes, mergeExisting){
// Place each note in a category based on certain attributes and fast filters
//Reset all sections if we are not merging existing
if(!mergeExisting){
Object.keys(this.noteSections).forEach( key => {
this.noteSections[key] = []
})
}
//Sort notes into defined sections
notes.forEach(note => {
if(note.archived == 1 && this.fastFilters.onlyArchived == 1){
this.noteSections.archived.push(note)
return
}
if(note.shareUsername != null){
this.noteSections.shared.push(note)
return
}
//Only show sent notes section if shared is selected
if(note.shared == 2 && this.fastFilters.onlyShowSharedNotes == 1){
this.noteSections.sent.push(note)
return
}
if(note.note_highlights.length > 0){
this.noteSections.highlights.push(note)
return
}
// Pinned notes are always first, they can appear in the archive
if(note.pinned == 1){
this.noteSections.pinned.push(note)
return
}
this.noteSections.notes.push(note)
})
},
searchKeyUp(){ searchKeyUp(){
let vm = this let vm = this
clearTimeout(vm.searchDebounce) clearTimeout(vm.searchDebounce)

View File

@ -7,31 +7,11 @@
<i class="paper plane outline icon"></i> <i class="paper plane outline icon"></i>
<div class="content"> <div class="content">
Quick Quick
<div class="sub header">Rapidly save text</div> <div class="sub header">Add new information with great speed</div>
</div> </div>
</h2> </h2>
</div> </div>
<div class="sixteen wide middle aligned column">
<div class="ui compact basic button"
v-on:click="enterToSubmit = !enterToSubmit">
<i v-if="enterToSubmit" class="green toggle on icon"></i>
<i v-else class="toggle off icon"></i>
<span v-if="enterToSubmit">Save after Enter press</span>
<span v-else>CTRL + Enter to Save</span>
</div>
<div class="ui compact basic button"
v-on:click="pasteToSubmit = !pasteToSubmit">
<i v-if="pasteToSubmit" class="green check circle outline icon"></i>
<i v-else class="circle outline icon"></i>
Save after Pasting
</div>
</div>
<div class="ui sixteen wide column"> <div class="ui sixteen wide column">
<div class="ui form"> <div class="ui form">
<div class="field"> <div class="field">
@ -41,15 +21,14 @@
ref="fastInput" ref="fastInput"
v-model="newText" v-model="newText"
v-on:keydown="checkKeyup" v-on:keydown="checkKeyup"
v-on:paste="onPaste"
placeholder="Push to the top of the quick note." placeholder="Push to the top of the quick note."
></textarea> ></textarea>
</div> </div>
<div class="field"> <div class="field">
<div v-on:click="appendQuickNote" class="ui green button">Save</div> <div v-on:click="appendQuickNote" class="ui green button">Save (CRTL + Enter)</div>
<div v-if="quickNoteId" class="ui right floated basic button" v-on:click="$router.push('/attachments/note/'+quickNoteId)"> <div v-if="quickNoteId" class="ui right floated basic button" v-on:click="$router.push('/attachments/note/'+quickNoteId)">
<i class="folder open outline icon"></i> <i class="folder open outline icon"></i>
Files Quick Files + Links
</div> </div>
<div v-if="quickNoteId" v-on:click="openNoteEdit" class="ui right floated basic button"> <div v-if="quickNoteId" v-on:click="openNoteEdit" class="ui right floated basic button">
<i class="file outline icon"></i> <i class="file outline icon"></i>
@ -78,9 +57,7 @@
return { return {
newText: '', newText: '',
savedQuickNoteText: '', savedQuickNoteText: '',
quickNoteId: null, quickNoteId: null
pasteToSubmit: true,
enterToSubmit: true,
} }
}, },
beforeCreate: function(){ beforeCreate: function(){
@ -118,17 +95,9 @@
element.style.height = 'auto'; element.style.height = 'auto';
element.style.height = (element.scrollHeight + padding) +'px'; element.style.height = (element.scrollHeight + padding) +'px';
//Enter Key submits by default
if(event.keyCode == 13 && this.enterToSubmit == true){
this.appendQuickNote()
return
}
//Alternate submit
//If command+enter or control+enter is pressed, submit //If command+enter or control+enter is pressed, submit
if((event.metaKey || event.ctrlKey) && [13].includes(event.keyCode) && this.enterToSubmit == false){ if((event.metaKey || event.ctrlKey) && [13].includes(event.keyCode)){
this.appendQuickNote() this.appendQuickNote()
return
} }
}, },
appendQuickNote(){ appendQuickNote(){
@ -153,15 +122,6 @@
this.quickNoteId = results.data.id this.quickNoteId = results.data.id
}) })
}, },
onPaste(event){
if(this.pasteToSubmit == true){
setTimeout( () => {
this.appendQuickNote()
}, 10)
}
return true
},
} }
} }
</script> </script>

View File

@ -92,7 +92,7 @@ ProcessText.deduceNoteTitle = (inString) => {
//Empty line, may be a list open or close //Empty line, may be a list open or close
if(cleanLine.length == 0 && (startTags.includes(lineStart) || endTags.includes(lineStart) )){ if(cleanLine.length == 0 && (startTags.includes(lineStart) || endTags.includes(lineStart) )){
if(listStart == false){ if(listStart == false){
//charLimit = 400 //Double size for list notes charLimit = 400 //Double size for list notes
} }
finalLines.push(lines[i]) finalLines.push(lines[i])
totalLines++ totalLines++

View File

@ -434,7 +434,6 @@ Note.search = (userId, searchQuery, searchTags, fastFilters) => {
let textSearchIds = [] let textSearchIds = []
let highlights = {} let highlights = {}
let returnTagResults = false let returnTagResults = false
let searchAllNotes = false
if(textSearchResults != null){ if(textSearchResults != null){
textSearchIds = textSearchResults['ids'] textSearchIds = textSearchResults['ids']
@ -485,13 +484,11 @@ Note.search = (userId, searchQuery, searchTags, fastFilters) => {
if(textSearchIds.length > 0){ if(textSearchIds.length > 0){
searchParams.push(textSearchIds) searchParams.push(textSearchIds)
noteSearchQuery += ' AND note.id IN (?)' noteSearchQuery += ' AND note.id IN (?)'
searchAllNotes = true
} }
if(fastFilters.noteIdSet && fastFilters.noteIdSet.length > 0){ if(fastFilters.noteIdSet && fastFilters.noteIdSet.length > 0){
searchParams.push(fastFilters.noteIdSet) searchParams.push(fastFilters.noteIdSet)
noteSearchQuery += ' AND note.id IN (?)' noteSearchQuery += ' AND note.id IN (?)'
searchAllNotes = true
} }
//If tags are passed, use those tags in search //If tags are passed, use those tags in search
@ -501,13 +498,11 @@ Note.search = (userId, searchQuery, searchTags, fastFilters) => {
} }
//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(fastFilters.onlyArchived == 1){ if(fastFilters.onlyArchived == 1){
noteSearchQuery += ' AND note.archived = 1' //Show Archived noteSearchQuery += ' AND note.archived = 1' //Show Archived
} else { } else {
noteSearchQuery += ' AND note.archived = 0' //Exclude archived noteSearchQuery += ' AND note.archived = 0' //Exclude archived
} }
}
//Finish up note query //Finish up note query
noteSearchQuery += ' GROUP BY note.id' noteSearchQuery += ' GROUP BY note.id'