parent
b2f241dbba
commit
8d3762e106
@ -85,7 +85,7 @@
|
|||||||
|
|
||||||
<!-- Tags -->
|
<!-- Tags -->
|
||||||
<nm-button
|
<nm-button
|
||||||
v-on:click.native="showTagSlideMenu = !showTagSlideMenu"
|
v-on:click.native="showTagSlideMenu = !showTagSlideMenu; modified = true"
|
||||||
icon="tags"
|
icon="tags"
|
||||||
text="Tags"
|
text="Tags"
|
||||||
tip="Tags"
|
tip="Tags"
|
||||||
|
@ -259,8 +259,6 @@
|
|||||||
},
|
},
|
||||||
removeTag(tagId){
|
removeTag(tagId){
|
||||||
|
|
||||||
console.log(tagId)
|
|
||||||
|
|
||||||
let postData = {
|
let postData = {
|
||||||
'tagId':tagId,
|
'tagId':tagId,
|
||||||
'noteId':this.noteId
|
'noteId':this.noteId
|
||||||
|
@ -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 && textResults" class="term-usage">
|
<div v-if="note.note_highlights.length > 0" 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"
|
||||||
|
@ -49,7 +49,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,72 +61,33 @@
|
|||||||
|
|
||||||
<!-- 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 v-if="notes !== null && notes.length > 0"
|
<div :class="{'one-column':(
|
||||||
:class="{'one-column':(
|
|
||||||
(activeNoteId1 != null || activeNoteId2 != null) &&
|
(activeNoteId1 != null || activeNoteId2 != null) &&
|
||||||
!$store.getters.getIsUserOnMobile
|
!$store.getters.getIsUserOnMobile
|
||||||
)}">
|
)}">
|
||||||
|
|
||||||
<!-- pinned notes -->
|
<!-- render each section based on notes in set -->
|
||||||
<div v-if="containsPinnednotes > 0" class="note-card-section">
|
<div v-for="section,index in noteSections" v-if="section.length > 0" class="note-card-section">
|
||||||
<!-- ({{containsPinnednotes}}) -->
|
<h4><i :class="`green ${sectionData[index][0]} icon`"></i>{{ sectionData[index][1] }}</h4>
|
||||||
<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 notes"
|
v-for="note in section"
|
||||||
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"
|
: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"
|
||||||
/>
|
/>
|
||||||
</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>
|
|
||||||
|
|
||||||
<!-- 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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -206,14 +167,22 @@
|
|||||||
|
|
||||||
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: [],
|
||||||
'recieved': {},
|
shared:[],
|
||||||
'sent':{},
|
sent:[],
|
||||||
'notes':{},
|
notes: [],
|
||||||
'textMatch':{}
|
highlights: [],
|
||||||
}
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -232,18 +201,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
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
|
||||||
this.notes.forEach( (note, index) => {
|
Object.keys(this.noteSections).forEach( key => {
|
||||||
if(note.id == noteId){
|
this.noteSections[key].forEach( (note, index) => {
|
||||||
if(note.pinned == 1){
|
if(note.id == noteId){
|
||||||
this.containsPinnednotes--
|
this.noteSections[key].splice(index,1)
|
||||||
} else {
|
return
|
||||||
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
|
||||||
@ -404,8 +373,6 @@
|
|||||||
//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){
|
||||||
|
|
||||||
@ -444,7 +411,6 @@
|
|||||||
//@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( () => {
|
||||||
@ -475,53 +441,52 @@
|
|||||||
let foundNote = false
|
let foundNote = false
|
||||||
|
|
||||||
if(newNote === undefined){
|
if(newNote === undefined){
|
||||||
console.log('Note not visible on this page')
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Go through each note and find the one just updated
|
//Find Just updated note and modify all its attributes
|
||||||
this.notes.forEach( (note,index) => {
|
Object.keys(this.noteSections).forEach(key => {
|
||||||
|
|
||||||
if(note.id == noteId){
|
this.noteSections[key].forEach( (note,index) => {
|
||||||
foundNote = true
|
|
||||||
|
if(note.id == noteId){
|
||||||
|
foundNote = true
|
||||||
|
|
||||||
|
//Don't move notes that were not changed
|
||||||
|
if(note.updated == newNote.updated){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Compare note tags, if they changed, reload tags
|
||||||
|
if(newNote.tag_count != note.tag_count){
|
||||||
|
this.fetchUserTags()
|
||||||
|
}
|
||||||
|
|
||||||
|
//go through each prop and update it with new values
|
||||||
|
Object.keys(newNote).forEach(prop => {
|
||||||
|
note[prop] = newNote[prop]
|
||||||
|
})
|
||||||
|
|
||||||
|
//Remove note from location and push to front
|
||||||
|
this.noteSections[key].splice(index, 1)
|
||||||
|
this.noteSections[key].unshift(note)
|
||||||
|
|
||||||
//Don't move notes that were not changed
|
|
||||||
if(note.updated == newNote.updated){
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
})
|
||||||
//Compare note tags, if they changed, reload tags
|
|
||||||
if(newNote.tag_count != note.tag_count){
|
|
||||||
console.log('Tags changed, update those bitches')
|
|
||||||
this.fetchUserTags()
|
|
||||||
}
|
|
||||||
|
|
||||||
//go through each prop and update it with new values
|
|
||||||
Object.keys(newNote).forEach(prop => {
|
|
||||||
note[prop] = newNote[prop]
|
|
||||||
})
|
|
||||||
|
|
||||||
this.notes.splice(index, 1)
|
|
||||||
this.notes.unshift(note)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
//This note was not found, update it in list
|
//New notes don't exist in list, push them to the front
|
||||||
if(foundNote == false){
|
if(!foundNote){
|
||||||
if(newNote.pinned == 1){
|
this.noteSections.notes.unshift(newNote)
|
||||||
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
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -549,10 +514,6 @@
|
|||||||
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)
|
||||||
@ -570,8 +531,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
|
||||||
@ -581,49 +542,62 @@
|
|||||||
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)
|
||||||
|
@ -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++
|
||||||
|
@ -434,6 +434,7 @@ 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']
|
||||||
@ -484,11 +485,13 @@ 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
|
||||||
@ -498,10 +501,12 @@ 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(fastFilters.onlyArchived == 1){
|
if(searchAllNotes == false){
|
||||||
noteSearchQuery += ' AND note.archived = 1' //Show Archived
|
if(fastFilters.onlyArchived == 1){
|
||||||
} else {
|
noteSearchQuery += ' AND note.archived = 1' //Show Archived
|
||||||
noteSearchQuery += ' AND note.archived = 0' //Exclude archived
|
} else {
|
||||||
|
noteSearchQuery += ' AND note.archived = 0' //Exclude archived
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Finish up note query
|
//Finish up note query
|
||||||
|
Loading…
Reference in New Issue
Block a user