diff options
author | Mario Vavti <mario@mariovavti.com> | 2025-01-17 12:37:21 +0100 |
---|---|---|
committer | Mario Vavti <mario@mariovavti.com> | 2025-01-17 12:37:21 +0100 |
commit | eab08d0bcba9dbdf81a77d4614e0c5ea6b8ccbf3 (patch) | |
tree | faf73a25df71d8fc96c4d4a3c349fcd1f0492635 /view | |
parent | 8fc0e41beb4563844541868b6c427720cf76d5aa (diff) | |
download | volse-hubzilla-eab08d0bcba9dbdf81a77d4614e0c5ea6b8ccbf3.tar.gz volse-hubzilla-eab08d0bcba9dbdf81a77d4614e0c5ea6b8ccbf3.tar.bz2 volse-hubzilla-eab08d0bcba9dbdf81a77d4614e0c5ea6b8ccbf3.zip |
rewrite redbasic javascript without jquery
Diffstat (limited to 'view')
-rw-r--r-- | view/theme/redbasic/js/redbasic.js | 456 | ||||
-rw-r--r-- | view/tpl/cover_photo_widget.tpl | 159 |
2 files changed, 328 insertions, 287 deletions
diff --git a/view/theme/redbasic/js/redbasic.js b/view/theme/redbasic/js/redbasic.js index 76d6c0854..be80cd268 100644 --- a/view/theme/redbasic/js/redbasic.js +++ b/view/theme/redbasic/js/redbasic.js @@ -6,239 +6,259 @@ let redbasic_dark_mode = localStorage.getItem('redbasic_dark_mode'); let redbasic_theme_color = localStorage.getItem('redbasic_theme_color'); if (redbasic_dark_mode == 1) { - $('html').attr('data-bs-theme', 'dark'); + document.documentElement.setAttribute('data-bs-theme', 'dark'); } if (redbasic_dark_mode == 0) { - $('html').attr('data-bs-theme', 'light'); + document.documentElement.setAttribute('data-bs-theme', 'light'); } if (redbasic_theme_color) { - $('meta[name=theme-color]').attr('content', redbasic_theme_color); + document.querySelector('meta[name=theme-color]').setAttribute('content', redbasic_theme_color); } -$(document).ready(function() { - // provide a fake progress bar for pwa standalone mode - if (window.matchMedia('(display-mode: standalone)').matches) { - $(window).on('beforeunload', function(){ - if ($('.page-loader').length) { - return; - } - $('<div class="bg-primary page-loader"></div>').prependTo('body'); - }); - } - - if (redbasic_dark_mode == 1) { - $('#theme-switch-icon').removeClass('bi-moon').addClass('bi-sun'); - $('[data-bs-theme="light"]').attr('data-bs-theme', 'dark'); - } - if (redbasic_dark_mode == 0) { - $('#theme-switch-icon').removeClass('bi-sun').addClass('bi-moon'); - $('[data-bs-theme="dark"]:not(nav)').attr('data-bs-theme', 'light'); - } - - if (redbasic_theme_color != $('nav').css('background-color')) { - $('meta[name=theme-color]').attr('content', $('nav').css('background-color')); - localStorage.setItem('redbasic_theme_color', $('nav').css('background-color')); - } - - // CSS3 calc() fallback (for unsupported browsers) - $('body').append('<div id="css3-calc" style="width: 10px; width: calc(10px + 10px); display: none;"></div>'); - if( $('#css3-calc').width() == 10) { - $(window).resize(function() { - if($(window).width() < 992) { - $('main').css('width', $(window).width() + $('aside').outerWidth() ); - } else { - $('main').css('width', '100%'); - } - }); - } - $('#css3-calc').remove(); // Remove the test element - - if($(window).width() < 1200) { - $("#right_aside_wrapper").children().detach().appendTo('#left_aside_wrapper'); - $('#notifications_wrapper').addClass('d-none'); - } - - - if (document.querySelector('#region_1')) { - stickyScroll('.aside_spacer_left', '.aside_spacer_top_left', 'section', parseFloat(document.querySelector('main').getBoundingClientRect().top), 20); - } - - if (document.querySelector('#region_3')) { - stickyScroll('.aside_spacer_right', '.aside_spacer_top_right', 'section', parseFloat(document.querySelector('main').getBoundingClientRect().top), 20); - } - - $('.usermenu').click(function() { - if($('#navbar-collapse-1, #navbar-collapse-2').hasClass('show')){ - $('#navbar-collapse-1, #navbar-collapse-2').removeClass('show'); - } - }); - - $('#theme-switch').click(function() { - if ($('html').attr('data-bs-theme') === 'dark') { - if ($('nav').data('bs-theme') === 'dark') { - $('[data-bs-theme="dark"]:not(nav)').attr('data-bs-theme', 'light'); - } - else { - $('[data-bs-theme="dark"]').attr('data-bs-theme', 'light'); - } - localStorage.setItem('redbasic_dark_mode', 0); - $('#theme-switch-icon').removeClass('bi-sun').addClass('bi-moon'); - } - else { - $('[data-bs-theme="light"]').attr('data-bs-theme', 'dark'); - localStorage.setItem('redbasic_dark_mode', 1); - $('#theme-switch-icon').removeClass('bi-moon').addClass('bi-sun'); - } - $('meta[name=theme-color]').attr('content', $('nav').css('background-color')); - localStorage.setItem('redbasic_theme_color', $('nav').css('background-color')); - }); - - - $('#menu-btn').click(function() { - if($('#navbar-collapse-1').hasClass('show')){ - $('#navbar-collapse-1').removeClass('show'); - } - }); - - $('.notifications-btn').click(function(e) { - e.preventDefault(); - e.stopPropagation(); - if($('#navbar-collapse-2').hasClass('show')){ - $('#navbar-collapse-2').removeClass('show'); - } - }); - - $("input[data-role=cat-tagsinput]").tagsinput({ - tagClass: 'badge rounded-pill bg-warning text-dark' - }); - - $('a.disabled').click(function(e) { - e.preventDefault(); - e.stopPropagation(); - }); - - var doctitle = document.title; - function checkNotify() { - var notifyUpdateElem = document.getElementById('notify-update'); - if(notifyUpdateElem !== null) { - if(notifyUpdateElem.innerHTML !== "") - document.title = "(" + notifyUpdateElem.innerHTML + ") " + doctitle; - else - document.title = doctitle; - } - } - setInterval(function () {checkNotify();}, 10 * 1000); - - var touch_start = null; - var touch_max = window.innerWidth / 10; - - window.addEventListener('touchstart', function(e) { - if (e.touches.length === 1){ - //just one finger touched - touch_start = e.touches.item(0).clientX; - if (touch_start < touch_max) { - $('body').css('overflow-y', 'hidden'); - } - } - else { - //a second finger hit the screen, abort the touch - touch_start = null; - } - }); - - window.addEventListener('touchend', function(e) { - $('body').css('overflow-y', ''); - - let touch_offset = 30; //at least 30px are a swipe - if (touch_start) { - //the only finger that hit the screen left it - let touch_end = e.changedTouches.item(0).clientX; - - if (touch_end > (touch_start + touch_offset)) { - //a left -> right swipe - if (touch_start < touch_max) { - toggleAside(); - } - } - if (touch_end < (touch_start - touch_offset)) { - //a right -> left swipe - } - } - }); - +document.addEventListener('DOMContentLoaded', function () { + // provide a fake progress bar for pwa standalone mode + if (window.matchMedia('(display-mode: standalone)').matches) { + window.addEventListener('beforeunload', function () { + if (!document.querySelector('.page-loader')) { + let loader = document.createElement('div'); + loader.classList.add('bg-primary', 'page-loader'); + document.body.prepend(loader); + } + }); + } + + if (redbasic_dark_mode == 1) { + document.getElementById('theme-switch-icon').classList.remove('bi-moon'); + document.getElementById('theme-switch-icon').classList.add('bi-sun'); + document.querySelector('[data-bs-theme="light"]').setAttribute('data-bs-theme', 'dark'); + } + if (redbasic_dark_mode == 0) { + document.getElementById('theme-switch-icon').classList.remove('bi-sun'); + document.getElementById('theme-switch-icon').classList.add('bi-moon'); + let darkElements = document.querySelectorAll('[data-bs-theme="dark"]:not(nav)'); + darkElements.forEach(el => el.setAttribute('data-bs-theme', 'light')); + } + + let navBackgroundColor = document.querySelector('nav').style.backgroundColor; + if (redbasic_theme_color !== navBackgroundColor) { + document.querySelector('meta[name=theme-color]').setAttribute('content', navBackgroundColor); + localStorage.setItem('redbasic_theme_color', navBackgroundColor); + } + + // CSS3 calc() fallback (for unsupported browsers) + let testElem = document.createElement('div'); + testElem.style.width = 'calc(10px + 10px)'; + testElem.style.display = 'none'; + testElem.id = 'css3-calc'; + document.body.appendChild(testElem); + + if (testElem.offsetWidth === 10) { + window.addEventListener('resize', function () { + if (window.innerWidth < 992) { + document.querySelector('main').style.width = `${window.innerWidth + document.querySelector('aside').offsetWidth}px`; + } else { + document.querySelector('main').style.width = '100%'; + } + }); + } + testElem.remove(); // Remove the test element + + if (window.innerWidth < 1200) { + let rightAsideWrapper = document.getElementById("right_aside_wrapper"); + let leftAsideWrapper = document.getElementById("left_aside_wrapper"); + leftAsideWrapper.appendChild(...rightAsideWrapper.children); + document.getElementById('notifications_wrapper').classList.add('d-none'); + } + + if (document.getElementById('region_1')) { + stickyScroll('.aside_spacer_left', '.aside_spacer_top_left', 'section', parseFloat(document.querySelector('main').getBoundingClientRect().top), 20); + } + + if (document.getElementById('region_3')) { + stickyScroll('.aside_spacer_right', '.aside_spacer_top_right', 'section', parseFloat(document.querySelector('main').getBoundingClientRect().top), 20); + } + + document.querySelectorAll('.usermenu').forEach(function (element) { + element.addEventListener('click', function () { + let navCollapse = document.querySelectorAll('#navbar-collapse-1, #navbar-collapse-2'); + navCollapse.forEach(function (nav) { + if (nav.classList.contains('show')) { + nav.classList.remove('show'); + } + }); + }); + }); + + document.getElementById('theme-switch').addEventListener('click', function () { + let html = document.documentElement; + if (html.getAttribute('data-bs-theme') === 'dark') { + let nav = document.querySelector('nav'); + if (nav.dataset.bsTheme === 'dark') { + document.querySelectorAll('[data-bs-theme="dark"]:not(nav)').forEach(function (el) { + el.setAttribute('data-bs-theme', 'light'); + }); + } else { + document.querySelector('[data-bs-theme="dark"]').setAttribute('data-bs-theme', 'light'); + } + localStorage.setItem('redbasic_dark_mode', 0); + document.getElementById('theme-switch-icon').classList.remove('bi-sun'); + document.getElementById('theme-switch-icon').classList.add('bi-moon'); + } else { + document.querySelectorAll('[data-bs-theme="light"]').forEach(function (el) { + el.setAttribute('data-bs-theme', 'dark'); + }); + localStorage.setItem('redbasic_dark_mode', 1); + document.getElementById('theme-switch-icon').classList.remove('bi-moon'); + document.getElementById('theme-switch-icon').classList.add('bi-sun'); + } + document.querySelector('meta[name=theme-color]').setAttribute('content', document.querySelector('nav').style.backgroundColor); + localStorage.setItem('redbasic_theme_color', document.querySelector('nav').style.backgroundColor); + }); + + document.getElementById('menu-btn').addEventListener('click', function () { + let navCollapse = document.getElementById('navbar-collapse-1'); + if (navCollapse.classList.contains('show')) { + navCollapse.classList.remove('show'); + } + }); + + document.querySelectorAll('.notifications-btn').forEach(function (element) { + element.addEventListener('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + let navCollapse = document.getElementById('navbar-collapse-2'); + if (navCollapse.classList.contains('show')) { + navCollapse.classList.remove('show'); + } + }); + }); + + document.querySelectorAll('input[data-role=cat-tagsinput]').forEach(function (input) { + input.addEventListener('change', function () { + input.classList.add('badge', 'rounded-pill', 'bg-warning', 'text-dark'); + }); + }); + + document.querySelectorAll('a.disabled').forEach(function (link) { + link.addEventListener('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + }); + }); + + let doctitle = document.title; + function checkNotify() { + let notifyUpdateElem = document.getElementById('notify-update'); + if (notifyUpdateElem && notifyUpdateElem.innerHTML !== '') { + document.title = '(' + notifyUpdateElem.innerHTML + ') ' + doctitle; + } else { + document.title = doctitle; + } + } + + setInterval(checkNotify, 10 * 1000); + + let touch_start = null; + let touch_max = window.innerWidth / 10; + + window.addEventListener('touchstart', function (e) { + if (e.touches.length === 1) { + touch_start = e.touches[0].clientX; + if (touch_start < touch_max) { + document.body.style.overflowY = 'hidden'; + } + } else { + touch_start = null; + } + }); + + window.addEventListener('touchend', function (e) { + document.body.style.overflowY = ''; + let touch_offset = 30; // at least 30px are a swipe + if (touch_start) { + let touch_end = e.changedTouches[0].clientX; + if (touch_end > (touch_start + touch_offset)) { + if (touch_start < touch_max) { + toggleAside(); + } + } + if (touch_end < (touch_start - touch_offset)) { + // a right -> left swipe + } + } + }); }); function setStyle(element, cssProperty) { - for (var property in cssProperty){ - element.style[property] = cssProperty[property]; - } + for (var property in cssProperty) { + element.style[property] = cssProperty[property]; + } } function stickyScroll(sticky, stickyTop, container, topOffset, bottomOffset) { - - var lastScrollTop = 0; - var sticky = document.querySelector(sticky); - - if (!sticky) { - return; - } - - var stickyHeight = sticky.getBoundingClientRect().height; - var stickyTop = document.querySelector(stickyTop); - var content = document.querySelector(container); - var diff = window.innerHeight - stickyHeight; - var h = 0; - var lasth = 0; - var st = window.pageYOffset || document.documentElement.scrollTop; - - var resizeObserver = new ResizeObserver(function(entries) { - stickyHeight = sticky.getBoundingClientRect().height; - st = window.pageYOffset || document.documentElement.scrollTop; - diff = window.innerHeight - stickyHeight; - }); - - resizeObserver.observe(sticky); - resizeObserver.observe(content); - - window.addEventListener('scroll', function() { - if(window.innerHeight > stickyHeight + topOffset) { - setStyle(stickyTop, { height: 0 + 'px' }); - setStyle(sticky, { position: 'sticky', top: topOffset + 'px'}); - } - else { - st = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426" - if (st > lastScrollTop){ - // downscroll code - setStyle(stickyTop, { height: lasth + 'px' }); - setStyle(sticky, { position: 'sticky', top: Math.round(diff) - bottomOffset + 'px', bottom: '' }); - } else { - // upscroll code - h = sticky.getBoundingClientRect().top - content.getBoundingClientRect().top; - if(Math.round(stickyTop.getBoundingClientRect().height) === lasth) { - setStyle(stickyTop, { height: Math.round(h) + 'px' }); - } - lasth = Math.round(h); - setStyle(sticky, { position: 'sticky', top: '', bottom: Math.round(diff) - topOffset + 'px' }); - } - lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling - } - }, false); - + let lastScrollTop = 0; + let stickyElement = document.querySelector(sticky); + + if (!stickyElement) { + return; + } + + let stickyHeight = stickyElement.getBoundingClientRect().height; + let stickyTopElement = document.querySelector(stickyTop); + let content = document.querySelector(container); + let diff = window.innerHeight - stickyHeight; + + let h = 0; + let lasth = 0; + let st = window.pageYOffset || document.documentElement.scrollTop; + + let resizeObserver = new ResizeObserver(function () { + stickyHeight = stickyElement.getBoundingClientRect().height; + st = window.pageYOffset || document.documentElement.scrollTop; + diff = window.innerHeight - stickyHeight; + }); + + resizeObserver.observe(stickyElement); + resizeObserver.observe(content); + + window.addEventListener('scroll', function () { + if (window.innerHeight > stickyHeight + topOffset) { + setStyle(stickyTopElement, { height: '0px' }); + setStyle(stickyElement, { position: 'sticky', top: `${topOffset}px` }); + } else { + st = window.pageYOffset || document.documentElement.scrollTop; + if (st > lastScrollTop) { + setStyle(stickyTopElement, { height: `${lasth}px` }); + setStyle(stickyElement, { position: 'sticky', top: `${Math.round(diff) - bottomOffset}px`, bottom: '' }); + } else { + h = stickyElement.getBoundingClientRect().top - content.getBoundingClientRect().top; + if (Math.round(stickyTopElement.getBoundingClientRect().height) === lasth) { + setStyle(stickyTopElement, { height: `${Math.round(h)}px` }); + } + lasth = Math.round(h); + setStyle(stickyElement, { position: 'sticky', top: '', bottom: `${Math.round(diff) - topOffset}px` }); + } + lastScrollTop = st <= 0 ? 0 : st; + } + }, false); } function makeFullScreen(full) { - if(typeof full=='undefined' || full == true) { - $('main').addClass('fullscreen'); - $('header, nav, aside, #fullscreen-btn').attr('style','display:none !important'); - $('#inline-btn').show(); - } - else { - $('main').removeClass('fullscreen'); - $('header, nav, aside, #fullscreen-btn').show(); - $('#inline-btn').hide(); - } + if (typeof full === 'undefined' || full === true) { + document.querySelector('main').classList.add('fullscreen'); + document.querySelector('header').style.display = 'none'; + document.querySelector('nav').style.display = 'none'; + document.querySelector('aside').style.display = 'none'; + document.getElementById('fullscreen-btn').style.display = 'none'; + document.getElementById('inline-btn').style.display = 'block'; + } else { + document.querySelector('main').classList.remove('fullscreen'); + document.querySelector('header').style.display = ''; + document.querySelector('nav').style.display = ''; + document.querySelector('aside').style.display = ''; + document.getElementById('fullscreen-btn').style.display = ''; + document.getElementById('inline-btn').style.display = 'none'; + } } - - diff --git a/view/tpl/cover_photo_widget.tpl b/view/tpl/cover_photo_widget.tpl index e7fe1effc..e26bd607f 100644 --- a/view/tpl/cover_photo_widget.tpl +++ b/view/tpl/cover_photo_widget.tpl @@ -1,103 +1,124 @@ <script> - var aside_padding_top; - var section_padding_top; - var coverSlid = false; - var hide_cover = Boolean({{$hide_cover}}); - var cover_height; - - $(document).ready(function() { - if(! $('#cover-photo').length) - return; + let asidePaddingTop; + let sectionPaddingTop; + let coverSlid = false; + const hideCover = Boolean({{$hide_cover}}); + let coverHeight; + + document.addEventListener('DOMContentLoaded', function() { + const coverPhoto = document.getElementById('cover-photo'); + if (!coverPhoto) return; - if($(window).width() < 755) { - $('#cover-photo').remove(); + // If screen width is smaller than 755px, remove the cover photo + if (window.innerWidth < 755) { + coverPhoto.remove(); coverSlid = true; return; } - $('#cover-photo').removeClass('d-none'); - cover_height = Math.ceil($(window).width()/2.75862069); - $('#cover-photo').css('height', cover_height + 'px'); + // Otherwise, set up the cover photo's size + coverPhoto.classList.remove('d-none'); + coverHeight = Math.ceil(window.innerWidth / 2.75862069); + coverPhoto.style.height = `${coverHeight}px`; datasrc2src('#cover-photo > img'); - $(document).on('click mouseup keyup', slideUpCover); + // Bind events for hiding the cover + document.addEventListener('click', slideUpCover); + document.addEventListener('mouseup', slideUpCover); + document.addEventListener('keyup', slideUpCover); - if(hide_cover) { - hideCover(); - } - else if(!hide_cover && !coverSlid) { + // Hide the cover if required + if (hideCover) { + hideCoverFunction(); + } else if (!coverSlid) { coverVisibleActions(); } - }); - - $(window).scroll(function () { - if(! $('#cover-photo').length) { - return; - } - if($(window).scrollTop() >= cover_height) { - coverHiddenActions(); - coverSlid = true; - } - else if ($(window).scrollTop() < cover_height){ - if(coverSlid) { - $(window).scrollTop(cover_height); - setTimeout(function(){ coverSlid = false; }, 1000); + // Throttle scroll event + let lastScrollTop = 0; + const scrollThreshold = 100; + window.addEventListener('scroll', function() { + const scrollTop = window.scrollY; + if (Math.abs(scrollTop - lastScrollTop) < scrollThreshold) { + return; } - else { - if($(window).scrollTop() < cover_height) { - coverVisibleActions(); - } + lastScrollTop = scrollTop; + handleScroll(scrollTop); + }); + + // Adjust cover photo on resize + window.addEventListener('resize', function() { + if (!coverPhoto) return; + + coverHeight = Math.ceil(window.innerWidth / 2.75862069); + coverPhoto.style.height = `${coverHeight}px`; + + if (window.innerWidth < 755) { + coverPhoto.remove(); + coverHiddenActions(); + coverSlid = true; } - } - if($('main').css('opacity') < 1) { - $('main').css('opacity', ($(window).scrollTop()/cover_height).toFixed(1)); - } + }); }); - $(window).resize(function () { - if(! $('#cover-photo').length) { - return; - } + // Scroll event handling + function handleScroll(scrollTop) { + const coverPhoto = document.getElementById('cover-photo'); + if (!coverPhoto) return; - cover_height = Math.ceil($(window).width()/2.75862069); - $('#cover-photo').css('height', cover_height + 'px'); - if($(window).width() < 755) { - $('#cover-photo').remove(); + if (scrollTop >= coverHeight) { coverHiddenActions(); coverSlid = true; + } else if (scrollTop < coverHeight) { + if (coverSlid) { + document.body.style.overflow = 'hidden'; // Disable scrolling + window.scrollTo(0, coverHeight); + setTimeout(function() { + coverSlid = false; + document.body.style.overflow = 'auto'; // Enable scrolling + }, 500); + } else { + coverVisibleActions(); + } } - }); + // Fade effect for main content opacity + const mainElement = document.querySelector('main'); + if (mainElement && parseFloat(getComputedStyle(mainElement).opacity) < 1) { + mainElement.style.opacity = (scrollTop / coverHeight).toFixed(1); + } + } + // Functions to handle showing/hiding the cover function slideUpCover() { - if(coverSlid) { - return; - } - $('html, body').animate({scrollTop: cover_height + 'px'}, 'fast'); - return; + if (coverSlid) return; + window.scrollTo({ + top: coverHeight, + behavior: 'smooth' + }); } - function hideCover() { - if(coverSlid) { - return; - } - window.scrollTo(0, cover_height); - return; + function hideCoverFunction() { + if (coverSlid) return; + window.scrollTo(0, coverHeight); } + // Actions when the cover is visible function coverVisibleActions() { - $('body').css('cursor', 'n-resize'); - $('.navbar').removeClass('fixed-top'); - //$('main').css('margin-top', - $('nav').outerHeight(true) + 'px'); - $('main').css('opacity', 0); + document.body.style.cursor = 'n-resize'; + const navbar = document.querySelector('.navbar'); + if (navbar) navbar.classList.remove('fixed-top'); + const mainElement = document.querySelector('main'); + if (mainElement) mainElement.style.opacity = 0; } + // Actions when the cover is hidden function coverHiddenActions() { - $('body').css('cursor', ''); - $('.navbar').addClass('fixed-top'); - //$('main').css('margin-top', ''); - $('main').css('opacity', 1); + document.body.style.cursor = ''; + const navbar = document.querySelector('.navbar'); + if (navbar) navbar.classList.add('fixed-top'); + const mainElement = document.querySelector('main'); + if (mainElement) mainElement.style.opacity = 1; } </script> |