import {UtilsOmnisearch} from "./utils-omnisearch.js";
class SearchPage {
static async pInit () {
await Promise.all([
PrereleaseUtil.pInit(),
BrewUtil2.pInit(),
]);
ExcludeUtil.pInitialise().then(null); // don't await, as this is only used for search
SearchPage._isAllExpanded = (await StorageUtil.pGetForPage(SearchPage._STORAGE_KEY_IS_EXPANDED)) || false;
SearchPage._$wrp = $(`#main_content`).empty();
this._render();
}
/* -------------------------------------------- */
static _PARAM_QUERY = "q";
static _PARAM_LUCKY = "lucky";
static _getSearchParams () {
const params = new URLSearchParams(location.search);
return Object.fromEntries(params);
}
static _setSearchParams (obj) {
const params = new URLSearchParams(obj);
location.search = params.toString();
}
/* -------------------------------------------- */
static _render_$getBtnToggleFilter (
{
propOmnisearch,
fnAddHookOmnisearch,
fnDoToggleOmnisearch,
title,
text,
},
) {
const $btn = $(``)
.click(() => Omnisearch[fnDoToggleOmnisearch]());
const hkBrew = (val) => {
$btn.toggleClass("active", Omnisearch[propOmnisearch]);
if (val == null) return;
this._doSearch();
};
Omnisearch[fnAddHookOmnisearch](hkBrew);
hkBrew();
return $btn;
}
static _render () {
Omnisearch.initState();
const $iptSearch = $(``)
.keydown(evt => {
if (evt.key !== "Enter") return;
$btnSearch.click();
})
.val(this._getSearchParams()[this._PARAM_QUERY]);
const $btnSearch = $(``)
.click(() => {
this._setSearchParams({
[this._PARAM_QUERY]: $iptSearch.val().trim().toLowerCase(),
});
});
const $btnHelp = $(``)
.click(() => Omnisearch.doShowHelp());
const $btnToggleBrew = this._render_$getBtnToggleFilter({
propOmnisearch: "isShowBrew",
fnAddHookOmnisearch: "addHookBrew",
fnDoToggleOmnisearch: "doToggleBrew",
title: "Include Homebrew",
text: "Include Homebrew",
});
const $btnToggleUa = this._render_$getBtnToggleFilter({
propOmnisearch: "isShowUa",
fnAddHookOmnisearch: "addHookUa",
fnDoToggleOmnisearch: "doToggleUa",
title: "Include Unearthed Arcana and other unofficial source results",
text: "Include UA",
});
const $btnToggleBlocklisted = this._render_$getBtnToggleFilter({
propOmnisearch: "isShowBlocklisted",
fnAddHookOmnisearch: "addHookBlocklisted",
fnDoToggleOmnisearch: "doToggleBlocklisted",
title: "Include blocklisted content results",
text: "Include Blocklisted",
});
const $btnToggleSrd = this._render_$getBtnToggleFilter({
propOmnisearch: "isSrdOnly",
fnAddHookOmnisearch: "addHookSrdOnly",
fnDoToggleOmnisearch: "doToggleSrdOnly",
title: "Exclude non- Systems Reference Document results",
text: "SRD Only",
});
const handleMassExpandCollapse = mode => {
SearchPage._isAllExpanded = mode;
StorageUtil.pSetForPage("isExpanded", SearchPage._isAllExpanded);
if (!SearchPage._rowMetas) return;
SearchPage._rowMetas
.filter(meta => meta.setIsExpanded)
.forEach(meta => meta.setIsExpanded(mode));
};
const $btnCollapseAll = $(``)
.click(() => handleMassExpandCollapse(false));
const $btnExpandAll = $(``)
.click(() => handleMassExpandCollapse(true));
SearchPage._$wrpResults = $(`
${this._getWrpResult_message("Loading...")}
`);
$$(SearchPage._$wrp)`
${$iptSearch}${$btnSearch}
${$btnHelp}
${$btnToggleBrew}
${$btnToggleUa}
${$btnToggleBlocklisted}
${$btnToggleSrd}
${$btnCollapseAll}
${$btnExpandAll}
${SearchPage._$wrpResults}
`;
this._doSearch();
}
static _doSearch () {
if (SearchPage._observer) {
for (const ele of SearchPage._observed.keys()) SearchPage._observer.unobserve(ele);
} else {
SearchPage._observer = new IntersectionObserver(
(obsEntries) => {
obsEntries.forEach(entry => {
if (entry.intersectionRatio > 0) { // filter observed entries for those that intersect
SearchPage._observer.unobserve(entry.target);
const meta = SearchPage._observed.get(entry.target);
meta.onObserve();
}
});
},
{rootMargin: "150px 0px", threshold: 0.01},
);
}
SearchPage._rowMetas = [];
const params = this._getSearchParams();
if (!params[this._PARAM_QUERY]) {
SearchPage._$wrpResults.empty().append(this._getWrpResult_message("Enter a search to view results"));
return;
}
Omnisearch.pGetResults(params[this._PARAM_QUERY])
.then(results => {
SearchPage._$wrpResults.empty();
if (!results.length) {
SearchPage._$wrpResults.append(this._getWrpResult_message("No results found."));
return;
}
if (this._PARAM_LUCKY in params) {
const [href] = results
.map(res => Omnisearch.getResultHref(res.doc))
.filter(Boolean);
if (href) {
window.location = `${Renderer.get().baseUrl}${href}`;
return;
}
}
SearchPage._rowMetas = results.map(result => {
const r = result.doc;
const $link = Omnisearch.$getResultLink(r);
const {
source,
page,
isHoverable,
category,
hash,
isSrd,
ptStyle,
sourceAbv,
sourceFull,
} = UtilsOmnisearch.getUnpackedSearchResult(r);
const ptPageInner = page ? `page ${page}` : "";
const adventureBookSourceHref = SourceUtil.getAdventureBookSourceHref(source, page);
const ptPage = ptPageInner && adventureBookSourceHref
? `${ptPageInner}`
: ptPageInner;
const ptSourceInner = source
? `${sourceFull} (${sourceAbv})${isSrd ? `[SRD]` : ""}${Parser.sourceJsonToMarkerHtml(source, {isList: false, additionalStyles: "pg-search__disp-source-marker"})}`
: ``;
const ptSource = ptPage || !adventureBookSourceHref
? ptSourceInner
: `${ptSourceInner}`;
const $dispImage = $(``);
const $dispPreview = $(``);
const $wrpPreviewControls = $(``);
const out = {};
const $row = $$`
${$dispImage}
${$link}
${ptSource}${ptPage ? `, ${ptPage}` : ""}
${$dispPreview}
${$wrpPreviewControls}
`.appendTo(SearchPage._$wrpResults);
if (isHoverable) {
out.isExpanded = !!SearchPage._isAllExpanded;
const handleIsExpanded = () => {
$dispPreview.toggleVe(out.isExpanded);
$btnTogglePreview
.html(out.isExpanded ? `` : ``)
.toggleClass("pg-search__btn-toggle-preview--expanded", out.isExpanded);
};
out.setIsExpanded = val => {
out.isExpanded = !!val;
handleIsExpanded();
};
const $btnTogglePreview = $(``)
.click(() => {
out.isExpanded = !out.isExpanded;
handleIsExpanded();
})
.appendTo($wrpPreviewControls);
handleIsExpanded();
}
const observationTarget = $row[0];
SearchPage._observed.set(
observationTarget,
{
onObserve: () => {
const page = UrlUtil.categoryToHoverPage(category);
if (!page) {
$dispImage.addClass(`mobile__hidden`);
return;
}
DataLoader.pCacheAndGet(
page,
source,
hash,
).then(ent => {
// region Render tokens, where available
let isImagePopulated = false;
const displayTokenImage = (
{
fnHasToken,
fnGetTokenUrl,
},
ent,
) => {
if (!fnHasToken(ent)) return;
isImagePopulated = true;
const tokenUrl = fnGetTokenUrl(ent);
$dispImage.html(`
`);
};
switch (category) {
case Parser.CAT_ID_CREATURE: {
displayTokenImage(
{
fnHasToken: Renderer.monster.hasToken,
fnGetTokenUrl: Renderer.monster.getTokenUrl,
},
ent,
);
break;
}
case Parser.CAT_ID_VEHICLE: {
displayTokenImage(
{
fnHasToken: Renderer.vehicle.hasToken,
fnGetTokenUrl: Renderer.vehicle.getTokenUrl,
},
ent,
);
break;
}
case Parser.CAT_ID_OBJECT: {
displayTokenImage(
{
fnHasToken: Renderer.object.hasToken,
fnGetTokenUrl: Renderer.object.getTokenUrl,
},
ent,
);
break;
}
case Parser.CAT_ID_BOOK:
case Parser.CAT_ID_ADVENTURE: {
const prop = category === Parser.CAT_ID_BOOK ? "book" : "adventure";
isImagePopulated = true;
$dispImage.html(`
`);
}
}
if (!isImagePopulated) $dispImage.addClass(`mobile__hidden`);
// endregion
if (isHoverable) {
// region Render preview
Renderer.hover.$getHoverContent_stats(page, ent)
.removeClass("w-100")
.addClass("pg-search__wrp-preview mobile__w-100 br-0")
.appendTo($dispPreview);
// endregion
}
});
},
},
);
SearchPage._observer.observe(observationTarget);
return out;
});
});
}
static _getWrpResult_message (message) {
return `${message.qq()}
`;
}
}
SearchPage._STORAGE_KEY_IS_EXPANDED = "isExpanded";
SearchPage._$wrp = null;
SearchPage._$wrpResults = null;
SearchPage._rowMetas = null;
SearchPage._observer = null;
SearchPage._observed = new Map();
SearchPage._isAllExpanded = false;
window.addEventListener("load", () => SearchPage.pInit());