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/ 根目录随静态资源分发。
This commit is contained in:
parent
afa6bf892e
commit
5ecaf86879
241
index.html
Normal file
241
index.html
Normal file
@ -0,0 +1,241 @@
|
||||
<!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>
|
||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Loading…
x
Reference in New Issue
Block a user