mirror of
https://github.com/KivotosRailway/website.git
synced 2026-11-03 19:07:56 +09:00
Add public
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
const coverColor = () => {
|
||||
const path = document.getElementById("post-cover")?.src;
|
||||
path ? handleApiColor(path) : setDefaultThemeColors();
|
||||
}
|
||||
|
||||
function handleApiColor(path) {
|
||||
const cacheGroup = JSON.parse(localStorage.getItem('Solitude')) || {};
|
||||
cacheGroup.postcolor && cacheGroup.postcolor[path] ? setThemeColors(cacheGroup.postcolor[path].value) : img2color(path);
|
||||
}
|
||||
|
||||
function img2color(src) {
|
||||
fetch(coverColorConfig.api + encodeURIComponent(src))
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
setThemeColors(data.RGB);
|
||||
cacheColor(src, data.RGB);
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
function setThemeColors(value) {
|
||||
if (value) {
|
||||
const [r, g, b] = value.match(/\w\w/g).map(x => parseInt(x, 16));
|
||||
document.documentElement.style.setProperty('--efu-main', value);
|
||||
document.documentElement.style.setProperty('--efu-main-op', value + '23');
|
||||
document.documentElement.style.setProperty('--efu-main-op-deep', value + 'dd');
|
||||
document.documentElement.style.setProperty('--efu-main-none', value + '00');
|
||||
adjustBrightness(r, g, b);
|
||||
document.getElementById("coverdiv").classList.add("loaded");
|
||||
initThemeColor();
|
||||
} else {
|
||||
setDefaultThemeColors();
|
||||
}
|
||||
}
|
||||
|
||||
function setDefaultThemeColors() {
|
||||
document.documentElement.style.setProperty('--efu-main', 'var(--efu-theme)');
|
||||
document.documentElement.style.setProperty('--efu-main-op', 'var(--efu-theme-op)');
|
||||
document.documentElement.style.setProperty('--efu-main-op-deep', 'var(--efu-theme-op-deep)');
|
||||
document.documentElement.style.setProperty('--efu-main-none', 'var(--efu-theme-none)');
|
||||
initThemeColor();
|
||||
}
|
||||
|
||||
function cacheColor(src, color) {
|
||||
const cacheGroup = JSON.parse(localStorage.getItem('Solitude')) || {};
|
||||
cacheGroup.postcolor = cacheGroup.postcolor || {};
|
||||
cacheGroup.postcolor[src] = {value: color, expiration: Date.now() + coverColorConfig.time};
|
||||
localStorage.setItem('Solitude', JSON.stringify(cacheGroup));
|
||||
}
|
||||
|
||||
function adjustBrightness(r, g, b) {
|
||||
if (Math.round(((r * 299) + (g * 587) + (b * 114)) / 1000) < 125) {
|
||||
[...document.getElementsByClassName('card-content')].forEach(item => item.style.setProperty('--efu-card-bg', 'var(--efu-white)'));
|
||||
[...document.getElementsByClassName('author-info__sayhi')].forEach(item => {
|
||||
item.style.setProperty('background', 'var(--efu-white-op)');
|
||||
item.style.setProperty('color', 'var(--efu-white)');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
const coverColor = () => {
|
||||
const path = document.getElementById("post-cover")?.src;
|
||||
path ? localColor(path) : setDefaultThemeColors();
|
||||
}
|
||||
|
||||
function setDefaultThemeColors() {
|
||||
document.documentElement.style.setProperty('--efu-main', 'var(--efu-theme)');
|
||||
document.documentElement.style.setProperty('--efu-main-op', 'var(--efu-theme-op)');
|
||||
document.documentElement.style.setProperty('--efu-main-op-deep', 'var(--efu-theme-op-deep)');
|
||||
document.documentElement.style.setProperty('--efu-main-none', 'var(--efu-theme-none)');
|
||||
initThemeColor();
|
||||
}
|
||||
|
||||
const localColor = path => {
|
||||
const img = new Image();
|
||||
img.crossOrigin = "Anonymous";
|
||||
img.onload = () => setThemeColors(calculateColor(img));
|
||||
img.onerror = () => console.error('Image Error');
|
||||
img.src = path;
|
||||
}
|
||||
|
||||
const calculateColor = img => {
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
const data = ctx.getImageData(0, 0, img.width, img.height).data;
|
||||
const {r, g, b} = calculateRGB(data);
|
||||
let value = rgbToHex(r, g, b);
|
||||
return getContrastYIQ(value) === "light" ? LightenDarkenColor(value, -50) : value;
|
||||
}
|
||||
|
||||
function calculateRGB(data) {
|
||||
let r = 0, g = 0, b = 0;
|
||||
const step = 5;
|
||||
for (let i = 0; i < data.length; i += 4 * step) {
|
||||
r += data[i];
|
||||
g += data[i + 1];
|
||||
b += data[i + 2];
|
||||
}
|
||||
r = Math.floor(r / (data.length / 4 / step));
|
||||
g = Math.floor(g / (data.length / 4 / step));
|
||||
b = Math.floor(b / (data.length / 4 / step));
|
||||
return {r, g, b};
|
||||
}
|
||||
|
||||
function rgbToHex(r, g, b) {
|
||||
return "#" + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
|
||||
function LightenDarkenColor(col, amt) {
|
||||
let usePound = false;
|
||||
|
||||
if (col[0] === "#") {
|
||||
col = col.slice(1);
|
||||
usePound = true;
|
||||
}
|
||||
|
||||
const num = parseInt(col, 16);
|
||||
const r = Math.min(255, Math.max(0, (num >> 16) + amt));
|
||||
const b = Math.min(255, Math.max(0, ((num >> 8) & 0xff) + amt));
|
||||
const g = Math.min(255, Math.max(0, (num & 0xff) + amt));
|
||||
|
||||
return `${usePound ? "#" : ""}${(g | (b << 8) | (r << 16)).toString(16).padStart(6, "0")}`;
|
||||
}
|
||||
|
||||
function getContrastYIQ(hexcolor) {
|
||||
let colorrgb = colorRgb(hexcolor);
|
||||
let colors = colorrgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
||||
let red = colors[1];
|
||||
let green = colors[2];
|
||||
let blue = colors[3];
|
||||
let brightness = (red * 299) + (green * 587) + (blue * 114);
|
||||
brightness = brightness / 255000;
|
||||
return brightness >= 0.5 ? "light" : "dark";
|
||||
}
|
||||
|
||||
function colorRgb(str) {
|
||||
const HEX_SHORT_REGEX = /^#([0-9a-fA-f]{3})$/;
|
||||
const HEX_LONG_REGEX = /^#([0-9a-fA-f]{6})$/;
|
||||
const HEX_SHORT_LENGTH = 4;
|
||||
|
||||
if (!str || typeof str !== 'string') {
|
||||
return str;
|
||||
}
|
||||
|
||||
const sColor = str.toLowerCase();
|
||||
let hexValue = "";
|
||||
|
||||
if (sColor && (HEX_SHORT_REGEX.test(sColor) || HEX_LONG_REGEX.test(sColor))) {
|
||||
hexValue = sColor.length === HEX_SHORT_LENGTH ?
|
||||
sColor.replace(/^#(.)/g, "#$1$1") :
|
||||
sColor;
|
||||
|
||||
const rgbValue = hexValue.slice(1)
|
||||
.match(/.{2}/g)
|
||||
.map(val => parseInt(val, 16));
|
||||
|
||||
return `rgb(${rgbValue[0]}, ${rgbValue[1]}, ${rgbValue[2]})`;
|
||||
} else {
|
||||
return sColor;
|
||||
}
|
||||
}
|
||||
|
||||
function setThemeColors(value, r = null, g = null, b = null) {
|
||||
if (value) {
|
||||
document.documentElement.style.setProperty('--efu-main', value);
|
||||
document.documentElement.style.setProperty('--efu-main-op', value + '23');
|
||||
document.documentElement.style.setProperty('--efu-main-op-deep', value + 'dd');
|
||||
document.documentElement.style.setProperty('--efu-main-none', value + '00');
|
||||
|
||||
if (r && g && b) {
|
||||
let brightness = Math.round(((parseInt(r) * 299) + (parseInt(g) * 587) + (parseInt(b) * 114)) / 1000);
|
||||
if (brightness < 125) {
|
||||
let cardContents = document.getElementsByClassName('card-content');
|
||||
for (let i = 0; i < cardContents.length; i++) {
|
||||
cardContents[i].style.setProperty('--efu-card-bg', 'var(--efu-white)');
|
||||
}
|
||||
|
||||
let authorInfo = document.getElementsByClassName('author-info__sayhi');
|
||||
for (let i = 0; i < authorInfo.length; i++) {
|
||||
authorInfo[i].style.setProperty('background', 'var(--efu-white-op)');
|
||||
authorInfo[i].style.setProperty('color', 'var(--efu-white)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("coverdiv").classList.add("loaded");
|
||||
initThemeColor();
|
||||
} else {
|
||||
document.documentElement.style.setProperty('--efu-main', 'var(--efu-theme)');
|
||||
document.documentElement.style.setProperty('--efu-main-op', 'var(--efu-theme-op)');
|
||||
document.documentElement.style.setProperty('--efu-main-op-deep', 'var(--efu-theme-op-deep)');
|
||||
document.documentElement.style.setProperty('--efu-main-none', 'var(--efu-theme-none)');
|
||||
initThemeColor();
|
||||
}
|
||||
}
|
||||
Vendored
+2
File diff suppressed because one or more lines are too long
@@ -0,0 +1,667 @@
|
||||
const sidebarFn = () => {
|
||||
const $toggleMenu = document.getElementById('toggle-menu');
|
||||
const $mobileSidebarMenus = document.getElementById('sidebar-menus');
|
||||
const $menuMask = document.getElementById('menu-mask');
|
||||
const $body = document.body;
|
||||
|
||||
const toggleMobileSidebar = (isOpen) => {
|
||||
utils.sidebarPaddingR();
|
||||
$body.style.overflow = isOpen ? 'hidden' : '';
|
||||
$body.style.paddingRight = isOpen ? '' : '';
|
||||
utils[isOpen ? 'fadeIn' : 'fadeOut']($menuMask, 0.5);
|
||||
$mobileSidebarMenus.classList[isOpen ? 'add' : 'remove']('open');
|
||||
}
|
||||
const closeMobileSidebar = () => {
|
||||
if ($mobileSidebarMenus.classList.contains('open')) {
|
||||
toggleMobileSidebar(false);
|
||||
}
|
||||
}
|
||||
$toggleMenu.addEventListener('click', () => toggleMobileSidebar(true));
|
||||
$menuMask.addEventListener('click', closeMobileSidebar);
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
if (utils.isHidden($toggleMenu) && $mobileSidebarMenus.classList.contains('open')) {
|
||||
closeMobileSidebar();
|
||||
}
|
||||
sco.refreshWaterFall();
|
||||
});
|
||||
}
|
||||
const scrollFn = () => {
|
||||
const innerHeight = window.innerHeight;
|
||||
let initTop = 0;
|
||||
const $header = document.getElementById('page-header');
|
||||
const throttledScroll = utils.throttle((e) => {
|
||||
initThemeColor();
|
||||
const currentTop = window.scrollY || document.documentElement.scrollTop;
|
||||
const isDown = scrollDirection(currentTop);
|
||||
if (currentTop > 0) {
|
||||
if (isDown) {
|
||||
if ($header.classList.contains('nav-visible')) $header.classList.remove('nav-visible');
|
||||
} else {
|
||||
if (!$header.classList.contains('nav-visible')) $header.classList.add('nav-visible');
|
||||
}
|
||||
$header.classList.add('nav-fixed');
|
||||
} else {
|
||||
$header.classList.remove('nav-fixed', 'nav-visible');
|
||||
}
|
||||
}, 200);
|
||||
window.addEventListener('scroll', (e) => {
|
||||
throttledScroll(e);
|
||||
if (window.scrollY === 0) {
|
||||
$header.classList.remove('nav-fixed', 'nav-visible');
|
||||
}
|
||||
});
|
||||
|
||||
function scrollDirection(currentTop) {
|
||||
const result = currentTop > initTop;
|
||||
initTop = currentTop;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
const percent = () => {
|
||||
const docEl = document.documentElement;
|
||||
const body = document.body;
|
||||
const scrollPos = window.pageYOffset || docEl.scrollTop;
|
||||
const totalScrollableHeight = Math.max(body.scrollHeight, docEl.scrollHeight, body.offsetHeight, docEl.offsetHeight, body.clientHeight, docEl.clientHeight) - docEl.clientHeight;
|
||||
const scrolledPercent = Math.round((scrollPos / totalScrollableHeight) * 100);
|
||||
const navToTop = document.querySelector("#nav-totop");
|
||||
const percentDisplay = document.querySelector("#percent");
|
||||
const isNearEnd = (window.scrollY + docEl.clientHeight) >= (document.getElementById("post-comment") || document.getElementById("footer")).offsetTop;
|
||||
navToTop.classList.toggle("long", isNearEnd || scrolledPercent > 90);
|
||||
percentDisplay.textContent = isNearEnd || scrolledPercent > 90 ? GLOBAL_CONFIG.lang.backtop : scrolledPercent;
|
||||
document.querySelectorAll(".needEndHide").forEach(item => item.classList.toggle("hide", totalScrollableHeight - scrollPos < 100));
|
||||
}
|
||||
const showTodayCard = () => {
|
||||
const el = document.getElementById('todayCard');
|
||||
const topGroup = document.querySelector('.topGroup');
|
||||
topGroup?.addEventListener('mouseleave', () => el?.classList.remove('hide'));
|
||||
}
|
||||
const initObserver = () => {
|
||||
const commentElement = document.getElementById("post-comment");
|
||||
const paginationElement = document.getElementById("pagination");
|
||||
const commentBarrageElement = document.querySelector(".comment-barrage");
|
||||
if (commentElement && paginationElement) {
|
||||
const observer = new IntersectionObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
const action = entry.isIntersecting ? 'add' : 'remove';
|
||||
paginationElement.classList[action]("show-window");
|
||||
if (GLOBAL_CONFIG.comment.commentBarrage) {
|
||||
commentBarrageElement.style.bottom = entry.isIntersecting ? "-200px" : "0px";
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.observe(commentElement);
|
||||
}
|
||||
};
|
||||
const addCopyright = () => {
|
||||
if (!GLOBAL_CONFIG.copyright) return;
|
||||
const {limit, author, link, source, info} = GLOBAL_CONFIG.copyright;
|
||||
document.body.addEventListener('copy', (e) => {
|
||||
e.preventDefault();
|
||||
const copyText = window.getSelection().toString();
|
||||
const text = copyText.length > limit ? `${copyText}\n\n${author}\n${link}${window.location.href}\n${source}\n${info}` : copyText;
|
||||
e.clipboardData.setData('text', text);
|
||||
});
|
||||
};
|
||||
const asideStatus = () => {
|
||||
const status = utils.saveToLocal.get('aside-status');
|
||||
document.documentElement.classList.toggle('hide-aside', status === 'hide');
|
||||
}
|
||||
function initThemeColor() {
|
||||
const currentTop = window.scrollY || document.documentElement.scrollTop;
|
||||
const themeColor = currentTop > 0 ? '--efu-card-bg' : PAGE_CONFIG.is_post ? '--efu-main' : '--efu-background';
|
||||
applyThemeColor(getComputedStyle(document.documentElement).getPropertyValue(themeColor));
|
||||
}
|
||||
function applyThemeColor(color) {
|
||||
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
|
||||
const appleMobileWebAppMeta = document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');
|
||||
themeColorMeta?.setAttribute("content", color);
|
||||
appleMobileWebAppMeta?.setAttribute("content", color);
|
||||
if (window.matchMedia("(display-mode: standalone)").matches) {
|
||||
document.body.style.backgroundColor = color;
|
||||
}
|
||||
}
|
||||
const handleThemeChange = mode => {
|
||||
const themeChange = window.globalFn?.themeChange || {}
|
||||
for (let key in themeChange) {
|
||||
themeChange[key](mode)
|
||||
}
|
||||
}
|
||||
const sco = {
|
||||
lastSayHello: "",
|
||||
wasPageHidden: false,
|
||||
musicPlaying: false,
|
||||
hideCookie() {
|
||||
const cookiesWindow = document.getElementById("cookies-window");
|
||||
if (cookiesWindow) {
|
||||
setTimeout(() => {
|
||||
cookiesWindow.classList.add("cw-hide");
|
||||
setTimeout(() => cookiesWindow.style.display = "none", 1000);
|
||||
}, 3000);
|
||||
}
|
||||
},
|
||||
scrollTo(elementId) {
|
||||
const targetElement = document.getElementById(elementId);
|
||||
if (targetElement) {
|
||||
const targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset - 80;
|
||||
window.scroll({
|
||||
top: targetPosition,
|
||||
behavior: "smooth"
|
||||
});
|
||||
}
|
||||
},
|
||||
musicToggle() {
|
||||
const $music = document.querySelector('#nav-music');
|
||||
const $meting = document.querySelector('meting-js');
|
||||
const $console = document.getElementById('consoleMusic');
|
||||
const $rm_text = document.querySelector('#menu-music-toggle span');
|
||||
const $rm_icon = document.querySelector('#menu-music-toggle i');
|
||||
this.musicPlaying = !this.musicPlaying;
|
||||
$music.classList.toggle("playing", this.musicPlaying);
|
||||
$console.classList.toggle("on", this.musicPlaying);
|
||||
if (this.musicPlaying) {
|
||||
$meting.aplayer.play();
|
||||
rm?.menuItems.music[0] && ($rm_text.textContent = GLOBAL_CONFIG.right_menu.music.stop) && ($rm_icon.className = 'solitude st-pause-fill')
|
||||
} else {
|
||||
$meting.aplayer.pause();
|
||||
rm?.menuItems.music[0] && ($rm_text.textContent = GLOBAL_CONFIG.right_menu.music.start) && ($rm_icon.className = 'solitude st-play-fill')
|
||||
}
|
||||
},
|
||||
switchCommentBarrage() {
|
||||
let commentBarrageElement = document.querySelector(".comment-barrage");
|
||||
if (!commentBarrageElement) return;
|
||||
const isDisplayed = window.getComputedStyle(commentBarrageElement).display === "flex";
|
||||
commentBarrageElement.style.display = isDisplayed ? "none" : "flex";
|
||||
document.querySelector("#consoleCommentBarrage").classList.toggle("on", !isDisplayed);
|
||||
utils.saveToLocal.set("commentBarrageSwitch", !isDisplayed, .2);
|
||||
rm?.menuItems.barrage && rm.barrage(isDisplayed)
|
||||
},
|
||||
switchHideAside() {
|
||||
const htmlClassList = document.documentElement.classList;
|
||||
const consoleHideAside = document.querySelector("#consoleHideAside");
|
||||
const isHideAside = htmlClassList.contains("hide-aside");
|
||||
utils.saveToLocal.set("aside-status", isHideAside ? "show" : "hide", 1);
|
||||
htmlClassList.toggle("hide-aside");
|
||||
consoleHideAside.classList.toggle("on", !isHideAside);
|
||||
},
|
||||
switchKeyboard() {
|
||||
this.sco_keyboards = !this.sco_keyboards;
|
||||
const consoleKeyboard = document.querySelector("#consoleKeyboard");
|
||||
const keyboardFunction = this.sco_keyboards ? openKeyboard : closeKeyboard;
|
||||
consoleKeyboard.classList.toggle("on", this.sco_keyboards);
|
||||
keyboardFunction();
|
||||
localStorage.setItem("keyboard", this.sco_keyboards);
|
||||
document.getElementById('keyboard-tips')?.classList.remove('show');
|
||||
},
|
||||
initConsoleState() {
|
||||
const consoleHideAside = document.querySelector("#consoleHideAside");
|
||||
consoleHideAside.classList.toggle("on", !document.documentElement.classList.contains("hide-aside"));
|
||||
},
|
||||
changeSayHelloText() {
|
||||
const greetings = GLOBAL_CONFIG.aside.sayhello2;
|
||||
const greetingElement = document.getElementById("author-info__sayhi");
|
||||
let randomGreeting;
|
||||
do {
|
||||
randomGreeting = greetings[Math.floor(Math.random() * greetings.length)];
|
||||
} while (randomGreeting === this.lastSayHello);
|
||||
greetingElement.textContent = randomGreeting;
|
||||
this.lastSayHello = randomGreeting;
|
||||
},
|
||||
switchDarkMode() {
|
||||
const isDarkMode = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||
const newMode = isDarkMode ? 'light' : 'dark';
|
||||
document.documentElement.setAttribute('data-theme', newMode);
|
||||
utils.saveToLocal.set('theme', newMode, 0.02);
|
||||
utils.snackbarShow(GLOBAL_CONFIG.lang.theme[newMode], false, 2000);
|
||||
if(typeof rm === 'object') rm.mode(!isDarkMode) && rm.hideRightMenu();
|
||||
handleThemeChange(newMode);
|
||||
},
|
||||
hideTodayCard: () => document.getElementById('todayCard').classList.add('hide'),
|
||||
toTop: () => utils.scrollToDest(0),
|
||||
showConsole: () => document.getElementById('console')?.classList.toggle('show', true),
|
||||
hideConsole: () => document.getElementById('console')?.classList.remove('show'),
|
||||
refreshWaterFall() {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
setTimeout(() => {
|
||||
waterfall(entry.target) || entry.target.classList.add('show');
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.waterfall').forEach(el => observer.observe(el));
|
||||
},
|
||||
addRuntime() {
|
||||
let el = document.getElementById('runtimeshow');
|
||||
el && GLOBAL_CONFIG.runtime && (el.innerText = utils.timeDiff(new Date(GLOBAL_CONFIG.runtime), new Date()) + GLOBAL_CONFIG.lang.day);
|
||||
},
|
||||
toTalk(txt) {
|
||||
const inputs = ["#wl-edit", ".el-textarea__inner", "#veditor", ".atk-textarea"];
|
||||
inputs.forEach(selector => {
|
||||
const el = document.querySelector(selector);
|
||||
if (el) {
|
||||
el.dispatchEvent(new Event('input', { bubble: true, cancelable: true }));
|
||||
el.value = '> ' + txt.replace(/\n/g, '\n> ') + '\n\n';
|
||||
utils.scrollToDest(utils.getEleTop(document.getElementById('post-comment')), 300);
|
||||
el.focus();
|
||||
el.setSelectionRange(-1, -1);
|
||||
}
|
||||
});
|
||||
utils.snackbarShow(GLOBAL_CONFIG.lang.totalk, false, 2000);
|
||||
},
|
||||
initbbtalk() {
|
||||
const bberTalkElement = document.querySelector('#bber-talk');
|
||||
if (bberTalkElement) {
|
||||
new Swiper('.swiper-container', {
|
||||
direction: 'vertical',
|
||||
loop: true,
|
||||
autoplay: {
|
||||
delay: 3000,
|
||||
pauseOnMouseEnter: true
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
addPhotoFigcaption() {
|
||||
document.querySelectorAll('#article-container img:not(.gallery-item img)').forEach(image => {
|
||||
const captionText = image.getAttribute('alt');
|
||||
captionText && image.insertAdjacentHTML('afterend', `<div class="img-alt is-center">${captionText}</div>`);
|
||||
});
|
||||
},
|
||||
scrollToComment: () => utils.scrollToDest(utils.getEleTop(document.getElementById('post-comment')), 300),
|
||||
setTimeState() {
|
||||
const el = document.getElementById('author-info__sayhi');
|
||||
if (el) {
|
||||
const hours = new Date().getHours();
|
||||
const lang = GLOBAL_CONFIG.aside.sayhello;
|
||||
|
||||
const localData = getLocalData(['twikoo', 'WALINE_USER_META', 'WALINE_USER', '_v_Cache_Meta', 'ArtalkUser']);
|
||||
|
||||
function getLocalData(keys) {
|
||||
for (let key of keys) {
|
||||
const data = localStorage.getItem(key);
|
||||
if (data) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const nick = localData ? (localData.nick ? localData.nick : localData.display_name) : null;
|
||||
|
||||
let prefix;
|
||||
if (this.wasPageHidden) {
|
||||
prefix = GLOBAL_CONFIG.aside.sayhello3.back + nick;
|
||||
this.wasPageHidden = false;
|
||||
} else {
|
||||
prefix = GLOBAL_CONFIG.aside.sayhello3.prefix + nick;
|
||||
}
|
||||
|
||||
const greetings = [
|
||||
{ start: 0, end: 5, text: nick ? prefix : lang.goodnight },
|
||||
{ start: 6, end: 10, text: nick ? prefix : lang.morning },
|
||||
{ start: 11, end: 14, text: nick ? prefix : lang.noon },
|
||||
{ start: 15, end: 18, text: nick ? prefix : lang.afternoon },
|
||||
{ start: 19, end: 24, text: nick ? prefix : lang.night },
|
||||
];
|
||||
const greeting = greetings.find(g => hours >= g.start && hours <= g.end);
|
||||
el.innerText = greeting.text;
|
||||
}
|
||||
},
|
||||
tagPageActive() {
|
||||
const decodedPath = decodeURIComponent(window.location.pathname);
|
||||
const isTagPage = /\/tags\/.*?\//.test(decodedPath);
|
||||
if (isTagPage) {
|
||||
const tag = decodedPath.split("/").slice(-2, -1)[0];
|
||||
const tagElement = document.getElementById(tag);
|
||||
if (tagElement) {
|
||||
document.querySelectorAll("a.select").forEach(link => {
|
||||
link.classList.remove("select");
|
||||
});
|
||||
tagElement.classList.add("select");
|
||||
}
|
||||
}
|
||||
},
|
||||
categoriesBarActive() {
|
||||
const categoryBar = document.querySelector("#category-bar");
|
||||
const currentPath = decodeURIComponent(window.location.pathname);
|
||||
const isHomePage = currentPath === "/";
|
||||
if (categoryBar) {
|
||||
const categoryItems = categoryBar.querySelectorAll(".category-bar-item");
|
||||
categoryItems.forEach(item => item.classList.remove("select"));
|
||||
const activeItemId = isHomePage ? "category-bar-home" : currentPath.split("/").slice(-2, -1)[0];
|
||||
const activeItem = document.getElementById(activeItemId);
|
||||
if (activeItem) {
|
||||
activeItem.classList.add("select");
|
||||
}
|
||||
}
|
||||
},
|
||||
scrollCategoryBarToRight() {
|
||||
const scrollBar = document.getElementById("category-bar-items");
|
||||
const nextElement = document.getElementById("category-bar-next");
|
||||
if (scrollBar) {
|
||||
const isScrollBarAtEnd = () => scrollBar.scrollLeft + scrollBar.clientWidth >= scrollBar.scrollWidth - 8;
|
||||
const scroll = () => {
|
||||
if (isScrollBarAtEnd()) {
|
||||
scrollBar.scroll({ left: 0, behavior: "smooth" });
|
||||
} else {
|
||||
scrollBar.scrollBy({ left: scrollBar.clientWidth, behavior: "smooth" });
|
||||
}
|
||||
};
|
||||
scrollBar.addEventListener("scroll", () => {
|
||||
clearTimeout(this.timeoutId);
|
||||
this.timeoutId = setTimeout(() => {
|
||||
nextElement.style.transform = isScrollBarAtEnd() ? "rotate(180deg)" : "";
|
||||
}, 150);
|
||||
});
|
||||
scroll();
|
||||
}
|
||||
},
|
||||
openAllTags() {
|
||||
document.querySelectorAll(".card-allinfo .card-tag-cloud").forEach(tagCloudElement => tagCloudElement.classList.add("all-tags"));
|
||||
document.getElementById("more-tags-btn")?.remove();
|
||||
},
|
||||
listenToPageInputPress() {
|
||||
const toGroup = document.querySelector(".toPageGroup")
|
||||
const pageText = document.getElementById("toPageText");
|
||||
if (!pageText) return;
|
||||
const pageButton = document.getElementById("toPageButton");
|
||||
const pageNumbers = document.querySelectorAll(".page-number");
|
||||
const lastPageNumber = +pageNumbers[pageNumbers.length - 1].textContent;
|
||||
if (!pageText || lastPageNumber === 1) {
|
||||
toGroup.style.display = "none";
|
||||
return
|
||||
}
|
||||
pageText.addEventListener("keydown", (event) => {
|
||||
if (event.keyCode === 13) {
|
||||
sco.toPage();
|
||||
pjax.loadUrl(pageButton.href);
|
||||
}
|
||||
});
|
||||
pageText.addEventListener("input", () => {
|
||||
pageButton.classList.toggle("haveValue", pageText.value !== "" && pageText.value !== "0");
|
||||
if (+pageText.value > lastPageNumber) {
|
||||
pageText.value = lastPageNumber;
|
||||
}
|
||||
});
|
||||
},
|
||||
addNavBackgroundInit() {
|
||||
const scrollTop = document.documentElement.scrollTop;
|
||||
(scrollTop !== 0) && document.getElementById("page-header").classList.add("nav-fixed", "nav-visible");
|
||||
},
|
||||
toPage() {
|
||||
const pageNumbers = document.querySelectorAll(".page-number");
|
||||
const maxPageNumber = parseInt(pageNumbers[pageNumbers.length - 1].innerHTML);
|
||||
const inputElement = document.getElementById("toPageText");
|
||||
const inputPageNumber = parseInt(inputElement.value);
|
||||
document.getElementById("toPageButton").href = (!isNaN(inputPageNumber) && inputPageNumber <= maxPageNumber && inputPageNumber > 1)
|
||||
? window.location.href.replace(/\/page\/\d+\/$/, "/") + "page/" + inputPageNumber + "/"
|
||||
: '/';
|
||||
},
|
||||
owoBig(owoSelector) {
|
||||
let owoBig = document.getElementById('owo-big');
|
||||
if (!owoBig) {
|
||||
owoBig = document.createElement('div');
|
||||
owoBig.id = 'owo-big';
|
||||
document.body.appendChild(owoBig);
|
||||
}
|
||||
const showOwoBig = event => {
|
||||
const target = event.target;
|
||||
const owoItem = target.closest(owoSelector.item);
|
||||
if (owoItem && target.closest(owoSelector.body)) {
|
||||
const imgSrc = owoItem.querySelector('img')?.src;
|
||||
if (imgSrc) {
|
||||
owoBig.innerHTML = `<img src="${imgSrc}" style="max-width: 100%; height: auto;">`;
|
||||
owoBig.style.display = 'block';
|
||||
positionOwoBig(owoItem);
|
||||
}
|
||||
}
|
||||
};
|
||||
const hideOwoBig = event => {
|
||||
if (event.target.closest(owoSelector.item) && event.target.closest(owoSelector.body)) {
|
||||
owoBig.style.display = 'none';
|
||||
}
|
||||
};
|
||||
const positionOwoBig = owoItem => {
|
||||
const itemRect = owoItem.getBoundingClientRect();
|
||||
owoBig.style.left = `${itemRect.left - (owoBig.offsetWidth / 4)}px`;
|
||||
owoBig.style.top = `${itemRect.top}px`;
|
||||
}
|
||||
document.addEventListener('mouseover', showOwoBig);
|
||||
document.addEventListener('mouseout', hideOwoBig);
|
||||
},
|
||||
changeTimeFormat(selector) {
|
||||
selector.forEach(item => {
|
||||
const timeVal = item.getAttribute('datetime')
|
||||
item.textContent = utils.diffDate(timeVal, true)
|
||||
item.style.display = 'inline'
|
||||
})
|
||||
},
|
||||
switchComments() {
|
||||
const switchBtn = document.getElementById('switch-btn')
|
||||
if (!switchBtn) return
|
||||
let switchDone = false
|
||||
const commentContainer = document.getElementById('post-comment')
|
||||
const handleSwitchBtn = () => {
|
||||
commentContainer.classList.toggle('move')
|
||||
if (!switchDone && typeof loadTwoComment === 'function') {
|
||||
switchDone = true
|
||||
loadTwoComment()
|
||||
}
|
||||
}
|
||||
utils.addEventListenerPjax(switchBtn, 'click', handleSwitchBtn)
|
||||
}
|
||||
};
|
||||
const addHighlight = () => {
|
||||
const highlight = GLOBAL_CONFIG.highlight;
|
||||
if (!highlight) return;
|
||||
const {copy, expand, limit, syntax} = highlight;
|
||||
const $isPrismjs = syntax === 'prismjs';
|
||||
const $isShowTool = highlight.enable || copy || expand || limit;
|
||||
const expandClass = !expand === true ? 'closed' : ''
|
||||
const $syntaxHighlight = syntax === 'highlight.js' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]')
|
||||
if (!(($isShowTool || limit) && $syntaxHighlight.length)) return
|
||||
const copyEle = copy ? `<i class="solitude st-copy-fill copy-button"></i>` : '<i></i>';
|
||||
const expandEle = `<i class="solitude st-arrow-down expand"></i>`;
|
||||
const limitEle = limit ? `<i class="solitude st-show-line"></i>` : '<i></i>';
|
||||
const alertInfo = (ele, text) => utils.snackbarShow(text, false, 2000)
|
||||
const copyFn = (e) => {
|
||||
const $buttonParent = e.parentNode
|
||||
$buttonParent.classList.add('copy-true')
|
||||
const selection = window.getSelection()
|
||||
const range = document.createRange()
|
||||
const preCodeSelector = $isPrismjs ? 'pre code' : 'table .code pre'
|
||||
range.selectNodeContents($buttonParent.querySelectorAll(`${preCodeSelector}`)[0])
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
document.execCommand('copy')
|
||||
alertInfo(e.lastChild, GLOBAL_CONFIG.lang.copy.success)
|
||||
selection.removeAllRanges()
|
||||
$buttonParent.classList.remove('copy-true')
|
||||
}
|
||||
const expandClose = (e) => e.classList.toggle('closed')
|
||||
const shrinkEle = function () {
|
||||
this.classList.toggle('expand-done')
|
||||
}
|
||||
const ToolsFn = function (e) {
|
||||
const $target = e.target.classList
|
||||
if ($target.contains('expand')) expandClose(this)
|
||||
else if ($target.contains('copy-button')) copyFn(this)
|
||||
}
|
||||
const createEle = (lang, item, service) => {
|
||||
const fragment = document.createDocumentFragment()
|
||||
if ($isShowTool) {
|
||||
const hlTools = document.createElement('div')
|
||||
hlTools.className = `highlight-tools ${expandClass}`
|
||||
hlTools.innerHTML = expandEle + lang + copyEle
|
||||
utils.addEventListenerPjax(hlTools, 'click', ToolsFn)
|
||||
fragment.appendChild(hlTools)
|
||||
}
|
||||
if (limit && item.offsetHeight > limit + 30) {
|
||||
const ele = document.createElement('div')
|
||||
ele.className = 'code-expand-btn'
|
||||
ele.innerHTML = limitEle
|
||||
utils.addEventListenerPjax(ele, 'click', shrinkEle)
|
||||
fragment.appendChild(ele)
|
||||
}
|
||||
if (service === 'hl') {
|
||||
item.insertBefore(fragment, item.firstChild)
|
||||
} else {
|
||||
item.parentNode.insertBefore(fragment, item)
|
||||
}
|
||||
}
|
||||
if ($isPrismjs) {
|
||||
$syntaxHighlight.forEach(item => {
|
||||
const langName = item.getAttribute('data-language') || 'Code'
|
||||
const highlightLangEle = `<div class="code-lang">${langName}</div>`
|
||||
utils.wrap(item, 'figure', {
|
||||
class: 'highlight'
|
||||
})
|
||||
createEle(highlightLangEle, item)
|
||||
})
|
||||
} else {
|
||||
$syntaxHighlight.forEach(item => {
|
||||
let langName = item.getAttribute('class').split(' ')[1]
|
||||
if (langName === 'plain' || langName === undefined) langName = 'Code'
|
||||
const highlightLangEle = `<div class="code-lang">${langName}</div>`
|
||||
createEle(highlightLangEle, item, 'hl')
|
||||
})
|
||||
}
|
||||
}
|
||||
class toc {
|
||||
static init() {
|
||||
const tocContainer = document.getElementById('card-toc')
|
||||
if (!tocContainer || !tocContainer.querySelector('.toc a')) {
|
||||
tocContainer.style.display = 'none'
|
||||
return
|
||||
}
|
||||
const el = document.querySelectorAll('.toc a')
|
||||
el.forEach((e) => {
|
||||
e.addEventListener('click', (event) => {
|
||||
event.preventDefault()
|
||||
utils.scrollToDest(utils.getEleTop(document.getElementById(decodeURI((event.target.className === 'toc-text' ? event.target.parentNode.hash : event.target.hash).replace('#', '')))), 300)
|
||||
})
|
||||
})
|
||||
this.active(el)
|
||||
}
|
||||
static active(toc) {
|
||||
const $article = document.getElementById('article-container')
|
||||
const $tocContent = document.getElementById('toc-content')
|
||||
const list = $article.querySelectorAll('h1,h2,h3,h4,h5,h6')
|
||||
let detectItem = ''
|
||||
function autoScroll(el) {
|
||||
const activePosition = el.getBoundingClientRect().top
|
||||
const sidebarScrollTop = $tocContent.scrollTop
|
||||
if (activePosition > (document.documentElement.clientHeight - 100)) {
|
||||
$tocContent.scrollTop = sidebarScrollTop + 150
|
||||
}
|
||||
if (activePosition < 100) {
|
||||
$tocContent.scrollTop = sidebarScrollTop - 150
|
||||
}
|
||||
}
|
||||
function findHeadPosition(top) {
|
||||
if (top === 0) return false
|
||||
let currentIndex = ''
|
||||
list.forEach(function (ele, index) {
|
||||
if (top > utils.getEleTop(ele) - 80) {
|
||||
currentIndex = index
|
||||
}
|
||||
})
|
||||
if (detectItem === currentIndex) return
|
||||
detectItem = currentIndex
|
||||
document.querySelectorAll('.toc .active').forEach((i) => {
|
||||
i.classList.remove('active')
|
||||
})
|
||||
const activeitem = toc[detectItem]
|
||||
if (activeitem) {
|
||||
let parent = toc[detectItem].parentNode
|
||||
activeitem.classList.add('active')
|
||||
autoScroll(activeitem)
|
||||
for (; !parent.matches('.toc'); parent = parent.parentNode) {
|
||||
if (parent.matches('li')) parent.classList.add('active')
|
||||
}
|
||||
}
|
||||
}
|
||||
window.tocScrollFn = utils.throttle(function () {
|
||||
const currentTop = window.scrollY || document.documentElement.scrollTop
|
||||
findHeadPosition(currentTop)
|
||||
}, 100)
|
||||
window.addEventListener('scroll', tocScrollFn)
|
||||
}
|
||||
}
|
||||
class tabs {
|
||||
static init() {
|
||||
this.clickFnOfTabs();
|
||||
this.backToTop();
|
||||
}
|
||||
static clickFnOfTabs() {
|
||||
document.querySelectorAll('#article-container .tab > button').forEach((item) => {
|
||||
item.addEventListener('click', function (e) {
|
||||
const that = this;
|
||||
const $tabItem = that.parentNode;
|
||||
if (!$tabItem.classList.contains('active')) {
|
||||
const $tabContent = $tabItem.parentNode.nextElementSibling;
|
||||
const $siblings = utils.siblings($tabItem, '.active')[0];
|
||||
$siblings && $siblings.classList.remove('active');
|
||||
$tabItem.classList.add('active');
|
||||
const tabId = that.getAttribute('data-href').replace('#', '');
|
||||
const childList = [...$tabContent.children];
|
||||
childList.forEach((item) => {
|
||||
if (item.id === tabId) item.classList.add('active');
|
||||
else item.classList.remove('active');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
static backToTop() {
|
||||
document.querySelectorAll('#article-container .tabs .tab-to-top').forEach((item) => {
|
||||
item.addEventListener('click', function () {
|
||||
utils.scrollToDest(utils.getEleTop(item.parentElement.parentElement.parentNode), 300);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window.refreshFn = () => {
|
||||
const {is_home, is_page, page, is_post} = PAGE_CONFIG;
|
||||
const {runtime, lazyload, lightbox, randomlink, covercolor, post_ai} = GLOBAL_CONFIG;
|
||||
const timeSelector = (is_home ? '.post-meta-date time' : is_post ? '.post-meta-date time' : '.datatime') + ', .webinfo-item time';
|
||||
document.body.setAttribute('data-type', page);
|
||||
sco.changeTimeFormat(document.querySelectorAll(timeSelector));
|
||||
runtime && sco.addRuntime();
|
||||
[scrollFn, sidebarFn, sco.hideCookie, sco.addPhotoFigcaption, sco.setTimeState, sco.tagPageActive, sco.categoriesBarActive, sco.listenToPageInputPress, sco.addNavBackgroundInit, sco.refreshWaterFall].forEach(fn => fn());
|
||||
lazyload.enable && utils.lazyloadImg();
|
||||
lightbox && utils.lightbox(document.querySelectorAll("#article-container img:not(.flink-avatar,.gallery-group img)"));
|
||||
randomlink && randomLinksList();
|
||||
post_ai && is_post && efu_ai.init();
|
||||
sco.switchComments();
|
||||
initObserver();
|
||||
if (is_home) showTodayCard();
|
||||
if (is_post || is_page) {
|
||||
addHighlight();
|
||||
tabs.init();
|
||||
}
|
||||
if (covercolor.enable) coverColor();
|
||||
if (PAGE_CONFIG.toc) toc.init();
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
[addCopyright, sco.initConsoleState, window.refreshFn, asideStatus, () => window.onscroll = percent].forEach(fn => fn());
|
||||
});
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.hidden) {
|
||||
sco.wasPageHidden = true;
|
||||
}
|
||||
});
|
||||
window.onkeydown = e => {
|
||||
const { keyCode, ctrlKey, shiftKey } = e;
|
||||
if (keyCode === 123 || (ctrlKey && shiftKey && keyCode === 67)) {
|
||||
utils.snackbarShow(GLOBAL_CONFIG.lang.f12, false, 3000);
|
||||
}
|
||||
if (keyCode === 27) {
|
||||
sco.hideConsole();
|
||||
}
|
||||
};
|
||||
document.addEventListener('copy', () => {
|
||||
utils.snackbarShow(GLOBAL_CONFIG.lang.copy.success, false, 3000);
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Music Player
|
||||
* @description Initialize the music player and add event listeners to control the player
|
||||
*/
|
||||
class ScoMusicPlayer {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
init() {
|
||||
document.documentElement.style.setProperty('--vh', `${window.innerHeight}px`);
|
||||
this.getCustomPlayList();
|
||||
this.addEventListenerToDocument();
|
||||
this.addButtonListEventListener();
|
||||
}
|
||||
|
||||
getCustomPlayList() {
|
||||
this.changeMusicBg(false);
|
||||
}
|
||||
addEventListenerToDocument() {
|
||||
document.addEventListener("keydown", this.handleKeydown.bind(this));
|
||||
}
|
||||
|
||||
addButtonListEventListener() {
|
||||
const aplayerList = document.querySelector(".aplayer-list");
|
||||
document.querySelector(".aplayer-lrc")?.addEventListener("click", () => {
|
||||
aplayerList.classList.toggle("aplayer-list-hide");
|
||||
});
|
||||
}
|
||||
|
||||
changeMusicBg(isChangeBg = true) {
|
||||
const musicBg = document.getElementById("Music-bg");
|
||||
const musicLoading = document.getElementsByClassName("Music-loading")[0];
|
||||
|
||||
if (isChangeBg) {
|
||||
this.updateBackgroundImage(musicBg);
|
||||
} else {
|
||||
this.setLoadingScreen(musicLoading, musicBg);
|
||||
}
|
||||
}
|
||||
|
||||
updateBackgroundImage(element) {
|
||||
const musicCover = document.querySelector("#Music-page .aplayer-pic");
|
||||
const img = new Image();
|
||||
img.src = this.extractValue(musicCover.style.backgroundImage);
|
||||
img.onload = () => {
|
||||
element.style.backgroundImage = musicCover.style.backgroundImage;
|
||||
};
|
||||
element.className = 'show'
|
||||
}
|
||||
|
||||
setLoadingScreen(loadingElement, backgroundElement) {
|
||||
const timer = setInterval(() => {
|
||||
const musicCover = document.querySelector("#Music-page .aplayer-pic");
|
||||
if (musicCover) {
|
||||
loadingElement.style.display = "none";
|
||||
clearInterval(timer);
|
||||
document.querySelector('meting-js').aplayer.volume(0.8, true);
|
||||
this.addEventListenerChangeMusicBg();
|
||||
backgroundElement.style.display = "block";
|
||||
}
|
||||
this.addButtonListEventListener();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
extractValue(input) {
|
||||
const valueRegex = /url\("([^"]+)"\)/;
|
||||
const match = valueRegex.exec(input);
|
||||
return match ? match[1] : '';
|
||||
}
|
||||
|
||||
addEventListenerChangeMusicBg() {
|
||||
const aplayer = document.querySelector("#Music-page meting-js").aplayer;
|
||||
aplayer.on('loadeddata', this.changeMusicBg.bind(this, true));
|
||||
aplayer.on('timeupdate', this.lrcUpdate.bind(this));
|
||||
}
|
||||
|
||||
lrcUpdate() {
|
||||
const aplayerLrcContents = document.querySelector('.aplayer-lrc-contents');
|
||||
const currentLrc = aplayerLrcContents.querySelector('p.aplayer-lrc-current');
|
||||
if (currentLrc) {
|
||||
const currentIndex = Array.from(aplayerLrcContents.children).indexOf(currentLrc);
|
||||
aplayerLrcContents.style.transform = `translateY(${-currentIndex * 80}px)`;
|
||||
}
|
||||
}
|
||||
|
||||
handleKeydown(event) {
|
||||
const aplayer = document.querySelector('meting-js').aplayer;
|
||||
switch (event.code) {
|
||||
case "Space":
|
||||
event.preventDefault();
|
||||
aplayer.toggle();
|
||||
break;
|
||||
case "ArrowRight":
|
||||
event.preventDefault();
|
||||
aplayer.skipForward();
|
||||
break;
|
||||
case "ArrowLeft":
|
||||
event.preventDefault();
|
||||
aplayer.skipBack();
|
||||
break;
|
||||
case "ArrowUp":
|
||||
event.preventDefault();
|
||||
if (aplayer.volume < 1) aplayer.volume(aplayer.volume + 0.1);
|
||||
break;
|
||||
case "ArrowDown":
|
||||
event.preventDefault();
|
||||
if (aplayer.volume > 0) aplayer.volume(aplayer.volume - 0.1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
destroy() {
|
||||
document.removeEventListener("keydown", this.handleKeydown);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the music player
|
||||
*/
|
||||
function initializeMusicPlayer() {
|
||||
let exitingMusic = window.scoMusic;
|
||||
if (exitingMusic) exitingMusic.destroy();
|
||||
window.scoMusic = new ScoMusicPlayer();
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
let selectTextNow = "";
|
||||
const selectText = () => {
|
||||
selectTextNow = document.selection
|
||||
? document.selection.createRange().text
|
||||
: window.getSelection() + "" || "";
|
||||
};
|
||||
document.onmouseup = document.ondbclick = selectText;
|
||||
|
||||
const rm = {
|
||||
mask: document.getElementById("rightmenu-mask"),
|
||||
menu: document.getElementById("rightMenu"),
|
||||
width: 0,
|
||||
height: 0,
|
||||
domhref: "",
|
||||
domsrc: "",
|
||||
globalEvent: null,
|
||||
menuItems: {
|
||||
other: document.getElementsByClassName("rightMenuOther"),
|
||||
plugin: document.getElementsByClassName("rightMenuPlugin"),
|
||||
back: document.getElementById("menu-backward"),
|
||||
forward: document.getElementById("menu-forward"),
|
||||
refresh: document.getElementById("menu-refresh"),
|
||||
top: document.getElementById("menu-top"),
|
||||
copy: document.getElementById("menu-copytext"),
|
||||
paste: document.getElementById("menu-pastetext"),
|
||||
comment: document.getElementById("menu-commenttext"),
|
||||
new: document.getElementById("menu-newwindow"),
|
||||
copyLink: document.getElementById("menu-copylink"),
|
||||
copyImg: document.getElementById("menu-copyimg"),
|
||||
downloadImg: document.getElementById("menu-downloadimg"),
|
||||
search: document.getElementById("menu-search"),
|
||||
barrage: document.getElementById("menu-commentBarrage"),
|
||||
mode: document.getElementById("menu-darkmode"),
|
||||
translate: document.getElementById("menu-translate"),
|
||||
music: [
|
||||
document.getElementById("menu-music-toggle"),
|
||||
document.getElementById("menu-music-back"),
|
||||
document.getElementById("menu-music-forward"),
|
||||
document.getElementById("menu-music-copyMusicName"),
|
||||
],
|
||||
},
|
||||
showRightMenu(e, x = 0, y = 0) {
|
||||
this.menu.style.top = y + "px";
|
||||
this.menu.style.left = x + "px";
|
||||
this.menu.style.display = e ? "block" : "none";
|
||||
e ? stopMaskScroll() : (this.mask.style.display = "none");
|
||||
},
|
||||
hideRightMenu() {
|
||||
rm.showRightMenu(false);
|
||||
rm.mask.style.display = "none";
|
||||
},
|
||||
reLoadSize() {
|
||||
rm.menu.style.display = "block";
|
||||
rm.width = rm.menu.offsetWidth;
|
||||
rm.height = rm.menu.offsetHeight;
|
||||
rm.menu.style.display = 'none';
|
||||
},
|
||||
copyText(e) {
|
||||
navigator.clipboard && navigator.clipboard.writeText(e);
|
||||
utils.snackbarShow(GLOBAL_CONFIG.lang.copy.success, false, 2000);
|
||||
this.hideRightMenu();
|
||||
},
|
||||
async downloadImage(imageUrl = this.domsrc, filename = "photo") {
|
||||
try {
|
||||
const response = await fetch(imageUrl);
|
||||
const blob = await response.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = filename || "image.jpg";
|
||||
link.style.display = "none";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
} catch (error) {
|
||||
utils.snackbarShow(GLOBAL_CONFIG.right_menu.img_error, false, 2000);
|
||||
}
|
||||
},
|
||||
copyImage(imgUrl = this.domsrc) {
|
||||
window.open(imgUrl);
|
||||
},
|
||||
mode(darkmode) {
|
||||
darkmode
|
||||
? (document.querySelector(".menu-darkmode-text").textContent =
|
||||
GLOBAL_CONFIG.right_menu.mode.light)
|
||||
: (document.querySelector(".menu-darkmode-text").textContent =
|
||||
GLOBAL_CONFIG.right_menu.mode.dark);
|
||||
this.hideRightMenu();
|
||||
},
|
||||
barrage(enable) {
|
||||
enable
|
||||
? (document.querySelector(".menu-commentBarrage-text").textContent =
|
||||
GLOBAL_CONFIG.right_menu.barrage.open)
|
||||
: (document.querySelector(".menu-commentBarrage-text").textContent =
|
||||
GLOBAL_CONFIG.right_menu.barrage.close);
|
||||
this.hideRightMenu();
|
||||
},
|
||||
};
|
||||
|
||||
function stopMaskScroll() {
|
||||
utils.addEventListenerPjax(rm.menu, "mousewheel", rm.hideRightMenu, { passive: true });
|
||||
utils.addEventListenerPjax(rm.mask, "mousewheel", rm.hideRightMenu, { passive: true });
|
||||
utils.addEventListenerPjax(rm.mask, "click", rm.hideRightMenu, { passive: true });
|
||||
}
|
||||
|
||||
window.oncontextmenu = (ele) => {
|
||||
if (document.body.clientWidth <= 768) return;
|
||||
let x = ele.clientX + 10;
|
||||
let y = ele.clientY;
|
||||
Array.from(rm.menuItems.other).forEach((item) => (item.style.display = "block"));
|
||||
rm.globalEvent = ele;
|
||||
|
||||
let display = false;
|
||||
let link = ele.target.href;
|
||||
let src = ele.target.currentSrc;
|
||||
|
||||
if (selectTextNow && window.getSelection()) {
|
||||
display = true;
|
||||
rm.menuItems.copy.style.display = "block";
|
||||
GLOBAL_CONFIG.comment && (rm.menuItems.comment.style.display = "block");
|
||||
rm.menuItems.search && (rm.menuItems.search.style.display = "block");
|
||||
} else {
|
||||
rm.menuItems.copy.style.display = "none";
|
||||
GLOBAL_CONFIG.comment && (rm.menuItems.comment.style.display = "none");
|
||||
rm.menuItems.search && (rm.menuItems.search.style.display = "none");
|
||||
}
|
||||
|
||||
if (link) {
|
||||
display = true;
|
||||
rm.menuItems.new.style.display = "block";
|
||||
rm.menuItems.copyLink.style.display = "block";
|
||||
rm.domhref = link;
|
||||
} else {
|
||||
rm.menuItems.new.style.display = "none";
|
||||
rm.menuItems.copyLink.style.display = "none";
|
||||
}
|
||||
|
||||
if (src) {
|
||||
display = true;
|
||||
rm.menuItems.copyImg.style.display = "block";
|
||||
rm.menuItems.downloadImg.style.display = "block";
|
||||
rm.domsrc = src;
|
||||
} else {
|
||||
rm.menuItems.copyImg.style.display = "none";
|
||||
rm.menuItems.downloadImg.style.display = "none";
|
||||
}
|
||||
|
||||
let tagName = ele.target.tagName.toLowerCase();
|
||||
if (tagName === "input" || tagName === "textarea") {
|
||||
display = true;
|
||||
rm.menuItems.paste.style.display = "block";
|
||||
} else {
|
||||
rm.menuItems.paste.style.display = "none";
|
||||
}
|
||||
|
||||
if (tagName === "meting-js") {
|
||||
display = true;
|
||||
rm.menuItems.music.forEach((item) => (item.style.display = "block"));
|
||||
} else {
|
||||
rm.menuItems.music[0] &&
|
||||
rm.menuItems.music.forEach((item) => (item.style.display = "none"));
|
||||
}
|
||||
|
||||
Array.from(display ? rm.menuItems.other : rm.menuItems.plugin).forEach(
|
||||
(item) => (item.style.display = "none")
|
||||
);
|
||||
Array.from(display ? rm.menuItems.plugin : rm.menuItems.other).forEach(
|
||||
(item) => (item.style.display = "block")
|
||||
);
|
||||
rm.reLoadSize();
|
||||
x + rm.width > window.innerWidth && (x -= rm.width + 10);
|
||||
y + rm.height > window.innerHeight && (y -= y + rm.height - window.innerHeight);
|
||||
rm.mask.style.display = "flex";
|
||||
rm.showRightMenu(true, x, y);
|
||||
return false;
|
||||
};
|
||||
|
||||
(function () {
|
||||
const addEventListener = (element, event, handler) =>
|
||||
element.addEventListener(event, handler);
|
||||
|
||||
addEventListener(rm.menuItems.back, "click", () =>
|
||||
window.history.back() || rm.hideRightMenu()
|
||||
);
|
||||
addEventListener(rm.menuItems.forward, "click", () =>
|
||||
window.history.forward() || rm.hideRightMenu()
|
||||
);
|
||||
addEventListener(rm.menuItems.refresh, "click", () =>
|
||||
window.location.reload()
|
||||
);
|
||||
addEventListener(rm.menuItems.top, "click", () =>
|
||||
sco.toTop() || rm.hideRightMenu()
|
||||
);
|
||||
|
||||
if (GLOBAL_CONFIG.right_menu.music) {
|
||||
addEventListener(rm.menuItems.music[0], "click", () => {
|
||||
sco.musicToggle();
|
||||
rm.hideRightMenu();
|
||||
});
|
||||
addEventListener(rm.menuItems.music[1], "click", () => {
|
||||
document.querySelector("meting-js").aplayer.skipBack();
|
||||
rm.hideRightMenu();
|
||||
});
|
||||
addEventListener(rm.menuItems.music[2], "click", () => {
|
||||
document.querySelector("meting-js").aplayer.skipForward();
|
||||
rm.hideRightMenu();
|
||||
});
|
||||
addEventListener(rm.menuItems.music[3], "click", () => {
|
||||
const title = Array.from(document.querySelectorAll(".aplayer-title")).map(
|
||||
(e) => e.innerText
|
||||
)[0];
|
||||
rm.copyText(title);
|
||||
});
|
||||
}
|
||||
|
||||
addEventListener(rm.menuItems.copy, "click", () => {
|
||||
if (GLOBAL_CONFIG.copyright) {
|
||||
const { limit, author, link, source, info } = GLOBAL_CONFIG.right_menu;
|
||||
if (selectTextNow.length > limit) {
|
||||
selectTextNow = `${selectTextNow}\n\n${author}\n${link}${window.location.href}\n${source}\n${info}`;
|
||||
}
|
||||
}
|
||||
rm.copyText(selectTextNow);
|
||||
rm.hideRightMenu();
|
||||
});
|
||||
|
||||
if (utils.saveToLocal.get("commentBarrageSwitch") !== null) {
|
||||
rm.menuItems.barrage && rm.barrage(!utils.saveToLocal.get("commentBarrageSwitch"));
|
||||
}
|
||||
|
||||
addEventListener(rm.menuItems.paste, "click", () =>
|
||||
rm.pasteText() && rm.hideRightMenu()
|
||||
);
|
||||
GLOBAL_CONFIG.comment &&
|
||||
addEventListener(rm.menuItems.comment, "click", () =>
|
||||
rm.hideRightMenu() || sco.toTalk(selectTextNow)
|
||||
);
|
||||
addEventListener(rm.menuItems.new, "click", () =>
|
||||
window.open(rm.domhref) && rm.hideRightMenu()
|
||||
);
|
||||
addEventListener(rm.menuItems.downloadImg, "click", () =>
|
||||
rm.downloadImage() && rm.hideRightMenu()
|
||||
);
|
||||
addEventListener(rm.menuItems.copyImg, "click", () =>
|
||||
rm.copyImage() && rm.hideRightMenu()
|
||||
);
|
||||
addEventListener(rm.menuItems.copyLink, "click", () =>
|
||||
rm.copyText(rm.domhref) && rm.hideRightMenu()
|
||||
);
|
||||
})();
|
||||
@@ -0,0 +1,138 @@
|
||||
(function($){
|
||||
// Search
|
||||
var $searchWrap = $('#search-form-wrap'),
|
||||
isSearchAnim = false,
|
||||
searchAnimDuration = 200;
|
||||
|
||||
var startSearchAnim = function(){
|
||||
isSearchAnim = true;
|
||||
};
|
||||
|
||||
var stopSearchAnim = function(callback){
|
||||
setTimeout(function(){
|
||||
isSearchAnim = false;
|
||||
callback && callback();
|
||||
}, searchAnimDuration);
|
||||
};
|
||||
|
||||
$('.nav-search-btn').on('click', function(){
|
||||
if (isSearchAnim) return;
|
||||
|
||||
startSearchAnim();
|
||||
$searchWrap.addClass('on');
|
||||
stopSearchAnim(function(){
|
||||
$('.search-form-input').focus();
|
||||
});
|
||||
});
|
||||
|
||||
$('.search-form-input').on('blur', function(){
|
||||
startSearchAnim();
|
||||
$searchWrap.removeClass('on');
|
||||
stopSearchAnim();
|
||||
});
|
||||
|
||||
// Share
|
||||
$('body').on('click', function(){
|
||||
$('.article-share-box.on').removeClass('on');
|
||||
}).on('click', '.article-share-link', function(e){
|
||||
e.stopPropagation();
|
||||
|
||||
var $this = $(this),
|
||||
url = $this.attr('data-url'),
|
||||
encodedUrl = encodeURIComponent(url),
|
||||
id = 'article-share-box-' + $this.attr('data-id'),
|
||||
title = $this.attr('data-title'),
|
||||
offset = $this.offset();
|
||||
|
||||
if ($('#' + id).length){
|
||||
var box = $('#' + id);
|
||||
|
||||
if (box.hasClass('on')){
|
||||
box.removeClass('on');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
var html = [
|
||||
'<div id="' + id + '" class="article-share-box">',
|
||||
'<input class="article-share-input" value="' + url + '">',
|
||||
'<div class="article-share-links">',
|
||||
'<a href="https://twitter.com/intent/tweet?text=' + encodeURIComponent(title) + '&url=' + encodedUrl + '" class="article-share-twitter" target="_blank" title="Twitter"><span class="fa fa-twitter"></span></a>',
|
||||
'<a href="https://www.facebook.com/sharer.php?u=' + encodedUrl + '" class="article-share-facebook" target="_blank" title="Facebook"><span class="fa fa-facebook"></span></a>',
|
||||
'<a href="http://pinterest.com/pin/create/button/?url=' + encodedUrl + '" class="article-share-pinterest" target="_blank" title="Pinterest"><span class="fa fa-pinterest"></span></a>',
|
||||
'<a href="https://www.linkedin.com/shareArticle?mini=true&url=' + encodedUrl + '" class="article-share-linkedin" target="_blank" title="LinkedIn"><span class="fa fa-linkedin"></span></a>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join('');
|
||||
|
||||
var box = $(html);
|
||||
|
||||
$('body').append(box);
|
||||
}
|
||||
|
||||
$('.article-share-box.on').hide();
|
||||
|
||||
box.css({
|
||||
top: offset.top + 25,
|
||||
left: offset.left
|
||||
}).addClass('on');
|
||||
}).on('click', '.article-share-box', function(e){
|
||||
e.stopPropagation();
|
||||
}).on('click', '.article-share-box-input', function(){
|
||||
$(this).select();
|
||||
}).on('click', '.article-share-box-link', function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
window.open(this.href, 'article-share-box-window-' + Date.now(), 'width=500,height=450');
|
||||
});
|
||||
|
||||
// Caption
|
||||
$('.article-entry').each(function(i){
|
||||
$(this).find('img').each(function(){
|
||||
if ($(this).parent().hasClass('fancybox') || $(this).parent().is('a')) return;
|
||||
|
||||
var alt = this.alt;
|
||||
|
||||
if (alt) $(this).after('<span class="caption">' + alt + '</span>');
|
||||
|
||||
$(this).wrap('<a href="' + this.src + '" data-fancybox=\"gallery\" data-caption="' + alt + '"></a>')
|
||||
});
|
||||
|
||||
$(this).find('.fancybox').each(function(){
|
||||
$(this).attr('rel', 'article' + i);
|
||||
});
|
||||
});
|
||||
|
||||
if ($.fancybox){
|
||||
$('.fancybox').fancybox();
|
||||
}
|
||||
|
||||
// Mobile nav
|
||||
var $container = $('#container'),
|
||||
isMobileNavAnim = false,
|
||||
mobileNavAnimDuration = 200;
|
||||
|
||||
var startMobileNavAnim = function(){
|
||||
isMobileNavAnim = true;
|
||||
};
|
||||
|
||||
var stopMobileNavAnim = function(){
|
||||
setTimeout(function(){
|
||||
isMobileNavAnim = false;
|
||||
}, mobileNavAnimDuration);
|
||||
}
|
||||
|
||||
$('#main-nav-toggle').on('click', function(){
|
||||
if (isMobileNavAnim) return;
|
||||
|
||||
startMobileNavAnim();
|
||||
$container.toggleClass('mobile-nav-on');
|
||||
stopMobileNavAnim();
|
||||
});
|
||||
|
||||
$('#wrap').on('click', function(){
|
||||
if (isMobileNavAnim || !$container.hasClass('mobile-nav-on')) return;
|
||||
|
||||
$container.removeClass('mobile-nav-on');
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,181 @@
|
||||
window.addEventListener("load", () => {
|
||||
const $searchMask = document.getElementById("search-mask");
|
||||
const $searchDialog = document.querySelector("#algolia-search .search-dialog");
|
||||
|
||||
window.openSearch = () => {
|
||||
utils.animateIn($searchMask, "to_show 0.5s");
|
||||
$searchDialog.style.display = "block";
|
||||
setTimeout(() => {
|
||||
document.querySelector("#algolia-search .ais-SearchBox-input").focus();
|
||||
}, 100);
|
||||
document.addEventListener("keydown", function f(event) {
|
||||
if (event.code === "Escape") {
|
||||
closeSearch();
|
||||
document.removeEventListener("keydown", f);
|
||||
}
|
||||
});
|
||||
fixSafariHeight();
|
||||
window.addEventListener("resize", fixSafariHeight);
|
||||
};
|
||||
|
||||
const closeSearch = () => {
|
||||
utils.animateOut($searchDialog, "search_close .5s");
|
||||
utils.animateOut($searchMask, "to_hide 0.5s");
|
||||
window.removeEventListener("resize", fixSafariHeight);
|
||||
};
|
||||
|
||||
const fixSafariHeight = () => {
|
||||
if (window.innerWidth < 768) {
|
||||
$searchDialog.style.setProperty("--search-height", window.innerHeight + "px");
|
||||
}
|
||||
};
|
||||
|
||||
const addEventCtrlK = () => {
|
||||
document.addEventListener("keydown", function (event) {
|
||||
if (event.ctrlKey && event.key === "k") {
|
||||
event.preventDefault();
|
||||
openSearch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addEventCtrlK()
|
||||
|
||||
const searchClickFn = () => {
|
||||
utils.addEventListenerPjax(document.querySelector("#search-button > .search"), "click", openSearch);
|
||||
|
||||
GLOBAL_CONFIG.right_menu && document.getElementById("menu-search").addEventListener("click", function (){
|
||||
rm.hideRightMenu();
|
||||
openSearch();
|
||||
let t=document.getElementsByClassName('ais-SearchBox-input')[0];
|
||||
let evt = document.createEvent('HTMLEvents');
|
||||
evt.initEvent('input', true,true)
|
||||
t.value = selectTextNow
|
||||
t.dispatchEvent(evt)
|
||||
})
|
||||
};
|
||||
|
||||
const searchFnOnce = () => {
|
||||
$searchMask.addEventListener("click", closeSearch);
|
||||
document.querySelector("#algolia-search .search-close-button").addEventListener("click", closeSearch);
|
||||
};
|
||||
|
||||
const algolia = GLOBAL_CONFIG.algolia;
|
||||
const isAlgoliaValid = algolia.appId && algolia.apiKey && algolia.indexName;
|
||||
if (!isAlgoliaValid) {
|
||||
return console.error("Algolia setting is invalid!");
|
||||
}
|
||||
|
||||
const search = instantsearch({
|
||||
indexName: algolia.indexName,
|
||||
searchClient: algoliasearch(algolia.appId, algolia.apiKey),
|
||||
searchFunction(helper) {
|
||||
if (helper.state.query) {
|
||||
let innerLoading = '<i class="solitude st-loading-line st-spin"></i>';
|
||||
document.getElementById("algolia-hits").innerHTML = innerLoading;
|
||||
helper.search();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const configure = instantsearch.widgets.configure({
|
||||
hitsPerPage: algolia.hits.per_page || 5,
|
||||
});
|
||||
|
||||
const searchBox = instantsearch.widgets.searchBox({
|
||||
container: "#algolia-search-input",
|
||||
showReset: false,
|
||||
showSubmit: false,
|
||||
placeholder: GLOBAL_CONFIG.lang.search.placeholder,
|
||||
showLoadingIndicator: true,
|
||||
searchOnEnterKeyPressOnly: true,
|
||||
searchAsYouType: false,
|
||||
});
|
||||
|
||||
const hits = instantsearch.widgets.hits({
|
||||
container: "#algolia-hits",
|
||||
templates: {
|
||||
item(data) {
|
||||
const link = data.permalink ? data.permalink : GLOBAL_CONFIG.root + data.path;
|
||||
const result = data._highlightResult;
|
||||
const loadingLogo = document.querySelector("#algolia-hits .st-spin");
|
||||
if (loadingLogo) {
|
||||
loadingLogo.style.display = "none";
|
||||
}
|
||||
setTimeout(() => {
|
||||
document.querySelector("#algolia-search .ais-SearchBox-input").focus();
|
||||
}, 200);
|
||||
return `
|
||||
<a href="${link}" class="algolia-hit-item-link">
|
||||
<span class="algolia-hits-item-title">${result.title.value || "no-title"}</span>
|
||||
</a>`;
|
||||
},
|
||||
empty: function (data) {
|
||||
const loadingLogo = document.querySelector("#algolia-hits .st-spin");
|
||||
if (loadingLogo) {
|
||||
loadingLogo.style.display = "none";
|
||||
}
|
||||
setTimeout(() => {
|
||||
document.querySelector("#algolia-search .ais-SearchBox-input").focus();
|
||||
}, 200);
|
||||
return (
|
||||
'<div id="algolia-hits-empty">' +
|
||||
GLOBAL_CONFIG.lang.search.empty.replace(/\$\{query}/, data.query) +
|
||||
"</div>"
|
||||
);
|
||||
},
|
||||
},
|
||||
cssClasses: {
|
||||
item: "algolia-hit-item",
|
||||
},
|
||||
});
|
||||
|
||||
const pagination = instantsearch.widgets.pagination({
|
||||
container: "#algolia-pagination",
|
||||
totalPages: algolia.hits.per_page ?? 5,
|
||||
scrollTo: false,
|
||||
showFirstLast: false,
|
||||
templates: {
|
||||
first: '<i class="solitude st-show-left-line"></i>',
|
||||
last: '<i class="solitude st-show-right-line"></i>',
|
||||
previous: '<i class="solitude st-arrow-left-bold"></i>',
|
||||
next: '<i class="solitude st-arrow-right-bold"></i>',
|
||||
},
|
||||
cssClasses: {
|
||||
root: "pagination",
|
||||
item: "pagination-item",
|
||||
link: "page-number",
|
||||
active: "current",
|
||||
disabled: "disabled-item",
|
||||
},
|
||||
});
|
||||
|
||||
const stats = instantsearch.widgets.stats({
|
||||
container: "#algolia-tips > #algolia-stats",
|
||||
templates: {
|
||||
text: function (data) {
|
||||
const stats = GLOBAL_CONFIG.lang.search.hit
|
||||
.replace(/\$\{hits}/, data.nbHits)
|
||||
.replace(/\$\{time}/, data.processingTimeMS);
|
||||
return `<hr>${stats}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
search.addWidgets([configure, searchBox,stats, hits, pagination]);
|
||||
|
||||
search.start();
|
||||
|
||||
searchClickFn();
|
||||
searchFnOnce();
|
||||
|
||||
window.addEventListener("pjax:complete", () => {
|
||||
!utils.isHidden($searchMask) && closeSearch();
|
||||
searchClickFn();
|
||||
});
|
||||
|
||||
window.pjax &&
|
||||
search.on("render", () => {
|
||||
window.pjax.refresh(document.getElementById("algolia-hits"));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,205 @@
|
||||
window.addEventListener("load", () => {
|
||||
let store = [];
|
||||
const $searchMask = document.getElementById("search-mask");
|
||||
const $searchDialog = document.querySelector("#local-search .search-dialog");
|
||||
window.openSearch = () => {
|
||||
utils.animateIn($searchMask, "to_show 0.5s");
|
||||
$searchDialog.style.display = "block";
|
||||
setTimeout(() => {
|
||||
document.querySelector("#local-search .search-box-input").focus();
|
||||
}, 100);
|
||||
document.addEventListener("keydown", function f(event) {
|
||||
if (event.code === "Escape") {
|
||||
closeSearch();
|
||||
document.removeEventListener("keydown", f);
|
||||
}
|
||||
});
|
||||
fixSafariHeight();
|
||||
window.addEventListener("resize", fixSafariHeight);
|
||||
};
|
||||
const fixSafariHeight = () => {
|
||||
if (window.innerWidth < 768) {
|
||||
$searchDialog.style.setProperty("--search-height", window.innerHeight + "px");
|
||||
}
|
||||
};
|
||||
const closeSearch = () => {
|
||||
utils.animateOut($searchDialog, "search_close .5s");
|
||||
utils.animateOut($searchMask, "to_hide 0.5s");
|
||||
window.removeEventListener("resize", fixSafariHeight);
|
||||
};
|
||||
|
||||
const addEventTagList = () => {
|
||||
const list = document.querySelectorAll("#local-search .tag-list");
|
||||
if (list.length > 0) {
|
||||
list.forEach(el => el.addEventListener("click", (e) => closeSearch()))
|
||||
}
|
||||
}
|
||||
|
||||
addEventTagList()
|
||||
|
||||
const addEventCtrlK = () => {
|
||||
document.addEventListener("keydown", function (event) {
|
||||
if (event.ctrlKey && event.key === "k") {
|
||||
event.preventDefault();
|
||||
openSearch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addEventCtrlK()
|
||||
|
||||
const searchFnOnce = () => {
|
||||
$searchMask.addEventListener("click", closeSearch);
|
||||
utils.addEventListenerPjax(document.querySelector("#local-search .search-close-button"), "click", closeSearch);
|
||||
};
|
||||
|
||||
searchFnOnce();
|
||||
|
||||
const searchClickFn = () => {
|
||||
utils.addEventListenerPjax(document.querySelector("#search-button > .search"), "click", openSearch);
|
||||
|
||||
GLOBAL_CONFIG.right_menu && document.getElementById("menu-search").addEventListener("click", function () {
|
||||
rm.hideRightMenu();
|
||||
openSearch();
|
||||
let t = document.getElementsByClassName('search-box-input')[0];
|
||||
let evt = document.createEvent('HTMLEvents');
|
||||
evt.initEvent('input', true, true)
|
||||
t.value = selectTextNow
|
||||
t.dispatchEvent(evt)
|
||||
})
|
||||
}
|
||||
|
||||
searchClickFn();
|
||||
|
||||
function init() {
|
||||
fetch(GLOBAL_CONFIG.localsearch.path)
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
let parser = new DOMParser();
|
||||
let xmlDoc = parser.parseFromString(data, "text/xml");
|
||||
let entries = xmlDoc.getElementsByTagName("entry");
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
let entry = entries[i];
|
||||
let title = entry.getElementsByTagName("title")[0].textContent;
|
||||
let link = entry.getElementsByTagName("url")[0].textContent;
|
||||
let content = entry.getElementsByTagName("content")[0].textContent;
|
||||
store.push({
|
||||
'title': title,
|
||||
'link': link,
|
||||
'content': content
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => console.error("Error loading search data:", err));
|
||||
}
|
||||
|
||||
let query = ''
|
||||
let currentPage = 0;
|
||||
const resultsPerPage = 10;
|
||||
let results = [];
|
||||
|
||||
function initUI() {
|
||||
const $results = document.getElementById("search-results");
|
||||
const $search = document.getElementById("search-input");
|
||||
$search.addEventListener('keydown', function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
$results.innerHTML = '';
|
||||
query = this.value.trim();
|
||||
if (query !== '') {
|
||||
results = search(query);
|
||||
renderResults(results, currentPage);
|
||||
renderPagination(results.length);
|
||||
} else {
|
||||
clearSearchResults();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function clearSearchResults() {
|
||||
const $results = document.getElementById("search-results");
|
||||
const $pagination = document.getElementById("search-pagination");
|
||||
const $tips = document.getElementById("search-tips");
|
||||
|
||||
$results.innerHTML = '';
|
||||
$pagination.innerHTML = '';
|
||||
$tips.innerHTML = '';
|
||||
}
|
||||
|
||||
function search(query) {
|
||||
const regex = new RegExp(query.split('').join('.*'), 'i');
|
||||
return store.filter(page => regex.test(page.title) || regex.test(page.content));
|
||||
}
|
||||
|
||||
function renderResults(results, page) {
|
||||
const $search_results = document.getElementById("search-results");
|
||||
$search_results.innerHTML = '';
|
||||
const $tips = document.getElementById("search-tips");
|
||||
$tips.innerHTML = '';
|
||||
const start = page * resultsPerPage;
|
||||
const end = start + resultsPerPage;
|
||||
if (!results.length) {
|
||||
const $empty = document.createElement("span");
|
||||
$empty.className = "search-result-empty";
|
||||
$empty.textContent = GLOBAL_CONFIG.lang.search.empty.replace(/\$\{query}/, query);
|
||||
$search_results.appendChild($empty);
|
||||
return;
|
||||
}
|
||||
results.slice(start, end).forEach(function (result) {
|
||||
const $result = document.createElement("li");
|
||||
$result.className = "search-result-item";
|
||||
const $link = document.createElement("a");
|
||||
$link.className = "search-result-title";
|
||||
$link.href = result.link;
|
||||
$link.innerHTML = highlightSearchKeyword(result.title, query);
|
||||
$result.appendChild($link);
|
||||
$search_results.appendChild($result);
|
||||
});
|
||||
const count = document.createElement("span");
|
||||
count.className = "search-result-count";
|
||||
count.innerHTML = GLOBAL_CONFIG.lang.search.count.replace(/\$\{count}/, results.length)
|
||||
$tips.appendChild(count);
|
||||
}
|
||||
|
||||
function highlightSearchKeyword(text, keyword) {
|
||||
const regex = new RegExp(`(${keyword.split(' ').join('|')})`, 'gi');
|
||||
return text.replace(regex, '<em>$1</em>');
|
||||
}
|
||||
|
||||
function renderPagination(totalResults) {
|
||||
const totalPages = Math.ceil(totalResults / resultsPerPage);
|
||||
const paginationContainer = document.getElementById("search-pagination");
|
||||
paginationContainer.innerHTML = '';
|
||||
const paginationList = document.createElement("ul");
|
||||
paginationList.className = "pagination-list";
|
||||
|
||||
for (let i = 0; i < totalPages; i++) {
|
||||
const button = document.createElement("li");
|
||||
button.className = "pagination-item";
|
||||
button.textContent = i + 1;
|
||||
if (i === currentPage) {
|
||||
button.classList.add('select');
|
||||
}
|
||||
button.addEventListener('click', function () {
|
||||
currentPage = i;
|
||||
renderResults(results, i);
|
||||
document.querySelectorAll(".pagination-item").forEach(function (btn) {
|
||||
btn.classList.remove('select');
|
||||
});
|
||||
button.classList.add('select');
|
||||
});
|
||||
paginationList.appendChild(button);
|
||||
}
|
||||
paginationContainer.appendChild(paginationList);
|
||||
}
|
||||
|
||||
init();
|
||||
initUI();
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
initUI();
|
||||
});
|
||||
window.addEventListener('pjax:complete', () => {
|
||||
searchClickFn()
|
||||
})
|
||||
});
|
||||
Vendored
+6
File diff suppressed because one or more lines are too long
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* author: Efu
|
||||
* email: o@efu.me
|
||||
* website: https://efu.me
|
||||
*/
|
||||
class efuAI{constructor(){this.root="https://summary.tianli0.top",this.aiTalkMode=!1,this.aiPostExplanation='',this.config=GLOBAL_CONFIG.post_ai,this.scoGPTIsRunning=!1}init(){if(!document.querySelector(".ai-explanation"))return;this.scoGPTIsRunning=!1;this.aiPostExplanation=PAGE_CONFIG.ai_text?PAGE_CONFIG.ai_text+"":false;if(!this.aiPostExplanation){this.generate()}else{this.aiShowAnimation(Promise.resolve(this.aiPostExplanation))}this.AIEngine()}getTitleAndContent(){const e=document.getElementById("article-container"),t=document.title,n=e.getElementsByTagName("p"),i=e.querySelectorAll("h1, h2, h3, h4, h5");return(t+" "+Array.from(i).concat(Array.from(n)).map((e=>e.innerText.replace(/https?:\/\/[^\s]+/g,""))).join(" ")).slice(0,1e3)}async generate(){this.aiShowAnimation(this.fetch(document.title,this.getTitleAndContent(),this.config.key))}async fetch(e,t,n){const i=`${this.root}/?content=${encodeURIComponent(t)}&title=${e}&key=${encodeURIComponent(n)}&url=${encodeURIComponent(window.location.href)}`,s=await fetch(i),o=await s.json();return s.ok?(this.aiPostExplanation=o.summary,o.summary):(console.error("Request failed:",o.err_msg),o.err_msg)}aiShowAnimation(e,t=!1){const n=document.querySelector(".ai-explanation"),i=document.querySelector(".ai-tag");if(!n||this.scoGPTIsRunning)return;this.scoGPTIsRunning=!0,this.cleanSuggestions(),i.classList.add("loadingAI"),n.style.display="block",n.innerHTML='生成中...<span class="blinking-cursor"></span>';let s,o,a=!0,c=0,r=!0;const l=new IntersectionObserver((e=>{a=e[0].isIntersecting,a&&requestAnimationFrame(o)}),{threshold:0});e.then((e=>{s=performance.now(),o=()=>{if(c<e.length&&a){const r=performance.now(),g=r-s,h=e.slice(c,c+1),u=/[,。!、?,.!?]/.test(h),m=/[a-zA-Z0-9]/.test(h);g>=(u?100*Math.random()+100:m?10:25)&&(n.innerText=e.slice(0,c+1),s=r,c++,c<e.length?n.innerHTML=e.slice(0,c)+'<span class="blinking-cursor"></span>':(n.innerHTML=e,n.style.display="block",this.scoGPTIsRunning=!1,i.classList.remove("loadingAI"),l.disconnect(),t&&this.createSuggestions())),a&&requestAnimationFrame(o)}},a&&r&&setTimeout((()=>{requestAnimationFrame(o),r=!1}),3e3),l.observe(n)})).catch((e=>{console.error("检索信息失败:",e),n.innerHTML="检索信息失败",n.style.display="block",this.scoGPTIsRunning=!1,i.classList.remove("loadingAI"),l.disconnect()}))}AIEngine(){const e=document.querySelector(".ai-tag");e&&e.addEventListener("click",(()=>{this.scoGPTIsRunning||(this.aiTalkMode=!0,this.aiShowAnimation(Promise.resolve(this.config.talk),!0))}))}cleanSuggestions(){const e=document.querySelector(".ai-suggestions");e?e.innerHTML="":console.error("没有这个元素:'ai-suggestions'")}createSuggestions(){this.aiTalkMode&&(this.cleanSuggestions(),this.createSuggestionItemWithAction("这篇文章讲了什么?",(()=>{""===this.aiPostExplanation?this.generate():this.aiShowAnimation(Promise.resolve(this.aiPostExplanation),!0)})),this.config.randomPost&&this.createSuggestionItemWithAction("带我去看看其他文章",(()=>toRandomPost())),this.aiTalkMode=!0)}createSuggestionItemWithAction(e,t){const n=document.querySelector(".ai-suggestions");if(!n)return void console.error("无法找到具有class为ai-suggestions的元素");const i=document.createElement("div");i.classList.add("ai-suggestions-item"),i.textContent=e,i.addEventListener("click",t),n.appendChild(i)}}const efu_ai=new efuAI;
|
||||
+5
File diff suppressed because one or more lines are too long
+5
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* @name: Universe
|
||||
* author: Leonus
|
||||
*/
|
||||
function dark(){window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;var t,i,e,s,n=.05,h=document.getElementById("universe"),a=!0,o="226,225,224",r=[];function d(){t=window.innerWidth,i=window.innerHeight,e=.216*t,h.setAttribute("width",t),h.setAttribute("height",i)}function c(){s.clearRect(0,0,t,i);for(var e=r.length,n=0;n<e;n++){var h=r[n];h.move(),h.fadeIn(),h.fadeOut(),h.draw()}}function f(){this.reset=function(){this.giant=u(3),this.comet=!this.giant&&!a&&u(10),this.x=m(0,t-10),this.y=m(0,i),this.r=m(1.1,2.6),this.dx=m(n,6*n)+(this.comet+1-1)*n*m(50,120)+.1,this.dy=-m(n,6*n)-(this.comet+1-1)*n*m(50,120),this.fadingOut=null,this.fadingIn=!0,this.opacity=0,this.opacityTresh=m(.2,1-.4*(this.comet+1-1)),this.do=m(5e-4,.002)+.001*(this.comet+1-1)},this.fadeIn=function(){this.fadingIn&&(this.fadingIn=!(this.opacity>this.opacityTresh),this.opacity+=this.do)},this.fadeOut=function(){this.fadingOut&&(this.fadingOut=!(this.opacity<0),this.opacity-=this.do/2,(this.x>t||this.y<0)&&(this.fadingOut=!1,this.reset()))},this.draw=function(){if(s.beginPath(),this.giant)s.fillStyle="rgba(180,184,240,"+this.opacity+")",s.arc(this.x,this.y,2,0,2*Math.PI,!1);else if(this.comet){s.fillStyle="rgba("+o+","+this.opacity+")",s.arc(this.x,this.y,1.5,0,2*Math.PI,!1);for(var t=0;t<30;t++)s.fillStyle="rgba("+o+","+(this.opacity-this.opacity/20*t)+")",s.rect(this.x-this.dx/4*t,this.y-this.dy/4*t-2,2,2),s.fill()}else s.fillStyle="rgba(226,225,142,"+this.opacity+")",s.rect(this.x,this.y,this.r,this.r);s.closePath(),s.fill()},this.move=function(){this.x+=this.dx,this.y+=this.dy,!1===this.fadingOut&&this.reset(),(this.x>t-t/4||this.y<0)&&(this.fadingOut=!0)},setTimeout((function(){a=!1}),50)}function u(t){return Math.floor(1e3*Math.random())+1<10*t}function m(t,i){return Math.random()*(i-t)+t}d(),window.addEventListener("resize",d,!1),function(){s=h.getContext("2d");for(var t=0;t<e;t++)r[t]=new f,r[t].reset();c()}(),function t(){"dark"==document.getElementsByTagName("html")[0].getAttribute("data-theme")&&c(),window.requestAnimationFrame(t)}()}
|
||||
+1
@@ -0,0 +1 @@
|
||||
function waterfall(a){function b(a,b){var c=window.getComputedStyle(b);return parseFloat(c["margin"+a])||0}function c(a){return a+"px"}function d(a){return parseFloat(a.style.top)}function e(a){return parseFloat(a.style.left)}function f(a){return a.clientWidth}function g(a){return a.clientHeight}function h(a){return d(a)+g(a)+b("Bottom",a)}function i(a){return e(a)+f(a)+b("Right",a)}function j(a){a=a.sort(function(a,b){return h(a)===h(b)?e(b)-e(a):h(b)-h(a)})}function k(b){f(a)!=t&&(b.target.removeEventListener(b.type,arguments.callee),waterfall(a))}"string"==typeof a&&(a=document.querySelector(a));var l=[].map.call(a.children,function(a){return a.style.position="absolute",a});a.style.position="relative";var m=[];l.length&&(l[0].style.top="0px",l[0].style.left=c(b("Left",l[0])),m.push(l[0]));for(var n=1;n<l.length;n++){var o=l[n-1],p=l[n],q=i(o)+f(p)<=f(a);if(!q)break;p.style.top=o.style.top,p.style.left=c(i(o)+b("Left",p)),m.push(p)}for(;n<l.length;n++){j(m);var p=l[n],r=m.pop();p.style.top=c(h(r)+b("Top",p)),p.style.left=c(e(r)),m.push(p)}j(m);var s=m[0];a.style.height=c(h(s)+b("Bottom",s));var t=f(a);window.addEventListener?window.addEventListener("resize",k):document.body.onresize=k}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,208 @@
|
||||
(() => {
|
||||
const utilsFn = {
|
||||
throttle: (func, wait, {leading = true, trailing = true} = {}) => {
|
||||
let timeout, previous = 0;
|
||||
const later = (context, args) => {
|
||||
timeout = previous = leading === false ? 0 : Date.now();
|
||||
func.apply(context, args);
|
||||
};
|
||||
return function () {
|
||||
const now = Date.now();
|
||||
if (!previous && leading === false) previous = now;
|
||||
const remaining = wait - (now - previous);
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
later(this, arguments);
|
||||
} else if (!timeout && trailing !== false) {
|
||||
timeout = setTimeout(() => later(this, arguments), remaining);
|
||||
}
|
||||
};
|
||||
},
|
||||
fadeIn: (ele, time) => ele.style.cssText = `display:block;animation: to_show ${time}s`,
|
||||
fadeOut: (ele, time) => {
|
||||
const resetStyles = () => {
|
||||
ele.style.cssText = "display: none; animation: '' ";
|
||||
ele.removeEventListener('animationend', resetStyles);
|
||||
};
|
||||
ele.addEventListener('animationend', resetStyles);
|
||||
ele.style.animation = `to_hide ${time}s`;
|
||||
},
|
||||
sidebarPaddingR: () => {
|
||||
const paddingRight = window.innerWidth - document.body.clientWidth;
|
||||
if (paddingRight > 0) {
|
||||
document.body.style.paddingRight = `${paddingRight}px`;
|
||||
}
|
||||
},
|
||||
snackbarShow: (text, showAction = false, duration = 5000) => {
|
||||
document.styleSheets[0].addRule(':root', `--efu-snackbar-time:${duration}ms!important`);
|
||||
Snackbar.show({
|
||||
text,
|
||||
showAction,
|
||||
duration,
|
||||
pos: 'top-center'
|
||||
});
|
||||
},
|
||||
copy: async (text) => {
|
||||
const message = await navigator.clipboard.writeText(text)
|
||||
.then(() => GLOBAL_CONFIG.lang.copy.success)
|
||||
.catch(() => GLOBAL_CONFIG.lang.copy.error);
|
||||
utils.snackbarShow(message, false, 2000);
|
||||
},
|
||||
getEleTop: ele => {
|
||||
let actualTop = ele.offsetTop;
|
||||
while (ele.offsetParent) {
|
||||
ele = ele.offsetParent;
|
||||
actualTop += ele.offsetTop;
|
||||
}
|
||||
return actualTop;
|
||||
},
|
||||
siblings: (ele, selector) => {
|
||||
return [...ele.parentNode.children].filter((child) => {
|
||||
if (selector) {
|
||||
return child !== ele && child.matches(selector)
|
||||
}
|
||||
return child !== ele
|
||||
})
|
||||
},
|
||||
randomNum: (length) => {
|
||||
return Math.floor(Math.random() * length)
|
||||
},
|
||||
timeDiff: (timeObj, today) => {
|
||||
const timeDiff = today.getTime() - timeObj.getTime();
|
||||
return Math.floor(timeDiff / (1000 * 3600 * 24));
|
||||
},
|
||||
scrollToDest: (pos, time = 500) => {
|
||||
const currentPos = window.pageYOffset;
|
||||
const isNavFixed = document.getElementById('page-header').classList.contains('nav-fixed');
|
||||
pos = currentPos > pos || isNavFixed ? pos - 70 : pos;
|
||||
|
||||
if ('scrollBehavior' in document.documentElement.style) {
|
||||
window.scrollTo({top: pos, behavior: 'smooth'});
|
||||
return;
|
||||
}
|
||||
|
||||
const distance = pos - currentPos;
|
||||
const step = currentTime => {
|
||||
const start = start || currentTime;
|
||||
const progress = currentTime - start;
|
||||
|
||||
if (progress < time) {
|
||||
window.scrollTo(0, currentPos + distance * progress / time);
|
||||
window.requestAnimationFrame(step);
|
||||
} else {
|
||||
window.scrollTo(0, pos);
|
||||
}
|
||||
};
|
||||
|
||||
window.requestAnimationFrame(step);
|
||||
},
|
||||
isMobile: () => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
|
||||
isHidden: e => 0 === e.offsetHeight && 0 === e.offsetWidth,
|
||||
addEventListenerPjax: (ele, event, fn, option = false) => {
|
||||
ele.addEventListener(event, fn, option)
|
||||
utils.addGlobalFn('pjax', () => {
|
||||
ele.removeEventListener(event, fn, option)
|
||||
})
|
||||
},
|
||||
animateIn: (ele, text) => {
|
||||
Object.assign(ele.style, {display: 'block', animation: text});
|
||||
},
|
||||
animateOut: (ele, text) => {
|
||||
const resetAnimation = () => {
|
||||
ele.style.display = '';
|
||||
ele.style.animation = '';
|
||||
ele.removeEventListener('animationend', resetAnimation);
|
||||
};
|
||||
ele.addEventListener('animationend', resetAnimation);
|
||||
ele.style.animation = text;
|
||||
},
|
||||
wrap: (selector, eleType, options) => {
|
||||
const createEle = document.createElement(eleType)
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
createEle.setAttribute(key, value)
|
||||
}
|
||||
selector.parentNode.insertBefore(createEle, selector)
|
||||
createEle.appendChild(selector)
|
||||
},
|
||||
lazyloadImg: () => {
|
||||
window.lazyLoadInstance = new LazyLoad({
|
||||
elements_selector: 'img',
|
||||
threshold: 0,
|
||||
data_src: 'lazy-src',
|
||||
callback_error: img => img.src = GLOBAL_CONFIG.lazyload.error
|
||||
});
|
||||
},
|
||||
lightbox: function (selector) {
|
||||
const lightboxType = GLOBAL_CONFIG.lightbox;
|
||||
const options = {
|
||||
class: 'fancybox',
|
||||
'data-fancybox': 'gallery',
|
||||
};
|
||||
|
||||
if (lightboxType === 'mediumZoom') {
|
||||
mediumZoom && mediumZoom(selector, {background: "var(--efu-card-bg)"});
|
||||
} else if (lightboxType === 'fancybox') {
|
||||
selector.forEach(i => {
|
||||
if (i.parentNode.tagName !== 'A') {
|
||||
options.href = options['data-thumb'] = i.dataset.lazySrc || i.src;
|
||||
options['data-caption'] = i.title || i.alt || '';
|
||||
utils.wrap(i, 'a', options);
|
||||
}
|
||||
});
|
||||
|
||||
if (!window.fancyboxRun) {
|
||||
Fancybox.bind('[data-fancybox]', {
|
||||
Hash: false,
|
||||
animated: true,
|
||||
Thumbs: {showOnStart: false},
|
||||
Images: {Panzoom: {maxScale: 4}},
|
||||
Carousel: {transition: 'slide'},
|
||||
Toolbar: {
|
||||
display: {
|
||||
left: ['infobar'],
|
||||
middle: ['zoomIn', 'zoomOut', 'toggle1to1', 'rotateCCW', 'rotateCW', 'flipX', 'flipY'],
|
||||
right: ['slideshow', 'thumbs', 'close']
|
||||
}
|
||||
},
|
||||
});
|
||||
window.fancyboxRun = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
diffDate: (d, more = false) => {
|
||||
const dateNow = new Date();
|
||||
const datePost = new Date(d);
|
||||
const dateDiff = dateNow - datePost;
|
||||
const minute = 60000;
|
||||
const hour = 3600000;
|
||||
const day = 86400000;
|
||||
const month = 2592000000;
|
||||
const {time} = GLOBAL_CONFIG.lang;
|
||||
const dayCount = Math.floor(dateDiff / day)
|
||||
if (!more) return dayCount
|
||||
const minuteCount = Math.floor(dateDiff / minute)
|
||||
const hourCount = Math.floor(dateDiff / hour)
|
||||
const monthCount = Math.floor(dateDiff / month)
|
||||
if (monthCount > 12) return datePost.toISOString().slice(0, 10)
|
||||
if (monthCount >= 1) return `${monthCount} ${time.month}`
|
||||
if (dayCount >= 1) return `${dayCount} ${time.day}`
|
||||
if (hourCount >= 1) return `${hourCount} ${time.hour}`
|
||||
if (minuteCount >= 1) return `${minuteCount} ${time.min}`
|
||||
return time.just
|
||||
},
|
||||
loadComment: (dom, callback) => {
|
||||
const observerItem = 'IntersectionObserver' in window ? new IntersectionObserver((entries) => {
|
||||
if (entries[0].isIntersecting) {
|
||||
callback();
|
||||
observerItem.disconnect();
|
||||
}
|
||||
}, {threshold: [0]}) : null;
|
||||
|
||||
observerItem ? observerItem.observe(dom) : callback();
|
||||
},
|
||||
}
|
||||
window.utils = {...window.utils, ...utilsFn};
|
||||
})()
|
||||
Reference in New Issue
Block a user