liebling/src/js/app.js

388 lines
9.6 KiB
JavaScript
Raw Normal View History

2019-05-21 19:50:29 +00:00
import $ from 'jquery'
import Headroom from "headroom.js"
2020-06-29 13:54:07 +00:00
import Glide, {
Swipe,
Breakpoints
} from '@glidejs/glide/dist/glide.modular.esm'
import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
2019-11-21 15:48:21 +00:00
import shave from 'shave'
2019-05-21 19:50:29 +00:00
import AOS from 'aos'
2020-06-29 13:54:07 +00:00
import Fuse from 'fuse.js/dist/fuse.basic.esm.min.js'
2019-10-27 10:43:31 +00:00
import {
isRTL,
2019-11-12 23:53:36 +00:00
formatDate,
2020-03-11 17:42:00 +00:00
isDarkMode,
2020-04-27 22:01:48 +00:00
isMobile,
2020-03-11 17:42:00 +00:00
getParameterByName
2019-10-27 10:43:31 +00:00
} from './helpers'
2019-05-21 19:50:29 +00:00
$(() => {
2019-10-27 10:43:31 +00:00
if (isRTL()) {
2019-09-20 21:30:08 +00:00
$('html').attr('dir', 'rtl').addClass('rtl')
}
2019-05-21 19:50:29 +00:00
const $body = $('body')
const $header = $('.js-header')
const $openMenu = $('.js-open-menu')
const $closeMenu = $('.js-close-menu')
const $menu = $('.js-menu')
const $toggleSubmenu = $('.js-toggle-submenu')
const $submenuOption = $('.js-submenu-option')[0]
const $submenu = $('.js-submenu')
2020-06-29 13:54:07 +00:00
const $recentSlider = $('.js-recent-slider')
2020-04-27 22:01:48 +00:00
const $openSecondaryMenu = $('.js-open-secondary-menu')
2019-05-21 19:50:29 +00:00
const $openSearch = $('.js-open-search')
const $closeSearch = $('.js-close-search')
const $search = $('.js-search')
const $inputSearch = $('.js-input-search')
const $searchResults = $('.js-search-results')
2019-08-17 18:34:39 +00:00
const $searchNoResults = $('.js-no-results')
2019-11-12 16:48:45 +00:00
const $toggleDarkMode = $('.js-toggle-darkmode')
2020-03-11 17:42:00 +00:00
const $closeNotification = $('.js-notification-close')
2020-08-05 19:37:36 +00:00
const $mainNav = $('.js-main-nav')
const $mainNavLeft = $('.js-main-nav-left')
const $newsletterElements = $('.js-newsletter')
2019-11-12 23:53:36 +00:00
const currentSavedTheme = localStorage.getItem('theme')
2019-05-21 19:50:29 +00:00
let fuse = null
let submenuIsOpen = false
2020-04-27 22:01:48 +00:00
let secondaryMenuTippy = null
2019-05-21 19:50:29 +00:00
2020-08-05 19:37:36 +00:00
const showSubmenu = () => {
2019-05-21 19:50:29 +00:00
$header.addClass('submenu-is-active')
$toggleSubmenu.addClass('active')
$submenu.removeClass('closed').addClass('opened')
}
2020-08-05 19:37:36 +00:00
const hideSubmenu = () => {
2019-05-21 19:50:29 +00:00
$header.removeClass('submenu-is-active')
$toggleSubmenu.removeClass('active')
$submenu.removeClass('opened').addClass('closed')
}
2020-08-05 19:37:36 +00:00
const toggleScrollVertical = () => {
2019-05-21 19:50:29 +00:00
$body.toggleClass('no-scroll-y')
}
const tryToRemoveNewsletter = () => {
if (typeof disableNewsletter !== 'undefined' && disableNewsletter) {
$newsletterElements.remove()
}
}
2020-08-05 19:37:36 +00:00
const trySearchFeature = () => {
2019-05-21 19:50:29 +00:00
if (typeof ghostSearchApiKey !== 'undefined') {
getAllPosts(ghostHost, ghostSearchApiKey)
} else {
2019-10-03 15:07:33 +00:00
$openSearch.css('visibility', 'hidden')
2019-05-21 19:50:29 +00:00
$closeSearch.remove()
$search.remove()
}
}
2020-08-05 19:37:36 +00:00
const getAllPosts = (host, key) => {
2019-05-21 19:50:29 +00:00
const api = new GhostContentAPI({
2019-09-20 21:30:08 +00:00
url: host,
2019-05-21 19:50:29 +00:00
key,
version: 'v2'
})
const allPosts = []
const fuseOptions = {
shouldSort: true,
ignoreLocation: true,
2020-06-29 13:54:07 +00:00
findAllMatches: true,
includeScore: true,
minMatchCharLength: 2,
2020-08-05 19:37:36 +00:00
keys: ['title', 'custom_excerpt', 'tags.name']
2019-05-21 19:50:29 +00:00
}
api.posts.browse({
limit: 'all',
2020-08-05 19:37:36 +00:00
include: 'tags',
fields: 'id, title, url, published_at, custom_excerpt'
2019-05-21 19:50:29 +00:00
})
.then((posts) => {
for (let i = 0, len = posts.length; i < len; i++) {
2019-05-21 19:50:29 +00:00
allPosts.push(posts[i])
}
fuse = new Fuse(allPosts, fuseOptions)
})
.catch((err) => {
console.log(err)
})
}
2020-03-11 17:42:00 +00:00
const showNotification = (typeNotification) => {
const $notification = $(`.js-alert[data-notification="${typeNotification}"]`)
$notification.addClass('opened')
setTimeout(() => {
closeNotification($notification)
}, 5000)
}
const closeNotification = ($notification) => {
$notification.removeClass('opened')
const url = window.location.toString()
if (url.indexOf('?') > 0) {
const cleanUrl = url.substring(0, url.indexOf('?'))
window.history.replaceState({}, document.title, cleanUrl)
}
}
const checkForActionParameter = () => {
const action = getParameterByName('action')
const stripe = getParameterByName('stripe')
if (action === 'subscribe') {
showNotification('subscribe')
}
if (action === 'signup') {
window.location = `${ghostHost}/signup/?action=checkout`
}
if (action === 'checkout') {
showNotification('signup')
}
if (action === 'signin') {
showNotification('signin')
}
if (stripe === 'success') {
showNotification('checkout')
}
}
2020-08-05 19:37:36 +00:00
const toggleDesktopTopbarOverflow = (disableOverflow) => {
if (!isMobile()) {
if (disableOverflow) {
$mainNav.addClass('toggle-overflow')
$mainNavLeft.addClass('toggle-overflow')
} else {
$mainNav.removeClass('toggle-overflow')
$mainNavLeft.removeClass('toggle-overflow')
}
}
}
$openMenu.on('click', () => {
2019-11-13 13:03:29 +00:00
$header.addClass('mobile-menu-opened')
2019-05-21 19:50:29 +00:00
$menu.addClass('opened')
toggleScrollVertical()
})
$closeMenu.on('click', () => {
2019-11-13 13:03:29 +00:00
$header.removeClass('mobile-menu-opened')
2019-05-21 19:50:29 +00:00
$menu.removeClass('opened')
toggleScrollVertical()
})
$toggleSubmenu.on('click', () => {
2019-05-21 19:50:29 +00:00
submenuIsOpen = !submenuIsOpen
if (submenuIsOpen) {
showSubmenu()
} else {
hideSubmenu()
}
})
$openSearch.on('click', () => {
2019-05-21 19:50:29 +00:00
$search.addClass('opened')
setTimeout(() => {
$inputSearch.trigger('focus')
2019-05-21 19:50:29 +00:00
}, 400);
toggleScrollVertical()
})
$closeSearch.on('click', () => {
$inputSearch.trigger('blur')
2019-05-21 19:50:29 +00:00
$search.removeClass('opened')
toggleScrollVertical()
})
$inputSearch.on('keyup', () => {
2019-05-21 19:50:29 +00:00
if ($inputSearch.val().length > 0 && fuse) {
const results = fuse.search($inputSearch.val())
2020-07-26 17:53:10 +00:00
const bestResults = results.filter((result) => {
if (result.score <= 0.5) {
return result
}
})
let htmlString = ''
2019-05-21 19:50:29 +00:00
2020-07-26 17:53:10 +00:00
if (bestResults.length > 0) {
for (let i = 0, len = bestResults.length; i < len; i++) {
htmlString += `
2019-05-21 19:50:29 +00:00
<article class="m-result">\
2020-07-26 17:53:10 +00:00
<a href="${bestResults[i].item.url}" class="m-result__link">\
<h3 class="m-result__title">${bestResults[i].item.title}</h3>\
<span class="m-result__date">${formatDate(bestResults[i].item.published_at)}</span>\
2019-05-21 19:50:29 +00:00
</a>\
</article>`
2019-05-21 19:50:29 +00:00
}
2019-08-17 18:34:39 +00:00
$searchNoResults.hide()
$searchResults.html(htmlString)
2019-08-17 18:34:39 +00:00
$searchResults.show()
2019-05-21 19:50:29 +00:00
} else {
2019-08-17 18:34:39 +00:00
$searchResults.html('')
$searchResults.hide()
$searchNoResults.show()
2019-05-21 19:50:29 +00:00
}
} else {
$searchResults.html('')
2019-08-17 18:34:39 +00:00
$searchResults.hide()
$searchNoResults.hide()
2019-05-21 19:50:29 +00:00
}
})
$toggleDarkMode.on('change', () => {
2019-11-12 16:48:45 +00:00
if ($toggleDarkMode.is(':checked')) {
$('html').attr('data-theme', 'dark')
localStorage.setItem('theme', 'dark')
} else {
$('html').attr('data-theme', 'light')
localStorage.setItem('theme', 'light')
}
})
$toggleDarkMode.on('hover', () => {
2020-08-05 19:37:36 +00:00
toggleDesktopTopbarOverflow(true)
}, () => {
toggleDesktopTopbarOverflow(false)
})
$closeNotification.on('click', function () {
2020-03-11 17:42:00 +00:00
closeNotification($(this).parent())
})
$(window).on('click', (e) => {
2019-05-21 19:50:29 +00:00
if (submenuIsOpen) {
if ($submenuOption && !$submenuOption.contains(e.target)) {
submenuIsOpen = false
hideSubmenu()
}
}
})
$(document).on('keyup', (e) => {
if (e.key === 'Escape' && $search.hasClass('opened')) {
$closeSearch.click()
}
})
2019-11-12 23:53:36 +00:00
if (currentSavedTheme) {
$('html').attr('data-theme', currentSavedTheme)
2019-11-12 16:48:45 +00:00
2019-11-12 23:53:36 +00:00
if (currentSavedTheme === 'dark') {
2019-11-12 16:48:45 +00:00
$toggleDarkMode.attr('checked', true)
}
} else {
if (isDarkMode()) {
$toggleDarkMode.attr('checked', true)
}
2019-11-12 23:53:36 +00:00
}
2020-04-27 22:14:10 +00:00
if ($header.length > 0) {
const headroom = new Headroom($header[0], {
tolerance: {
down: 10,
up: 20
},
2020-04-27 22:01:48 +00:00
offset: 15,
onUnpin: () => {
if (!isMobile() && secondaryMenuTippy) {
const desktopSecondaryMenuTippy = secondaryMenuTippy[0]
if (
desktopSecondaryMenuTippy && desktopSecondaryMenuTippy.state.isVisible
) {
desktopSecondaryMenuTippy.hide()
}
}
}
})
headroom.init()
}
2020-06-29 13:54:07 +00:00
if ($recentSlider.length > 0) {
const recentSlider = new Glide('.js-recent-slider', {
type: 'slider',
rewind: false,
perView: 4,
swipeThreshold: false,
dragThreshold: false,
gap: 0,
direction: isRTL() ? 'rtl' : 'ltr',
breakpoints: {
1024: {
perView: 3,
swipeThreshold: 80,
dragThreshold: 120
},
768: {
perView: 2,
swipeThreshold: 80,
dragThreshold: 120,
peek: { before: 0, after: 115 }
},
568: {
perView: 1,
swipeThreshold: 80,
dragThreshold: 120,
peek: { before: 0, after: 115 }
}
}
2019-11-21 15:48:21 +00:00
})
2020-06-29 13:54:07 +00:00
recentSlider.on('mount.after', () => {
shave('.js-recent-article-title', 50)
2019-05-21 19:50:29 +00:00
})
2020-06-29 13:54:07 +00:00
recentSlider.mount({ Swipe, Breakpoints })
2019-05-21 19:50:29 +00:00
}
2019-08-20 11:16:45 +00:00
if (typeof disableFadeAnimation === 'undefined' || !disableFadeAnimation) {
AOS.init({
once: true,
startEvent: 'DOMContentLoaded',
})
} else {
$('[data-aos]').addClass('no-aos-animation')
}
2019-05-21 19:50:29 +00:00
2020-04-27 22:01:48 +00:00
if ($openSecondaryMenu.length > 0) {
const template = document.getElementById('secondary-navigation-template')
secondaryMenuTippy = tippy('.js-open-secondary-menu', {
appendTo: document.body,
2020-04-27 22:01:48 +00:00
content: template.innerHTML,
2020-08-05 19:37:36 +00:00
allowHTML: true,
2020-04-27 22:01:48 +00:00
arrow: true,
trigger: 'click',
2020-08-05 19:37:36 +00:00
interactive: true,
onShow() {
toggleDesktopTopbarOverflow(true)
},
onHidden() {
toggleDesktopTopbarOverflow(false)
}
2020-04-27 22:01:48 +00:00
})
}
2019-05-21 19:50:29 +00:00
tippy('.js-tooltip')
2019-11-21 15:48:21 +00:00
shave('.js-article-card-title', 100)
shave('.js-article-card-title-no-image', 250)
2020-03-11 17:42:00 +00:00
checkForActionParameter()
tryToRemoveNewsletter()
2019-05-21 19:50:29 +00:00
trySearchFeature()
})