/** * Enable gif loading on hover */ function gifOver(thumbnail, hit) { let callee = arguments.callee; thumbnail.addEventListener("mouseover", function () { thumbnail.mouseStayedOver = true; window.setTimeout(function () { if (thumbnail.mouseStayedOver) { thumbnail.removeEventListener('mouseover', callee, false); //Load gif thumbnail.setAttribute("src", "f/" + hit["_id"]); } }, 600); }); thumbnail.addEventListener("mouseout", function () { //Reset timer thumbnail.mouseStayedOver = false; thumbnail.setAttribute("src", `t/${hit["_source"]["index"]}/${hit["_id"]}`); }) } function getContentHighlight(hit) { if (hit.hasOwnProperty("highlight")) { if (hit["highlight"].hasOwnProperty("content")) { return hit["highlight"]["content"][0]; } else if (hit["highlight"].hasOwnProperty("content.nGram")) { return hit["highlight"]["content.nGram"][0]; } } return undefined; } function getPathHighlight(hit) { if (hit.hasOwnProperty("highlight")) { if (hit["highlight"].hasOwnProperty("path.text")) { return hit["highlight"]["path.text"][0]; } else if (hit["highlight"].hasOwnProperty("path.nGram")) { return hit["highlight"]["path.nGram"][0]; } } return undefined; } function applyNameToTitle(hit, title, extension) { if (hit.hasOwnProperty("highlight")) { if (hit["highlight"].hasOwnProperty("name")) { title.insertAdjacentHTML('afterbegin', hit["highlight"]["name"] + extension); return; } else if (hit["highlight"].hasOwnProperty("name.nGram")) { title.insertAdjacentHTML('afterbegin', hit["highlight"]["name.nGram"] + extension); return; } } title.appendChild(document.createTextNode(hit["_source"]["name"] + extension)); } function shouldPlayVideo(hit) { const videoc = hit["_source"]["videoc"]; const mime = hit["_source"]["mime"]; return mime && mime.startsWith("video/") && !("parent" in hit["_source"]) && hit["_source"]["extension"] !== "mkv" && hit["_source"]["extension"] !== "avi" && videoc !== "hevc" && videoc !== "mpeg2video" && videoc !== "wmv3"; } function shouldDisplayRawImage(hit) { const mime = hit["_source"]["mime"]; return mime && mime.startsWith("image/") && hit["_source"]["mime"] && !hit["_source"]["parent"] && hit["_source"]["videoc"] !== "tiff" && hit["_source"]["videoc"] !== "raw" && hit["_source"]["videoc"] !== "ppm"; } function makePlaceholder(w, h, small) { let calc; if (small) { calc = w > h ? (64 / w / h) >= 100 ? (64 * w / h) : 64 : 64; } else { calc = w > h ? (175 / w / h) >= 272 ? (175 * w / h) : 175 : 175; } const el = document.createElement("div"); el.setAttribute("style", `height: ${calc}px`); return el; } function ext(hit) { return hit["_source"].hasOwnProperty("extension") && hit["_source"]["extension"] !== "" ? "." + hit["_source"]["extension"] : ""; } function makeTitle(hit) { let title = document.createElement("div"); title.setAttribute("class", "file-title"); let extension = ext(hit); applyNameToTitle(hit, title, extension); title.setAttribute("title", hit["_source"]["path"] + "/" + hit["_source"]["name"] + extension); return title; } function getTags(hit, mimeCategory) { let tags = []; switch (mimeCategory) { case "video": case "image": if (hit["_source"].hasOwnProperty("videoc") && hit["_source"]["videoc"]) { const formatTag = document.createElement("span"); formatTag.setAttribute("class", "badge badge-pill badge-video"); formatTag.appendChild(document.createTextNode(hit["_source"]["videoc"].replace(" ", ""))); tags.push(formatTag); } break; case "audio": { if (hit["_source"].hasOwnProperty("audioc") && hit["_source"]["audioc"]) { let formatTag = document.createElement("span"); formatTag.setAttribute("class", "badge badge-pill badge-audio"); formatTag.appendChild(document.createTextNode(hit["_source"]["audioc"])); tags.push(formatTag); } } break; } // User tags if (hit["_source"].hasOwnProperty("tag")) { hit["_source"]["tag"].forEach(tag => { const userTag = document.createElement("span"); userTag.setAttribute("class", "badge badge-pill badge-user"); const tokens = tag.split("#"); if (tokens.length > 1) { const bg = "#" + tokens[1]; const fg = lum(tokens[1]) > 50 ? "#000" : "#fff"; userTag.setAttribute("style", `background-color: ${bg}; color: ${fg}`); } const name = tokens[0].split(".")[tokens[0].split(".").length - 1]; userTag.appendChild(document.createTextNode(name)); tags.push(userTag); }) } return tags } function infoButtonCb(hit) { return () => { getDocumentInfo(hit["_id"]).then(doc => { $("#modal-title").text(doc["name"] + ext(hit)); const tbody = $("
"); $("#modal-body").empty() .append($("").text("Field")) .append($(" | ").text("Value")) ) ) .append(tbody) ); const displayFields = new Set([ "mime", "size", "mtime", "path", "title", "width", "height", "duration", "audioc", "videoc", "bitrate", "artist", "album", "album_artist", "genre", "title", "font_name", "tag" ]); Object.keys(doc) .filter(key => key.startsWith("_keyword.") || key.startsWith("_text.") || displayFields.has(key) || key.startsWith("exif_")) .forEach(key => { tbody.append($(" |
---|---|
").text(key)) .append($(" | ").text(doc[key]))
);
});
if (doc.hasOwnProperty("content") && doc["content"]) {
$("#modal-body").append($(" ").text(doc["content"]))
}
$("#modal").modal();
});
}
}
function createDocCard(hit) {
let docCard = document.createElement("div");
docCard.setAttribute("class", "card");
let docCardBody = document.createElement("div");
docCardBody.setAttribute("class", "card-body document");
//Title
let title = makeTitle(hit);
let isSubDocument = false;
let link = document.createElement("a");
link.setAttribute("href", "f/" + hit["_id"]);
link.setAttribute("target", "_blank");
link.style.maxWidth = "calc(100% - 1.2rem)";
link.appendChild(title);
if (hit["_source"].hasOwnProperty("parent")) {
docCard.classList.add("sub-document");
isSubDocument = true;
}
let tagContainer = document.createElement("div");
tagContainer.setAttribute("class", "card-text");
if (hit["_source"].hasOwnProperty("mime") && hit["_source"]["mime"] !== null) {
let thumbnailOverlay = null;
let imgWrapper = document.createElement("div");
imgWrapper.setAttribute("style", "position: relative");
imgWrapper.setAttribute("class", "img-wrapper");
let mimeCategory = hit["_source"]["mime"].split("/")[0];
//Thumbnail
let thumbnail = makeThumbnail(mimeCategory, hit, imgWrapper, false);
//Thumbnail overlay
switch (mimeCategory) {
case "image":
thumbnailOverlay = document.createElement("div");
thumbnailOverlay.setAttribute("class", "card-img-overlay");
//Resolution
if (hit["_source"].hasOwnProperty("width") && hit["_source"]["width"] > 32 && hit["_source"]["height"] > 32) {
let resolutionBadge = document.createElement("span");
resolutionBadge.setAttribute("class", "badge badge-resolution");
if (hit["_source"].hasOwnProperty("width")) {
resolutionBadge.appendChild(document.createTextNode(hit["_source"]["width"] + "x" + hit["_source"]["height"]));
}
thumbnailOverlay.appendChild(resolutionBadge);
}
// Hover
if (thumbnail && hit["_source"]["videoc"] === "gif" && !isSubDocument) {
gifOver(thumbnail, hit);
}
break;
case "video":
//Duration
if (hit["_source"].hasOwnProperty("duration")) {
thumbnailOverlay = document.createElement("div");
thumbnailOverlay.setAttribute("class", "card-img-overlay");
const durationBadge = document.createElement("span");
durationBadge.setAttribute("class", "badge badge-resolution");
durationBadge.appendChild(document.createTextNode(humanTime(hit["_source"]["duration"])));
thumbnailOverlay.appendChild(durationBadge);
}
}
// Tags
let tags = getTags(hit, mimeCategory);
for (let i = 0; i < tags.length; i++) {
tagContainer.appendChild(tags[i]);
}
//Content
let contentHl = getContentHighlight(hit);
if (contentHl !== undefined) {
const contentDiv = document.createElement("div");
contentDiv.setAttribute("class", "content-div");
contentDiv.insertAdjacentHTML('afterbegin', contentHl);
docCard.appendChild(contentDiv);
}
if (thumbnail !== null) {
docCard.appendChild(imgWrapper);
}
//Audio
if (mimeCategory === "audio" && hit["_source"].hasOwnProperty("audioc") && !isSubDocument) {
let audio = document.createElement("audio");
audio.setAttribute("preload", "none");
audio.setAttribute("class", "audio-fit fit");
audio.setAttribute("controls", "");
audio.setAttribute("type", hit["_source"]["mime"]);
audio.setAttribute("src", "f/" + hit["_id"]);
docCard.appendChild(audio)
}
if (thumbnailOverlay !== null) {
imgWrapper.appendChild(thumbnailOverlay);
}
}
//Size tag
let sizeTag = document.createElement("small");
sizeTag.appendChild(document.createTextNode(humanFileSize(hit["_source"]["size"])));
sizeTag.setAttribute("class", "text-muted");
tagContainer.appendChild(sizeTag);
const titleWrapper = document.createElement("div");
titleWrapper.style.display = "flex";
const infoButton = makeInfoButton(hit);
titleWrapper.appendChild(infoButton);
titleWrapper.appendChild(link);
docCardBody.appendChild(titleWrapper);
docCard.appendChild(docCardBody);
docCardBody.appendChild(tagContainer);
return docCard;
}
function makeThumbnail(mimeCategory, hit, imgWrapper, small) {
if (!hit["_source"].hasOwnProperty("thumbnail")) {
return null;
}
let thumbnail = document.createElement("img");
if (small) {
thumbnail.setAttribute("class", "fit-sm");
} else {
thumbnail.setAttribute("class", "card-img-top fit");
}
thumbnail.setAttribute("src", `t/${hit["_source"]["index"]}/${hit["_id"]}`);
if (shouldDisplayRawImage(hit)) {
thumbnail.addEventListener("click", () => {
const l = lity(`f/${hit["_id"]}#.jpg`);
window.addEventListener("scroll", () => l.close());
});
thumbnail.classList.add("pointer");
} else if (shouldPlayVideo(hit)) {
thumbnail.addEventListener("click", () => lity(`f/${hit["_id"]}#.mp4`));
thumbnail.classList.add("pointer");
if (!small) {
const playOverlay = document.createElement("div");
playOverlay.innerHTML = '';
playOverlay.classList.add("play");
imgWrapper.prepend(playOverlay);
}
}
const placeholder = makePlaceholder(hit["_source"]["width"], hit["_source"]["height"], small);
imgWrapper.appendChild(placeholder);
thumbnail.addEventListener("error", () => {
imgWrapper.remove();
});
thumbnail.addEventListener("load", () => {
placeholder.remove();
imgWrapper.appendChild(thumbnail);
});
return thumbnail;
}
function makeInfoButton(hit) {
const infoButton = document.createElement("span");
infoButton.setAttribute("class", "info-icon");
infoButton.addEventListener("click", infoButtonCb(hit));
return infoButton;
}
function createDocLine(hit) {
const mime = hit["_source"]["mime"];
let mimeCategory = mime ? mime.split("/")[0] : null;
let tags = getTags(hit, mimeCategory);
let imgWrapper = document.createElement("div");
imgWrapper.setAttribute("class", "align-self-start mr-1 wrapper-sm");
let media = document.createElement("div");
media.setAttribute("class", "media");
const line = document.createElement("div");
line.setAttribute("class", "list-group-item flex-column align-items-start");
if (hit["_source"].hasOwnProperty("parent")) {
line.classList.add("sub-document");
isSubDocument = true;
}
const infoButton = makeInfoButton(hit);
const title = makeTitle(hit);
let link = document.createElement("a");
link.setAttribute("href", "f/" + hit["_id"]);
link.setAttribute("target", "_blank");
link.style.maxWidth = "calc(100% - 1.2rem)";
link.appendChild(title);
const titleDiv = document.createElement("div");
const titleWrapper = document.createElement("div");
titleWrapper.style.display = "flex";
titleWrapper.appendChild(infoButton);
titleWrapper.appendChild(link);
titleDiv.appendChild(titleWrapper);
line.appendChild(media);
let thumbnail = makeThumbnail(mimeCategory, hit, imgWrapper, true);
if (thumbnail) {
media.appendChild(imgWrapper);
titleDiv.style.maxWidth = "calc(100% - 64px)";
} else {
titleDiv.style.maxWidth = "100%";
}
media.appendChild(titleDiv);
// Content
let contentHl = getContentHighlight(hit);
if (contentHl !== undefined) {
const contentDiv = document.createElement("div");
contentDiv.setAttribute("class", "content-div");
contentDiv.insertAdjacentHTML("afterbegin", contentHl);
titleDiv.appendChild(contentDiv);
}
let pathLine = document.createElement("div");
pathLine.setAttribute("class", "path-row");
let path = document.createElement("div");
path.setAttribute("class", "path-line");
path.setAttribute("title", hit["_source"]["path"] + "/");
const pathHighlight = getPathHighlight(hit);
if (pathHighlight) {
path.insertAdjacentHTML("afterbegin", pathHighlight + "/");
} else {
path.appendChild(document.createTextNode(hit["_source"]["path"] + "/"));
}
let tagContainer = document.createElement("div");
tagContainer.setAttribute("class", "tag-container");
for (let i = 0; i < tags.length; i++) {
tagContainer.appendChild(tags[i]);
}
//Size tag
let sizeTag = document.createElement("small");
sizeTag.appendChild(document.createTextNode(humanFileSize(hit["_source"]["size"])));
sizeTag.setAttribute("class", "text-muted");
tagContainer.appendChild(sizeTag);
titleDiv.appendChild(pathLine);
pathLine.appendChild(path);
pathLine.appendChild(tagContainer);
return line;
}
function makePreloader() {
const elem = document.createElement("div");
elem.setAttribute("class", "progress");
const bar = document.createElement("div");
bar.setAttribute("class", "progress-bar progress-bar-striped progress-bar-animated");
bar.setAttribute("style", "width: 100%");
elem.appendChild(bar);
return elem;
}
function makePageIndicator(searchResult) {
let pageIndicator = document.createElement("div");
pageIndicator.setAttribute("class", "page-indicator font-weight-light");
const totalHits = searchResult["aggregations"]["total_count"]["value"];
pageIndicator.appendChild(document.createTextNode(docCount + " / " + totalHits));
return pageIndicator;
}
function makeStatsCard(searchResult) {
let statsCard = document.createElement("div");
statsCard.setAttribute("class", "card stat");
let statsCardBody = document.createElement("div");
statsCardBody.setAttribute("class", "card-body");
// Stats
let stat = document.createElement("span");
const totalHits = searchResult["aggregations"]["total_count"]["value"];
stat.appendChild(document.createTextNode(totalHits + " results in " + searchResult["took"] + "ms"));
statsCardBody.appendChild(stat);
// Display mode
const resultMode = document.createElement("div");
resultMode.setAttribute("class", "btn-group btn-group-toggle");
resultMode.setAttribute("data-toggle", "buttons");
resultMode.style.cssFloat = "right";
const listMode = document.createElement("label");
listMode.setAttribute("class", "btn btn-primary");
listMode.setAttribute("title", "List mode");
listMode.innerHTML = '';
const gridMode = document.createElement("label");
gridMode.setAttribute("class", "btn btn-primary");
gridMode.setAttribute("title", "Grid mode");
gridMode.innerHTML = '';
resultMode.appendChild(gridMode);
resultMode.appendChild(listMode);
if (CONF.options.display === "grid") {
gridMode.classList.add("active")
} else {
listMode.classList.add("active")
}
gridMode.addEventListener("click", () => {
CONF.options.display = "grid";
CONF.save();
searchDebounced();
});
listMode.addEventListener("click", () => {
CONF.options.display = "list";
CONF.save();
searchDebounced();
});
statsCardBody.appendChild(resultMode);
// Sort mode
const sortMode = document.createElement("div");
sortMode.setAttribute("class", "dropdown");
sortMode.style.cssFloat = "right";
sortMode.style.marginRight = "10px";
const sortModeBtn = document.createElement("button");
sortModeBtn.setAttribute("class", "btn btn-md btn-primary dropdown-toggle");
sortModeBtn.setAttribute("id", "sortModeBtn");
sortModeBtn.setAttribute("type", "button");
sortModeBtn.setAttribute("data-toggle", "dropdown");
sortModeBtn.setAttribute("aria-haspopup", "true");
sortModeBtn.setAttribute("aria-expanded", "false");
sortModeBtn.setAttribute("title", "Sort options");
sortModeBtn.innerHTML = '';
const sortModeMenu = document.createElement("div");
sortModeMenu.setAttribute("class", "dropdown-menu");
sortModeMenu.setAttribute("aria-labelledby", "sortModeBtn");
Object.keys(SORT_MODES).forEach(mode => {
const item = document.createElement("div");
item.setAttribute("class", "dropdown-item");
item.appendChild(document.createTextNode(SORT_MODES[mode].text));
sortModeMenu.appendChild(item);
item.onclick = function () {
CONF.options.sort = mode;
CONF.save();
searchDebounced();
};
});
sortMode.appendChild(sortModeBtn);
sortMode.appendChild(sortModeMenu);
statsCardBody.appendChild(sortMode);
if (totalHits !== 0) {
let sizeStat = document.createElement("div");
sizeStat.appendChild(document.createTextNode(humanFileSize(searchResult["aggregations"]["total_size"]["value"])));
statsCardBody.appendChild(sizeStat);
}
statsCard.appendChild(statsCardBody);
return statsCard;
}
function makeResultContainer() {
let resultContainer = document.createElement("div");
if (CONF.options.display === "grid") {
resultContainer.setAttribute("class", "bricklayer");
} else {
resultContainer.setAttribute("class", "list-group");
}
return resultContainer;
}
|