Skip to content

Commit f6768dc

Browse files
committed
Merge branch 'master' of https://github.com/LyraVoid/Mizuki
2 parents 2f11798 + 015d5ef commit f6768dc

47 files changed

Lines changed: 3521 additions & 943 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

public/pio/l2d-widget.min.js

Lines changed: 689 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/pio/live2d-host.html

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<style>
5+
* { margin: 0; padding: 0; }
6+
html, body { width: 100%; height: 100%; overflow: hidden; background: transparent; }
7+
</style>
8+
</head>
9+
<body>
10+
<script src="/pio/l2d-widget.min.js"></script>
11+
<script>
12+
var menuActions = {
13+
home: function() { parent.postMessage({ type: 'l2d-action', action: 'home' }, '*'); },
14+
scrollToTop: function() { parent.postMessage({ type: 'l2d-action', action: 'scrollToTop' }, '*'); },
15+
sleep: function(w) { w.sleep(); },
16+
};
17+
18+
window.addEventListener('message', function(e) {
19+
if (e.data.type !== 'l2d-init') return;
20+
var config = e.data.config;
21+
22+
if (config.menus && config.menus.items) {
23+
config.menus.items = config.menus.items.map(function(item) {
24+
return {
25+
icon: item.icon,
26+
label: item.label,
27+
onClick: menuActions[item.action] || function() {}
28+
};
29+
});
30+
}
31+
32+
L2D_WIDGET.createWidget(config);
33+
34+
if (config._hideAbout) {
35+
var style = document.createElement('style');
36+
style.textContent = 'button[title="About"] { display: none !important; }';
37+
document.head.appendChild(style);
38+
}
39+
40+
var notified = false;
41+
function notifyLoaded() {
42+
if (notified) return;
43+
notified = true;
44+
45+
var maxBottom = 0;
46+
document.querySelectorAll('*').forEach(function(el) {
47+
if (el.getBoundingClientRect) {
48+
var r = el.getBoundingClientRect();
49+
if (r.width > 0 && r.height > 0 && r.bottom > maxBottom) {
50+
maxBottom = r.bottom;
51+
}
52+
}
53+
});
54+
55+
parent.postMessage({ type: 'l2d-loaded', contentHeight: Math.ceil(maxBottom) || 500 }, '*');
56+
}
57+
58+
var checkInterval = setInterval(function() {
59+
var canvas = document.querySelector('canvas');
60+
if (canvas && canvas.width > 0 && canvas.height > 0) {
61+
clearInterval(checkInterval);
62+
setTimeout(notifyLoaded, 300);
63+
}
64+
}, 200);
65+
66+
setTimeout(function() {
67+
clearInterval(checkInterval);
68+
notifyLoaded();
69+
}, 15000);
70+
});
71+
</script>
72+
</body>
73+
</html>

src/components/control/LayoutSwitch.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ function handleMediaQueryChange(e: MediaQueryListEvent | MediaQueryList) {
7070
onMount(() => {
7171
mounted = true;
7272
73-
const sessionLayout = getSavedSessionLayout();
73+
const layoutEnabled = siteConfig.postListLayout?.enable ?? true;
74+
const sessionLayout = layoutEnabled ? getSavedSessionLayout() : null;
7475
const defaultLayout = siteConfig.postListLayout.defaultMode as LayoutMode;
7576
7677
if (sessionLayout === "list" || sessionLayout === "grid") {
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
import type { PioConfig } from "@/types/config";
3+
4+
interface Props {
5+
config: PioConfig;
6+
}
7+
8+
const { config } = Astro.props;
9+
10+
const modelPaths = config.models ?? ["/pio/models/NOIR/noir.model3.json"];
11+
const modelConfigs = modelPaths.map((p) => ({ path: p }));
12+
13+
const position = config.position === "right" ? "bottom-right" : "bottom-left";
14+
15+
const tipsData: Record<string, unknown> = {};
16+
if (config.tips) {
17+
if (config.tips.welcomeMessage)
18+
tipsData.welcomeMessage = config.tips.welcomeMessage;
19+
if (config.tips.messages) tipsData.messages = config.tips.messages;
20+
if (config.tips.duration) tipsData.duration = config.tips.duration;
21+
if (config.tips.interval) tipsData.interval = tipsData.interval;
22+
} else if (config.dialog?.welcome || config.dialog?.touch) {
23+
const welcome = config.dialog.welcome;
24+
const touch = config.dialog.touch;
25+
if (welcome)
26+
tipsData.welcomeMessage = Array.isArray(welcome) ? welcome : [welcome];
27+
if (touch) tipsData.messages = Array.isArray(touch) ? touch : [touch];
28+
}
29+
30+
const widgetConfig: Record<string, unknown> = {
31+
model: modelConfigs.length === 1 ? modelConfigs[0] : modelConfigs,
32+
position,
33+
size: config.width ?? 280,
34+
transitionDuration: 1500,
35+
transitionType: "slide",
36+
_hideAbout: config.hideAboutMenu ?? true,
37+
};
38+
39+
if (config.menus?.items && config.menus.items.length > 0) {
40+
widgetConfig.menus = {
41+
items: config.menus.items.map(({ icon, label, action }) => ({
42+
icon,
43+
label,
44+
action,
45+
})),
46+
...(config.menus.align && { align: config.menus.align }),
47+
};
48+
}
49+
50+
if (Object.keys(tipsData).length > 0) {
51+
if (!Array.isArray(widgetConfig.model)) {
52+
(widgetConfig.model as Record<string, unknown>).tips = tipsData;
53+
}
54+
}
55+
56+
const widgetWidth = config.width ?? 280;
57+
const hiddenOnMobile = config.hiddenOnMobile ?? true;
58+
const isRight = config.position === "right";
59+
---
60+
61+
<iframe
62+
id="l2d-iframe"
63+
src="/pio/live2d-host.html"
64+
allowtransparency="true"
65+
style={"position: fixed; z-index: 999; pointer-events: none; border: none; bottom: 0;"
66+
+ (isRight ? " right: 0;" : " left: 0;")
67+
+ " width: " + widgetWidth + "px;"
68+
+ " height: 600px;"
69+
+ " opacity: 0;"}
70+
data-config={JSON.stringify(widgetConfig)}
71+
data-hidden-on-mobile={hiddenOnMobile ? "true" : "false"}
72+
data-width={widgetWidth}
73+
></iframe>
74+
75+
<script>
76+
const el = document.getElementById("l2d-iframe") as HTMLIFrameElement;
77+
if (!el) throw new Error("l2d-iframe not found");
78+
79+
const menuActions: Record<string, () => void> = {
80+
home: () => (window.location.href = "/"),
81+
scrollToTop: () => window.scrollTo({ top: 0, behavior: "smooth" }),
82+
};
83+
84+
const config = JSON.parse(el.dataset.config || "{}");
85+
const hiddenOnMobile = el.dataset.hiddenOnMobile === "true";
86+
let isTransitioning = false;
87+
88+
function applyVisibility() {
89+
if (hiddenOnMobile && window.innerWidth <= 1280) {
90+
el.style.display = "none";
91+
} else {
92+
el.style.display = "";
93+
}
94+
}
95+
96+
function sendInit() {
97+
if (isTransitioning) return;
98+
if (hiddenOnMobile && window.innerWidth <= 1280) return;
99+
el.contentWindow?.postMessage({ type: "l2d-init", config }, "*");
100+
}
101+
102+
function handleMessage(e: MessageEvent) {
103+
if (e.source !== el.contentWindow) return;
104+
105+
if (e.data.type === "l2d-loaded") {
106+
const h = e.data.contentHeight || 500;
107+
el.style.height = h + "px";
108+
el.style.opacity = "1";
109+
el.style.pointerEvents = "auto";
110+
}
111+
112+
if (e.data.type === "l2d-action") {
113+
menuActions[e.data.action]?.();
114+
}
115+
}
116+
117+
window.addEventListener("message", handleMessage);
118+
119+
if (el.contentDocument?.readyState === "complete") {
120+
sendInit();
121+
} else {
122+
el.addEventListener("load", sendInit);
123+
}
124+
125+
function setupSwupHooks() {
126+
if (!window.swup?.hooks) return;
127+
128+
const hooks = window.swup as unknown as {
129+
hooks: { on: (event: string, handler: (...args: unknown[]) => void) => void };
130+
};
131+
132+
hooks.hooks.on("link:click", () => {
133+
isTransitioning = true;
134+
});
135+
136+
hooks.hooks.on("visit:end", () => {
137+
isTransitioning = false;
138+
});
139+
}
140+
141+
if (window.swup) {
142+
setupSwupHooks();
143+
} else {
144+
document.addEventListener("swup:enable", setupSwupHooks);
145+
}
146+
147+
applyVisibility();
148+
149+
window.addEventListener("resize", () => {
150+
applyVisibility();
151+
});
152+
</script>

src/components/features/pio/Pio.svelte

Lines changed: 0 additions & 152 deletions
This file was deleted.
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
export { default as Pio } from "./Pio.svelte";
2-
export * from "./types";
1+
export { default as Pio } from "./Pio.astro";

0 commit comments

Comments
 (0)