mirror of https://github.com/immich-app/immich.git
parent
d34585e4b0
commit
4cdc59e51c
@ -0,0 +1,2 @@
|
|||||||
|
build/
|
||||||
|
.docusaurus/
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"printWidth": 120,
|
||||||
|
"semi": true
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"label": "Administration",
|
"label": "Administration",
|
||||||
"position": 4
|
"position": 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,147 +1,161 @@
|
|||||||
import lunr from "@generated/lunr.client";
|
import lunr from '@generated/lunr.client';
|
||||||
lunr.tokenizer.separator = /[\s\-/]+/;
|
lunr.tokenizer.separator = /[\s\-/]+/;
|
||||||
|
|
||||||
class LunrSearchAdapter {
|
class LunrSearchAdapter {
|
||||||
constructor(searchDocs, searchIndex, baseUrl = '/') {
|
constructor(searchDocs, searchIndex, baseUrl = '/') {
|
||||||
this.searchDocs = searchDocs;
|
this.searchDocs = searchDocs;
|
||||||
this.lunrIndex = lunr.Index.load(searchIndex);
|
this.lunrIndex = lunr.Index.load(searchIndex);
|
||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLunrResult(input) {
|
getLunrResult(input) {
|
||||||
return this.lunrIndex.query(function (query) {
|
return this.lunrIndex.query(function (query) {
|
||||||
const tokens = lunr.tokenizer(input);
|
const tokens = lunr.tokenizer(input);
|
||||||
query.term(tokens, {
|
query.term(tokens, {
|
||||||
boost: 10
|
boost: 10,
|
||||||
});
|
});
|
||||||
query.term(tokens, {
|
query.term(tokens, {
|
||||||
wildcard: lunr.Query.wildcard.TRAILING
|
wildcard: lunr.Query.wildcard.TRAILING,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getHit(doc, formattedTitle, formattedContent) {
|
getHit(doc, formattedTitle, formattedContent) {
|
||||||
return {
|
return {
|
||||||
hierarchy: {
|
hierarchy: {
|
||||||
lvl0: doc.pageTitle || doc.title,
|
lvl0: doc.pageTitle || doc.title,
|
||||||
lvl1: doc.type === 0 ? null : doc.title
|
lvl1: doc.type === 0 ? null : doc.title,
|
||||||
|
},
|
||||||
|
url: doc.url,
|
||||||
|
_snippetResult: formattedContent
|
||||||
|
? {
|
||||||
|
content: {
|
||||||
|
value: formattedContent,
|
||||||
|
matchLevel: 'full',
|
||||||
},
|
},
|
||||||
url: doc.url,
|
}
|
||||||
_snippetResult: formattedContent ? {
|
: null,
|
||||||
content: {
|
_highlightResult: {
|
||||||
value: formattedContent,
|
hierarchy: {
|
||||||
matchLevel: "full"
|
lvl0: {
|
||||||
}
|
value: doc.type === 0 ? formattedTitle || doc.title : doc.pageTitle,
|
||||||
} : null,
|
},
|
||||||
_highlightResult: {
|
lvl1:
|
||||||
hierarchy: {
|
doc.type === 0
|
||||||
lvl0: {
|
? null
|
||||||
value: doc.type === 0 ? formattedTitle || doc.title : doc.pageTitle,
|
: {
|
||||||
},
|
value: formattedTitle || doc.title,
|
||||||
lvl1:
|
},
|
||||||
doc.type === 0
|
},
|
||||||
? null
|
},
|
||||||
: {
|
};
|
||||||
value: formattedTitle || doc.title
|
}
|
||||||
}
|
getTitleHit(doc, position, length) {
|
||||||
}
|
const start = position[0];
|
||||||
}
|
const end = position[0] + length;
|
||||||
};
|
let formattedTitle =
|
||||||
|
doc.title.substring(0, start) +
|
||||||
|
'<span class="algolia-docsearch-suggestion--highlight">' +
|
||||||
|
doc.title.substring(start, end) +
|
||||||
|
'</span>' +
|
||||||
|
doc.title.substring(end, doc.title.length);
|
||||||
|
return this.getHit(doc, formattedTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
getKeywordHit(doc, position, length) {
|
||||||
|
const start = position[0];
|
||||||
|
const end = position[0] + length;
|
||||||
|
let formattedTitle =
|
||||||
|
doc.title +
|
||||||
|
'<br /><i>Keywords: ' +
|
||||||
|
doc.keywords.substring(0, start) +
|
||||||
|
'<span class="algolia-docsearch-suggestion--highlight">' +
|
||||||
|
doc.keywords.substring(start, end) +
|
||||||
|
'</span>' +
|
||||||
|
doc.keywords.substring(end, doc.keywords.length) +
|
||||||
|
'</i>';
|
||||||
|
return this.getHit(doc, formattedTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
getContentHit(doc, position) {
|
||||||
|
const start = position[0];
|
||||||
|
const end = position[0] + position[1];
|
||||||
|
let previewStart = start;
|
||||||
|
let previewEnd = end;
|
||||||
|
let ellipsesBefore = true;
|
||||||
|
let ellipsesAfter = true;
|
||||||
|
for (let k = 0; k < 3; k++) {
|
||||||
|
const nextSpace = doc.content.lastIndexOf(' ', previewStart - 2);
|
||||||
|
const nextDot = doc.content.lastIndexOf('.', previewStart - 2);
|
||||||
|
if (nextDot > 0 && nextDot > nextSpace) {
|
||||||
|
previewStart = nextDot + 1;
|
||||||
|
ellipsesBefore = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nextSpace < 0) {
|
||||||
|
previewStart = 0;
|
||||||
|
ellipsesBefore = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previewStart = nextSpace + 1;
|
||||||
}
|
}
|
||||||
getTitleHit(doc, position, length) {
|
for (let k = 0; k < 10; k++) {
|
||||||
const start = position[0];
|
const nextSpace = doc.content.indexOf(' ', previewEnd + 1);
|
||||||
const end = position[0] + length;
|
const nextDot = doc.content.indexOf('.', previewEnd + 1);
|
||||||
let formattedTitle = doc.title.substring(0, start) + '<span class="algolia-docsearch-suggestion--highlight">' + doc.title.substring(start, end) + '</span>' + doc.title.substring(end, doc.title.length);
|
if (nextDot > 0 && nextDot < nextSpace) {
|
||||||
return this.getHit(doc, formattedTitle)
|
previewEnd = nextDot;
|
||||||
|
ellipsesAfter = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nextSpace < 0) {
|
||||||
|
previewEnd = doc.content.length;
|
||||||
|
ellipsesAfter = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previewEnd = nextSpace;
|
||||||
}
|
}
|
||||||
|
let preview = doc.content.substring(previewStart, start);
|
||||||
getKeywordHit(doc, position, length) {
|
if (ellipsesBefore) {
|
||||||
const start = position[0];
|
preview = '... ' + preview;
|
||||||
const end = position[0] + length;
|
|
||||||
let formattedTitle = doc.title + '<br /><i>Keywords: ' + doc.keywords.substring(0, start) + '<span class="algolia-docsearch-suggestion--highlight">' + doc.keywords.substring(start, end) + '</span>' + doc.keywords.substring(end, doc.keywords.length) + '</i>'
|
|
||||||
return this.getHit(doc, formattedTitle)
|
|
||||||
}
|
}
|
||||||
|
preview += '<span class="algolia-docsearch-suggestion--highlight">' + doc.content.substring(start, end) + '</span>';
|
||||||
getContentHit(doc, position) {
|
preview += doc.content.substring(end, previewEnd);
|
||||||
const start = position[0];
|
if (ellipsesAfter) {
|
||||||
const end = position[0] + position[1];
|
preview += ' ...';
|
||||||
let previewStart = start;
|
}
|
||||||
let previewEnd = end;
|
return this.getHit(doc, null, preview);
|
||||||
let ellipsesBefore = true;
|
}
|
||||||
let ellipsesAfter = true;
|
search(input) {
|
||||||
for (let k = 0; k < 3; k++) {
|
return new Promise((resolve, rej) => {
|
||||||
const nextSpace = doc.content.lastIndexOf(' ', previewStart - 2);
|
const results = this.getLunrResult(input);
|
||||||
const nextDot = doc.content.lastIndexOf('.', previewStart - 2);
|
const hits = [];
|
||||||
if ((nextDot > 0) && (nextDot > nextSpace)) {
|
results.length > 5 && (results.length = 5);
|
||||||
previewStart = nextDot + 1;
|
this.titleHitsRes = [];
|
||||||
ellipsesBefore = false;
|
this.contentHitsRes = [];
|
||||||
break;
|
results.forEach((result) => {
|
||||||
}
|
const doc = this.searchDocs[result.ref];
|
||||||
if (nextSpace < 0) {
|
const { metadata } = result.matchData;
|
||||||
previewStart = 0;
|
for (let i in metadata) {
|
||||||
ellipsesBefore = false;
|
if (metadata[i].title) {
|
||||||
break;
|
if (!this.titleHitsRes.includes(result.ref)) {
|
||||||
}
|
const position = metadata[i].title.position[0];
|
||||||
previewStart = nextSpace + 1;
|
hits.push(this.getTitleHit(doc, position, input.length));
|
||||||
}
|
this.titleHitsRes.push(result.ref);
|
||||||
for (let k = 0; k < 10; k++) {
|
|
||||||
const nextSpace = doc.content.indexOf(' ', previewEnd + 1);
|
|
||||||
const nextDot = doc.content.indexOf('.', previewEnd + 1);
|
|
||||||
if ((nextDot > 0) && (nextDot < nextSpace)) {
|
|
||||||
previewEnd = nextDot;
|
|
||||||
ellipsesAfter = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (nextSpace < 0) {
|
|
||||||
previewEnd = doc.content.length;
|
|
||||||
ellipsesAfter = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
previewEnd = nextSpace;
|
} else if (metadata[i].content) {
|
||||||
}
|
const position = metadata[i].content.position[0];
|
||||||
let preview = doc.content.substring(previewStart, start);
|
hits.push(this.getContentHit(doc, position));
|
||||||
if (ellipsesBefore) {
|
} else if (metadata[i].keywords) {
|
||||||
preview = '... ' + preview;
|
const position = metadata[i].keywords.position[0];
|
||||||
|
hits.push(this.getKeywordHit(doc, position, input.length));
|
||||||
|
this.titleHitsRes.push(result.ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
preview += '<span class="algolia-docsearch-suggestion--highlight">' + doc.content.substring(start, end) + '</span>';
|
});
|
||||||
preview += doc.content.substring(end, previewEnd);
|
hits.length > 5 && (hits.length = 5);
|
||||||
if (ellipsesAfter) {
|
resolve(hits);
|
||||||
preview += ' ...';
|
});
|
||||||
}
|
}
|
||||||
return this.getHit(doc, null, preview);
|
|
||||||
|
|
||||||
}
|
|
||||||
search(input) {
|
|
||||||
return new Promise((resolve, rej) => {
|
|
||||||
const results = this.getLunrResult(input);
|
|
||||||
const hits = [];
|
|
||||||
results.length > 5 && (results.length = 5);
|
|
||||||
this.titleHitsRes = []
|
|
||||||
this.contentHitsRes = []
|
|
||||||
results.forEach(result => {
|
|
||||||
const doc = this.searchDocs[result.ref];
|
|
||||||
const { metadata } = result.matchData;
|
|
||||||
for (let i in metadata) {
|
|
||||||
if (metadata[i].title) {
|
|
||||||
if (!this.titleHitsRes.includes(result.ref)) {
|
|
||||||
const position = metadata[i].title.position[0]
|
|
||||||
hits.push(this.getTitleHit(doc, position, input.length));
|
|
||||||
this.titleHitsRes.push(result.ref);
|
|
||||||
}
|
|
||||||
} else if (metadata[i].content) {
|
|
||||||
const position = metadata[i].content.position[0]
|
|
||||||
hits.push(this.getContentHit(doc, position))
|
|
||||||
} else if (metadata[i].keywords) {
|
|
||||||
const position = metadata[i].keywords.position[0]
|
|
||||||
hits.push(this.getKeywordHit(doc, position, input.length));
|
|
||||||
this.titleHitsRes.push(result.ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
hits.length > 5 && (hits.length = 5);
|
|
||||||
resolve(hits);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LunrSearchAdapter;
|
export default LunrSearchAdapter;
|
||||||
|
|||||||
Loading…
Reference in New Issue