mirror of
https://github.com/Dvorinka/bizoni.git
synced 2026-06-03 18:22:57 +00:00
update
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
'use strict';
|
||||
(function(){
|
||||
const KEY = 'adminAuthB64'; // stores base64 of user:pass
|
||||
|
||||
function b64(u, p){
|
||||
try { return btoa(`${u}:${p}`); } catch { return ''; }
|
||||
}
|
||||
|
||||
function get(){
|
||||
try { return localStorage.getItem(KEY) || ''; } catch { return ''; }
|
||||
}
|
||||
function set(val){
|
||||
try { localStorage.setItem(KEY, val||''); } catch {}
|
||||
}
|
||||
function clear(){
|
||||
try { localStorage.removeItem(KEY); } catch {}
|
||||
}
|
||||
|
||||
window.AdminAuth = {
|
||||
has(){ return !!get(); },
|
||||
getHeaders(){ const v = get(); return v ? { 'Authorization': 'Basic '+v } : {}; },
|
||||
setCreds(user, pass){ set(b64(user, pass)); },
|
||||
clear(){ clear(); }
|
||||
};
|
||||
|
||||
// small UI helper (optional) – appears bottom-left
|
||||
function ensureWidget(){
|
||||
if (document.getElementById('admin-auth-widget')) return;
|
||||
const wrap = document.createElement('div');
|
||||
wrap.id = 'admin-auth-widget';
|
||||
wrap.style.position = 'fixed';
|
||||
wrap.style.left = '12px';
|
||||
wrap.style.bottom = '12px';
|
||||
wrap.style.zIndex = '9999';
|
||||
wrap.style.display = 'flex';
|
||||
wrap.style.gap = '6px';
|
||||
|
||||
const btnSet = document.createElement('button');
|
||||
btnSet.textContent = 'Přihlásit';
|
||||
btnSet.style.padding = '6px 10px';
|
||||
btnSet.style.borderRadius = '8px';
|
||||
btnSet.style.border = '1px solid #cbd5e1';
|
||||
btnSet.style.background = '#fff';
|
||||
btnSet.addEventListener('click', () => {
|
||||
const u = prompt('Uživatel (e-mail):');
|
||||
if (!u) return;
|
||||
const p = prompt('Heslo:');
|
||||
if (p == null) return;
|
||||
window.AdminAuth.setCreds(u, p);
|
||||
alert('Přihlašovací údaje uloženy do tohoto prohlížeče.');
|
||||
});
|
||||
|
||||
const btnClr = document.createElement('button');
|
||||
btnClr.textContent = 'Odhlásit';
|
||||
btnClr.style.padding = '6px 10px';
|
||||
btnClr.style.borderRadius = '8px';
|
||||
btnClr.style.border = '1px solid #cbd5e1';
|
||||
btnClr.style.background = '#fff';
|
||||
btnClr.addEventListener('click', () => {
|
||||
window.AdminAuth.clear();
|
||||
alert('Odhlášeno – uložené údaje odstraněny.');
|
||||
});
|
||||
|
||||
wrap.appendChild(btnSet);
|
||||
wrap.appendChild(btnClr);
|
||||
document.body.appendChild(wrap);
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', ensureWidget);
|
||||
} else {
|
||||
ensureWidget();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,89 @@
|
||||
'use strict';
|
||||
(function(){
|
||||
function h(el, attrs={}, children=[]) {
|
||||
const e = document.createElement(el);
|
||||
for (const [k,v] of Object.entries(attrs||{})) {
|
||||
if (k === 'class') e.className = v; else if (k === 'html') e.innerHTML = v; else e.setAttribute(k, v);
|
||||
}
|
||||
for (const c of (children||[])) e.appendChild(c);
|
||||
return e;
|
||||
}
|
||||
|
||||
function renderItem(item){
|
||||
const col = h('div', {class: 'items col-xl-6 col-lg-6 col-md-6 col-sm-6 col-ms-6 col-xs-12'});
|
||||
const article = h('article', {class: 'post-25620 post type-post status-publish format-standard has-post-thumbnail hentry'});
|
||||
|
||||
const aPhoto = h('a', {href: item.link, class: 'lte-photo'});
|
||||
const img = h('img', {
|
||||
src: item.image,
|
||||
width: '500',
|
||||
height: '300',
|
||||
decoding: 'async',
|
||||
fetchpriority: 'high',
|
||||
class: 'attachment-atleticos-blog size-atleticos-blog wp-post-image',
|
||||
alt: ''
|
||||
});
|
||||
aPhoto.appendChild(img);
|
||||
aPhoto.appendChild(h('span', {class: 'lte-photo-overlay'}));
|
||||
|
||||
const descr = h('div', {class: 'lte-description'});
|
||||
const aHeader = h('a', {href: item.link, class: 'lte-header'});
|
||||
const h3 = h('h3', {html: item.title || ('Článek ' + item.id)});
|
||||
aHeader.appendChild(h3);
|
||||
// const excerpt = h('div', {class: 'lte-excerpt', html: ''});
|
||||
|
||||
descr.appendChild(aHeader);
|
||||
// descr.appendChild(excerpt);
|
||||
|
||||
article.appendChild(aPhoto);
|
||||
article.appendChild(descr);
|
||||
col.appendChild(article);
|
||||
return col;
|
||||
}
|
||||
|
||||
async function loadLatest(attempt = 0) {
|
||||
const primary = document.getElementById('latest-blog-items');
|
||||
const secondary = document.getElementById('other-blog-items');
|
||||
if (!primary && !secondary) return;
|
||||
if (primary) primary.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#888;">Načítání…</div>';
|
||||
if (secondary) secondary.innerHTML = '';
|
||||
try {
|
||||
const res = await fetch('/api/blog/latest?limit=12', {credentials: 'omit'});
|
||||
if (!res.ok) throw new Error('HTTP '+res.status);
|
||||
let items = await res.json();
|
||||
if (primary) primary.innerHTML = '';
|
||||
if (!Array.isArray(items) || items.length === 0) {
|
||||
if (primary) primary.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#888;">Žádné příspěvky zatím nejsou.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Exclude carousel-used posts and pinned 0000 from the 4-grid
|
||||
const hasCarouselIds = Array.isArray(window.CAROUSEL_BLOG_IDS) && window.CAROUSEL_BLOG_IDS.length > 0;
|
||||
// If carousel IDs are not ready yet, retry shortly (max 5 attempts)
|
||||
if (!hasCarouselIds && attempt < 5) {
|
||||
setTimeout(() => loadLatest(attempt + 1), 300);
|
||||
return;
|
||||
}
|
||||
const excluded = new Set(hasCarouselIds ? window.CAROUSEL_BLOG_IDS : []);
|
||||
const four = items.filter(it => it && it.id !== '0000' && !excluded.has(it.id)).slice(0, 4);
|
||||
|
||||
// Prefer rendering into primary; keep secondary empty to avoid duplicates
|
||||
const target = primary || secondary;
|
||||
if (target) {
|
||||
const frag = document.createDocumentFragment();
|
||||
four.forEach(it => frag.appendChild(renderItem(it)));
|
||||
target.appendChild(frag);
|
||||
}
|
||||
if (secondary && secondary !== target) secondary.innerHTML = '';
|
||||
} catch (e) {
|
||||
console.error('Load latest blog error', e);
|
||||
if (primary) primary.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#c00;">Nepodařilo se načíst novinky.</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => loadLatest(0));
|
||||
} else {
|
||||
loadLatest(0);
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,85 @@
|
||||
'use strict';
|
||||
(function(){
|
||||
function h(el, attrs={}, children=[]) {
|
||||
const e = document.createElement(el);
|
||||
for (const [k,v] of Object.entries(attrs||{})) {
|
||||
if (k === 'class') e.className = v; else if (k === 'html') e.innerHTML = v; else e.setAttribute(k, v);
|
||||
}
|
||||
for (const c of (children||[])) e.appendChild(c);
|
||||
return e;
|
||||
}
|
||||
|
||||
function renderItem(item){
|
||||
const col = h('div', {class: 'col-xl-4 col-lg-6 col-md-6 col-sm-12 col-xs-12 item div-thumbnail'});
|
||||
const article = h('article', {class: 'post-25620 post type-post status-publish format-standard has-post-thumbnail hentry'});
|
||||
const aPhoto = h('a', {href: item.link, class: 'lte-photo'});
|
||||
const img = h('img', {
|
||||
src: item.image,
|
||||
width: '500', height: '300', decoding: 'async', fetchpriority: 'high',
|
||||
class: 'attachment-atleticos-blog size-atleticos-blog wp-post-image', alt: ''
|
||||
});
|
||||
aPhoto.appendChild(img);
|
||||
aPhoto.appendChild(h('span', {class: 'lte-photo-overlay'}));
|
||||
const descr = h('div', {class: 'lte-description'});
|
||||
const aHeader = h('a', {href: item.link, class: 'lte-header'});
|
||||
aHeader.appendChild(h('h3', {html: item.title || ('Článek ' + item.id)}));
|
||||
descr.appendChild(aHeader);
|
||||
article.appendChild(aPhoto);
|
||||
article.appendChild(descr);
|
||||
col.appendChild(article);
|
||||
return col;
|
||||
}
|
||||
|
||||
function numericDesc(a,b){
|
||||
const ai = parseInt(a.id,10); const bi = parseInt(b.id,10);
|
||||
if (!isNaN(ai) && !isNaN(bi)) return bi - ai;
|
||||
return (b.id||'').localeCompare(a.id||'');
|
||||
}
|
||||
|
||||
function getQueryParam(name){
|
||||
const url = new URL(window.location.href);
|
||||
return url.searchParams.get(name);
|
||||
}
|
||||
|
||||
function normalize(s){ return (s||'').toString().trim().toLowerCase(); }
|
||||
|
||||
async function loadAll(){
|
||||
// Render into the primary masonry grid, overwriting any static items
|
||||
const mount = document.querySelector('.lte-blog-wrap .blog .row.masonry');
|
||||
if (!mount) return;
|
||||
mount.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#888;">Načítání…</div>';
|
||||
try {
|
||||
const res = await fetch('/api/blog/latest?limit=10000', {credentials: 'omit'});
|
||||
if (!res.ok) throw new Error('HTTP '+res.status);
|
||||
let items = await res.json();
|
||||
if (!Array.isArray(items)) items = [];
|
||||
// Sort by numeric ID desc to ensure largest number is latest
|
||||
items.sort(numericDesc);
|
||||
|
||||
// Optional filter by category via ?category=XYZ
|
||||
const qCat = getQueryParam('category');
|
||||
if (qCat) {
|
||||
const want = normalize(qCat);
|
||||
items = items.filter(it => Array.isArray(it.categories) && it.categories.some(c => normalize(c) === want));
|
||||
}
|
||||
|
||||
mount.innerHTML = '';
|
||||
if (items.length === 0) {
|
||||
mount.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#888;">Žádné příspěvky zatím nejsou.</div>';
|
||||
return;
|
||||
}
|
||||
const frag = document.createDocumentFragment();
|
||||
items.forEach(it => frag.appendChild(renderItem(it)));
|
||||
mount.appendChild(frag);
|
||||
} catch (e) {
|
||||
console.error('Load blog list error', e);
|
||||
mount.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#c00;">Nepodařilo se načíst seznam článků.</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', loadAll);
|
||||
} else {
|
||||
loadAll();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,67 @@
|
||||
'use strict';
|
||||
(function(){
|
||||
async function updateHeroFromLatest() {
|
||||
try {
|
||||
const res = await fetch('/api/blog/latest?limit=8', {credentials:'omit'});
|
||||
if (!res.ok) throw new Error('HTTP '+res.status);
|
||||
let items = await res.json();
|
||||
if (!Array.isArray(items) || items.length === 0) items = [];
|
||||
|
||||
// Update background images of zoom slider slides if present
|
||||
const slides = document.querySelectorAll('.lte-slider-zoom .zs-slides .zs-slide');
|
||||
// If slides are not yet initialized by the plugin, try again shortly
|
||||
if (!slides || slides.length === 0) {
|
||||
setTimeout(updateHeroFromLatest, 600);
|
||||
return;
|
||||
}
|
||||
|
||||
// Track which IDs are used in the carousel
|
||||
const usedIds = [];
|
||||
|
||||
// Slide 0 is always the intro post 0000
|
||||
const slide0 = slides[0];
|
||||
if (slide0) {
|
||||
usedIds.push('0000');
|
||||
slide0.style.backgroundImage = `url('img/blog/0000.png')`;
|
||||
const content0 = document.querySelector(`.lte-zs-slider-inner.lte-zs-slide-0`);
|
||||
if (content0) {
|
||||
const btn0 = content0.querySelector('a.lte-btn');
|
||||
if (btn0) btn0.setAttribute('href', 'blog/0000.html');
|
||||
// Do not alter existing H2 text; designers may have custom text
|
||||
}
|
||||
}
|
||||
|
||||
// Fill remaining slides with latest posts, skipping 0000
|
||||
const rest = items.filter(it => it && it.id !== '0000');
|
||||
const max = Math.min(rest.length, Math.max(0, slides.length - 1));
|
||||
for (let i = 0; i < max; i++) {
|
||||
const it = rest[i];
|
||||
if (it && it.id) usedIds.push(it.id);
|
||||
const slide = slides[i+1];
|
||||
if (!slide) continue;
|
||||
slide.style.backgroundImage = `url('${it.image}')`;
|
||||
const content = document.querySelector(`.lte-zs-slider-inner.lte-zs-slide-${i+1}`);
|
||||
if (content) {
|
||||
const header = content.querySelector('h2.lte-header');
|
||||
if (header) header.textContent = it.title || '';
|
||||
const btn = content.querySelector('a.lte-btn');
|
||||
if (btn) btn.setAttribute('href', it.link);
|
||||
}
|
||||
}
|
||||
|
||||
// Expose used IDs so other widgets can exclude them (e.g., 4-post grid)
|
||||
window.CAROUSEL_BLOG_IDS = usedIds;
|
||||
} catch (e) {
|
||||
console.error('home-autofill hero update error', e);
|
||||
}
|
||||
}
|
||||
|
||||
function onReady(fn){
|
||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fn); else fn();
|
||||
}
|
||||
|
||||
onReady(() => {
|
||||
// Delay a bit to allow zoomslider to initialize, then update
|
||||
setTimeout(updateHeroFromLatest, 500);
|
||||
});
|
||||
})();
|
||||
+71
-6
@@ -2,13 +2,15 @@
|
||||
|
||||
jQuery( function() {
|
||||
|
||||
initEvents();
|
||||
initEvents();
|
||||
|
||||
initStyles();
|
||||
initCollapseMenu();
|
||||
checkCountUp();
|
||||
initScrollReveal();
|
||||
checkScrollAnimation();
|
||||
initStyles();
|
||||
sanitizeBlogContent();
|
||||
cleanupDuplicateBlocks();
|
||||
initCollapseMenu();
|
||||
checkCountUp();
|
||||
initScrollReveal();
|
||||
checkScrollAnimation();
|
||||
});
|
||||
|
||||
jQuery(window).on('scroll', function (event) {
|
||||
@@ -71,6 +73,23 @@ function initCollapseMenu() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove duplicate footers and duplicate blog grids (defensive cleanup)
|
||||
function cleanupDuplicateBlocks(){
|
||||
try {
|
||||
// Keep only the first footer wrapper
|
||||
var footers = document.querySelectorAll('.lte-footer-wrapper');
|
||||
for (var i = 1; i < footers.length; i++) {
|
||||
footers[i].remove();
|
||||
}
|
||||
// Keep only the first blog grid inside main blog wrap
|
||||
var grids = document.querySelectorAll('.lte-blog-wrap .blog.blog-block');
|
||||
for (var j = 1; j < grids.length; j++) {
|
||||
grids[j].remove();
|
||||
}
|
||||
} catch(e) { /* no-op */ }
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -86,6 +105,52 @@ function initCollapseMenu() {
|
||||
});
|
||||
}
|
||||
|
||||
// Remove empty/garbage paragraphs from blog content and normalize spacing
|
||||
function sanitizeBlogContent(){
|
||||
try {
|
||||
var blocks = document.querySelectorAll('.text.lte-text-page.clearfix');
|
||||
blocks.forEach(function(block){
|
||||
// remove <p> that are empty or contain only <br> or whitespace
|
||||
Array.from(block.querySelectorAll('p')).forEach(function(p){
|
||||
var html = p.innerHTML.trim();
|
||||
var text = p.textContent.replace(/\u00A0/g,' ').trim();
|
||||
if (!text || /^<br\s*\/?>(\s| )*$/i.test(html)) {
|
||||
p.remove();
|
||||
return;
|
||||
}
|
||||
// remove hashtag-only paragraphs (e.g., #tag #tag2)
|
||||
var anchors = Array.from(p.querySelectorAll('a'));
|
||||
var allHashLinks = anchors.length > 0 && anchors.every(function(a){
|
||||
var t = (a.textContent||'').trim();
|
||||
return t.startsWith('#');
|
||||
});
|
||||
var pureHashText = /^#\S+(?:\s+#\S+)*$/.test(text);
|
||||
if (allHashLinks || pureHashText) {
|
||||
p.remove();
|
||||
return;
|
||||
}
|
||||
// strip excessive bottom margins coming from pasted content
|
||||
p.style.marginBottom = '';
|
||||
p.style.marginTop = '';
|
||||
});
|
||||
// collapse consecutive <p> duplicates with same text
|
||||
var prevText = null;
|
||||
Array.from(block.querySelectorAll('p')).forEach(function(p){
|
||||
var t = p.textContent.trim();
|
||||
if (prevText !== null && t === prevText) {
|
||||
p.remove();
|
||||
} else {
|
||||
prevText = t;
|
||||
}
|
||||
});
|
||||
});
|
||||
// Remove tags/sharing/related containers if still present in DOM
|
||||
document.querySelectorAll('.blog-info-post-bottom, .tags-line, .lte-sharing, .lte-related').forEach(function(el){
|
||||
el.remove();
|
||||
});
|
||||
} catch(e) { /* no-op */ }
|
||||
}
|
||||
|
||||
/* Navbar attributes with dependency on resolution and scroll status */
|
||||
function checkNavbar() {
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
'use strict';
|
||||
(function(){
|
||||
function h(el, attrs={}, children=[]) {
|
||||
const e = document.createElement(el);
|
||||
for (const [k,v] of Object.entries(attrs||{})) {
|
||||
if (k === 'class') e.className = v; else if (k === 'html') e.innerHTML = v; else e.setAttribute(k, v);
|
||||
}
|
||||
for (const c of (children||[])) e.appendChild(c);
|
||||
return e;
|
||||
}
|
||||
|
||||
function ytUrl(videoId){
|
||||
return 'https://www.youtube.com/watch?v=' + videoId;
|
||||
}
|
||||
|
||||
function renderFeatured(v) {
|
||||
const article = h('article', {class: 'post format-video has-post-thumbnail hentry'});
|
||||
const wrap = h('div', {class: 'lte-wrapper'});
|
||||
const a = h('a', {href: ytUrl(v.video_id), target: '_blank', class: 'lte-photo lte-video-popup swipebox'});
|
||||
const img = h('img', {loading: 'lazy', decoding: 'async', width: '1600', height: '969', src: v.thumbnail_url, class: 'attachment-full size-full wp-post-image', alt: ''});
|
||||
const iconWrap = h('span', {class: 'lte-icon-video'});
|
||||
iconWrap.appendChild(h('ion-icon', {name: 'play-circle-outline', size: 'large'}));
|
||||
iconWrap.appendChild(h('span', {html: v.length || ''}));
|
||||
a.appendChild(img);
|
||||
a.appendChild(iconWrap);
|
||||
wrap.appendChild(a);
|
||||
const descr = h('div', {class: 'lte-description'});
|
||||
const dateTop = h('span', {class: 'lte-date-top'});
|
||||
const dateA = h('a', {href: '', class: 'lte-date'});
|
||||
dateA.appendChild(h('span', {class: 'dt', html: v.published_text || v.published_date || ''}));
|
||||
dateTop.appendChild(dateA);
|
||||
const headerA = h('a', {href: ytUrl(v.video_id), class: 'lte-header', target: '_blank'});
|
||||
headerA.appendChild(h('h3', {html: v.title || ''}));
|
||||
descr.appendChild(dateTop);
|
||||
descr.appendChild(headerA);
|
||||
// keep layout spacing consistent
|
||||
descr.appendChild(h('div', {class: 'lte-excerpt'}));
|
||||
article.appendChild(wrap);
|
||||
article.appendChild(descr);
|
||||
return article;
|
||||
}
|
||||
|
||||
function renderGridItem(v){
|
||||
const col = h('div', {class: 'items col-xl-6 col-lg-6 col-md-6 col-sm-6 col-ms-12 col-xs-12'});
|
||||
const article = h('article', {class: 'post format-video has-post-thumbnail hentry'});
|
||||
const wrap = h('div', {class: 'lte-wrapper'});
|
||||
const a = h('a', {href: ytUrl(v.video_id), target: '_blank', class: 'lte-photo lte-video-popup swipebox'});
|
||||
const img = h('img', {loading: 'lazy', decoding: 'async', width: '1600', height: '969', src: v.thumbnail_url, class: 'attachment-full size-full wp-post-image', alt: ''});
|
||||
const iconWrap = h('span', {class: 'lte-icon-video'});
|
||||
iconWrap.appendChild(h('ion-icon', {name: 'play-circle-outline', size: 'large'}));
|
||||
iconWrap.appendChild(h('span', {html: v.length || ''}));
|
||||
a.appendChild(img);
|
||||
a.appendChild(iconWrap);
|
||||
wrap.appendChild(a);
|
||||
const descr = h('div', {class: 'lte-description'});
|
||||
const dateTop = h('span', {class: 'lte-date-top'});
|
||||
const dateA = h('a', {href: '', class: 'lte-date'});
|
||||
dateA.appendChild(h('span', {class: 'dt', html: v.published_text || v.published_date || ''}));
|
||||
dateTop.appendChild(dateA);
|
||||
const headerA = h('a', {href: ytUrl(v.video_id), class: 'lte-header', target: '_blank'});
|
||||
headerA.appendChild(h('h3', {html: v.title || ''}));
|
||||
descr.appendChild(dateTop);
|
||||
descr.appendChild(headerA);
|
||||
// keep layout spacing consistent
|
||||
descr.appendChild(h('div', {class: 'lte-excerpt'}));
|
||||
article.appendChild(wrap);
|
||||
article.appendChild(descr);
|
||||
col.appendChild(article);
|
||||
return col;
|
||||
}
|
||||
|
||||
async function loadVideos(){
|
||||
const featureMount = document.getElementById('latest-video-feature');
|
||||
const gridMount = document.getElementById('latest-videos-grid');
|
||||
if (!featureMount && !gridMount) return;
|
||||
if (featureMount) featureMount.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#888;">Načítání…</div>';
|
||||
if (gridMount) gridMount.innerHTML = '';
|
||||
try {
|
||||
// Try fast local JSON first
|
||||
let data = null;
|
||||
const tryUrls = ['/data/video.json', '/data/videos.json', '/api/videos/latest'];
|
||||
for (const u of tryUrls){
|
||||
try {
|
||||
const res = await fetch(u, {credentials: 'omit', cache: 'no-store'});
|
||||
if (res.ok) { data = await res.json(); break; }
|
||||
} catch (_) {}
|
||||
}
|
||||
if (!data) throw new Error('No videos data available');
|
||||
let items = Array.isArray(data.items) ? data.items : data.Items || [];
|
||||
// ensure most recent first: sort by published_date or published_text desc
|
||||
const parseDate = (v) => {
|
||||
const s = v && (v.published_date || v.published_text || '').trim();
|
||||
// try ISO/date parsing
|
||||
const t = Date.parse(s);
|
||||
return isNaN(t) ? 0 : t;
|
||||
};
|
||||
items = items.slice().sort((a,b) => parseDate(b) - parseDate(a));
|
||||
if (featureMount) featureMount.innerHTML = '';
|
||||
if (!items || items.length === 0){
|
||||
if (featureMount) featureMount.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#888;">Žádná videa zatím nejsou.</div>';
|
||||
return;
|
||||
}
|
||||
const [first, ...rest] = items;
|
||||
if (featureMount && first) {
|
||||
const container = document.createElement('div');
|
||||
container.className = 'items col-xl-12 col-lg-12 col-md-12 col-sm-12 col-ms-12 col-xs-12';
|
||||
container.appendChild(renderFeatured(first));
|
||||
featureMount.appendChild(container);
|
||||
}
|
||||
if (gridMount && rest.length){
|
||||
const frag = document.createDocumentFragment();
|
||||
rest.forEach(v => frag.appendChild(renderGridItem(v)));
|
||||
gridMount.appendChild(frag);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('videos load error', e);
|
||||
if (featureMount) featureMount.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#c00;">Nepodařilo se načíst videa.</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', loadVideos);
|
||||
} else {
|
||||
loadVideos();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user