yggdrasil/index.html
xfy 5ecaf86879 feat(web): 设置网站 favicon
Dioxus.toml 的 [web.app] 无 favicon 配置项,dx CLI 默认 shell 也不注入
<link rel="icon">。新增 index.html 自定义 shell(复制自 dx 默认模板,含
toast 基础设施),加上 favicon 链接。<title> 留空由 [web.app] title 注入,
避免重复。favicon.ico 放 public/ 根目录随静态资源分发。
2026-07-01 17:00:58 +08:00

242 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!--
自定义 HTML shell替代 dx CLI 默认模板)。
存在的唯一原因:注入 favicon<link rel="icon">Dioxus.toml 的 [web.app]
没有提供 favicon 配置项。
注意:本文件复制自 dx CLI 生成的默认 shell含 toast 基础设施 JS/CSS
因此升级 dioxus-cli 后如 toast 行为有变,需重新从 `target/dx/.../index.html`
抓取默认模板并重新加上 favicon 链接。<title> 留空,由 [web.app] title 注入。
-->
<html>
<head>
<title></title>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<style>
/* Inter Font */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap') layer;
#dx-toast-template {
display: none;
visibility: hidden;
}
.dx-toast {
position: absolute;
top: 10px;
right: 0;
padding-right: 10px;
user-select: none;
/* transition: transform 0.2s ease; */
z-index: 2147483647;
}
.dx-toast .dx-toast-inner {
/* transition: right 0.2s ease-out; */
position: fixed;
background-color: #181B20;
color: #ffffff;
font-family: "Inter", sans-serif;
display: grid;
grid-template-columns: auto auto;
max-width: 400px;
min-height: 56px;
border-radius: 5px;
}
.dx-toast .dx-toast-inner {
cursor: pointer;
margin-right: 10px;
}
.dx-toast .dx-toast-level-bar-container {
height: 100%;
width: 6px;
}
.dx-toast .dx-toast-level-bar-container .dx-toast-level-bar {
width: 100%;
height: 100%;
border-radius: 5px 0px 0px 5px;
}
.dx-toast .dx-toast-content {
padding: 8px;
}
.dx-toast .dx-toast-header {
display: flex;
flex-direction: row;
justify-content: start;
align-items: end;
margin-bottom: 10px;
}
.dx-toast .dx-toast-header>svg {
height: 18px;
margin-right: 5px;
}
.dx-toast .dx-toast-header .dx-toast-header-text {
font-size: 14px;
font-weight: 700;
padding: 0;
margin: 0;
}
.dx-toast .dx-toast-msg {
font-size: 11px;
font-weight: 400;
padding: 0;
margin: 0;
}
.dx-toast-level-bar.info {
background-color: #428EFF;
}
.dx-toast-level-bar.success {
background-color: #42FF65;
}
.dx-toast-level-bar.error {
background-color: #FF4242;
}
</style>
<script>
const STORAGE_KEY = "SCHEDULED-DX-TOAST";
let currentTimeout = null;
let currentToastId = 0;
// Show a toast, removing the previous one.
function showDXToast(headerText, message, progressLevel, durationMs) {
const decor = document.getElementById("__dx-toast-decor");
const text = document.getElementById("__dx-toast-text");
const msg = document.getElementById("__dx-toast-msg");
const inner = document.getElementById("__dx-toast-inner");
const toast = document.getElementById("__dx-toast");
if (decor) decor.className = `dx-toast-level-bar ${progressLevel}`;
if (text) text.innerText = headerText;
if (msg) msg.innerText = message;
if (inner) inner.style.right = "0";
if (toast) {
toast.removeAttribute("aria-hidden");
toast.addEventListener("click", closeDXToast);
}
// Wait a bit of time so animation plays correctly.
setTimeout(
() => {
let ourToastId = currentToastId;
currentTimeout = setTimeout(() => {
if (ourToastId == currentToastId) {
closeDXToast();
}
}, durationMs);
},
100
);
currentToastId += 1;
}
// Schedule a toast to be displayed after reload.
function scheduleDXToast(headerText, message, level, durationMs) {
let data = {
headerText,
message,
level,
durationMs,
};
let jsonData = JSON.stringify(data);
sessionStorage.setItem(STORAGE_KEY, jsonData);
}
// Close the current toast.
function closeDXToast() {
document.getElementById("__dx-toast-inner").style.right = "-1000px";
document.getElementById("__dx-toast").setAttribute("aria-hidden", "true");
clearTimeout(currentTimeout);
}
// Handle any scheduled toasts after reload.
let potentialData = sessionStorage.getItem(STORAGE_KEY);
if (potentialData) {
sessionStorage.removeItem(STORAGE_KEY);
let data = JSON.parse(potentialData);
showDXToast(data.headerText, data.message, data.level, data.durationMs);
}
window.scheduleDXToast = scheduleDXToast;
window.showDXToast = showDXToast;
window.closeDXToast = closeDXToast;
</script>
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="/highlight.css">
<link rel="stylesheet" href="/tiptap/editor.css">
<link rel="stylesheet" href="/lightbox/lightbox.css">
<link rel="stylesheet" href="/yggdrasil-core/yggdrasil-core.css">
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="/highlight.css">
<link rel="stylesheet" href="/tiptap/editor.css">
<link rel="stylesheet" href="/lightbox/lightbox.css">
<link rel="stylesheet" href="/yggdrasil-core/yggdrasil-core.css">
<script src="/tiptap/editor.js"></script>
<script src="/codemirror/editor.js"></script>
<script src="/lightbox/lightbox.js"></script>
<script src="/yggdrasil-core/yggdrasil-core.js"></script>
<script src="/tiptap/editor.js"></script>
<script src="/codemirror/editor.js"></script>
<script src="/lightbox/lightbox.js"></script>
<script src="/yggdrasil-core/yggdrasil-core.js"></script>
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="/highlight.css">
<link rel="stylesheet" href="/tiptap/editor.css">
<link rel="stylesheet" href="/lightbox/lightbox.css">
<link rel="stylesheet" href="/yggdrasil-core/yggdrasil-core.css">
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="/highlight.css">
<link rel="stylesheet" href="/tiptap/editor.css">
<link rel="stylesheet" href="/lightbox/lightbox.css">
<link rel="stylesheet" href="/yggdrasil-core/yggdrasil-core.css">
<script src="/tiptap/editor.js"></script>
<script src="/codemirror/editor.js"></script>
<script src="/lightbox/lightbox.js"></script>
<script src="/yggdrasil-core/yggdrasil-core.js"></script>
<script src="/tiptap/editor.js"></script>
<script src="/codemirror/editor.js"></script>
<script src="/lightbox/lightbox.js"></script>
<script src="/yggdrasil-core/yggdrasil-core.js"></script>
</head>
<body>
<div id="__dx-toast" class="dx-toast" aria-hidden="true">
<div id="__dx-toast-inner" class="dx-toast-inner" style="right:-1000px;">
<div class="dx-toast-level-bar-container">
<div id="__dx-toast-decor" class="dx-toast-level-bar __info"></div>
</div>
<div class="dx-toast-content">
<div class="dx-toast-header">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" preserveAspectRatio="none">
<path d="M22.158 1.783c0 3.077-.851 5.482-2.215 7.377s-3.32 3.557-5.447 5.33-4.425 3.657-6.252 6.195-3.102 5.515-3.102 9.532h4.699c0-3.077.853-5.377 2.217-7.272s3.32-3.557 5.447-5.33 4.425-3.657 6.252-6.195 3.102-5.62 3.102-9.637z" fill="#e96020"/>
<path d="M9.531 25.927c-.635 0-1.021.515-1.02 1.15s.385 1.151 1.02 1.15H22.47a1.151 1.151 0 1 0 0-2.301zm1.361-4.076c-.608 0-.954.558-.953 1.166s.346 1.035.953 1.035h10.217a1.101 1.101 0 1 0 0-2.201zm0-13.594a1.101 1.101 0 1 0 0 2.201h10.217c.607 0 .953-.598.953-1.205s-.345-.996-.953-.996zM9.531 4.021A1.15 1.15 0 0 0 8.38 5.17a1.15 1.15 0 0 0 1.15 1.15h12.94c.635 0 1.021-.498 1.02-1.133s-.386-1.166-1.02-1.166z" fill="#2d323b"/>
<path d="M5.142 1.783c0 4.016 1.275 7.099 3.102 9.637s4.125 4.422 6.252 6.195 4.083 3.656 5.447 5.551 2.215 3.974 2.215 7.051h4.701c0-4.016-1.275-7.038-3.102-9.576s-4.125-4.422-6.252-6.195-4.083-3.435-5.447-5.33S9.841 4.86 9.841 1.783z" fill="#00a8d6"/>
</svg>
<h3 id="__dx-toast-text" class="dx-toast-header-text">Your app is being rebuilt.</h3>
</div>
<p id="__dx-toast-msg" class="dx-toast-msg">A non-hot-reloadable change occurred and we must rebuild.</p>
</div>
</div>
</div>
<div id="main"></div>
<script type="module" async src="/./wasm/yggdrasil.js"></script>
<script type="module" async src="/./wasm/yggdrasil.js"></script>
</body>
</html>