hexo-theme-solitude 3.0.21 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +3 -3
- package/README.md +11 -1
- package/README_en-US.md +11 -1
- package/_config.yml +16 -7
- package/languages/default.yml +56 -36
- package/languages/en.yml +90 -69
- package/languages/es.yml +94 -73
- package/languages/zh-CN.yml +56 -34
- package/languages/zh-TW.yml +80 -57
- package/layout/archive.pug +60 -14
- package/layout/category.pug +13 -11
- package/layout/includes/body/gadsense.pug +2 -2
- package/layout/includes/console.pug +71 -72
- package/layout/includes/footer.pug +24 -9
- package/layout/includes/head/config.pug +83 -39
- package/layout/includes/head/mode.pug +7 -7
- package/layout/includes/head/page_config.pug +20 -11
- package/layout/includes/inject/body.pug +14 -36
- package/layout/includes/keyboard.pug +3 -3
- package/layout/includes/loading.pug +1 -37
- package/layout/includes/mixins/articleSort.pug +3 -3
- package/layout/includes/mixins/common.pug +8 -4
- package/layout/includes/mixins/pace.pug +1 -1
- package/layout/includes/mixins/pagination.pug +3 -3
- package/layout/includes/nav.pug +4 -3
- package/layout/includes/page/about.pug +9 -8
- package/layout/includes/page/brevity.pug +2 -2
- package/layout/includes/page/links.pug +23 -11
- package/layout/includes/page/music.pug +0 -5
- package/layout/includes/rightmenu.pug +20 -20
- package/layout/includes/sidebar.pug +2 -2
- package/layout/includes/widgets/aside/asideInfoCard.pug +2 -2
- package/layout/includes/widgets/aside/asideTag.pug +2 -2
- package/layout/includes/widgets/home/bbTimeList.pug +3 -3
- package/layout/includes/widgets/home/categoryBar.pug +30 -15
- package/layout/includes/widgets/home/hometop.pug +113 -8
- package/layout/includes/widgets/home/postList.pug +1 -2
- package/layout/includes/widgets/home/topGroup.pug +3 -7
- package/layout/includes/widgets/nav/group.pug +4 -2
- package/layout/includes/widgets/nav/menu.pug +6 -4
- package/layout/includes/widgets/nav/right.pug +7 -6
- package/layout/includes/widgets/page/about/award.pug +67 -38
- package/layout/includes/widgets/page/about/hobbies.pug +12 -3
- package/layout/includes/widgets/page/banner.pug +1 -1
- package/layout/includes/widgets/page/kit/content.pug +2 -2
- package/layout/includes/widgets/page/links/banner.pug +30 -19
- package/layout/includes/widgets/page/message/artalk.pug +3 -3
- package/layout/includes/widgets/page/message/content.pug +3 -3
- package/layout/includes/widgets/page/message/twikoo.pug +3 -3
- package/layout/includes/widgets/page/message/valine.pug +4 -4
- package/layout/includes/widgets/page/message/waline.pug +3 -3
- package/layout/includes/widgets/page/recentcomment/artalk.pug +5 -9
- package/layout/includes/widgets/page/recentcomment/twikoo.pug +5 -9
- package/layout/includes/widgets/page/recentcomment/valine.pug +6 -10
- package/layout/includes/widgets/page/recentcomment/waline.pug +5 -9
- package/layout/includes/widgets/post/award.pug +1 -28
- package/layout/includes/widgets/post/copyright.pug +10 -10
- package/layout/includes/widgets/post/postInfo.pug +10 -11
- package/layout/includes/widgets/post/postMeta.pug +3 -2
- package/layout/includes/widgets/rightside/hide.pug +5 -5
- package/layout/includes/widgets/rightside/show.pug +7 -7
- package/layout/includes/widgets/third-party/comments/artalk.pug +9 -9
- package/layout/includes/widgets/third-party/comments/giscus.pug +2 -2
- package/layout/includes/widgets/third-party/comments/twikoo.pug +5 -5
- package/layout/includes/widgets/third-party/comments/valine.pug +6 -6
- package/layout/includes/widgets/third-party/comments/waline.pug +6 -6
- package/layout/includes/widgets/third-party/hot/twikoo.pug +1 -1
- package/layout/includes/widgets/third-party/music.pug +9 -5
- package/layout/includes/widgets/third-party/news-comment/artalk.pug +6 -6
- package/layout/includes/widgets/third-party/news-comment/twikoo.pug +7 -7
- package/layout/includes/widgets/third-party/news-comment/valine.pug +8 -8
- package/layout/includes/widgets/third-party/news-comment/waline.pug +7 -7
- package/layout/includes/widgets/third-party/pjax.pug +16 -10
- package/layout/includes/widgets/third-party/search/algolia-search.pug +2 -2
- package/layout/includes/widgets/third-party/search/docsearch.pug +3 -3
- package/layout/includes/widgets/third-party/search/index.pug +1 -3
- package/layout/includes/widgets/third-party/search/local-search.pug +9 -9
- package/layout/index.pug +8 -6
- package/package.json +8 -7
- package/plugins.yml +22 -21
- package/scripts/event/cdn.js +11 -6
- package/scripts/event/friend_links.js +30 -0
- package/scripts/event/merge_config.js +15 -7
- package/scripts/filter/comment.js +2 -2
- package/scripts/filter/default.js +1 -1
- package/scripts/helper/inject_head_js.js +79 -33
- package/scripts/helper/related_post.js +16 -21
- package/scripts/tags/chart.js +1 -1
- package/scripts/tags/typeit.js +1 -1
- package/source/css/_components/capsule.styl +259 -168
- package/source/css/_components/rightside.styl +98 -242
- package/source/css/_global/animation.styl +1 -10
- package/source/css/_global/index.styl +27 -1
- package/source/css/_layout/aside.styl +7 -1
- package/source/css/_layout/console.styl +145 -165
- package/source/css/_layout/header.styl +238 -47
- package/source/css/_layout/pagination.styl +176 -132
- package/source/css/_layout/rightmenu.styl +11 -2
- package/source/css/_layout/sidebar.styl +39 -17
- package/source/css/_mode/index.styl +7 -1
- package/source/css/_page/_about/about.styl +18 -2
- package/source/css/_page/_about/buff.styl +1 -1
- package/source/css/_page/_about/contentinfo.styl +2 -1
- package/source/css/_page/_about/game.styl +57 -1
- package/source/css/_page/_about/like.styl +7 -2
- package/source/css/_page/_about/maxim.styl +1 -1
- package/source/css/_page/_about/reward.styl +226 -108
- package/source/css/_page/_about/skills.styl +5 -3
- package/source/css/_page/_home/category-bar.styl +162 -88
- package/source/css/_page/_home/home-top.styl +309 -263
- package/source/css/_page/_home/home.styl +34 -7
- package/source/css/_page/archive.styl +412 -0
- package/source/css/_page/category.styl +27 -1
- package/source/css/_page/index.styl +2 -0
- package/source/css/_page/links.styl +190 -0
- package/source/css/_page/other.styl +37 -0
- package/source/css/_post/index.styl +2 -1
- package/source/css/_post/meta.styl +245 -217
- package/source/css/_search/local-search.styl +158 -82
- package/source/css/var.styl +2 -2
- package/source/js/archive-page.js +191 -0
- package/source/js/core/actions.js +48 -0
- package/source/js/core/api.js +32 -0
- package/source/js/core/config.js +13 -0
- package/source/js/core/lifecycle.js +52 -0
- package/source/js/core/preloader.js +34 -0
- package/source/js/core/resources.js +65 -0
- package/source/js/covercolor/api.js +13 -103
- package/source/js/covercolor/ave.js +14 -77
- package/source/js/covercolor/local.js +22 -116
- package/source/js/covercolor/shared.js +102 -0
- package/source/js/friend_links.js +502 -0
- package/source/js/main.js +793 -177
- package/source/js/music.js +24 -14
- package/source/js/post_ai.js +13 -2
- package/source/js/right_menu.js +44 -24
- package/source/js/search/algolia.js +29 -21
- package/source/js/search/local.js +231 -266
- package/source/js/tw_cn.js +37 -12
- package/source/js/utils.js +37 -25
- package/layout/includes/widgets/randomlink.pug +0 -43
- package/scripts/filter/randomPosts.js +0 -16
package/source/js/main.js
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
import { Solitude } from "./core/api.js";
|
|
2
|
+
import { initActionDelegation } from "./core/actions.js";
|
|
3
|
+
import { lifecycle } from "./core/lifecycle.js";
|
|
4
|
+
import { initPreloader } from "./core/preloader.js";
|
|
5
|
+
|
|
6
|
+
let ai = null;
|
|
7
|
+
let coverColor = () => {};
|
|
8
|
+
let initializeMusicPlayer = () => {};
|
|
9
|
+
|
|
10
|
+
const loadFeatureModules = async () => {
|
|
11
|
+
const features = Solitude.config.feature_modules || {};
|
|
12
|
+
const requests = [];
|
|
13
|
+
|
|
14
|
+
if (features.search === "local") requests.push(import("./search/local.js"));
|
|
15
|
+
if (features.search === "algolia") requests.push(import("./search/algolia.js"));
|
|
16
|
+
if (features.friend_links) requests.push(import("./friend_links.js"));
|
|
17
|
+
if (features.right_menu) requests.push(import("./right_menu.js"));
|
|
18
|
+
if (features.translate) requests.push(import("./tw_cn.js"));
|
|
19
|
+
if (features.post_ai && Solitude.page.is_post) {
|
|
20
|
+
requests.push(import("./post_ai.js").then((module) => { ai = module.default; }));
|
|
21
|
+
}
|
|
22
|
+
if (features.music) {
|
|
23
|
+
requests.push(import("./music.js").then((module) => {
|
|
24
|
+
initializeMusicPlayer = module.initializeMusicPlayer;
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
if (features.covercolor) {
|
|
28
|
+
requests.push(import(`./covercolor/${features.covercolor}.js`).then((module) => {
|
|
29
|
+
coverColor = module.coverColor;
|
|
30
|
+
Solitude.coverColor = coverColor;
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
await Promise.all(requests);
|
|
35
|
+
};
|
|
36
|
+
|
|
1
37
|
const sidebarFn = () => {
|
|
2
38
|
const $toggleMenu = document.getElementById("toggle-menu");
|
|
3
39
|
const $mobileSidebarMenus = document.getElementById("sidebar-menus");
|
|
@@ -6,7 +42,7 @@ const sidebarFn = () => {
|
|
|
6
42
|
|
|
7
43
|
const toggleMobileSidebar = (isOpen) => {
|
|
8
44
|
$body.style.overflow = isOpen ? "hidden" : "";
|
|
9
|
-
|
|
45
|
+
Solitude[isOpen ? "fadeIn" : "fadeOut"]($menuMask, 0.5);
|
|
10
46
|
$mobileSidebarMenus.classList.toggle("open", isOpen);
|
|
11
47
|
};
|
|
12
48
|
|
|
@@ -16,31 +52,41 @@ const sidebarFn = () => {
|
|
|
16
52
|
}
|
|
17
53
|
};
|
|
18
54
|
|
|
19
|
-
|
|
20
|
-
$menuMask.addEventListener("click", closeMobileSidebar);
|
|
55
|
+
if (!$toggleMenu || !$mobileSidebarMenus || !$menuMask) return;
|
|
21
56
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
57
|
+
lifecycle.listen($toggleMenu, "click", () => toggleMobileSidebar(true));
|
|
58
|
+
lifecycle.listen($menuMask, "click", closeMobileSidebar);
|
|
59
|
+
|
|
60
|
+
let resizeFrame;
|
|
61
|
+
lifecycle.listen(window, "resize", () => {
|
|
62
|
+
if (resizeFrame) return;
|
|
63
|
+
resizeFrame = requestAnimationFrame(() => {
|
|
64
|
+
resizeFrame = null;
|
|
65
|
+
if (
|
|
66
|
+
Solitude.isHidden($toggleMenu) &&
|
|
67
|
+
$mobileSidebarMenus.classList.contains("open")
|
|
68
|
+
) {
|
|
69
|
+
closeMobileSidebar();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
30
72
|
});
|
|
73
|
+
lifecycle.add(() => cancelAnimationFrame(resizeFrame));
|
|
31
74
|
};
|
|
32
75
|
|
|
33
76
|
const scrollFn = () => {
|
|
34
77
|
const $rightside = document.getElementById("rightside");
|
|
35
78
|
const $header = document.getElementById("page-header");
|
|
36
|
-
let initTop =
|
|
79
|
+
let initTop = window.scrollY || document.documentElement.scrollTop;
|
|
37
80
|
|
|
38
81
|
const updateHeaderAndRightside = (isDown, currentTop) => {
|
|
39
|
-
|
|
82
|
+
const isAtTop = currentTop <= 0;
|
|
83
|
+
$header.classList.toggle("nav-at-top", isAtTop);
|
|
84
|
+
|
|
85
|
+
if (!isAtTop) {
|
|
40
86
|
$header.classList.toggle("nav-visible", !isDown);
|
|
41
87
|
$header.classList.add("nav-fixed");
|
|
42
88
|
if ($rightside) {
|
|
43
|
-
$rightside.style.opacity = "
|
|
89
|
+
$rightside.style.opacity = "1";
|
|
44
90
|
$rightside.style.transform = "translateX(-58px)";
|
|
45
91
|
}
|
|
46
92
|
} else {
|
|
@@ -52,23 +98,33 @@ const scrollFn = () => {
|
|
|
52
98
|
}
|
|
53
99
|
};
|
|
54
100
|
|
|
55
|
-
const
|
|
101
|
+
const handleScroll = () => {
|
|
56
102
|
initThemeColor();
|
|
57
103
|
const currentTop = window.scrollY || document.documentElement.scrollTop;
|
|
58
104
|
const isDown = currentTop > initTop;
|
|
59
105
|
initTop = currentTop;
|
|
60
106
|
updateHeaderAndRightside(isDown, currentTop);
|
|
61
|
-
}
|
|
107
|
+
};
|
|
62
108
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
109
|
+
let ticking = false;
|
|
110
|
+
const onScroll = () => {
|
|
111
|
+
const currentTop = window.scrollY || document.documentElement.scrollTop;
|
|
112
|
+
if (currentTop <= 0) {
|
|
113
|
+
initTop = 0;
|
|
114
|
+
updateHeaderAndRightside(false, 0);
|
|
115
|
+
return;
|
|
70
116
|
}
|
|
71
|
-
|
|
117
|
+
if (!ticking) {
|
|
118
|
+
window.requestAnimationFrame(() => {
|
|
119
|
+
handleScroll();
|
|
120
|
+
ticking = false;
|
|
121
|
+
});
|
|
122
|
+
ticking = true;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
lifecycle.listen(window, "scroll", onScroll, { passive: true });
|
|
127
|
+
updateHeaderAndRightside(false, initTop);
|
|
72
128
|
};
|
|
73
129
|
|
|
74
130
|
const percent = () => {
|
|
@@ -84,23 +140,24 @@ const percent = () => {
|
|
|
84
140
|
body.clientHeight,
|
|
85
141
|
docEl.clientHeight
|
|
86
142
|
) - docEl.clientHeight;
|
|
87
|
-
const scrolledPercent =
|
|
143
|
+
const scrolledPercent = totalScrollableHeight > 0
|
|
144
|
+
? Math.round((scrollPos / totalScrollableHeight) * 100)
|
|
145
|
+
: 0;
|
|
88
146
|
const navToTop = document.querySelector("#nav-totop");
|
|
89
147
|
const rsToTop = document.querySelector(".rs_show .top i");
|
|
90
148
|
const percentDisplay = document.querySelector("#percent");
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
).offsetTop;
|
|
149
|
+
const endTarget =
|
|
150
|
+
document.getElementById("post-comment") || document.getElementById("footer");
|
|
151
|
+
const isNearEnd = endTarget
|
|
152
|
+
? window.scrollY + docEl.clientHeight >= endTarget.offsetTop
|
|
153
|
+
: false;
|
|
97
154
|
|
|
98
155
|
navToTop?.classList.toggle("long", isNearEnd || scrolledPercent > 90);
|
|
99
156
|
rsToTop?.classList.toggle("show", isNearEnd || scrolledPercent > 90);
|
|
100
|
-
percentDisplay.textContent =
|
|
157
|
+
if (percentDisplay) percentDisplay.textContent =
|
|
101
158
|
isNearEnd || scrolledPercent > 90
|
|
102
159
|
? navToTop
|
|
103
|
-
?
|
|
160
|
+
? Solitude.config.lang.backtop
|
|
104
161
|
: ""
|
|
105
162
|
: scrolledPercent;
|
|
106
163
|
|
|
@@ -114,7 +171,290 @@ const percent = () => {
|
|
|
114
171
|
const showTodayCard = () => {
|
|
115
172
|
const el = document.getElementById("todayCard");
|
|
116
173
|
const topGroup = document.querySelector(".topGroup");
|
|
117
|
-
topGroup
|
|
174
|
+
lifecycle.listen(topGroup, "mouseleave", () => el?.classList.remove("hide"));
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const initHomeCenter = () => {
|
|
178
|
+
const container = document.getElementById("home_center");
|
|
179
|
+
if (!container || container.dataset.initialized === "true") return;
|
|
180
|
+
container.dataset.initialized = "true";
|
|
181
|
+
|
|
182
|
+
const banners = [...container.querySelectorAll(".home-center-banner-item")];
|
|
183
|
+
const items = [...container.querySelectorAll(".home-center-item")];
|
|
184
|
+
const indicators = [
|
|
185
|
+
...container.querySelectorAll(".home-center-indicator"),
|
|
186
|
+
];
|
|
187
|
+
const banner = container.querySelector(".home-center-banner");
|
|
188
|
+
const titleLink = container.querySelector(".home-center-title-link");
|
|
189
|
+
const titleTag = container.querySelector(".home-center-title-tag span");
|
|
190
|
+
const categoryBar = document.getElementById("category-bar");
|
|
191
|
+
let activeIndex = 0;
|
|
192
|
+
let scrollFrame;
|
|
193
|
+
|
|
194
|
+
const getCachedColor = (src) => {
|
|
195
|
+
try {
|
|
196
|
+
const cache = JSON.parse(localStorage.getItem("Solitude")) || {};
|
|
197
|
+
const item = cache.postcolor?.[src];
|
|
198
|
+
if (item && (!item.expiration || item.expiration > Date.now())) {
|
|
199
|
+
return item.value;
|
|
200
|
+
}
|
|
201
|
+
} catch (error) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const cacheColor = (src, color) => {
|
|
208
|
+
try {
|
|
209
|
+
const cache = JSON.parse(localStorage.getItem("Solitude")) || {};
|
|
210
|
+
cache.postcolor = cache.postcolor || {};
|
|
211
|
+
cache.postcolor[src] = {
|
|
212
|
+
value: color,
|
|
213
|
+
expiration: Date.now() + 43200000,
|
|
214
|
+
};
|
|
215
|
+
localStorage.setItem("Solitude", JSON.stringify(cache));
|
|
216
|
+
} catch (error) {
|
|
217
|
+
// Color caching is optional; rendering must continue without storage.
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const rgbToThemeHex = ([r, g, b]) =>
|
|
222
|
+
`#${[r, g, b]
|
|
223
|
+
.map((value) =>
|
|
224
|
+
Math.floor(value * 0.8)
|
|
225
|
+
.toString(16)
|
|
226
|
+
.padStart(2, "0")
|
|
227
|
+
)
|
|
228
|
+
.join("")}`;
|
|
229
|
+
|
|
230
|
+
const getAverageColor = (image) => {
|
|
231
|
+
const canvas = document.createElement("canvas");
|
|
232
|
+
canvas.width = 32;
|
|
233
|
+
canvas.height = 32;
|
|
234
|
+
const context = canvas.getContext("2d", { willReadFrequently: true });
|
|
235
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
236
|
+
const pixels = context.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
237
|
+
const color = [0, 0, 0];
|
|
238
|
+
let count = 0;
|
|
239
|
+
for (let index = 0; index < pixels.length; index += 4) {
|
|
240
|
+
if (pixels[index + 3] < 128) continue;
|
|
241
|
+
color[0] += pixels[index];
|
|
242
|
+
color[1] += pixels[index + 1];
|
|
243
|
+
color[2] += pixels[index + 2];
|
|
244
|
+
count++;
|
|
245
|
+
}
|
|
246
|
+
return count ? color.map((value) => Math.round(value / count)) : null;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const normalizeHomeCenterColor = (value) => {
|
|
250
|
+
const match = value?.match(/^#([0-9a-f]{6})$/i);
|
|
251
|
+
if (!match) return value;
|
|
252
|
+
const number = parseInt(match[1], 16);
|
|
253
|
+
const rgb = [number >> 16, (number >> 8) & 0xff, number & 0xff];
|
|
254
|
+
const brightness = Math.round(
|
|
255
|
+
(rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000
|
|
256
|
+
);
|
|
257
|
+
if (brightness >= 125) return value;
|
|
258
|
+
return `#${rgb
|
|
259
|
+
.map((channel) => Math.min(channel + 50, 255).toString(16).padStart(2, "0"))
|
|
260
|
+
.join("")}`;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const applyItemColor = (index, color) => {
|
|
264
|
+
if (!color || !banners[index]) return;
|
|
265
|
+
const colorOp = `color-mix(in srgb, ${color} 14%, transparent)`;
|
|
266
|
+
const colorDeep = `color-mix(in srgb, ${color} 87%, transparent)`;
|
|
267
|
+
banners[index].style.setProperty("--home-center-theme", color);
|
|
268
|
+
banners[index].style.setProperty("--home-center-theme-op", colorOp);
|
|
269
|
+
banners[index].style.setProperty("--home-center-theme-op-deep", colorDeep);
|
|
270
|
+
items[index]?.style.setProperty("--item-theme", color);
|
|
271
|
+
items[index]?.style.setProperty("--item-theme-op", colorOp);
|
|
272
|
+
items[index]?.style.setProperty("--item-theme-op-deep", colorDeep);
|
|
273
|
+
if (activeIndex === index) select(index);
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const extractItemColor = (index, sourceImage) => {
|
|
277
|
+
if (banners[index].dataset.color) return;
|
|
278
|
+
const src = sourceImage.currentSrc || sourceImage.src;
|
|
279
|
+
if (!src) return;
|
|
280
|
+
const cachedColor = getCachedColor(src);
|
|
281
|
+
if (cachedColor) {
|
|
282
|
+
applyItemColor(index, normalizeHomeCenterColor(cachedColor));
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const image = new Image();
|
|
287
|
+
image.crossOrigin = "Anonymous";
|
|
288
|
+
image.onload = () => {
|
|
289
|
+
if (!container.isConnected) return;
|
|
290
|
+
try {
|
|
291
|
+
const dominantColor = window.ColorThief?.getColorSync(image);
|
|
292
|
+
const rgb = dominantColor ? dominantColor.array() : getAverageColor(image);
|
|
293
|
+
if (!rgb) return;
|
|
294
|
+
const color = rgbToThemeHex(rgb);
|
|
295
|
+
cacheColor(src, color);
|
|
296
|
+
applyItemColor(index, normalizeHomeCenterColor(color));
|
|
297
|
+
} catch (error) {
|
|
298
|
+
// Canvas access can fail for image hosts without CORS support.
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
image.onerror = () => {};
|
|
302
|
+
image.src = src;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const navigate = (link, event) => {
|
|
306
|
+
if (!link) return;
|
|
307
|
+
if (event?.metaKey || event?.ctrlKey) {
|
|
308
|
+
window.open(link, "_blank");
|
|
309
|
+
} else if (Solitude.pjax?.loadUrl) {
|
|
310
|
+
Solitude.navigate(link);
|
|
311
|
+
} else {
|
|
312
|
+
window.location.href = link;
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
const select = (index) => {
|
|
317
|
+
if (!banners[index]) return;
|
|
318
|
+
activeIndex = index;
|
|
319
|
+
banners.forEach((banner, bannerIndex) => {
|
|
320
|
+
const isActive = bannerIndex === index;
|
|
321
|
+
banner.classList.toggle("active", isActive);
|
|
322
|
+
banner.setAttribute("aria-hidden", String(!isActive));
|
|
323
|
+
banner.tabIndex = isActive ? 0 : -1;
|
|
324
|
+
});
|
|
325
|
+
items.forEach((item, itemIndex) => {
|
|
326
|
+
const isActive = itemIndex === index;
|
|
327
|
+
item.classList.toggle("active", isActive);
|
|
328
|
+
item.setAttribute("aria-current", String(isActive));
|
|
329
|
+
});
|
|
330
|
+
indicators.forEach((indicator, indicatorIndex) =>
|
|
331
|
+
indicator.classList.toggle("active", indicatorIndex === index)
|
|
332
|
+
);
|
|
333
|
+
const selected = banners[index];
|
|
334
|
+
const selectedStyle = getComputedStyle(selected);
|
|
335
|
+
const color = selectedStyle.getPropertyValue("--home-center-theme").trim();
|
|
336
|
+
const colorOp = selectedStyle
|
|
337
|
+
.getPropertyValue("--home-center-theme-op")
|
|
338
|
+
.trim();
|
|
339
|
+
const colorDeep = selectedStyle
|
|
340
|
+
.getPropertyValue("--home-center-theme-op-deep")
|
|
341
|
+
.trim();
|
|
342
|
+
titleLink.textContent = selected.dataset.title;
|
|
343
|
+
titleLink.href = selected.dataset.link;
|
|
344
|
+
titleTag.textContent = selected.dataset.label;
|
|
345
|
+
container.style.setProperty("--current-theme", color);
|
|
346
|
+
container.style.setProperty("--current-theme-op", colorOp);
|
|
347
|
+
container.style.setProperty("--current-theme-op-deep", colorDeep);
|
|
348
|
+
categoryBar?.style.setProperty("--current-banner-theme", color);
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
items.forEach((item, index) => {
|
|
352
|
+
item.addEventListener("mouseenter", () => select(index));
|
|
353
|
+
item.addEventListener("focusin", () => select(index));
|
|
354
|
+
});
|
|
355
|
+
banners.forEach((item, index) => {
|
|
356
|
+
let pointerType = "";
|
|
357
|
+
item.addEventListener(
|
|
358
|
+
"pointerdown",
|
|
359
|
+
(event) => (pointerType = event.pointerType),
|
|
360
|
+
true
|
|
361
|
+
);
|
|
362
|
+
item.addEventListener("click", (event) => {
|
|
363
|
+
if (pointerType === "touch" && window.innerWidth <= 768) {
|
|
364
|
+
event.preventDefault();
|
|
365
|
+
select(index);
|
|
366
|
+
} else {
|
|
367
|
+
navigate(item.dataset.link, event);
|
|
368
|
+
}
|
|
369
|
+
pointerType = "";
|
|
370
|
+
});
|
|
371
|
+
item.addEventListener("keydown", (event) => {
|
|
372
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
373
|
+
event.preventDefault();
|
|
374
|
+
navigate(item.dataset.link, event);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
indicators.forEach((indicator, index) => {
|
|
379
|
+
indicator.addEventListener("click", (event) => {
|
|
380
|
+
event.preventDefault();
|
|
381
|
+
select(index);
|
|
382
|
+
banner.scrollTo({ left: banner.clientWidth * index, behavior: "smooth" });
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
banner.addEventListener("scroll", () => {
|
|
386
|
+
cancelAnimationFrame(scrollFrame);
|
|
387
|
+
scrollFrame = requestAnimationFrame(() => {
|
|
388
|
+
if (window.innerWidth > 768 || !banner.clientWidth) return;
|
|
389
|
+
select(Math.round(banner.scrollLeft / banner.clientWidth));
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
select(0);
|
|
393
|
+
banners.forEach((item, index) => {
|
|
394
|
+
if (item.dataset.color) return;
|
|
395
|
+
const image = item.querySelector(".home-center-cover-img");
|
|
396
|
+
if (!image) return;
|
|
397
|
+
if (image.complete && image.naturalWidth) {
|
|
398
|
+
extractItemColor(index, image);
|
|
399
|
+
} else {
|
|
400
|
+
image.addEventListener("load", () => extractItemColor(index, image), {
|
|
401
|
+
once: true,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
const initTooltip = () => {
|
|
408
|
+
const tooltip =
|
|
409
|
+
document.querySelector(".custom-tooltip") ||
|
|
410
|
+
document.body.appendChild(
|
|
411
|
+
Object.assign(document.createElement("div"), {
|
|
412
|
+
className: "custom-tooltip",
|
|
413
|
+
})
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
tooltip.style.opacity = "0";
|
|
417
|
+
tooltip.style.backdropFilter = "none";
|
|
418
|
+
if (!window.matchMedia("(hover: hover)").matches) return;
|
|
419
|
+
|
|
420
|
+
const rootFontSize = parseFloat(
|
|
421
|
+
getComputedStyle(document.documentElement).fontSize
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
document.querySelectorAll("[heotip]").forEach((element) => {
|
|
425
|
+
if (element.dataset.tooltipInitialized === "true") return;
|
|
426
|
+
element.dataset.tooltipInitialized = "true";
|
|
427
|
+
|
|
428
|
+
element.addEventListener("mouseenter", () => {
|
|
429
|
+
tooltip.textContent = element.getAttribute("heotip");
|
|
430
|
+
tooltip.style.left = "0";
|
|
431
|
+
tooltip.style.top = "0";
|
|
432
|
+
tooltip.style.backdropFilter = "blur(10px)";
|
|
433
|
+
tooltip.style.opacity = "1";
|
|
434
|
+
|
|
435
|
+
const targetRect = element.getBoundingClientRect();
|
|
436
|
+
const tooltipRect = tooltip.getBoundingClientRect();
|
|
437
|
+
const gap = 10;
|
|
438
|
+
const maxLeft = window.innerWidth - tooltipRect.width - rootFontSize;
|
|
439
|
+
const centeredLeft =
|
|
440
|
+
targetRect.left + (targetRect.width - tooltipRect.width) / 2;
|
|
441
|
+
const left = Math.max(rootFontSize, Math.min(centeredLeft, maxLeft));
|
|
442
|
+
const preferredTop =
|
|
443
|
+
targetRect.top >= tooltipRect.height + gap
|
|
444
|
+
? targetRect.top - tooltipRect.height - gap
|
|
445
|
+
: targetRect.bottom + gap;
|
|
446
|
+
const maxTop = window.innerHeight - tooltipRect.height - rootFontSize;
|
|
447
|
+
const top = Math.max(rootFontSize, Math.min(preferredTop, maxTop));
|
|
448
|
+
|
|
449
|
+
tooltip.style.left = `${left}px`;
|
|
450
|
+
tooltip.style.top = `${top}px`;
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
element.addEventListener("mouseleave", () => {
|
|
454
|
+
tooltip.style.backdropFilter = "none";
|
|
455
|
+
tooltip.style.opacity = "0";
|
|
456
|
+
});
|
|
457
|
+
});
|
|
118
458
|
};
|
|
119
459
|
|
|
120
460
|
const initObserver = () => {
|
|
@@ -126,7 +466,7 @@ const initObserver = () => {
|
|
|
126
466
|
const observer = new IntersectionObserver((entries) => {
|
|
127
467
|
entries.forEach((entry) => {
|
|
128
468
|
paginationElement.classList.toggle("show-window", entry.isIntersecting);
|
|
129
|
-
if (
|
|
469
|
+
if (Solitude.config.comment?.commentBarrage && commentBarrageElement) {
|
|
130
470
|
commentBarrageElement.style.bottom = entry.isIntersecting
|
|
131
471
|
? "-200px"
|
|
132
472
|
: "0px";
|
|
@@ -134,12 +474,13 @@ const initObserver = () => {
|
|
|
134
474
|
});
|
|
135
475
|
});
|
|
136
476
|
observer.observe(commentElement);
|
|
477
|
+
lifecycle.add(() => observer.disconnect());
|
|
137
478
|
}
|
|
138
479
|
};
|
|
139
480
|
|
|
140
481
|
const addCopyright = () => {
|
|
141
|
-
if (!
|
|
142
|
-
const { limit, author, link, source, info } =
|
|
482
|
+
if (!Solitude.config.copyright) return;
|
|
483
|
+
const { limit, author, link, source, info } = Solitude.config.copyright;
|
|
143
484
|
|
|
144
485
|
document.body.addEventListener("copy", (e) => {
|
|
145
486
|
e.preventDefault();
|
|
@@ -153,7 +494,7 @@ const addCopyright = () => {
|
|
|
153
494
|
};
|
|
154
495
|
|
|
155
496
|
const asideStatus = () => {
|
|
156
|
-
const status =
|
|
497
|
+
const status = Solitude.saveToLocal.get("aside-status");
|
|
157
498
|
document.documentElement.classList.toggle("hide-aside", status === "hide");
|
|
158
499
|
};
|
|
159
500
|
|
|
@@ -162,7 +503,7 @@ function initThemeColor() {
|
|
|
162
503
|
const themeColor =
|
|
163
504
|
currentTop > 0
|
|
164
505
|
? "--efu-card-bg"
|
|
165
|
-
:
|
|
506
|
+
: Solitude.page.is_post
|
|
166
507
|
? "--efu-main"
|
|
167
508
|
: "--efu-background";
|
|
168
509
|
applyThemeColor(
|
|
@@ -170,6 +511,8 @@ function initThemeColor() {
|
|
|
170
511
|
);
|
|
171
512
|
}
|
|
172
513
|
|
|
514
|
+
Solitude.initThemeColor = initThemeColor;
|
|
515
|
+
|
|
173
516
|
function applyThemeColor(color) {
|
|
174
517
|
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
|
|
175
518
|
const appleMobileWebAppMeta = document.querySelector(
|
|
@@ -185,12 +528,64 @@ function applyThemeColor(color) {
|
|
|
185
528
|
const handleThemeChange = (mode) => {
|
|
186
529
|
const themeChange = window.globalFn?.themeChange || {};
|
|
187
530
|
Object.values(themeChange).forEach((fn) => fn(mode));
|
|
531
|
+
lifecycle.emit("themeChange", { mode });
|
|
188
532
|
};
|
|
189
533
|
|
|
190
|
-
const
|
|
534
|
+
const actions = {
|
|
191
535
|
lastWittyWord: "",
|
|
192
536
|
wasPageHidden: false,
|
|
193
537
|
musicPlaying: false,
|
|
538
|
+
consoleNavState: null,
|
|
539
|
+
randomPost() {
|
|
540
|
+
const posts = Solitude.config.random_posts || [];
|
|
541
|
+
if (!posts.length) return;
|
|
542
|
+
Solitude.navigate(`${Solitude.config.root}${posts[Solitude.randomNum(posts.length)]}`);
|
|
543
|
+
},
|
|
544
|
+
noop() {},
|
|
545
|
+
navigateTo(url) {
|
|
546
|
+
Solitude.navigate(url);
|
|
547
|
+
},
|
|
548
|
+
openExternal(url) {
|
|
549
|
+
if (url) window.open(url, "_blank", "noopener");
|
|
550
|
+
},
|
|
551
|
+
toggleTargetClass(target, event, element) {
|
|
552
|
+
const selector = target || element?.dataset.solitudeTarget;
|
|
553
|
+
const className = element?.dataset.solitudeClass || "show";
|
|
554
|
+
document.querySelector(selector)?.classList.toggle(className);
|
|
555
|
+
},
|
|
556
|
+
setTargetClass(target, event, element) {
|
|
557
|
+
const selector = target || element?.dataset.solitudeTarget;
|
|
558
|
+
const className = element?.dataset.solitudeClass || "show";
|
|
559
|
+
const enabled = element?.dataset.solitudeEnabled !== "false";
|
|
560
|
+
document
|
|
561
|
+
.querySelectorAll(selector)
|
|
562
|
+
.forEach((item) => item.classList.toggle(className, enabled));
|
|
563
|
+
},
|
|
564
|
+
showReward() {
|
|
565
|
+
document
|
|
566
|
+
.querySelectorAll(".reward-main")
|
|
567
|
+
.forEach((item) => { item.style.display = "flex"; });
|
|
568
|
+
const quitBox = document.getElementById("quit-box");
|
|
569
|
+
if (quitBox) quitBox.style.display = "flex";
|
|
570
|
+
},
|
|
571
|
+
hideReward() {
|
|
572
|
+
document
|
|
573
|
+
.querySelectorAll(".reward-main")
|
|
574
|
+
.forEach((item) => { item.style.display = "none"; });
|
|
575
|
+
const quitBox = document.getElementById("quit-box");
|
|
576
|
+
if (quitBox) quitBox.style.display = "none";
|
|
577
|
+
},
|
|
578
|
+
runConfiguredAction(command) {
|
|
579
|
+
const source = String(command || "").trim().replace(/;$/, "");
|
|
580
|
+
const call = source.match(/^(?:Solitude\.)?([A-Za-z_$][\w$]*)\(\)$/);
|
|
581
|
+
if (call && typeof Solitude[call[1]] === "function") {
|
|
582
|
+
Solitude[call[1]]();
|
|
583
|
+
} else {
|
|
584
|
+
const navigation = source.match(/^(?:pjax\.loadUrl|Solitude\.navigate)\((['"])(.*?)\1\)$/);
|
|
585
|
+
if (navigation) Solitude.navigate(navigation[2]);
|
|
586
|
+
}
|
|
587
|
+
Solitude.hideRightMenu?.();
|
|
588
|
+
},
|
|
194
589
|
scrollTo(elementId) {
|
|
195
590
|
const targetElement = document.getElementById(elementId);
|
|
196
591
|
if (targetElement) {
|
|
@@ -199,47 +594,73 @@ const sco = {
|
|
|
199
594
|
window.scroll({ top: targetPosition, behavior: "smooth" });
|
|
200
595
|
}
|
|
201
596
|
},
|
|
202
|
-
|
|
203
|
-
const $music = document.
|
|
204
|
-
if ($music && $music.aplayer) {
|
|
205
|
-
this.isMusicBind = true;
|
|
206
|
-
$music.onclick = () => this.musicPlaying && this.musicToggle(true);
|
|
207
|
-
$music.aplayer.on('loadeddata', () =>{
|
|
208
|
-
coverColor(true);
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
|
-
},
|
|
212
|
-
musicToggle(isMeting = true) {
|
|
213
|
-
if (!this.isMusicBind) this.musicBind();
|
|
214
|
-
|
|
215
|
-
const $music = document.querySelector("#nav-music");
|
|
216
|
-
const $meting = document.querySelector("#nav-music meting-js");
|
|
597
|
+
syncMusicState(isPlaying) {
|
|
598
|
+
const $music = document.getElementById("nav-music");
|
|
217
599
|
const $console = document.getElementById("consoleMusic");
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
$music
|
|
222
|
-
$music.classList.toggle("stretch", this.musicPlaying);
|
|
600
|
+
this.musicPlaying = Boolean(isPlaying);
|
|
601
|
+
|
|
602
|
+
$music?.classList.toggle("playing", this.musicPlaying);
|
|
603
|
+
$music?.classList.toggle("stretch", this.musicPlaying);
|
|
223
604
|
$console?.classList.toggle("on", this.musicPlaying);
|
|
224
|
-
|
|
225
|
-
if (
|
|
605
|
+
|
|
606
|
+
if (Solitude.rightMenu?.menuItems?.music?.[0]) {
|
|
226
607
|
const $rmText = document.querySelector("#menu-music-toggle span");
|
|
227
608
|
const $rmIcon = document.querySelector("#menu-music-toggle i");
|
|
228
|
-
$rmText
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
609
|
+
if ($rmText) {
|
|
610
|
+
const label = this.musicPlaying
|
|
611
|
+
? Solitude.config.right_menu.music.stop
|
|
612
|
+
: Solitude.config.right_menu.music.start;
|
|
613
|
+
Solitude.rightMenu.setLabel($rmText, label);
|
|
614
|
+
}
|
|
615
|
+
if ($rmIcon) {
|
|
616
|
+
$rmIcon.className = `solitude fas ${this.musicPlaying ? "fa-pause" : "fa-play"}`;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
musicBind() {
|
|
621
|
+
const $meting = document.querySelector("#nav-music meting-js");
|
|
622
|
+
const aplayer = $meting?.aplayer;
|
|
623
|
+
if (!aplayer) {
|
|
624
|
+
this.isMusicBind = false;
|
|
625
|
+
return null;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
this.isMusicBind = true;
|
|
629
|
+
if (!aplayer.solitudeCapsuleBound) {
|
|
630
|
+
aplayer.on("play", () => this.syncMusicState(true));
|
|
631
|
+
aplayer.on("pause", () => this.syncMusicState(false));
|
|
632
|
+
aplayer.on("ended", () => this.syncMusicState(false));
|
|
633
|
+
aplayer.on("loadeddata", () => {
|
|
634
|
+
if (typeof coverColor === "function") coverColor(true);
|
|
635
|
+
this.syncMusicState(Boolean(aplayer.audio && !aplayer.audio.paused));
|
|
636
|
+
});
|
|
637
|
+
aplayer.solitudeCapsuleBound = true;
|
|
232
638
|
}
|
|
233
639
|
|
|
234
|
-
|
|
235
|
-
|
|
640
|
+
this.syncMusicState(Boolean(aplayer.audio && !aplayer.audio.paused));
|
|
641
|
+
return aplayer;
|
|
642
|
+
},
|
|
643
|
+
handleMusicClick(event) {
|
|
644
|
+
if (event.target?.closest?.(".music-control-btn")) return;
|
|
645
|
+
if (!this.musicPlaying) this.musicToggle();
|
|
646
|
+
},
|
|
647
|
+
musicToggle(isMeting = true) {
|
|
648
|
+
const aplayer = this.musicBind();
|
|
649
|
+
if (!aplayer) return;
|
|
650
|
+
|
|
651
|
+
const shouldPlay = Boolean(aplayer.audio?.paused);
|
|
652
|
+
if (!isMeting) {
|
|
653
|
+
this.syncMusicState(shouldPlay);
|
|
654
|
+
return;
|
|
236
655
|
}
|
|
656
|
+
|
|
657
|
+
shouldPlay ? aplayer.play() : aplayer.pause();
|
|
237
658
|
},
|
|
238
659
|
musicSkipBack() {
|
|
239
|
-
document.querySelector("meting-js")?.aplayer?.skipBack();
|
|
660
|
+
document.querySelector("#nav-music meting-js")?.aplayer?.skipBack();
|
|
240
661
|
},
|
|
241
662
|
musicSkipForward() {
|
|
242
|
-
document.querySelector("meting-js")?.aplayer?.skipForward();
|
|
663
|
+
document.querySelector("#nav-music meting-js")?.aplayer?.skipForward();
|
|
243
664
|
},
|
|
244
665
|
switchCommentBarrage() {
|
|
245
666
|
const commentBarrageElement = document.querySelector(".comment-barrage");
|
|
@@ -252,14 +673,16 @@ const sco = {
|
|
|
252
673
|
window.getComputedStyle(commentBarrageElement).display === "flex";
|
|
253
674
|
commentBarrageElement.style.display = isDisplayed ? "none" : "flex";
|
|
254
675
|
consoleCommentBarrage?.classList.toggle("on", !isDisplayed);
|
|
255
|
-
|
|
256
|
-
|
|
676
|
+
Solitude.saveToLocal.set("commentBarrageSwitch", !isDisplayed, 0.2);
|
|
677
|
+
if (Solitude.rightMenu?.menuItems.barrage) {
|
|
678
|
+
Solitude.rightMenu.barrage(isDisplayed);
|
|
679
|
+
}
|
|
257
680
|
},
|
|
258
681
|
switchHideAside() {
|
|
259
682
|
const htmlClassList = document.documentElement.classList;
|
|
260
683
|
const consoleHideAside = document.querySelector("#consoleHideAside");
|
|
261
684
|
const isHideAside = htmlClassList.contains("hide-aside");
|
|
262
|
-
|
|
685
|
+
Solitude.saveToLocal.set("aside-status", isHideAside ? "show" : "hide", 1);
|
|
263
686
|
htmlClassList.toggle("hide-aside");
|
|
264
687
|
consoleHideAside.classList.toggle("on", !isHideAside);
|
|
265
688
|
},
|
|
@@ -281,7 +704,7 @@ const sco = {
|
|
|
281
704
|
);
|
|
282
705
|
},
|
|
283
706
|
changeWittyWord() {
|
|
284
|
-
const greetings =
|
|
707
|
+
const greetings = Solitude.config.aside.witty_words || [];
|
|
285
708
|
if (greetings.length === 0) {
|
|
286
709
|
document.getElementById("sayhi").textContent = "Solitude";
|
|
287
710
|
this.lastWittyWord = null;
|
|
@@ -304,40 +727,115 @@ const sco = {
|
|
|
304
727
|
document.documentElement.getAttribute("data-theme") === "dark";
|
|
305
728
|
const newMode = isDarkMode ? "light" : "dark";
|
|
306
729
|
document.documentElement.setAttribute("data-theme", newMode);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (
|
|
730
|
+
Solitude.saveToLocal.set("theme", newMode, 0.02);
|
|
731
|
+
Solitude.snackbarShow(Solitude.config.lang.theme[newMode], false, 2000);
|
|
732
|
+
if (Solitude.rightMenu) {
|
|
733
|
+
Solitude.rightMenu.mode(!isDarkMode);
|
|
734
|
+
Solitude.rightMenu.hideRightMenu();
|
|
735
|
+
}
|
|
310
736
|
handleThemeChange(newMode);
|
|
311
737
|
},
|
|
312
738
|
hideTodayCard: () =>
|
|
313
739
|
document.getElementById("todayCard").classList.add("hide"),
|
|
314
|
-
toTop: () =>
|
|
315
|
-
showConsole
|
|
316
|
-
document.getElementById("console")
|
|
317
|
-
|
|
318
|
-
|
|
740
|
+
toTop: () => Solitude.scrollToDest(0),
|
|
741
|
+
showConsole() {
|
|
742
|
+
const consoleElement = document.getElementById("console");
|
|
743
|
+
if (!consoleElement || consoleElement.classList.contains("show")) return;
|
|
744
|
+
|
|
745
|
+
const header = document.getElementById("page-header");
|
|
746
|
+
if (header) {
|
|
747
|
+
this.consoleNavState = {
|
|
748
|
+
fixed: header.classList.contains("nav-fixed"),
|
|
749
|
+
visible: header.classList.contains("nav-visible"),
|
|
750
|
+
};
|
|
751
|
+
header.classList.add("nav-fixed");
|
|
752
|
+
header.classList.remove("nav-visible");
|
|
753
|
+
header.classList.add("console-open");
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
consoleElement.classList.add("show");
|
|
757
|
+
document
|
|
758
|
+
.querySelector("#nav-console .console_switchbutton")
|
|
759
|
+
?.classList.add("console-open");
|
|
760
|
+
},
|
|
761
|
+
hideConsole() {
|
|
762
|
+
const consoleElement = document.getElementById("console");
|
|
763
|
+
if (!consoleElement?.classList.contains("show")) return;
|
|
764
|
+
|
|
765
|
+
consoleElement.classList.remove("show");
|
|
766
|
+
document
|
|
767
|
+
.querySelector("#nav-console .console_switchbutton")
|
|
768
|
+
?.classList.remove("console-open");
|
|
769
|
+
|
|
770
|
+
const header = document.getElementById("page-header");
|
|
771
|
+
if (header && this.consoleNavState) {
|
|
772
|
+
header.classList.remove("console-open");
|
|
773
|
+
header.classList.toggle("nav-fixed", this.consoleNavState.fixed);
|
|
774
|
+
header.classList.toggle("nav-visible", this.consoleNavState.visible);
|
|
775
|
+
}
|
|
776
|
+
this.consoleNavState = null;
|
|
777
|
+
},
|
|
778
|
+
toggleConsole() {
|
|
779
|
+
const consoleElement = document.getElementById("console");
|
|
780
|
+
if (consoleElement?.classList.contains("show")) {
|
|
781
|
+
this.hideConsole();
|
|
782
|
+
} else {
|
|
783
|
+
this.showConsole();
|
|
784
|
+
}
|
|
785
|
+
},
|
|
786
|
+
onConsoleCardGroupClick(event) {
|
|
787
|
+
if (event.target.closest?.(".console-card")) return;
|
|
788
|
+
this.hideConsole();
|
|
789
|
+
},
|
|
790
|
+
onNavBlankClickCloseConsole(event) {
|
|
791
|
+
if (!document.getElementById("console")?.classList.contains("show")) return;
|
|
792
|
+
if (
|
|
793
|
+
event.target.closest?.(
|
|
794
|
+
"a, button, .back-home-button, .menus_item, #page-name"
|
|
795
|
+
)
|
|
796
|
+
) {
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
this.hideConsole();
|
|
800
|
+
},
|
|
319
801
|
refreshWaterFall() {
|
|
802
|
+
const allElements = [...document.querySelectorAll(".waterfall")];
|
|
803
|
+
const elements = allElements.filter(
|
|
804
|
+
(element) => element.dataset.solitudeWaterfall !== "true"
|
|
805
|
+
);
|
|
806
|
+
if (!elements.length) return;
|
|
807
|
+
elements.forEach((element) => {
|
|
808
|
+
element.dataset.solitudeWaterfall = "true";
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
const timers = new Set();
|
|
320
812
|
const observer = new IntersectionObserver((entries) => {
|
|
321
813
|
entries.forEach((entry) => {
|
|
322
814
|
if (entry.isIntersecting) {
|
|
323
|
-
|
|
815
|
+
observer.unobserve(entry.target);
|
|
816
|
+
const timer = setTimeout(() => {
|
|
817
|
+
timers.delete(timer);
|
|
818
|
+
if (!entry.target.isConnected) return;
|
|
324
819
|
waterfall(entry.target).then(() => {
|
|
325
|
-
entry.target.classList.add("show");
|
|
820
|
+
if (entry.target.isConnected) entry.target.classList.add("show");
|
|
326
821
|
});
|
|
327
822
|
}, 300);
|
|
823
|
+
timers.add(timer);
|
|
328
824
|
}
|
|
329
825
|
});
|
|
330
826
|
});
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
827
|
+
elements.forEach((element) => observer.observe(element));
|
|
828
|
+
lifecycle.add(() => {
|
|
829
|
+
observer.disconnect();
|
|
830
|
+
timers.forEach(clearTimeout);
|
|
831
|
+
});
|
|
334
832
|
},
|
|
335
833
|
addRuntime() {
|
|
336
834
|
const el = document.getElementById("runtimeshow");
|
|
337
|
-
if (el &&
|
|
835
|
+
if (el && Solitude.config.runtime) {
|
|
338
836
|
el.innerText =
|
|
339
|
-
|
|
340
|
-
|
|
837
|
+
Solitude.timeDiff(new Date(Solitude.config.runtime), new Date()) +
|
|
838
|
+
Solitude.config.lang.day;
|
|
341
839
|
}
|
|
342
840
|
},
|
|
343
841
|
toTalk(txt) {
|
|
@@ -354,15 +852,15 @@ const sco = {
|
|
|
354
852
|
new Event("input", { bubble: true, cancelable: true })
|
|
355
853
|
);
|
|
356
854
|
el.value = "> " + txt.replace(/\n/g, "\n> ") + "\n\n";
|
|
357
|
-
|
|
358
|
-
|
|
855
|
+
Solitude.scrollToDest(
|
|
856
|
+
Solitude.getEleTop(document.getElementById("post-comment")),
|
|
359
857
|
300
|
|
360
858
|
);
|
|
361
859
|
el.focus();
|
|
362
860
|
el.setSelectionRange(-1, -1);
|
|
363
861
|
}
|
|
364
862
|
});
|
|
365
|
-
|
|
863
|
+
Solitude.snackbarShow(Solitude.config.lang.totalk, false, 2000);
|
|
366
864
|
},
|
|
367
865
|
initbbtalk() {
|
|
368
866
|
const bberTalkElement = document.querySelector("#bber-talk");
|
|
@@ -385,7 +883,7 @@ const sco = {
|
|
|
385
883
|
if (captionText) {
|
|
386
884
|
image.insertAdjacentHTML(
|
|
387
885
|
"afterend",
|
|
388
|
-
`<div class="img-alt is-center">${
|
|
886
|
+
`<div class="img-alt is-center">${Solitude.escapeHtml(
|
|
389
887
|
captionText
|
|
390
888
|
)}</div>`
|
|
391
889
|
);
|
|
@@ -393,15 +891,15 @@ const sco = {
|
|
|
393
891
|
});
|
|
394
892
|
},
|
|
395
893
|
scrollToComment: () =>
|
|
396
|
-
|
|
397
|
-
|
|
894
|
+
Solitude.scrollToDest(
|
|
895
|
+
Solitude.getEleTop(document.getElementById("post-comment")),
|
|
398
896
|
300
|
|
399
897
|
),
|
|
400
898
|
setTimeState() {
|
|
401
899
|
const el = document.getElementById("sayhi");
|
|
402
900
|
if (el) {
|
|
403
901
|
const hours = new Date().getHours();
|
|
404
|
-
const lang =
|
|
902
|
+
const lang = Solitude.config.aside.state;
|
|
405
903
|
|
|
406
904
|
const localData = getLocalData([
|
|
407
905
|
"twikoo",
|
|
@@ -415,7 +913,11 @@ const sco = {
|
|
|
415
913
|
for (let key of keys) {
|
|
416
914
|
const data = localStorage.getItem(key);
|
|
417
915
|
if (data) {
|
|
418
|
-
|
|
916
|
+
try {
|
|
917
|
+
return JSON.parse(data);
|
|
918
|
+
} catch (error) {
|
|
919
|
+
localStorage.removeItem(key);
|
|
920
|
+
}
|
|
419
921
|
}
|
|
420
922
|
}
|
|
421
923
|
return null;
|
|
@@ -423,8 +925,8 @@ const sco = {
|
|
|
423
925
|
const nick = localData ? localData.nick || localData.display_name : null;
|
|
424
926
|
|
|
425
927
|
const prefix = this.wasPageHidden
|
|
426
|
-
?
|
|
427
|
-
:
|
|
928
|
+
? Solitude.config.aside.witty_comment.back + nick
|
|
929
|
+
: Solitude.config.aside.witty_comment.prefix + nick;
|
|
428
930
|
|
|
429
931
|
const greetings = [
|
|
430
932
|
{ start: 0, end: 5, text: nick ? prefix : lang.goodnight },
|
|
@@ -456,7 +958,7 @@ const sco = {
|
|
|
456
958
|
categoriesBarActive() {
|
|
457
959
|
const categoryBar = document.querySelector("#category-bar");
|
|
458
960
|
const currentPath = decodeURIComponent(window.location.pathname);
|
|
459
|
-
const isHomePage = currentPath ===
|
|
961
|
+
const isHomePage = currentPath === Solitude.config.root;
|
|
460
962
|
if (categoryBar) {
|
|
461
963
|
const categoryItems = categoryBar.querySelectorAll(".category-bar-item");
|
|
462
964
|
categoryItems.forEach((item) => item.classList.remove("select"));
|
|
@@ -482,14 +984,19 @@ const sco = {
|
|
|
482
984
|
behavior: "smooth",
|
|
483
985
|
});
|
|
484
986
|
};
|
|
485
|
-
scrollBar.
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
987
|
+
if (scrollBar.dataset.solitudeScrollBound !== "true") {
|
|
988
|
+
scrollBar.dataset.solitudeScrollBound = "true";
|
|
989
|
+
lifecycle.listen(scrollBar, "scroll", () => {
|
|
990
|
+
clearTimeout(this.timeoutId);
|
|
991
|
+
this.timeoutId = setTimeout(() => {
|
|
992
|
+
if (nextElement) {
|
|
993
|
+
nextElement.style.transform = isScrollBarAtEnd()
|
|
994
|
+
? "rotate(180deg)"
|
|
995
|
+
: "";
|
|
996
|
+
}
|
|
997
|
+
}, 150);
|
|
998
|
+
}, { passive: true });
|
|
999
|
+
}
|
|
493
1000
|
scroll();
|
|
494
1001
|
}
|
|
495
1002
|
},
|
|
@@ -505,18 +1012,20 @@ const sco = {
|
|
|
505
1012
|
if (!pageText) return;
|
|
506
1013
|
const pageButton = document.getElementById("toPageButton");
|
|
507
1014
|
const pageNumbers = document.querySelectorAll(".page-number");
|
|
508
|
-
const lastPageNumber = +pageNumbers[pageNumbers.length - 1]
|
|
509
|
-
if (
|
|
510
|
-
toGroup.style.display = "none";
|
|
1015
|
+
const lastPageNumber = +(pageNumbers[pageNumbers.length - 1]?.textContent || 1);
|
|
1016
|
+
if (lastPageNumber === 1) {
|
|
1017
|
+
if (toGroup) toGroup.style.display = "none";
|
|
511
1018
|
return;
|
|
512
1019
|
}
|
|
513
|
-
|
|
1020
|
+
lifecycle.listen(pageText, "keydown", (event) => {
|
|
514
1021
|
if (event.key === "Enter") {
|
|
515
|
-
|
|
516
|
-
|
|
1022
|
+
Solitude.toPage();
|
|
1023
|
+
Solitude.navigate(pageButton.href);
|
|
517
1024
|
}
|
|
518
1025
|
});
|
|
519
|
-
|
|
1026
|
+
lifecycle.listen(pageText, "input", () => {
|
|
1027
|
+
pageText.value = pageText.value.replace(/[^0-9]/g, "");
|
|
1028
|
+
if (pageText.value === "0") pageText.value = "";
|
|
520
1029
|
pageButton.classList.toggle(
|
|
521
1030
|
"haveValue",
|
|
522
1031
|
pageText.value !== "" && pageText.value !== "0"
|
|
@@ -583,13 +1092,13 @@ const sco = {
|
|
|
583
1092
|
owoBig.style.left = `${itemRect.left - owoBig.offsetWidth / 4}px`;
|
|
584
1093
|
owoBig.style.top = `${itemRect.top}px`;
|
|
585
1094
|
};
|
|
586
|
-
|
|
587
|
-
|
|
1095
|
+
lifecycle.listen(document, "mouseover", showOwoBig);
|
|
1096
|
+
lifecycle.listen(document, "mouseout", hideOwoBig);
|
|
588
1097
|
},
|
|
589
1098
|
changeTimeFormat(selector) {
|
|
590
1099
|
selector.forEach((item) => {
|
|
591
1100
|
const timeVal = item.getAttribute("datetime");
|
|
592
|
-
item.textContent =
|
|
1101
|
+
item.textContent = Solitude.diffDate(timeVal, true);
|
|
593
1102
|
item.style.display = "inline";
|
|
594
1103
|
});
|
|
595
1104
|
},
|
|
@@ -605,7 +1114,7 @@ const sco = {
|
|
|
605
1114
|
loadTwoComment();
|
|
606
1115
|
}
|
|
607
1116
|
};
|
|
608
|
-
|
|
1117
|
+
Solitude.addEventListenerPjax(switchBtn, "click", handleSwitchBtn);
|
|
609
1118
|
},
|
|
610
1119
|
homeTypeit() {
|
|
611
1120
|
if (typeof home_subtitle === "undefined") return;
|
|
@@ -619,11 +1128,15 @@ const sco = {
|
|
|
619
1128
|
ty.type(item).pause(500).delete(item);
|
|
620
1129
|
});
|
|
621
1130
|
ty.go();
|
|
1131
|
+
lifecycle.add(() => ty.destroy?.());
|
|
622
1132
|
},
|
|
623
1133
|
};
|
|
624
1134
|
|
|
1135
|
+
Object.assign(Solitude, actions);
|
|
1136
|
+
Solitude.toggleTheme = () => Solitude.switchDarkMode();
|
|
1137
|
+
|
|
625
1138
|
const addHighlight = () => {
|
|
626
|
-
const highlight =
|
|
1139
|
+
const highlight = Solitude.config.highlight;
|
|
627
1140
|
if (!highlight) return;
|
|
628
1141
|
const { copy, expand, limit, syntax } = highlight;
|
|
629
1142
|
const $isPrismjs = syntax === "prismjs";
|
|
@@ -644,7 +1157,7 @@ const addHighlight = () => {
|
|
|
644
1157
|
? `<i class="solitude fas fa-angles-down"></i>`
|
|
645
1158
|
: "<i></i>";
|
|
646
1159
|
|
|
647
|
-
const alertInfo = (ele, text) =>
|
|
1160
|
+
const alertInfo = (ele, text) => Solitude.snackbarShow(text, false, 2000);
|
|
648
1161
|
|
|
649
1162
|
const copyFn = (e) => {
|
|
650
1163
|
const $buttonParent = e.parentNode;
|
|
@@ -658,7 +1171,7 @@ const addHighlight = () => {
|
|
|
658
1171
|
selection.removeAllRanges();
|
|
659
1172
|
selection.addRange(range);
|
|
660
1173
|
document.execCommand("copy");
|
|
661
|
-
alertInfo(e.lastChild,
|
|
1174
|
+
alertInfo(e.lastChild, Solitude.config.lang.copy.success);
|
|
662
1175
|
selection.removeAllRanges();
|
|
663
1176
|
$buttonParent.classList.remove("copy-true");
|
|
664
1177
|
};
|
|
@@ -686,14 +1199,14 @@ const addHighlight = () => {
|
|
|
686
1199
|
const hlTools = document.createElement("div");
|
|
687
1200
|
hlTools.className = `highlight-tools ${expandClass}`;
|
|
688
1201
|
hlTools.innerHTML = expandEle + lang + caption + copyEle;
|
|
689
|
-
|
|
1202
|
+
Solitude.addEventListenerPjax(hlTools, "click", ToolsFn);
|
|
690
1203
|
fragment.appendChild(hlTools);
|
|
691
1204
|
}
|
|
692
1205
|
if (limit && item.offsetHeight > limit + 30) {
|
|
693
1206
|
const ele = document.createElement("div");
|
|
694
1207
|
ele.className = "code-expand-btn";
|
|
695
1208
|
ele.innerHTML = limitEle;
|
|
696
|
-
|
|
1209
|
+
Solitude.addEventListenerPjax(ele, "click", shrinkEle);
|
|
697
1210
|
fragment.appendChild(ele);
|
|
698
1211
|
}
|
|
699
1212
|
if (service === "hl") {
|
|
@@ -706,17 +1219,17 @@ const addHighlight = () => {
|
|
|
706
1219
|
if ($isPrismjs) {
|
|
707
1220
|
$syntaxHighlight.forEach((item) => {
|
|
708
1221
|
const langName = item.getAttribute("data-language") || "Code";
|
|
709
|
-
const highlightLangEle = `<div class="code-lang">${
|
|
1222
|
+
const highlightLangEle = `<div class="code-lang">${Solitude.escapeHtml(
|
|
710
1223
|
langName
|
|
711
1224
|
)}</div>`;
|
|
712
|
-
|
|
1225
|
+
Solitude.wrap(item, "figure", { class: "highlight" });
|
|
713
1226
|
createEle(highlightLangEle, item);
|
|
714
1227
|
});
|
|
715
1228
|
} else {
|
|
716
1229
|
$syntaxHighlight.forEach((item) => {
|
|
717
1230
|
let langName = item.getAttribute("class").split(" ")[1];
|
|
718
1231
|
if (langName === "plain" || langName === undefined) langName = "Code";
|
|
719
|
-
const highlightLangEle = `<div class="code-lang">${
|
|
1232
|
+
const highlightLangEle = `<div class="code-lang">${Solitude.escapeHtml(
|
|
720
1233
|
langName
|
|
721
1234
|
)}</div>`;
|
|
722
1235
|
createEle(highlightLangEle, item, "hl");
|
|
@@ -735,8 +1248,8 @@ class toc {
|
|
|
735
1248
|
el.forEach((e) => {
|
|
736
1249
|
e.addEventListener("click", (event) => {
|
|
737
1250
|
event.preventDefault();
|
|
738
|
-
|
|
739
|
-
|
|
1251
|
+
Solitude.scrollToDest(
|
|
1252
|
+
Solitude.getEleTop(
|
|
740
1253
|
document.getElementById(
|
|
741
1254
|
decodeURI(
|
|
742
1255
|
(event.target.className === "toc-text"
|
|
@@ -774,7 +1287,7 @@ class toc {
|
|
|
774
1287
|
if (top === 0) return false;
|
|
775
1288
|
let currentIndex = "";
|
|
776
1289
|
list.forEach((ele, index) => {
|
|
777
|
-
if (top >
|
|
1290
|
+
if (top > Solitude.getEleTop(ele) - 80) {
|
|
778
1291
|
currentIndex = index;
|
|
779
1292
|
}
|
|
780
1293
|
});
|
|
@@ -794,11 +1307,11 @@ class toc {
|
|
|
794
1307
|
}
|
|
795
1308
|
};
|
|
796
1309
|
|
|
797
|
-
|
|
1310
|
+
const tocScrollFn = Solitude.throttle(() => {
|
|
798
1311
|
const currentTop = window.scrollY || document.documentElement.scrollTop;
|
|
799
1312
|
findHeadPosition(currentTop);
|
|
800
1313
|
}, 100);
|
|
801
|
-
|
|
1314
|
+
lifecycle.listen(window, "scroll", tocScrollFn, { passive: true });
|
|
802
1315
|
}
|
|
803
1316
|
}
|
|
804
1317
|
|
|
@@ -815,7 +1328,7 @@ class tabs {
|
|
|
815
1328
|
const $tabItem = this.parentNode;
|
|
816
1329
|
if (!$tabItem.classList.contains("active")) {
|
|
817
1330
|
const $tabContent = $tabItem.parentNode.nextElementSibling;
|
|
818
|
-
const $siblings =
|
|
1331
|
+
const $siblings = Solitude.siblings($tabItem, ".active")[0];
|
|
819
1332
|
$siblings && $siblings.classList.remove("active");
|
|
820
1333
|
$tabItem.classList.add("active");
|
|
821
1334
|
const tabId = this.getAttribute("data-href").replace("#", "");
|
|
@@ -828,22 +1341,25 @@ class tabs {
|
|
|
828
1341
|
}
|
|
829
1342
|
|
|
830
1343
|
static lureAddListener() {
|
|
831
|
-
if (!
|
|
1344
|
+
if (!Solitude.config.lure) return;
|
|
832
1345
|
const title = document.title;
|
|
833
|
-
|
|
834
|
-
|
|
1346
|
+
let restoreTimer;
|
|
1347
|
+
lifecycle.listen(document, "visibilitychange", () => {
|
|
1348
|
+
const { lure } = Solitude.config;
|
|
835
1349
|
document.title =
|
|
836
1350
|
document.visibilityState === "hidden" ? lure.jump : lure.back;
|
|
837
1351
|
if (document.visibilityState === "visible") {
|
|
838
|
-
|
|
1352
|
+
clearTimeout(restoreTimer);
|
|
1353
|
+
restoreTimer = setTimeout(() => {
|
|
839
1354
|
document.title = title;
|
|
840
1355
|
}, 2000);
|
|
841
1356
|
}
|
|
842
1357
|
});
|
|
1358
|
+
lifecycle.add(() => clearTimeout(restoreTimer));
|
|
843
1359
|
}
|
|
844
1360
|
|
|
845
1361
|
static expireAddListener() {
|
|
846
|
-
const { expire } =
|
|
1362
|
+
const { expire } = Solitude.config;
|
|
847
1363
|
if (!expire) return;
|
|
848
1364
|
const list = document.querySelectorAll(".post-meta-date time");
|
|
849
1365
|
const post_date = list.length
|
|
@@ -873,7 +1389,7 @@ class tabs {
|
|
|
873
1389
|
}
|
|
874
1390
|
|
|
875
1391
|
const scrollFnToDo = () => {
|
|
876
|
-
const { toc } =
|
|
1392
|
+
const { toc } = Solitude.page;
|
|
877
1393
|
|
|
878
1394
|
if (toc) {
|
|
879
1395
|
const $cardTocLayout = document.getElementById("card-toc");
|
|
@@ -883,8 +1399,8 @@ const scrollFnToDo = () => {
|
|
|
883
1399
|
if (!target) return;
|
|
884
1400
|
|
|
885
1401
|
e.preventDefault();
|
|
886
|
-
|
|
887
|
-
|
|
1402
|
+
Solitude.scrollToDest(
|
|
1403
|
+
Solitude.getEleTop(
|
|
888
1404
|
document.getElementById(
|
|
889
1405
|
decodeURI(target.getAttribute("href")).replace("#", "")
|
|
890
1406
|
)
|
|
@@ -895,7 +1411,7 @@ const scrollFnToDo = () => {
|
|
|
895
1411
|
$cardTocLayout.classList.remove("open");
|
|
896
1412
|
}
|
|
897
1413
|
};
|
|
898
|
-
|
|
1414
|
+
Solitude.addEventListenerPjax($cardToc, "click", tocItemClickFn);
|
|
899
1415
|
}
|
|
900
1416
|
};
|
|
901
1417
|
|
|
@@ -903,44 +1419,128 @@ const forPostFn = () => {
|
|
|
903
1419
|
scrollFnToDo();
|
|
904
1420
|
};
|
|
905
1421
|
|
|
906
|
-
|
|
907
|
-
const
|
|
1422
|
+
const initPostCoverTilt = () => {
|
|
1423
|
+
const cover = document.querySelector(".post-cover-aside");
|
|
1424
|
+
const canTilt = window.matchMedia(
|
|
1425
|
+
"(hover: hover) and (pointer: fine)"
|
|
1426
|
+
).matches;
|
|
1427
|
+
const reduceMotion = window.matchMedia(
|
|
1428
|
+
"(prefers-reduced-motion: reduce)"
|
|
1429
|
+
).matches;
|
|
1430
|
+
if (!cover || !canTilt || reduceMotion) return;
|
|
1431
|
+
|
|
1432
|
+
const updateTilt = (event) => {
|
|
1433
|
+
const rect = cover.getBoundingClientRect();
|
|
1434
|
+
const x = (event.clientX - rect.left) / rect.width;
|
|
1435
|
+
const y = (event.clientY - rect.top) / rect.height;
|
|
1436
|
+
const rotateX = (0.5 - y) * 10;
|
|
1437
|
+
const rotateY = (x - 0.5) * 10;
|
|
1438
|
+
|
|
1439
|
+
cover.style.setProperty("--post-cover-glow-x", `${(x * 100).toFixed(2)}%`);
|
|
1440
|
+
cover.style.setProperty("--post-cover-glow-y", `${(y * 100).toFixed(2)}%`);
|
|
1441
|
+
cover.style.setProperty("--post-cover-rotate-x", `${rotateX.toFixed(2)}deg`);
|
|
1442
|
+
cover.style.setProperty("--post-cover-rotate-y", `${rotateY.toFixed(2)}deg`);
|
|
1443
|
+
cover.style.setProperty("--post-cover-img-x", `${(-rotateY).toFixed(2)}px`);
|
|
1444
|
+
cover.style.setProperty("--post-cover-img-y", `${rotateX.toFixed(2)}px`);
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
const resetTilt = () => {
|
|
1448
|
+
cover.style.setProperty("--post-cover-rotate-x", "0deg");
|
|
1449
|
+
cover.style.setProperty("--post-cover-rotate-y", "0deg");
|
|
1450
|
+
cover.style.setProperty("--post-cover-img-x", "0px");
|
|
1451
|
+
cover.style.setProperty("--post-cover-img-y", "0px");
|
|
1452
|
+
};
|
|
1453
|
+
|
|
1454
|
+
lifecycle.listen(cover, "pointerenter", updateTilt);
|
|
1455
|
+
lifecycle.listen(cover, "pointermove", updateTilt);
|
|
1456
|
+
lifecycle.listen(cover, "pointerleave", resetTilt);
|
|
1457
|
+
lifecycle.listen(cover, "pointercancel", resetTilt);
|
|
1458
|
+
};
|
|
1459
|
+
|
|
1460
|
+
const initAboutCardGlow = () => {
|
|
1461
|
+
const aboutPage = document.getElementById("about-page");
|
|
1462
|
+
const canHover = window.matchMedia(
|
|
1463
|
+
"(hover: hover) and (pointer: fine)"
|
|
1464
|
+
).matches;
|
|
1465
|
+
if (!aboutPage || !canHover) return;
|
|
1466
|
+
|
|
1467
|
+
aboutPage.querySelectorAll(".author-content-item").forEach((card) => {
|
|
1468
|
+
if (card.dataset.aboutGlowBound === "true") return;
|
|
1469
|
+
|
|
1470
|
+
const glow = document.createElement("div");
|
|
1471
|
+
glow.className = "about-pointer-glow";
|
|
1472
|
+
glow.setAttribute("aria-hidden", "true");
|
|
1473
|
+
card.prepend(glow);
|
|
1474
|
+
card.classList.add("about-glow-host");
|
|
1475
|
+
card.dataset.aboutGlowBound = "true";
|
|
1476
|
+
|
|
1477
|
+
const updateGlowPosition = (event) => {
|
|
1478
|
+
const rect = card.getBoundingClientRect();
|
|
1479
|
+
const x = ((event.clientX - rect.left) / rect.width) * 100;
|
|
1480
|
+
const y = ((event.clientY - rect.top) / rect.height) * 100;
|
|
1481
|
+
card.style.setProperty("--about-glow-x", `${x}%`);
|
|
1482
|
+
card.style.setProperty("--about-glow-y", `${y}%`);
|
|
1483
|
+
};
|
|
1484
|
+
|
|
1485
|
+
card.addEventListener("pointerenter", (event) => {
|
|
1486
|
+
updateGlowPosition(event);
|
|
1487
|
+
card.classList.add("is-about-glow-active");
|
|
1488
|
+
});
|
|
1489
|
+
card.addEventListener("pointermove", updateGlowPosition);
|
|
1490
|
+
card.addEventListener("pointerleave", () => {
|
|
1491
|
+
card.classList.remove("is-about-glow-active");
|
|
1492
|
+
});
|
|
1493
|
+
card.addEventListener("pointercancel", () => {
|
|
1494
|
+
card.classList.remove("is-about-glow-active");
|
|
1495
|
+
});
|
|
1496
|
+
});
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
Solitude.refresh = async () => {
|
|
1500
|
+
lifecycle.disposePage();
|
|
1501
|
+
await loadFeatureModules();
|
|
1502
|
+
const { is_home, is_page, page, is_post, ai_text } = Solitude.page;
|
|
908
1503
|
const { runtime, lazyload, lightbox, randomlink, covercolor, lure, expire } =
|
|
909
|
-
|
|
1504
|
+
Solitude.config;
|
|
910
1505
|
const timeSelector = ".datetime, .webinfo-item time, .post-meta-date time";
|
|
911
1506
|
document.body.setAttribute("data-type", page);
|
|
912
|
-
|
|
913
|
-
runtime &&
|
|
1507
|
+
Solitude.changeTimeFormat(document.querySelectorAll(timeSelector));
|
|
1508
|
+
runtime && Solitude.addRuntime();
|
|
914
1509
|
[
|
|
915
1510
|
scrollFn,
|
|
916
1511
|
sidebarFn,
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1512
|
+
initTooltip,
|
|
1513
|
+
() => Solitude.addPhotoFigcaption(),
|
|
1514
|
+
() => Solitude.setTimeState(),
|
|
1515
|
+
() => Solitude.tagPageActive(),
|
|
1516
|
+
() => Solitude.categoriesBarActive(),
|
|
1517
|
+
() => Solitude.listenToPageInputPress(),
|
|
1518
|
+
() => Solitude.musicBind(),
|
|
1519
|
+
() => Solitude.addNavBackgroundInit(),
|
|
1520
|
+
() => Solitude.refreshWaterFall(),
|
|
925
1521
|
].forEach((fn) => fn());
|
|
926
|
-
lazyload.enable &&
|
|
1522
|
+
lazyload.enable && Solitude.lazyloadImg();
|
|
927
1523
|
lightbox &&
|
|
928
|
-
|
|
1524
|
+
Solitude.lightbox(
|
|
929
1525
|
document.querySelectorAll(
|
|
930
1526
|
".article-container img:not(.flink-avatar,.gallery-group img, .no-lightbox)"
|
|
931
1527
|
)
|
|
932
1528
|
);
|
|
933
|
-
randomlink && randomLinksList();
|
|
1529
|
+
randomlink && Solitude.randomLinksList?.();
|
|
1530
|
+
Solitude.config.friend_links.async && Solitude.friendLinks?.init();
|
|
934
1531
|
if (is_post) {
|
|
935
|
-
|
|
1532
|
+
initPostCoverTilt();
|
|
1533
|
+
if (ai_text && ai) {
|
|
936
1534
|
ai.init();
|
|
1535
|
+
lifecycle.add(() => ai.cancel());
|
|
937
1536
|
}
|
|
938
1537
|
}
|
|
939
|
-
|
|
1538
|
+
Solitude.switchComments();
|
|
940
1539
|
initObserver();
|
|
941
1540
|
if (is_home) {
|
|
942
1541
|
showTodayCard();
|
|
943
|
-
|
|
1542
|
+
initHomeCenter();
|
|
1543
|
+
Solitude.homeTypeit();
|
|
944
1544
|
}
|
|
945
1545
|
typeof updatePostsBasedOnComments === "function" &&
|
|
946
1546
|
updatePostsBasedOnComments();
|
|
@@ -952,25 +1552,41 @@ window.refreshFn = () => {
|
|
|
952
1552
|
tabs.expireAddListener();
|
|
953
1553
|
}
|
|
954
1554
|
if (covercolor.enable) coverColor();
|
|
955
|
-
if (
|
|
1555
|
+
if (Solitude.page.toc) toc.init();
|
|
956
1556
|
if (lure) tabs.lureAddListener();
|
|
957
|
-
page === "music"
|
|
1557
|
+
if (page === "music") {
|
|
1558
|
+
initializeMusicPlayer();
|
|
1559
|
+
lifecycle.add(() => Solitude.musicPlayer?.destroy?.());
|
|
1560
|
+
}
|
|
1561
|
+
if (page === "archive") {
|
|
1562
|
+
const { archivePageController, initArchivePage } = await import("./archive-page.js");
|
|
1563
|
+
initArchivePage();
|
|
1564
|
+
lifecycle.add(() => archivePageController.destroy());
|
|
1565
|
+
}
|
|
1566
|
+
initAboutCardGlow();
|
|
958
1567
|
forPostFn();
|
|
959
1568
|
};
|
|
960
1569
|
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
});
|
|
1570
|
+
const initializeApp = async () => {
|
|
1571
|
+
initActionDelegation(Solitude);
|
|
1572
|
+
initPreloader(Solitude);
|
|
1573
|
+
addCopyright();
|
|
1574
|
+
await Solitude.refresh();
|
|
1575
|
+
asideStatus();
|
|
1576
|
+
window.onscroll = percent;
|
|
1577
|
+
Solitude.initConsoleState();
|
|
1578
|
+
lifecycle.emit("ready", { config: Solitude.config, page: Solitude.page });
|
|
1579
|
+
};
|
|
1580
|
+
|
|
1581
|
+
if (document.readyState === "loading") {
|
|
1582
|
+
document.addEventListener("DOMContentLoaded", initializeApp, { once: true });
|
|
1583
|
+
} else {
|
|
1584
|
+
initializeApp();
|
|
1585
|
+
}
|
|
970
1586
|
|
|
971
1587
|
document.addEventListener("visibilitychange", () => {
|
|
972
1588
|
if (document.hidden) {
|
|
973
|
-
|
|
1589
|
+
Solitude.wasPageHidden = true;
|
|
974
1590
|
}
|
|
975
1591
|
});
|
|
976
1592
|
|
|
@@ -980,13 +1596,13 @@ window.onkeydown = (e) => {
|
|
|
980
1596
|
code === "F12" ||
|
|
981
1597
|
(ctrlKey && shiftKey && (code === "KeyI" || code === "KeyC"))
|
|
982
1598
|
) {
|
|
983
|
-
|
|
1599
|
+
Solitude.snackbarShow(Solitude.config.lang.f12, false, 3000);
|
|
984
1600
|
}
|
|
985
1601
|
if (code === "Escape") {
|
|
986
|
-
|
|
1602
|
+
Solitude.hideConsole();
|
|
987
1603
|
}
|
|
988
1604
|
};
|
|
989
1605
|
|
|
990
1606
|
document.addEventListener("copy", () => {
|
|
991
|
-
|
|
1607
|
+
Solitude.snackbarShow(Solitude.config.lang.copy.success, false, 3000);
|
|
992
1608
|
});
|