* Added an auth screen that isn't integrated at all or working

* Force logout of user with authorization error
* Wrong site blocker doesn't trigger on the solid scribe domain
* Added log out button to main side bar making it easier to find
* Improved icon set for notes
* Colored notes display better on mobile, fixed text color based on color brightness
* Moved terms of use link to the bottom of a few pages
* Updated feature sections on home page, make them clearer and easier to process
* Tweaked color themes
* Deleted links no longer show up in search
* Updated search to use multiple key words
* Updated tests to do a multi word search
* Tweaked a bunch of styles to look better on chrome and browsers
This commit is contained in:
Max G
2020-08-03 02:40:27 +00:00
parent b34a62e114
commit b0c487404c
17 changed files with 399 additions and 193 deletions

View File

@@ -32,6 +32,7 @@ Attachment.textSearch = (userId, searchTerm) => {
) as snippet
FROM attachment
WHERE user_id = ?
AND visible != 0
AND MATCH(text)
AGAINST(? IN NATURAL LANGUAGE MODE)
LIMIT 1000`

View File

@@ -42,7 +42,7 @@ Note.test = (userId, masterKey, printResults) => {
testNoteId = newNoteId
return Note.update
(userId, testNoteId, 'Note text', 'Test Note beans Title', 0, 0, 0, 'hash', masterKey)
(userId, testNoteId, 'Note text', 'Test Note beans barns Title', 0, 0, 0, 'hash', masterKey)
})
.then(() => {
@@ -63,14 +63,14 @@ Note.test = (userId, masterKey, printResults) => {
if(printResults) console.log('Test: Reindex normal note - Pass')
return Note.encryptedIndexSearch(userId, 'beans', null, masterKey)
return Note.encryptedIndexSearch(userId, 'beans barns', null, masterKey)
})
.then(textSearchResults => {
if(textSearchResults['ids'] && textSearchResults['ids'].length >= 1){
if(printResults) console.log('Test: Normal Note Search Index - Pass')
} else { console.log('Test: Search Index - Fail') }
} else { console.log('Test: Search Index - Fail-------------> 🥱') }
return ShareNote.addUserToSharedNote(userId, testNoteId, shareUserId, masterKey)
})
@@ -868,39 +868,98 @@ Note.encryptedIndexSearch = (userId, searchQuery, searchTags, masterKey) => {
const decipheredSearchIndex = cs.decrypt(masterKey, row.salt, row.index)
const searchIndex = JSON.parse(decipheredSearchIndex)
//Clean up search word
const word = searchQuery.toLowerCase().replace(/[^a-z0-9]/g, '')
//Clean up search word, leave in spaces, split to array
const words = searchQuery.toLowerCase().replace(/[^a-z0-9 ]/g, '').split(' ')
let noteIds = []
let partials = []
Object.keys(searchIndex).forEach(wordIndex => {
if( wordIndex.indexOf(word) != -1 && wordIndex != word){
partials.push(wordIndex)
noteIds.push(...searchIndex[wordIndex])
let wordSearchCount = 0;
let partialWords = [] //For debugging
let exactWords = [] //For debugging
let exactWordIdSets = []
let partialMatchNoteIds = []
words.forEach(word => {
//Skip short words
if(word.length <= 2){
return
}
//count all words being searched
wordSearchCount++
//Save all exact match sets if found
if(searchIndex[word]){
// exactWords.push(word) //Words for debugging
exactWordIdSets.push(...searchIndex[word])
}
//Find all partial word matches in index
Object.keys(searchIndex).forEach(wordIndex => {
if( wordIndex.indexOf(word) != -1 && wordIndex != word){
// partialWords.push(wordIndex) //partialWords for debugging
partialMatchNoteIds.push(...searchIndex[wordIndex])
}
})
})
const exactArray = searchIndex[word] ? searchIndex[word] : []
//If more than one work was searched, remove notes that don't contain both
if(words.length > 1 && exactWordIdSets.length > 0){
let searchData = {
'word':word,
'exact': exactArray,
'partials': partials,
'partial': [...new Set(noteIds) ],
//Find ids that appear more than once, this means there was an exact match in more than one note
let overlappingIds = exactWordIdSets.filter((e, i, a) => a.indexOf(e) !== i)
overlappingIds = [...new Set(overlappingIds)]
//If there are notes that appear
if(overlappingIds.length > 0){
exactWordIdSets = overlappingIds
}
//If note appears in partial and exact, show only that set
const partialIntersect = exactWordIdSets.filter(x => partialMatchNoteIds.includes(x))
if(partialIntersect.length > 0){
exactWordIdSets = partialIntersect
partialMatchNoteIds = []
}
}
//Remove duplicates from final id sets
let finalExact = [ ...new Set(exactWordIdSets) ]
let finalPartial = [ ...new Set(partialMatchNoteIds) ]
//Remove exact matches from partials set if there is overlap
if(searchData['exact'].length > 0 && searchData['partial'].length > 0){
searchData['partial'] = searchData['partial']
.filter( ( el ) => !searchData['exact'].includes( el ) )
if(finalExact.length > 0 && finalPartial.length > 0){
finalPartial = finalPartial
.filter( ( el ) => !finalExact.includes( el ) )
}
searchData['ids'] = searchData['exact'].concat(searchData['partial'])
searchData['total'] = searchData['ids'].length
//Combine the two filtered sets
let finalIdSearchSet = finalExact.concat(finalPartial)
// console.log(searchData['total'])
// let searchData = {
// 'query':searchQuery,
// 'words_count': words.length,
// 'exact_matches': exactWordIdSets.length,
// 'word_search_count': wordSearchCount,
// 'exactWords': exactWords,
// 'exact': finalExact,
// 'partialWords': partialWords,
// 'partial': finalPartial,
// }
return resolve({ 'ids':searchData['ids'] })
// //Lump all found note ids into one array
// searchData['ids'] = finalIdSearchSet
// searchData['total'] = searchData['ids'].length
// console.log('-----------------')
// console.log(searchData)
// console.log('-----------------')
return resolve({ 'ids':finalIdSearchSet })
} else {
@@ -971,7 +1030,8 @@ Note.search = (userId, searchQuery, searchTags, fastFilters, masterKey) => {
GROUP_CONCAT(DISTINCT attachment.file_location) as thumbs,
shareUser.username as shareUsername,
note.shared,
note.encrypted_share_password_key
note.encrypted_share_password_key,
note.indexed
FROM note
JOIN note_raw_text ON (note_raw_text.id = note.note_raw_text_id)
LEFT JOIN note_tag ON (note.id = note_tag.note_id)