mirror of
https://github.com/KivotosRailway/website.git
synced 2026-11-03 19:07:56 +09:00
Add solitude
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
window.addEventListener("load", () => {
|
||||
const $searchMask = document.getElementById("search-mask");
|
||||
const $searchDialog = document.querySelector("#algolia-search .search-dialog");
|
||||
|
||||
window.openSearch = () => {
|
||||
utils.animateIn($searchMask, "to_show 0.5s");
|
||||
$searchDialog.style.display = "block";
|
||||
setTimeout(() => {
|
||||
document.querySelector("#algolia-search .ais-SearchBox-input").focus();
|
||||
}, 100);
|
||||
document.addEventListener("keydown", function f(event) {
|
||||
if (event.code === "Escape") {
|
||||
closeSearch();
|
||||
document.removeEventListener("keydown", f);
|
||||
}
|
||||
});
|
||||
fixSafariHeight();
|
||||
window.addEventListener("resize", fixSafariHeight);
|
||||
};
|
||||
|
||||
const closeSearch = () => {
|
||||
utils.animateOut($searchDialog, "search_close .5s");
|
||||
utils.animateOut($searchMask, "to_hide 0.5s");
|
||||
window.removeEventListener("resize", fixSafariHeight);
|
||||
};
|
||||
|
||||
const fixSafariHeight = () => {
|
||||
if (window.innerWidth < 768) {
|
||||
$searchDialog.style.setProperty("--search-height", window.innerHeight + "px");
|
||||
}
|
||||
};
|
||||
|
||||
const addEventCtrlK = () => {
|
||||
document.addEventListener("keydown", function (event) {
|
||||
if (event.ctrlKey && event.key === "k") {
|
||||
event.preventDefault();
|
||||
openSearch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addEventCtrlK()
|
||||
|
||||
const searchClickFn = () => {
|
||||
utils.addEventListenerPjax(document.querySelector("#search-button > .search"), "click", openSearch);
|
||||
|
||||
GLOBAL_CONFIG.right_menu && document.getElementById("menu-search").addEventListener("click", function (){
|
||||
rm.hideRightMenu();
|
||||
openSearch();
|
||||
let t=document.getElementsByClassName('ais-SearchBox-input')[0];
|
||||
let evt = document.createEvent('HTMLEvents');
|
||||
evt.initEvent('input', true,true)
|
||||
t.value = selectTextNow
|
||||
t.dispatchEvent(evt)
|
||||
})
|
||||
};
|
||||
|
||||
const searchFnOnce = () => {
|
||||
$searchMask.addEventListener("click", closeSearch);
|
||||
document.querySelector("#algolia-search .search-close-button").addEventListener("click", closeSearch);
|
||||
};
|
||||
|
||||
const algolia = GLOBAL_CONFIG.algolia;
|
||||
const isAlgoliaValid = algolia.appId && algolia.apiKey && algolia.indexName;
|
||||
if (!isAlgoliaValid) {
|
||||
return console.error("Algolia setting is invalid!");
|
||||
}
|
||||
|
||||
const search = instantsearch({
|
||||
indexName: algolia.indexName,
|
||||
searchClient: algoliasearch(algolia.appId, algolia.apiKey),
|
||||
searchFunction(helper) {
|
||||
if (helper.state.query) {
|
||||
let innerLoading = '<i class="solitude st-loading-line st-spin"></i>';
|
||||
document.getElementById("algolia-hits").innerHTML = innerLoading;
|
||||
helper.search();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const configure = instantsearch.widgets.configure({
|
||||
hitsPerPage: algolia.hits.per_page || 5,
|
||||
});
|
||||
|
||||
const searchBox = instantsearch.widgets.searchBox({
|
||||
container: "#algolia-search-input",
|
||||
showReset: false,
|
||||
showSubmit: false,
|
||||
placeholder: GLOBAL_CONFIG.lang.search.placeholder,
|
||||
showLoadingIndicator: true,
|
||||
searchOnEnterKeyPressOnly: true,
|
||||
searchAsYouType: false,
|
||||
});
|
||||
|
||||
const hits = instantsearch.widgets.hits({
|
||||
container: "#algolia-hits",
|
||||
templates: {
|
||||
item(data) {
|
||||
const link = data.permalink ? data.permalink : GLOBAL_CONFIG.root + data.path;
|
||||
const result = data._highlightResult;
|
||||
const loadingLogo = document.querySelector("#algolia-hits .st-spin");
|
||||
if (loadingLogo) {
|
||||
loadingLogo.style.display = "none";
|
||||
}
|
||||
setTimeout(() => {
|
||||
document.querySelector("#algolia-search .ais-SearchBox-input").focus();
|
||||
}, 200);
|
||||
return `
|
||||
<a href="${link}" class="algolia-hit-item-link">
|
||||
<span class="algolia-hits-item-title">${result.title.value || "no-title"}</span>
|
||||
</a>`;
|
||||
},
|
||||
empty: function (data) {
|
||||
const loadingLogo = document.querySelector("#algolia-hits .st-spin");
|
||||
if (loadingLogo) {
|
||||
loadingLogo.style.display = "none";
|
||||
}
|
||||
setTimeout(() => {
|
||||
document.querySelector("#algolia-search .ais-SearchBox-input").focus();
|
||||
}, 200);
|
||||
return (
|
||||
'<div id="algolia-hits-empty">' +
|
||||
GLOBAL_CONFIG.lang.search.empty.replace(/\$\{query}/, data.query) +
|
||||
"</div>"
|
||||
);
|
||||
},
|
||||
},
|
||||
cssClasses: {
|
||||
item: "algolia-hit-item",
|
||||
},
|
||||
});
|
||||
|
||||
const pagination = instantsearch.widgets.pagination({
|
||||
container: "#algolia-pagination",
|
||||
totalPages: algolia.hits.per_page ?? 5,
|
||||
scrollTo: false,
|
||||
showFirstLast: false,
|
||||
templates: {
|
||||
first: '<i class="solitude st-show-left-line"></i>',
|
||||
last: '<i class="solitude st-show-right-line"></i>',
|
||||
previous: '<i class="solitude st-arrow-left-bold"></i>',
|
||||
next: '<i class="solitude st-arrow-right-bold"></i>',
|
||||
},
|
||||
cssClasses: {
|
||||
root: "pagination",
|
||||
item: "pagination-item",
|
||||
link: "page-number",
|
||||
active: "current",
|
||||
disabled: "disabled-item",
|
||||
},
|
||||
});
|
||||
|
||||
const stats = instantsearch.widgets.stats({
|
||||
container: "#algolia-tips > #algolia-stats",
|
||||
templates: {
|
||||
text: function (data) {
|
||||
const stats = GLOBAL_CONFIG.lang.search.hit
|
||||
.replace(/\$\{hits}/, data.nbHits)
|
||||
.replace(/\$\{time}/, data.processingTimeMS);
|
||||
return `<hr>${stats}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
search.addWidgets([configure, searchBox,stats, hits, pagination]);
|
||||
|
||||
search.start();
|
||||
|
||||
searchClickFn();
|
||||
searchFnOnce();
|
||||
|
||||
window.addEventListener("pjax:complete", () => {
|
||||
!utils.isHidden($searchMask) && closeSearch();
|
||||
searchClickFn();
|
||||
});
|
||||
|
||||
window.pjax &&
|
||||
search.on("render", () => {
|
||||
window.pjax.refresh(document.getElementById("algolia-hits"));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,205 @@
|
||||
window.addEventListener("load", () => {
|
||||
let store = [];
|
||||
const $searchMask = document.getElementById("search-mask");
|
||||
const $searchDialog = document.querySelector("#local-search .search-dialog");
|
||||
window.openSearch = () => {
|
||||
utils.animateIn($searchMask, "to_show 0.5s");
|
||||
$searchDialog.style.display = "block";
|
||||
setTimeout(() => {
|
||||
document.querySelector("#local-search .search-box-input").focus();
|
||||
}, 100);
|
||||
document.addEventListener("keydown", function f(event) {
|
||||
if (event.code === "Escape") {
|
||||
closeSearch();
|
||||
document.removeEventListener("keydown", f);
|
||||
}
|
||||
});
|
||||
fixSafariHeight();
|
||||
window.addEventListener("resize", fixSafariHeight);
|
||||
};
|
||||
const fixSafariHeight = () => {
|
||||
if (window.innerWidth < 768) {
|
||||
$searchDialog.style.setProperty("--search-height", window.innerHeight + "px");
|
||||
}
|
||||
};
|
||||
const closeSearch = () => {
|
||||
utils.animateOut($searchDialog, "search_close .5s");
|
||||
utils.animateOut($searchMask, "to_hide 0.5s");
|
||||
window.removeEventListener("resize", fixSafariHeight);
|
||||
};
|
||||
|
||||
const addEventTagList = () => {
|
||||
const list = document.querySelectorAll("#local-search .tag-list");
|
||||
if (list.length > 0) {
|
||||
list.forEach(el => el.addEventListener("click", (e) => closeSearch()))
|
||||
}
|
||||
}
|
||||
|
||||
addEventTagList()
|
||||
|
||||
const addEventCtrlK = () => {
|
||||
document.addEventListener("keydown", function (event) {
|
||||
if (event.ctrlKey && event.key === "k") {
|
||||
event.preventDefault();
|
||||
openSearch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addEventCtrlK()
|
||||
|
||||
const searchFnOnce = () => {
|
||||
$searchMask.addEventListener("click", closeSearch);
|
||||
utils.addEventListenerPjax(document.querySelector("#local-search .search-close-button"), "click", closeSearch);
|
||||
};
|
||||
|
||||
searchFnOnce();
|
||||
|
||||
const searchClickFn = () => {
|
||||
utils.addEventListenerPjax(document.querySelector("#search-button > .search"), "click", openSearch);
|
||||
|
||||
GLOBAL_CONFIG.right_menu && document.getElementById("menu-search").addEventListener("click", function () {
|
||||
rm.hideRightMenu();
|
||||
openSearch();
|
||||
let t = document.getElementsByClassName('search-box-input')[0];
|
||||
let evt = document.createEvent('HTMLEvents');
|
||||
evt.initEvent('input', true, true)
|
||||
t.value = selectTextNow
|
||||
t.dispatchEvent(evt)
|
||||
})
|
||||
}
|
||||
|
||||
searchClickFn();
|
||||
|
||||
function init() {
|
||||
fetch(GLOBAL_CONFIG.localsearch.path)
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
let parser = new DOMParser();
|
||||
let xmlDoc = parser.parseFromString(data, "text/xml");
|
||||
let entries = xmlDoc.getElementsByTagName("entry");
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
let entry = entries[i];
|
||||
let title = entry.getElementsByTagName("title")[0].textContent;
|
||||
let link = entry.getElementsByTagName("url")[0].textContent;
|
||||
let content = entry.getElementsByTagName("content")[0].textContent;
|
||||
store.push({
|
||||
'title': title,
|
||||
'link': link,
|
||||
'content': content
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => console.error("Error loading search data:", err));
|
||||
}
|
||||
|
||||
let query = ''
|
||||
let currentPage = 0;
|
||||
const resultsPerPage = 10;
|
||||
let results = [];
|
||||
|
||||
function initUI() {
|
||||
const $results = document.getElementById("search-results");
|
||||
const $search = document.getElementById("search-input");
|
||||
$search.addEventListener('keydown', function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
$results.innerHTML = '';
|
||||
query = this.value.trim();
|
||||
if (query !== '') {
|
||||
results = search(query);
|
||||
renderResults(results, currentPage);
|
||||
renderPagination(results.length);
|
||||
} else {
|
||||
clearSearchResults();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function clearSearchResults() {
|
||||
const $results = document.getElementById("search-results");
|
||||
const $pagination = document.getElementById("search-pagination");
|
||||
const $tips = document.getElementById("search-tips");
|
||||
|
||||
$results.innerHTML = '';
|
||||
$pagination.innerHTML = '';
|
||||
$tips.innerHTML = '';
|
||||
}
|
||||
|
||||
function search(query) {
|
||||
const regex = new RegExp(query.split('').join('.*'), 'i');
|
||||
return store.filter(page => regex.test(page.title) || regex.test(page.content));
|
||||
}
|
||||
|
||||
function renderResults(results, page) {
|
||||
const $search_results = document.getElementById("search-results");
|
||||
$search_results.innerHTML = '';
|
||||
const $tips = document.getElementById("search-tips");
|
||||
$tips.innerHTML = '';
|
||||
const start = page * resultsPerPage;
|
||||
const end = start + resultsPerPage;
|
||||
if (!results.length) {
|
||||
const $empty = document.createElement("span");
|
||||
$empty.className = "search-result-empty";
|
||||
$empty.textContent = GLOBAL_CONFIG.lang.search.empty.replace(/\$\{query}/, query);
|
||||
$search_results.appendChild($empty);
|
||||
return;
|
||||
}
|
||||
results.slice(start, end).forEach(function (result) {
|
||||
const $result = document.createElement("li");
|
||||
$result.className = "search-result-item";
|
||||
const $link = document.createElement("a");
|
||||
$link.className = "search-result-title";
|
||||
$link.href = result.link;
|
||||
$link.innerHTML = highlightSearchKeyword(result.title, query);
|
||||
$result.appendChild($link);
|
||||
$search_results.appendChild($result);
|
||||
});
|
||||
const count = document.createElement("span");
|
||||
count.className = "search-result-count";
|
||||
count.innerHTML = GLOBAL_CONFIG.lang.search.count.replace(/\$\{count}/, results.length)
|
||||
$tips.appendChild(count);
|
||||
}
|
||||
|
||||
function highlightSearchKeyword(text, keyword) {
|
||||
const regex = new RegExp(`(${keyword.split(' ').join('|')})`, 'gi');
|
||||
return text.replace(regex, '<em>$1</em>');
|
||||
}
|
||||
|
||||
function renderPagination(totalResults) {
|
||||
const totalPages = Math.ceil(totalResults / resultsPerPage);
|
||||
const paginationContainer = document.getElementById("search-pagination");
|
||||
paginationContainer.innerHTML = '';
|
||||
const paginationList = document.createElement("ul");
|
||||
paginationList.className = "pagination-list";
|
||||
|
||||
for (let i = 0; i < totalPages; i++) {
|
||||
const button = document.createElement("li");
|
||||
button.className = "pagination-item";
|
||||
button.textContent = i + 1;
|
||||
if (i === currentPage) {
|
||||
button.classList.add('select');
|
||||
}
|
||||
button.addEventListener('click', function () {
|
||||
currentPage = i;
|
||||
renderResults(results, i);
|
||||
document.querySelectorAll(".pagination-item").forEach(function (btn) {
|
||||
btn.classList.remove('select');
|
||||
});
|
||||
button.classList.add('select');
|
||||
});
|
||||
paginationList.appendChild(button);
|
||||
}
|
||||
paginationContainer.appendChild(paginationList);
|
||||
}
|
||||
|
||||
init();
|
||||
initUI();
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
initUI();
|
||||
});
|
||||
window.addEventListener('pjax:complete', () => {
|
||||
searchClickFn()
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user