mirror of
https://github.com/kiwix/libkiwix.git
synced 2025-08-03 18:26:11 -04:00
Show spinner while loading ZIM content in viewer iframe
- Implemented a spinner to improve user experience while ZIM content is loading in the viewer iframe. - Added .loader and .spinner styles in kiwix.css. - The iframe content is initially hidden (visibility: hidden) and will be displayed once loading completes. - Used CSS animations (@keyframes spin) for a smooth rotating effect.
This commit is contained in:
parent
ad58a501b0
commit
c7e86c9dbb
@ -78,4 +78,5 @@
|
|||||||
, "book-category.wikivoyage": "Wikivoyage"
|
, "book-category.wikivoyage": "Wikivoyage"
|
||||||
, "book-category.wiktionary": "Wiktionary"
|
, "book-category.wiktionary": "Wiktionary"
|
||||||
, "book-category.other": "Other"
|
, "book-category.other": "Other"
|
||||||
|
, "text-loading-content": "Loading Content"
|
||||||
}
|
}
|
||||||
|
@ -80,5 +80,6 @@
|
|||||||
"book-category.wikiversity": "Name for the category of Wikiversity books",
|
"book-category.wikiversity": "Name for the category of Wikiversity books",
|
||||||
"book-category.wikivoyage": "Name for the category of Wikivoyage books",
|
"book-category.wikivoyage": "Name for the category of Wikivoyage books",
|
||||||
"book-category.wiktionary": "Name for the category of Wiktionary books",
|
"book-category.wiktionary": "Name for the category of Wiktionary books",
|
||||||
"book-category.other": "Books not belonging to any special category are listed under this one"
|
"book-category.other": "Books not belonging to any special category are listed under this one",
|
||||||
|
"text-loading-content": "Text displayed while content is being loaded"
|
||||||
}
|
}
|
||||||
|
@ -65,4 +65,5 @@
|
|||||||
, "book-category.wikivoyage": "[I18N] Wikivoyage [TESTING]"
|
, "book-category.wikivoyage": "[I18N] Wikivoyage [TESTING]"
|
||||||
, "book-category.wiktionary": "[I18N] Wiktionary [TESTING]"
|
, "book-category.wiktionary": "[I18N] Wiktionary [TESTING]"
|
||||||
, "book-category.other": "[I18N] Other [TESTING]"
|
, "book-category.other": "[I18N] Other [TESTING]"
|
||||||
|
, "text-loading-content": "[I18N TESTING] Loading content"
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,35 @@ body {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
font-size: 24px;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
white-space: nowrap; /* Prevents text from wrapping */
|
||||||
|
min-width: fit-content; /* Ensures the container doesn’t shrink */
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 3px solid #ccc;
|
||||||
|
border-top: 3px solid #007bff;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
::selection {
|
::selection {
|
||||||
background-color: #00b4e4;
|
background-color: #00b4e4;
|
||||||
color: white;
|
color: white;
|
||||||
@ -96,6 +125,11 @@ body {
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "poppins";
|
font-family: "poppins";
|
||||||
src: url("../skin/fonts/Poppins.ttf?KIWIXCACHEID") format("truetype");
|
src: url("../skin/fonts/Poppins.ttf?KIWIXCACHEID") format("truetype");
|
||||||
|
@ -424,6 +424,10 @@ function setup_external_link_blocker() {
|
|||||||
let viewerSetupComplete = false;
|
let viewerSetupComplete = false;
|
||||||
|
|
||||||
function on_content_load() {
|
function on_content_load() {
|
||||||
|
const loader = document.getElementById("kiwix__loader");
|
||||||
|
|
||||||
|
contentIframe.classList.remove("hidden");
|
||||||
|
loader.style.display = "none";
|
||||||
if ( viewerSetupComplete ) {
|
if ( viewerSetupComplete ) {
|
||||||
handle_content_url_change();
|
handle_content_url_change();
|
||||||
}
|
}
|
||||||
@ -612,6 +616,12 @@ function updateUIText() {
|
|||||||
|
|
||||||
setTitle(document.getElementById("kiwix_serve_taskbar_random_button"),
|
setTitle(document.getElementById("kiwix_serve_taskbar_random_button"),
|
||||||
$t("random-page-button-text"));
|
$t("random-page-button-text"));
|
||||||
|
|
||||||
|
// Add translation for loading text as soon as translations are available
|
||||||
|
const loadingTextElement = document.getElementById("kiwix__loading_text");
|
||||||
|
if (loadingTextElement) {
|
||||||
|
loadingTextElement.textContent = $t("text-loading-content");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishViewerSetupOnceTranslationsAreLoaded()
|
function finishViewerSetupOnceTranslationsAreLoaded()
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="margin:0" onload="setupViewer()">
|
<body style="margin:0" onload="setupViewer()">
|
||||||
|
<div class="loader" id="kiwix__loader">
|
||||||
|
<div class="spinner"></div>
|
||||||
|
<span id="kiwix__loading_text">Loading content...</span>
|
||||||
|
</div>
|
||||||
<div class="kiwix" style="display:none" id="kiwixtoolbarwrapper">
|
<div class="kiwix" style="display:none" id="kiwixtoolbarwrapper">
|
||||||
<div id="kiwixtoolbar" class="ui-widget-header">
|
<div id="kiwixtoolbar" class="ui-widget-header">
|
||||||
<div class="kiwix_centered">
|
<div class="kiwix_centered">
|
||||||
@ -78,7 +82,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<iframe id="content_iframe"
|
<iframe id="content_iframe" class="hidden"
|
||||||
referrerpolicy="no-referrer"
|
referrerpolicy="no-referrer"
|
||||||
onload="on_content_load()"
|
onload="on_content_load()"
|
||||||
src="./skin/blank.html?KIWIXCACHEID" title="ZIM content" width="100%"
|
src="./skin/blank.html?KIWIXCACHEID" title="ZIM content" width="100%"
|
||||||
|
@ -1189,7 +1189,7 @@ TEST_F(LibraryServerTest, no_name_mapper_catalog_v2_individual_entry_access)
|
|||||||
" <title>Welcome to Kiwix Server</title>\n" \
|
" <title>Welcome to Kiwix Server</title>\n" \
|
||||||
" <link\n" \
|
" <link\n" \
|
||||||
" type=\"text/css\"\n" \
|
" type=\"text/css\"\n" \
|
||||||
" href=\"/ROOT%23%3F/skin/kiwix.css?cacheid=2158fad9\"\n" \
|
" href=\"/ROOT%23%3F/skin/kiwix.css?cacheid=3948b846\"\n" \
|
||||||
" rel=\"Stylesheet\"\n" \
|
" rel=\"Stylesheet\"\n" \
|
||||||
" />\n" \
|
" />\n" \
|
||||||
" <link\n" \
|
" <link\n" \
|
||||||
|
@ -69,13 +69,13 @@ const ResourceCollection resources200Compressible{
|
|||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/kiwix.css" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/kiwix.css" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/kiwix.css?cacheid=2158fad9" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/kiwix.css?cacheid=3948b846" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/mustache.min.js" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/mustache.min.js" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/mustache.min.js?cacheid=bd23c4fb" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/mustache.min.js?cacheid=bd23c4fb" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=80d56607" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=80d56607" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=787e61d4" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=d6f747f5" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" },
|
||||||
@ -280,7 +280,7 @@ TEST_F(ServerTest, CacheIdsOfStaticResources)
|
|||||||
const std::vector<UrlAndExpectedResult> testData{
|
const std::vector<UrlAndExpectedResult> testData{
|
||||||
{
|
{
|
||||||
/* url */ "/ROOT%23%3F/",
|
/* url */ "/ROOT%23%3F/",
|
||||||
R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/kiwix.css?cacheid=2158fad9"
|
R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/kiwix.css?cacheid=3948b846"
|
||||||
href="/ROOT%23%3F/skin/index.css?cacheid=ae79e41a"
|
href="/ROOT%23%3F/skin/index.css?cacheid=ae79e41a"
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/ROOT%23%3F/skin/favicon/apple-touch-icon.png?cacheid=f86f8df3">
|
<link rel="apple-touch-icon" sizes="180x180" href="/ROOT%23%3F/skin/favicon/apple-touch-icon.png?cacheid=f86f8df3">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/ROOT%23%3F/skin/favicon/favicon-32x32.png?cacheid=79ded625">
|
<link rel="icon" type="image/png" sizes="32x32" href="/ROOT%23%3F/skin/favicon/favicon-32x32.png?cacheid=79ded625">
|
||||||
@ -321,13 +321,13 @@ R"EXPECTEDRESULT( <img src="${root}/skin/download-white.svg?cac
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* url */ "/ROOT%23%3F/viewer",
|
/* url */ "/ROOT%23%3F/viewer",
|
||||||
R"EXPECTEDRESULT( <link type="text/css" href="./skin/kiwix.css?cacheid=2158fad9" rel="Stylesheet" />
|
R"EXPECTEDRESULT( <link type="text/css" href="./skin/kiwix.css?cacheid=3948b846" rel="Stylesheet" />
|
||||||
<link type="text/css" href="./skin/taskbar.css?cacheid=80d56607" rel="Stylesheet" />
|
<link type="text/css" href="./skin/taskbar.css?cacheid=80d56607" rel="Stylesheet" />
|
||||||
<link type="text/css" href="./skin/autoComplete/css/autoComplete.css?cacheid=f2d376c4" rel="Stylesheet" />
|
<link type="text/css" href="./skin/autoComplete/css/autoComplete.css?cacheid=f2d376c4" rel="Stylesheet" />
|
||||||
<script type="text/javascript" src="./skin/polyfills.js?cacheid=a0e0343d"></script>
|
<script type="text/javascript" src="./skin/polyfills.js?cacheid=a0e0343d"></script>
|
||||||
<script type="module" src="./skin/i18n.js?cacheid=071abc9a" defer></script>
|
<script type="module" src="./skin/i18n.js?cacheid=071abc9a" defer></script>
|
||||||
<script type="text/javascript" src="./skin/languages.js?cacheid=ee7d95b5" defer></script>
|
<script type="text/javascript" src="./skin/languages.js?cacheid=ee7d95b5" defer></script>
|
||||||
<script type="text/javascript" src="./skin/viewer.js?cacheid=787e61d4" defer></script>
|
<script type="text/javascript" src="./skin/viewer.js?cacheid=d6f747f5" defer></script>
|
||||||
<script type="text/javascript" src="./skin/autoComplete/autoComplete.min.js?cacheid=1191aaaf"></script>
|
<script type="text/javascript" src="./skin/autoComplete/autoComplete.min.js?cacheid=1191aaaf"></script>
|
||||||
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
|
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
|
||||||
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>
|
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user