'use strict'; $(document).ready(function () { setupSkinSwitcher(); setupNProgress(); setupMobileMenu(); setupSearch(); setupDrafts(); handleMobileNavigator(); setupNavTooltips(); fixPlaceholders(); fixSidebarOverflow(); function setupSkinSwitcher() { $('[component="skinSwitcher"]').on('click', '.dropdown-item', function () { const skin = $(this).attr('data-value'); $('[component="skinSwitcher"] .dropdown-item .fa-check').addClass('invisible'); $(this).find('.fa-check').removeClass('invisible'); require(['forum/account/settings', 'hooks'], function (accountSettings, hooks) { hooks.one('action:skin.change', function () { $('[component="skinSwitcher"] [component="skinSwitcher/icon"]').removeClass('fa-fade'); }); $('[component="skinSwitcher"] [component="skinSwitcher/icon"]').addClass('fa-fade'); accountSettings.changeSkin(skin); }); }); } require(['hooks'], function (hooks) { $(window).on('action:composer.resize action:sidebar.toggle', function () { const isRtl = $('html').attr('data-dir') === 'rtl'; const css = { width: $('#panel').width(), }; const sidebarEl = $('.sidebar-left'); css[isRtl ? 'right' : 'left'] = sidebarEl.is(':visible') ? sidebarEl.outerWidth(true) : 0; $('[component="composer"]').css(css); }); hooks.on('filter:chat.openChat', function (hookData) { // disables chat modals & goes straight to chat page based on user setting hookData.modal = config.theme.chatModals && !utils.isMobile(); return hookData; }); }); function setupMobileMenu() { require(['hooks', 'api', 'navigator'], function (hooks, api, navigator) { $('[component="sidebar/toggle"]').on('click', async function () { const sidebarEl = $('.sidebar'); sidebarEl.toggleClass('open'); if (app.user.uid) { await api.put(`/users/${app.user.uid}/settings`, { settings: { openSidebars: sidebarEl.hasClass('open') ? 'on' : 'off', }, }); } $(window).trigger('action:sidebar.toggle'); if (ajaxify.data.template.topic) { hooks.fire('action:navigator.update', { newIndex: navigator.getIndex() }); } }); const bottomBar = $('[component="bottombar"]'); let stickyTools = null; const location = config.theme.topMobilebar ? 'top' : 'bottom'; const $body = $('body'); const $window = $(window); $body.on('shown.bs.dropdown hidden.bs.dropdown', '.sticky-tools', function () { bottomBar.toggleClass('hidden', $(this).find('.dropdown-menu.show').length); }); function isSearchVisible() { return !!$('[component="bottombar"] [component="sidebar/search"] .search-dropdown.show').length; } let lastScrollTop = $window.scrollTop(); let newPostsLoaded = false; function onWindowScroll() { const st = $window.scrollTop(); if (newPostsLoaded) { newPostsLoaded = false; lastScrollTop = st; return; } if (st !== lastScrollTop && !navigator.scrollActive && !isSearchVisible()) { const diff = Math.abs(st - lastScrollTop); const scrolledDown = st > lastScrollTop; const scrolledUp = st < lastScrollTop; const isHiding = !scrolledUp && scrolledDown; if (diff > 10) { bottomBar.css({ [location]: isHiding ? -bottomBar.find('.bottombar-nav').outerHeight(true) : 0, }); if (stickyTools && config.theme.topMobilebar && config.theme.autohideBottombar) { stickyTools.css({ top: isHiding ? 0 : 'var(--panel-offset)', }); } } } lastScrollTop = st; } const delayedScroll = utils.throttle(onWindowScroll, 250); function enableAutohide() { $window.off('scroll', delayedScroll); if (config.theme.autohideBottombar) { lastScrollTop = $window.scrollTop(); $window.on('scroll', delayedScroll); } } hooks.on('action:posts.loading', function () { $window.off('scroll', delayedScroll); }); hooks.on('action:posts.loaded', function () { newPostsLoaded = true; setTimeout(enableAutohide, 250); }); hooks.on('action:ajaxify.end', function () { bottomBar.removeClass('hidden'); const { template } = ajaxify.data; stickyTools = (template.category || template.topic) ? $('.sticky-tools') : null; $window.off('scroll', delayedScroll); if (config.theme.autohideBottombar) { bottomBar.css({ [location]: 0 }); setTimeout(enableAutohide, 250); } }); }); } function setupSearch() { $('[component="sidebar/search"]').on('shown.bs.dropdown', function () { $(this).find('[component="search/fields"] input[name="query"]').trigger('focus'); }); } function setupDrafts() { require(['composer/drafts', 'bootbox'], function (drafts, bootbox) { const draftsEl = $('[component="sidebar/drafts"]'); function updateBadgeCount() { const count = drafts.getAvailableCount(); if (count > 0) { draftsEl.removeClass('hidden'); } $('[component="drafts/count"]').toggleClass('hidden', count <= 0).text(count); } async function renderDraftList() { const draftListEl = $('[component="drafts/list"]'); const draftItems = drafts.listAvailable(); if (!draftItems.length) { draftListEl.find('.no-drafts').removeClass('hidden'); draftListEl.find('.placeholder-wave').addClass('hidden'); draftListEl.find('.draft-item-container').html(''); return; } draftItems.reverse().forEach((draft) => { if (draft) { if (draft.title) { draft.title = utils.escapeHTML(String(draft.title)); } draft.text = utils.escapeHTML( draft.text ).replace(/(?:\r\n|\r|\n)/g, '
'); } }); const html = await app.parseAndTranslate('partials/sidebar/drafts', 'drafts', { drafts: draftItems }); draftListEl.find('.no-drafts').addClass('hidden'); draftListEl.find('.placeholder-wave').addClass('hidden'); draftListEl.find('.draft-item-container').html(html).find('.timeago').timeago(); } draftsEl.on('shown.bs.dropdown', renderDraftList); draftsEl.on('click', '[component="drafts/open"]', function () { drafts.open($(this).attr('data-save-id')); }); draftsEl.on('click', '[component="drafts/delete"]', function () { const save_id = $(this).attr('data-save-id'); bootbox.confirm('[[modules:composer.discard-draft-confirm]]', function (ok) { if (ok) { drafts.removeDraft(save_id); renderDraftList(); } }); return false; }); $(window).on('action:composer.drafts.save', updateBadgeCount); $(window).on('action:composer.drafts.remove', updateBadgeCount); updateBadgeCount(); }); } function setupNProgress() { require(['nprogress'], function (NProgress) { window.nprogress = NProgress; if (NProgress) { $(window).on('action:ajaxify.start', function () { NProgress.set(0.7); }); $(window).on('action:ajaxify.end', function () { NProgress.done(true); }); } }); } function handleMobileNavigator() { const paginationBlockEl = $('.pagination-block'); require(['hooks'], function (hooks) { hooks.on('action:ajaxify.end', function () { paginationBlockEl.find('.dropdown-menu.show').removeClass('show'); }); hooks.on('filter:navigator.scroll', function (hookData) { paginationBlockEl.find('.dropdown-menu.show').removeClass('show'); return hookData; }); }); } function setupNavTooltips() { // remove title from user icon in sidebar to prevent double tooltip $('.sidebar [component="header/avatar"] .avatar').removeAttr('title'); const tooltipEls = $('.sidebar [title]'); const lefttooltipEls = $('.sidebar-left [title]'); const rightooltipEls = $('.sidebar-right [title]'); const isRtl = $('html').attr('data-dir') === 'rtl'; lefttooltipEls.tooltip({ trigger: 'manual', animation: false, placement: isRtl ? 'left' : 'right', }); rightooltipEls.tooltip({ trigger: 'manual', animation: false, placement: isRtl ? 'right' : 'left', }); tooltipEls.on('mouseenter', function (ev) { const target = $(ev.target); const isDropdown = target.hasClass('dropdown-menu') || !!target.parents('.dropdown-menu').length; if (!$('.sidebar').hasClass('open') && !isDropdown) { $(this).tooltip('show'); } }); tooltipEls.on('click mouseleave', function () { $(this).tooltip('hide'); }); } function fixPlaceholders() { if (!config.loggedIn) { return; } ['notifications', 'chat'].forEach((type) => { const countEl = $(`nav.sidebar [component="${type}/count"]`).first(); if (!countEl.length) { return; } const count = parseInt(countEl.text(), 10); if (count > 1) { const listEls = $(`.dropdown-menu [component="${type}/list"]`); listEls.each((index, el) => { const placeholder = $(el).children().first(); for (let x = 0; x < count - 1; x++) { const cloneEl = placeholder.clone(true); cloneEl.insertAfter(placeholder); } }); } }); } function fixSidebarOverflow() { // overflow-y-auto needs to be removed on main-nav when dropdowns are opened const mainNavEl = $('#main-nav'); function toggleOverflow() { mainNavEl.toggleClass( 'overflow-y-auto', !mainNavEl.find('.dropdown-menu.show').length ); } mainNavEl.on('shown.bs.dropdown', toggleOverflow) .on('hidden.bs.dropdown', toggleOverflow); } });