mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-02-18 04:58:06 +01:00
🎨 Improve error window information layout (#16735)
This commit is contained in:
parent
76267fd782
commit
7221367334
2 changed files with 203 additions and 124 deletions
|
|
@ -3,12 +3,14 @@
|
|||
<head>
|
||||
<title>Error - SiYuan</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #fff;
|
||||
color: #202124;
|
||||
font-family: "Helvetica Neue", "Luxi Sans", "DejaVu Sans", "Hiragino Sans GB", "Microsoft Yahei", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", "EmojiSymbols";
|
||||
font-family: BlinkMacSystemFont, "Helvetica Neue", "Luxi Sans", "DejaVu Sans", "Hiragino Sans GB", "Microsoft Yahei", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", "EmojiSymbols";
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.fn__flex-column {
|
||||
|
|
@ -28,12 +30,71 @@
|
|||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.title-container {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.title-emoji {
|
||||
font-size: 40px;
|
||||
line-height: 50px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.title-line {
|
||||
font-size: 24px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0 0 4px 0;
|
||||
line-height: 24px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#content div {
|
||||
line-height: 1.6;
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid rgba(0, 0, 0, .06);
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
font-size: 14px;
|
||||
color: #5f6368;
|
||||
}
|
||||
|
||||
.info-section div:not(:last-child) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.feedback {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #218bff;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
color: #0969da;
|
||||
}
|
||||
|
||||
.svg {
|
||||
position: fixed;
|
||||
right: 32px;
|
||||
|
|
@ -61,52 +122,9 @@
|
|||
fill: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #218bff;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
color: #0969da;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 2px 4px;
|
||||
font: 75% Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
line-height: 1;
|
||||
color: #5f6368;
|
||||
vertical-align: middle;
|
||||
background-color: #f3f3f3;
|
||||
border: solid 1px rgba(0, 0, 0, .06);
|
||||
border-radius: 6px;
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .06);
|
||||
}
|
||||
|
||||
.feedback {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.drag {
|
||||
-webkit-app-region: drag;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 44px;
|
||||
}
|
||||
|
||||
#content div {
|
||||
line-height: 1.6;
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
#content div:last-child {
|
||||
margin-bottom: 0;
|
||||
.darwin #min,
|
||||
.darwin #close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#icon {
|
||||
|
|
@ -117,40 +135,99 @@
|
|||
color: #5f6368;
|
||||
}
|
||||
|
||||
.darwin #icon {
|
||||
left: 74px;
|
||||
}
|
||||
|
||||
#icon img {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
padding: 8px 16px;
|
||||
font-size: 85%;
|
||||
font-family: mononoki, Consolas, "Liberation Mono", Menlo, Courier, monospace, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", "EmojiSymbols";
|
||||
color: #5f6368;
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
word-break: break-all;
|
||||
white-space: pre-wrap;
|
||||
.drag {
|
||||
-webkit-app-region: drag;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 64px;
|
||||
}
|
||||
|
||||
.darwin .drag {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #1e1e1e;
|
||||
color: #e4e4e4;
|
||||
}
|
||||
|
||||
.fn__flex-column {
|
||||
border: 1px solid rgba(255, 255, 255, .1);
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid rgba(255, 255, 255, .1);
|
||||
}
|
||||
|
||||
.info-section {
|
||||
color: #9aa0a6;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #58a6ff;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #79c0ff;
|
||||
}
|
||||
|
||||
.svg {
|
||||
fill: #9aa0a6;
|
||||
}
|
||||
|
||||
.svg:hover {
|
||||
background: #3c3c3c;
|
||||
fill: #e4e4e4;
|
||||
}
|
||||
|
||||
#close:hover {
|
||||
background-color: #d23f31;
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
#icon {
|
||||
color: #9aa0a6;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="fn__flex-column">
|
||||
<div class="fn__flex-1"></div>
|
||||
<h2 id="title"></h2>
|
||||
<div id="title" class="title-container">
|
||||
<span class="title-emoji" id="titleEmoji"></span>
|
||||
<div class="title-text">
|
||||
<h2 class="title-line" id="titleZh"></h2>
|
||||
<h2 class="title-line" id="titleEn"></h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fn__flex-1"></div>
|
||||
<div id="content"></div>
|
||||
<hr>
|
||||
<div class="info-section">
|
||||
<div id="time"></div>
|
||||
<div id="systemInfo"></div>
|
||||
</div>
|
||||
<div class="fn__flex-1"></div>
|
||||
<div class="feedback">
|
||||
<span><a href="https://ld246.com/article/1649901726096" target="_blank">求助反馈建议</a></span>
|
||||
<span><a href="https://b3log.org/siyuan/download.html" target="_blank">下载最新版</a></span>
|
||||
</div>
|
||||
<div class="feedback">
|
||||
<span><a href="https://liuyun.io/article/1686530886208" target="_blank">Feedback and support</a></span>
|
||||
<span><a href="https://b3log.org/siyuan/en/download.html" target="_blank">Download the latest version</a></span>
|
||||
<a href="https://ld246.com/article/1649901726096" target="_blank">求助反馈建议</a>
|
||||
<a href="https://b3log.org/siyuan/download.html" target="_blank">下载最新版</a>
|
||||
<a href="https://liuyun.io/article/1686530886208" target="_blank">Feedback and support</a>
|
||||
<a href="https://b3log.org/siyuan/en/download.html" target="_blank">Download the latest version</a>
|
||||
</div>
|
||||
<div class="fn__flex-1"></div>
|
||||
</div>
|
||||
|
|
@ -163,58 +240,58 @@
|
|||
<div id="icon"></div>
|
||||
<div class="drag"></div>
|
||||
<script>
|
||||
const getSearch = (key) => {
|
||||
if (window.location.search.indexOf('?') === -1) {
|
||||
return ''
|
||||
}
|
||||
let value = ''
|
||||
const data = window.location.search.split('?')[1].split('&')
|
||||
data.find(item => {
|
||||
const keyValue = item.split('=')
|
||||
if (keyValue[0] === key) {
|
||||
value = keyValue[1]
|
||||
return true
|
||||
}
|
||||
})
|
||||
return value
|
||||
'use strict';
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
// 窗口控制按钮
|
||||
if (process.platform === 'darwin') {
|
||||
document.body.classList.add('darwin');
|
||||
}
|
||||
document.getElementById('close').addEventListener('click', () => {
|
||||
const {ipcRenderer} = require('electron');
|
||||
ipcRenderer.send("siyuan-cmd", "destroy");
|
||||
});
|
||||
document.getElementById('min').addEventListener('click', () => {
|
||||
const {ipcRenderer} = require('electron');
|
||||
ipcRenderer.send("siyuan-cmd", "minimize");
|
||||
});
|
||||
|
||||
(() => {
|
||||
if (process.platform === 'darwin') {
|
||||
document.getElementById('min').style.display = 'none';
|
||||
document.getElementById('close').style.display = 'none';
|
||||
document.querySelector('.drag').style.right = '0';
|
||||
document.querySelector('#icon').style.left = '74px';
|
||||
} else {
|
||||
document.querySelector('#icon').style.right = '70px';
|
||||
}
|
||||
// LOGO和版本号
|
||||
const version = 'SiYuan v' + params.get('v') || '';
|
||||
document.querySelector('#icon').innerHTML = `<img src="${params.get('icon') || ''}" alt="SiYuan LOGO"> ${version}`;
|
||||
|
||||
const os = require('os')
|
||||
const platformMap = {
|
||||
'darwin': 'macOS',
|
||||
'win32': 'Windows',
|
||||
'linux': 'Linux'
|
||||
}
|
||||
const platform = platformMap[process.platform] || process.platform
|
||||
const release = os.release()
|
||||
const arch = os.arch()
|
||||
const cpus = os.cpus()
|
||||
const cpuModel = cpus.length > 0 ? cpus[0].model : ''
|
||||
const systemInfo = `· ${platform} ${release} · ${arch} · ${cpuModel}`
|
||||
document.querySelector('#icon').innerHTML = `<img src="${decodeURIComponent(getSearch('icon'))}"> SiYuan v${getSearch('v')} ${systemInfo}`
|
||||
// 标题
|
||||
document.getElementById('titleEmoji').textContent = params.get('emoji') || '⚠️';
|
||||
document.getElementById('titleZh').textContent = params.get('titleZh') || '';
|
||||
document.getElementById('titleEn').textContent = params.get('titleEn') || '';
|
||||
|
||||
document.getElementById('title').innerHTML = decodeURIComponent(getSearch('title'))
|
||||
document.getElementById('content').innerHTML = decodeURIComponent(getSearch('content'))
|
||||
// 内容
|
||||
document.getElementById('content').innerHTML = params.get('content') || '';
|
||||
|
||||
document.getElementById('close').addEventListener('click', () => {
|
||||
const {ipcRenderer} = require('electron')
|
||||
ipcRenderer.send("siyuan-cmd", "destroy");
|
||||
})
|
||||
document.getElementById('min').addEventListener('click', () => {
|
||||
const {ipcRenderer} = require('electron')
|
||||
ipcRenderer.send("siyuan-cmd", "minimize");
|
||||
})
|
||||
})()
|
||||
// 时间信息
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const hours = String(now.getHours()).padStart(2, '0');
|
||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
const timeString = `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
|
||||
document.getElementById('time').innerHTML = timeString;
|
||||
|
||||
// 系统信息
|
||||
const os = require('os');
|
||||
const platformMap = {
|
||||
'darwin': 'macOS',
|
||||
'win32': 'Windows',
|
||||
'linux': 'Linux'
|
||||
};
|
||||
const platform = platformMap[process.platform] || process.platform;
|
||||
const release = os.release();
|
||||
const arch = os.arch();
|
||||
const cpus = os.cpus();
|
||||
const cpuModel = cpus[0]?.model || '';
|
||||
document.getElementById('systemInfo').innerHTML = `${version} · ${platform} ${release} · ${arch} · ${cpuModel}`;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ const sleep = (ms) => {
|
|||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
};
|
||||
|
||||
const showErrorWindow = (title, content) => {
|
||||
const showErrorWindow = (titleZh, titleEn, content, emoji = "⚠️") => {
|
||||
let errorHTMLPath = path.join(appDir, "app", "electron", "error.html");
|
||||
if (isDevEnv) {
|
||||
errorHTMLPath = path.join(appDir, "electron", "error.html");
|
||||
|
|
@ -226,7 +226,9 @@ const showErrorWindow = (title, content) => {
|
|||
query: {
|
||||
home: app.getPath("home"),
|
||||
v: appVer,
|
||||
title: title,
|
||||
titleZh: titleZh,
|
||||
titleEn: titleEn,
|
||||
emoji: emoji,
|
||||
content: content,
|
||||
icon: path.join(appDir, "stage", "icon-large.png"),
|
||||
},
|
||||
|
|
@ -516,7 +518,7 @@ const initKernel = (workspace, port, lang) => {
|
|||
const kernelName = "win32" === process.platform ? "SiYuan-Kernel.exe" : "SiYuan-Kernel";
|
||||
const kernelPath = path.join(appDir, "kernel", kernelName);
|
||||
if (!fs.existsSync(kernelPath)) {
|
||||
showErrorWindow("⚠️ 内核程序丢失 Kernel program is missing", `<div>内核程序丢失,请重新安装思源,并将思源内核程序加入杀毒软件信任列表。</div><div>The kernel program is not found, please reinstall SiYuan and add SiYuan Kernel prgram into the trust list of your antivirus software.</div><div><i>${kernelPath}</i></div>`);
|
||||
showErrorWindow("内核程序丢失", "Kernel program is missing", `<div>内核程序丢失,请重新安装思源,并将思源内核程序加入杀毒软件信任列表。</div><div>The kernel program is not found, please reinstall SiYuan and add SiYuan Kernel prgram into the trust list of your antivirus software.</div><div><i>${kernelPath}</i></div>`);
|
||||
bootWindow.destroy();
|
||||
resolve(false);
|
||||
return;
|
||||
|
|
@ -580,28 +582,28 @@ const initKernel = (workspace, port, lang) => {
|
|||
let errorWindowId;
|
||||
switch (code) {
|
||||
case 20:
|
||||
errorWindowId = showErrorWindow("⚠️ 数据库被锁定 The database is locked", "<div>数据库文件正在被其他进程占用,请检查是否同时存在多个内核进程(SiYuan Kernel)服务相同的工作空间。</div><div>The database file is being occupied by other processes, please check whether there are multiple kernel processes (SiYuan Kernel) serving the same workspace at the same time.</div>");
|
||||
errorWindowId = showErrorWindow("数据库被锁定", "The database is locked", "<div>数据库文件正在被其他进程占用,请检查是否同时存在多个内核进程(SiYuan Kernel)服务相同的工作空间。</div><div>The database file is being occupied by other processes, please check whether there are multiple kernel processes (SiYuan Kernel) serving the same workspace at the same time.</div>");
|
||||
break;
|
||||
case 21:
|
||||
errorWindowId = showErrorWindow("⚠️ 监听端口 " + currentKernelPort + " 失败 Failed to listen to port " + currentKernelPort, "<div>监听 " + currentKernelPort + " 端口失败,请确保程序拥有网络权限并不受防火墙和杀毒软件阻止。</div><div>Failed to listen to port " + currentKernelPort + ", please make sure the program has network permissions and is not blocked by firewalls and antivirus software.</div>");
|
||||
errorWindowId = showErrorWindow("监听端口 " + currentKernelPort + " 失败", "Failed to listen to port " + currentKernelPort, "<div>监听 " + currentKernelPort + " 端口失败,请确保程序拥有网络权限并不受防火墙和杀毒软件阻止。</div><div>Failed to listen to port " + currentKernelPort + ", please make sure the program has network permissions and is not blocked by firewalls and antivirus software.</div>");
|
||||
break;
|
||||
case 24: // 工作空间已被锁定,尝试切换到第一个打开的工作空间
|
||||
if (workspaces && 0 < workspaces.length) {
|
||||
showWindow(workspaces[0].browserWindow);
|
||||
}
|
||||
|
||||
errorWindowId = showErrorWindow("⚠️ 工作空间已被锁定 The workspace is locked", "<div>该工作空间正在被使用,请尝试在任务管理器中结束 SiYuan-Kernel 进程或者重启操作系统后再启动思源。</div><div>The workspace is being used, please try to end the SiYuan-Kernel process in the task manager or restart the operating system and then start SiYuan.</div>");
|
||||
errorWindowId = showErrorWindow("工作空间已被锁定", "The workspace is locked", "<div>该工作空间正在被使用,请尝试在任务管理器中结束 SiYuan-Kernel 进程或者重启操作系统后再启动思源。</div><div>The workspace is being used, please try to end the SiYuan-Kernel process in the task manager or restart the operating system and then start SiYuan.</div>");
|
||||
break;
|
||||
case 25:
|
||||
errorWindowId = showErrorWindow("⚠️ 初始化工作空间失败 Failed to create workspace directory", "<div>初始化工作空间失败。</div><div>Failed to init workspace.</div>");
|
||||
errorWindowId = showErrorWindow("初始化工作空间失败", "Failed to create workspace directory", "<div>初始化工作空间失败。</div><div>Failed to init workspace.</div>");
|
||||
break;
|
||||
case 26:
|
||||
errorWindowId = showErrorWindow("🚒 已成功避免潜在的数据损坏<br>Successfully avoid potential data corruption", "<div>工作空间下的文件正在被第三方软件(比如同步网盘、杀毒软件等)打开占用,继续使用会导致数据损坏,思源内核已经安全退出。<br><br>请将工作空间移动到其他路径后再打开,停止同步盘同步工作空间,并将工作空间加入杀毒软件信任列表。如果以上步骤无法解决问题,请参考<a href=\"https://ld246.com/article/1684586140917\" target=\"_blank\">这里</a>或者<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">发帖</a>寻求帮助。</div><hr><div>The files in the workspace are being opened and occupied by third-party software (such as synchronized network disk, antivirus software, etc.), continuing to use it will cause data corruption, and the SiYuan Kernel is already safe shutdown.<br><br>Move the workspace to another path and open it again, stop the network disk to sync the workspace, and add the workspace to the antivirus software trust list. If the above steps do not resolve the issue, please look for help or report bugs <a href=\"https://liuyun.io/article/1686530886208\" target=\"_blank\">here</a>.</div>");
|
||||
errorWindowId = showErrorWindow("已成功避免潜在的数据损坏", "Successfully avoid potential data corruption", "<div>工作空间下的文件正在被第三方软件(比如同步网盘、杀毒软件等)打开占用,继续使用会导致数据损坏,思源内核已经安全退出。</div><div>请将工作空间移动到其他路径后再打开,停止同步盘同步工作空间,并将工作空间加入杀毒软件信任列表。如果以上步骤无法解决问题,请参考<a href=\"https://ld246.com/article/1684586140917\" target=\"_blank\">这里</a>或者<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">发帖</a>寻求帮助。</div><div>The files in the workspace are being opened and occupied by third-party software (such as synchronized network disk, antivirus software, etc.), continuing to use it will cause data corruption, and the SiYuan Kernel is already safe shutdown.</div><div>Move the workspace to another path and open it again, stop the network disk to sync the workspace, and add the workspace to the antivirus software trust list. If the above steps do not resolve the issue, please look for help or report bugs <a href=\"https://liuyun.io/article/1686530886208\" target=\"_blank\">here</a>.</div>", "🚒");
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
errorWindowId = showErrorWindow("⚠️ 内核因未知原因退出 The kernel exited for unknown reasons", `<div>思源内核因未知原因退出 [code=${code}],请尝试重启操作系统后再启动思源。如果该问题依然发生,请检查杀毒软件是否阻止思源内核启动。</div><div>SiYuan Kernel exited for unknown reasons [code=${code}], please try to reboot your operating system and then start SiYuan again. If occurs this problem still, please check your anti-virus software whether kill the SiYuan Kernel.</div>`);
|
||||
errorWindowId = showErrorWindow("内核因未知原因退出", "The kernel exited for unknown reasons", `<div>思源内核因未知原因退出 [code=${code}],请尝试重启操作系统后再启动思源。如果该问题依然发生,请检查杀毒软件是否阻止思源内核启动。</div><div>SiYuan Kernel exited for unknown reasons [code=${code}], please try to reboot your operating system and then start SiYuan again. If occurs this problem still, please check your anti-virus software whether kill the SiYuan Kernel.</div>`);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -625,7 +627,7 @@ const initKernel = (workspace, port, lang) => {
|
|||
writeLog("get kernel version failed: " + e.message);
|
||||
if (14 < ++count) {
|
||||
writeLog("get kernel ver failed");
|
||||
showErrorWindow("⚠️ 获取内核服务端口失败 Failed to Obtain Kernel Service Port", "<div>获取内核服务端口失败,请确保程序拥有网络权限并不受防火墙和杀毒软件阻止。</div><div>Failed to obtain kernel service port. Please ensure SiYuan has network permissions and is not blocked by firewalls or antivirus software.</div>");
|
||||
showErrorWindow("获取内核服务端口失败", "Failed to Obtain Kernel Service Port", "<div>获取内核服务端口失败,请确保程序拥有网络权限并不受防火墙和杀毒软件阻止。</div><div>Failed to obtain kernel service port. Please ensure SiYuan has network permissions and is not blocked by firewalls or antivirus software.</div>");
|
||||
bootWindow.destroy();
|
||||
resolve(false);
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue