diff --git a/.gitignore b/.gitignore index 1a8f75003..4f46d8e43 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ subprojects/googletest-release* *.class build/ .vscode/ +builddir/ diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index e248de055..8b9ae36ff 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -281,27 +281,6 @@ MustacheData InternalServer::get_default_data() const return data; } -MustacheData InternalServer::homepage_data() const -{ - auto data = get_default_data(); - - MustacheData books{MustacheData::type::list}; - for (auto& bookId: mp_library->filter(kiwix::Filter().local(true).valid(true))) { - auto& currentBook = mp_library->getBookById(bookId); - - MustacheData book; - book.set("name", mp_nameMapper->getNameForId(bookId)); - book.set("title", currentBook.getTitle()); - book.set("description", currentBook.getDescription()); - book.set("articleCount", beautifyInteger(currentBook.getArticleCount())); - book.set("mediaCount", beautifyInteger(currentBook.getMediaCount())); - books.push_back(book); - } - - data.set("books", books); - return data; -} - bool InternalServer::etag_not_needed(const RequestContext& request) const { const std::string url = request.get_url(); @@ -325,7 +304,7 @@ InternalServer::get_matching_if_none_match_etag(const RequestContext& r) const std::unique_ptr InternalServer::build_homepage(const RequestContext& request) { - return ContentResponse::build(*this, RESOURCE::templates::index_html, homepage_data(), "text/html; charset=utf-8"); + return ContentResponse::build(*this, RESOURCE::templates::index_html, get_default_data(), "text/html; charset=utf-8"); } std::unique_ptr InternalServer::handle_meta(const RequestContext& request) @@ -663,7 +642,7 @@ std::vector InternalServer::search_catalog(const RequestContext& request, kiwix::OPDSDumper& opdsDumper) { - auto filter = kiwix::Filter().valid(true).local(true).remote(true); + auto filter = kiwix::Filter().valid(true).local(true); string query(""); size_t count(10); size_t startIndex(0); diff --git a/src/server/internalServer.h b/src/server/internalServer.h index 318f4d426..0106014c6 100644 --- a/src/server/internalServer.h +++ b/src/server/internalServer.h @@ -84,7 +84,6 @@ class InternalServer { kiwix::OPDSDumper& opdsDumper); MustacheData get_default_data() const; - MustacheData homepage_data() const; std::shared_ptr get_reader(const std::string& bookName) const; bool etag_not_needed(const RequestContext& r) const; diff --git a/static/resources_list.txt b/static/resources_list.txt index d31c323ba..6c0570442 100644 --- a/static/resources_list.txt +++ b/static/resources_list.txt @@ -19,6 +19,7 @@ skin/jquery-ui/jquery-ui.theme.min.css skin/jquery-ui/jquery-ui.min.css skin/caret.png skin/taskbar.js +skin/index.js skin/taskbar.css skin/block_external.js templates/search_result.html diff --git a/static/skin/index.js b/static/skin/index.js new file mode 100644 index 000000000..e0a063cac --- /dev/null +++ b/static/skin/index.js @@ -0,0 +1,78 @@ +(function() { + const root = $(`link[type='root']`).attr('href'); + const incrementalLoadingParams = { + start: 0, + count: viewPortToCount() + }; + let isFetching = false; + let timer; + + function queryUrlBuilder() { + let url = `${root}/catalog/search?`; + url += Object.keys(incrementalLoadingParams).map(key => `${key}=${incrementalLoadingParams[key]}`).join("&"); + return url; + } + + function viewPortToCount(){ + return Math.floor(window.innerHeight/100 + 1)*(window.innerWidth>1000 ? 3 : 2); + } + + function getInnerHtml(node, query) { + return node.querySelector(query).innerHTML; + } + + function generateBookHtml(book) { + const link = book.querySelector('link').getAttribute('href'); + const title = getInnerHtml(book, 'title'); + const description = getInnerHtml(book, 'summary'); + const id = getInnerHtml(book, 'id'); + const iconUrl = getInnerHtml(book, 'icon'); + const articleCount = getInnerHtml(book, 'articleCount'); + const mediaCount = getInnerHtml(book, 'mediaCount'); + + return `
+
+
${title}
+
${description}
+
${articleCount} articles, ${mediaCount} medias
+
+
`; + } + + async function loadAndDisplayBooks() { + if (isFetching) return; + isFetching = true; + fetch(queryUrlBuilder()).then(async (resp) => { + const data = new window.DOMParser().parseFromString(await resp.text(), 'application/xml'); + const books = data.querySelectorAll('entry'); + let bookHtml = ''; + books.forEach((book) => {bookHtml += generateBookHtml(book)}); + document.querySelector('.book__list').innerHTML += bookHtml; + incrementalLoadingParams.start += books.length; + if (books.length < incrementalLoadingParams.count) { + incrementalLoadingParams.count = 0; + } + isFetching = false; + }); + } + + async function loadSubset() { + if (incrementalLoadingParams.count && window.innerHeight + window.scrollY >= document.body.offsetHeight) { + loadAndDisplayBooks(); + } + } + + window.addEventListener('resize', (event) => { + if (timer) {clearTimeout(timer)} + timer = setTimeout(() => { + incrementalLoadingParams.count = incrementalLoadingParams.count && viewPortToCount(); + loadSubset(); + }, 100, event); + }); + + window.addEventListener('scroll', loadSubset); + + window.onload = async () => { + loadAndDisplayBooks(); + } +})(); diff --git a/static/templates/index.html b/static/templates/index.html index dc355aa63..09ac8068c 100644 --- a/static/templates/index.html +++ b/static/templates/index.html @@ -1,66 +1,96 @@ - - - Welcome to Kiwix Server - - - - - - - - + + + Welcome to Kiwix Server + + + + + + + + +
+
+
- - -
- Powered by Kiwix -
- - +
Powered by Kiwix
+