liebling/src/js/app.js

348 lines
8.4 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'
2019-05-21 19:50:29 +00:00
import tippy from 'tippy.js'
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
$(document).ready(() => {
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')
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
function showSubmenu() {
$header.addClass('submenu-is-active')
$toggleSubmenu.addClass('active')
$submenu.removeClass('closed').addClass('opened')
}
function hideSubmenu() {
$header.removeClass('submenu-is-active')
$toggleSubmenu.removeClass('active')
$submenu.removeClass('opened').addClass('closed')
}
function toggleScrollVertical() {
$body.toggleClass('no-scroll-y')
}
function trySearchFeature() {
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()
}
}
function getAllPosts(host, key) {
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,
keys: ['title', 'custom_excerpt']
2019-05-21 19:50:29 +00:00
}
api.posts.browse({
limit: 'all',
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')
}
}
2019-05-21 19:50:29 +00:00
$openMenu.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.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.click(() => {
submenuIsOpen = !submenuIsOpen
if (submenuIsOpen) {
showSubmenu()
} else {
hideSubmenu()
}
})
$openSearch.click(() => {
$search.addClass('opened')
setTimeout(() => {
$inputSearch.focus()
}, 400);
toggleScrollVertical()
})
$closeSearch.click(() => {
$inputSearch.blur()
$search.removeClass('opened')
toggleScrollVertical()
})
$inputSearch.keyup(() => {
if ($inputSearch.val().length > 0 && fuse) {
const results = fuse.search($inputSearch.val())
let htmlString = ''
2019-05-21 19:50:29 +00:00
if (results.length > 0) {
for (let i = 0, len = results.length; i < len; i++) {
if (results[i].score > 0.5) {
continue
}
htmlString += `
2019-05-21 19:50:29 +00:00
<article class="m-result">\
2020-06-29 13:54:07 +00:00
<a href="${results[i].item.url}" class="m-result__link">\
<h3 class="m-result__title">${results[i].item.title}</h3>\
<span class="m-result__date">${formatDate(results[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
}
})
2019-11-12 16:48:45 +00:00
$toggleDarkMode.change(() => {
if ($toggleDarkMode.is(':checked')) {
$('html').attr('data-theme', 'dark')
localStorage.setItem('theme', 'dark')
} else {
$('html').attr('data-theme', 'light')
localStorage.setItem('theme', 'light')
}
})
2020-03-11 17:42:00 +00:00
$closeNotification.click(function () {
closeNotification($(this).parent())
})
2019-05-21 19:50:29 +00:00
$(window).click((e) => {
if (submenuIsOpen) {
if ($submenuOption && !$submenuOption.contains(e.target)) {
submenuIsOpen = false
hideSubmenu()
}
}
})
$(document).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', {
content: template.innerHTML,
arrow: true,
trigger: 'click',
interactive: true
})
}
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()
2019-05-21 19:50:29 +00:00
trySearchFeature()
})