UNPKG

nodebb-theme-persona

Version:
255 lines (209 loc) • 7.06 kB
'use strict'; $(document).ready(function () { setupNProgress(); setupTaskbar(); setupEditedByIcon(); setupMobileMenu(); configureNavbarHiding(); $(window).on('resize', utils.debounce(configureNavbarHiding, 200)); $(window).on('resize', updatePanelOffset); function updatePanelOffset() { const header = document.getElementById('header-menu'); if (!header) { console.warn('[persona/updatePanelOffset] Could not find #header-menu, panel offset unchanged.'); return; } const rect = header.getBoundingClientRect(); const offset = Math.max(0, rect.bottom); document.documentElement.style.setProperty('--panel-offset', `${offset}px`); } var lastBSEnv = ''; function configureNavbarHiding() { if (!$.fn.autoHidingNavbar) { return; } require(['hooks', 'storage'], (hooks, Storage) => { let preference = ['xs', 'sm']; try { preference = JSON.parse(Storage.getItem('persona:navbar:autohide')) || preference; } catch (e) { console.warn('[persona/settings] Unable to parse value for navbar autohiding'); } var env = utils.findBootstrapEnvironment(); // if env didn't change don't destroy and recreate if (env === lastBSEnv) { return; } lastBSEnv = env; var navbarEl = $('[component="navbar"]'); navbarEl.autoHidingNavbar('destroy').removeData('plugin_autoHidingNavbar'); navbarEl.css('top', ''); hooks .on('filter:navigator.scroll', (data) => { navbarEl.autoHidingNavbar('setDisableAutohide', true); return data; }) .on('action:navigator.scrolled', () => { navbarEl.autoHidingNavbar('setDisableAutohide', false); }); hooks.fire('filter:persona.configureNavbarHiding', { resizeEnvs: preference, }).then(({ resizeEnvs }) => { if (resizeEnvs.includes(env)) { navbarEl.autoHidingNavbar({ showOnBottom: false, }); } function fixTopCss(topValue) { if (ajaxify.data.template.topic) { $('.topic .topic-header').css({ top: topValue }); } else { var topicListHeader = $('.topic-list-header'); if (topicListHeader.length) { topicListHeader.css({ top: topValue }); } } } navbarEl.off('show.autoHidingNavbar') .on('show.autoHidingNavbar', function () { fixTopCss(''); }); navbarEl.off('hide.autoHidingNavbar') .on('hide.autoHidingNavbar', function () { fixTopCss('0px'); }); }); }); } function setupNProgress() { require(['nprogress'], function (NProgress) { if (typeof NProgress === 'undefined') { return; } $(window).on('action:ajaxify.start', function () { NProgress.set(0.7); }); $(window).on('action:ajaxify.end', function (ev, data) { NProgress.done(); setupHoverCards(); if (data.url && data.url.match('user/')) { setupFavouriteButtonOnProfile(); } }); }); } function setupTaskbar() { require(['persona/taskbar'], function (taskbar) { taskbar.init(); }); } function setupEditedByIcon() { function activateEditedTooltips() { $('[data-pid] [component="post/editor"]').each(function () { var el = $(this); var icon; if (!el.attr('data-editor')) { return; } icon = el.closest('[data-pid]').find('.edit-icon').first(); icon.prop('title', el.text()).tooltip().removeClass('hidden'); }); } $(window).on('action:posts.edited', function (ev, data) { var parent = $('[data-pid="' + data.post.pid + '"]'); var icon = parent.find('.edit-icon').filter(function (index, el) { return parseInt($(el).closest('[data-pid]').attr('data-pid'), 10) === parseInt(data.post.pid, 10); }); var el = parent.find('[component="post/editor"]').first(); icon.prop('title', el.text()).tooltip().removeClass('hidden'); }); $(window).on('action:topic.loaded', activateEditedTooltips); $(window).on('action:posts.loaded', activateEditedTooltips); } function setupMobileMenu() { require(['persona/mobile-menu'], function (mobileMenu) { mobileMenu.init(); }); } function setupHoverCards() { require(['components'], function (components) { components.get('topic') .on('click', '[component="user/picture"],[component="user/status"]', generateUserCard); }); $(window).on('action:posts.loading', function (ev, data) { for (var i = 0, ii = data.posts.length; i < ii; i++) { (ajaxify.data.topics || ajaxify.data.posts)[data.posts[i].index] = data.posts[i]; } }); } function generateUserCard(ev) { var avatar = $(this); var uid = avatar.parents('[data-uid]').attr('data-uid'); const topicOrPost = (ajaxify.data.topics || ajaxify.data.posts || []).find(d => String(d.uid) === String(uid)); if (!topicOrPost) return; const user = topicOrPost.user; $('.persona-usercard').remove(); if (!user.userslug) { return false; } socket.emit('user.isFollowing', { uid: user.uid }, function (err, isFollowing) { if (err) { return err; } app.parseAndTranslate('modules/usercard', user, function (html) { var card = $(html); avatar.parents('a').after(card.hide()); if (String(app.user.uid) === String(user.uid) || !app.user.uid) { card.find('.btn-morph').hide(); } else { const uid = isFinite(user.uid) ? user.uid : encodeURIComponent(user.userslug); setupFavouriteMorph(card, uid, user.username); if (isFollowing) { $('.btn-morph').addClass('heart'); } else { $('.btn-morph').addClass('plus'); } } setupCardRemoval(card); card.fadeIn(); }); }); ev.preventDefault(); return false; } function setupFavouriteButtonOnProfile() { const uid = isFinite(ajaxify.data.uid) ? ajaxify.data.uid : encodeURIComponent(ajaxify.data.userslug); setupFavouriteMorph($('[component="account/cover"]'), uid, ajaxify.data.username); } function setupCardRemoval(card) { function removeCard(ev) { if ($(ev.target).closest('.persona-usercard').length === 0) { card.fadeOut(function () { card.remove(); }); $(document).off('click', removeCard); } } $(document).on('click', removeCard); } function setupFavouriteMorph(parent, uid, username) { require(['api', 'alerts'], function (api, alerts) { parent.find('.btn-morph').click(function (ev) { var type = $(this).hasClass('plus') ? 'follow' : 'unfollow'; var method = $(this).hasClass('plus') ? 'put' : 'del'; api[method]('/users/' + uid + '/follow').then(() => { alerts.success('[[global:alert.' + type + ', ' + username + ']]'); }); $(this).toggleClass('plus').toggleClass('heart'); $(this).translateAttr('title', type === 'follow' ? '[[global:unfollow]]' : '[[global:follow]]'); if ($(this).find('b.drop').length === 0) { $(this).prepend('<b class="drop"></b>'); } var drop = $(this).find('b.drop').removeClass('animate'); var x = ev.pageX - (drop.width() / 2) - $(this).offset().left; var y = ev.pageY - (drop.height() / 2) - $(this).offset().top; drop.css({ top: y + 'px', left: x + 'px' }).addClass('animate'); }); }); } });