siyuan/app/electron/init.html

473 lines
16 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>
<head>
<title>SiYuan</title>
<meta charset="UTF-8">
<style>
body {
margin: 0;
background-color: #fff;
text-align: center;
color: #202124;
user-select: none;
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";
}
.fn__flex-column {
display: flex;
flex-direction: column;
width: 100%;
margin: 0 auto;
border: 1px solid rgba(0, 0, 0, .06);
min-height: 100vh;
box-sizing: border-box;
padding: 0 calc((100vw - 608px) * 0.3);
}
.fn__flex-1 {
flex: 1;
min-height: 16px;
flex-shrink: 0;
}
h2 {
margin: 0 0 12px 0;
line-height: 24px;
}
.b3-select {
border: 1px solid rgba(0, 0, 0, .06);
border-radius: 6px;
padding: 4px 8px;
line-height: 20px;
box-sizing: border-box;
color: #202124;
transition: box-shadow 120ms 0ms cubic-bezier(0, 0, 0.2, 1);
background-color: #fff;
height: 28px;
font-size: 14px;
width: 96px;
}
.b3-select:focus {
border: 1px solid #218bff;
outline: none;
}
.b3-button {
cursor: pointer;
color: #fff;
border-radius: 6px;
line-height: 20px;
padding: 4px 8px;
background-color: #218bff;
white-space: nowrap;
display: inline-flex;
align-items: center;
justify-content: center;
transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
border: 0;
box-sizing: border-box;
text-align: center;
width: 96px;
}
.b3-button:hover, .b3-button:focus {
text-decoration: none;
background-color: #0969da;
box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12)
}
.b3-button:active {
box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12)
}
.b3-label {
padding: 12px 24px;
line-height: 20px;
display: flex;
text-align: left;
border-bottom: 1px solid rgba(0, 0, 0, .06);
}
.b3-label__text {
color: #5f6368;
font-size: 14px;
margin-top: 4px;
}
.fn__space {
width: 8px;
flex-shrink: 0;
}
.fn__flex-center {
align-self: center;
}
.svg {
position: fixed;
right: 22px;
top: 0;
width: 12px;
fill: #5f6368;
padding: 5px;
cursor: pointer;
z-index: 1;
}
.svg:hover {
background: #dfe0e1;
fill: #202124;
}
#close {
right: 0;
width: 8px;
padding: 7px 7px;
}
#close:hover {
background-color: #d23f31;
fill: #fff;
}
a {
text-decoration: none;
color: #218bff;
}
a:hover {
text-decoration: underline;
color: #0969da;
}
.fn__none {
display: none !important;
}
.slogan {
color: #5f6368;
font-size: 15px;
}
.notice {
font-size: 14px;
color: #5f6368;
}
.icon {
width: 88px;
margin: 0 auto
}
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: 22px;
cursor: pointer;
position: fixed;
top: 0;
left: 0;
right: 44px;
}
</style>
</head>
<body>
<div id="zhCN" class="fn__flex-column">
<div class="fn__flex-1"></div>
<img class="icon">
<h2>思源笔记</h2>
<div class="slogan">重构你的思维</div>
<div class="fn__flex-1"></div>
<label class="b3-label">
<div>
🌐 外观语言
<div class="b3-label__text">用户界面语言,后续可以在 <kbd>设置</kbd> - <kbd>外观</kbd> 中进行切换</div>
</div>
<div class="fn__space"></div>
<div class="fn__flex-1"></div>
<select class="b3-select lang">
<option value="en_US">English</option>
<option value="es_ES">Español</option>
<option value="fr_FR">Français</option>
<option value="zh_CN">简体中文</option>
<option value="zh_CHT">繁體中文</option>
</select>
</label>
<label class="b3-label">
<div>
🗂️ 工作空间
<div class="b3-label__text"> 工作空间用于存放数据,后续可以在顶栏左上角的主菜单中进行切换</div>
</div>
<div class="fn__space"></div>
<div class="fn__flex-1"></div>
<button class="b3-button fn__flex-center choosePath">选择</button>
</label>
<div class="fn__flex-1"></div>
<div class="fn__flex-1 notice">
<span>⚠️ 请勿使用第三方同步盘同步数据,否则会导致运行异常和数据损坏</span>
</div>
<div class="feedback">
<span>❤️ <a href="https://ld246.com/article/1649901726096" target="_blank">求助反馈建议</a></span>
<span>🏘️ <a href="https://ld246.com/article/1640266171309" target="_blank">用户社区汇总</a></span>
<span>🔖 <a href="https://b3log.org/siyuan/download.html" target="_blank" class="version"></a></span>
</div>
<div class="fn__flex-1"></div>
</div>
<div class="fn__none fn__flex-column" id="enUS">
<div class="fn__flex-1"></div>
<img class="icon">
<h2>SiYuan</h2>
<div class="slogan">Refactor your thinking</div>
<div class="fn__flex-1"></div>
<label class="b3-label">
<div>
🌐 Language
<div class="b3-label__text">User interface language, which can be switched later in <kbd>Settings</kbd> -
<kbd>Appearance</kbd>
</div>
</div>
<div class="fn__space"></div>
<div class="fn__flex-1"></div>
<select class="b3-select lang">
<option value="en_US">English</option>
<option value="es_ES">Español</option>
<option value="fr_FR">Français</option>
<option value="zh_CN">简体中文</option>
<option value="zh_CHT">繁體中文</option>
</select>
</label>
<label class="b3-label">
<div>
🗂️ Workspace
<div class="b3-label__text">The workspace is used to store data, which can be switched later in the top bar
menu later
</div>
</div>
<div class="fn__space"></div>
<div class="fn__flex-1"></div>
<button class="b3-button fn__flex-center choosePath">Select</button>
</label>
<div class="fn__flex-1"></div>
<div class="fn__flex-1 notice">
<span>⚠️ Do not use a third-party sync disk to sync data, otherwise it will cause abnormal operation and data damage</span>
</div>
<div class="feedback">
<span>❤️ <a href="https://liuyun.io/article/1686530886208" target="_blank">Support and Feedback</a></span>
<span>🏘️ <a href="https://liuyun.io/article/1687779743723" target="_blank">User community summary</a></span>
<span>🔖 <a href="https://b3log.org/siyuan/en/download.html" target="_blank" class="version"></a></span>
</div>
<div class="fn__flex-1"></div>
</div>
<svg class="svg" id="min" viewBox="0 0 32 32">
<path d="M1.333 14.667h29.333q1.333 0 1.333 1.333v0q0 1.333-1.333 1.333h-29.333q-1.333 0-1.333-1.333v0q0-1.333 1.333-1.333z"></path>
</svg>
<svg class="svg" id="close" viewBox="0 0 32 32">
<path d="M32 3.221l-12.779 12.779 12.779 12.779-3.221 3.221-12.779-12.779-12.779 12.779-3.221-3.221 12.779-12.779-12.779-12.779 3.221-3.221 12.779 12.779 12.779-12.779z"></path>
</svg>
<div class="drag"></div>
<script>
const isChinese = (lang) => {
return 'zh_CN' === lang || 'zh_CHT' === lang
}
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
}
let currentLang = decodeURIComponent(getSearch('lang'))
const setLang = (lang) => {
if (isChinese(lang)) {
document.title = `思源笔记 v${getSearch('v')}`
document.getElementById('zhCN').classList.remove('fn__none')
document.getElementById('enUS').classList.add('fn__none')
} else {
document.title = `SiYuan v${getSearch('v')}`
document.getElementById('zhCN').classList.add('fn__none')
document.getElementById('enUS').classList.remove('fn__none')
}
currentLang = lang
}
setLang(currentLang)
document.querySelectorAll('.version').forEach(item => {
item.textContent = `v${getSearch('v')}`
})
document.querySelectorAll('.icon').forEach(item => {
item.src = decodeURIComponent(`${getSearch('icon')}`)
})
document.querySelectorAll('.lang').forEach(item => {
item.value = currentLang
item.addEventListener('change', () => {
document.querySelectorAll('.lang').forEach(item1 => {
item1.value = item.value
})
setLang(item.value)
})
})
document.getElementById('close').addEventListener('click', () => {
const {ipcRenderer} = require('electron')
ipcRenderer.send('siyuan-first-quit')
})
document.getElementById('min').addEventListener('click', () => {
const {getCurrentWindow} = require('@electron/remote')
getCurrentWindow().minimize()
})
document.querySelectorAll('.choosePath').forEach((item) => {
item.addEventListener('click', () => {
const {dialog} = require('@electron/remote')
const path = require('path')
const fs = require('fs')
const defaultWorkspace = path.join(decodeURIComponent(getSearch('home')), "SiYuan")
if (!fs.existsSync(defaultWorkspace)) {
fs.mkdirSync(defaultWorkspace, {mode: 0o755, recursive: true})
}
dialog.showOpenDialog({
defaultPath: defaultWorkspace,
properties: ['openDirectory', 'createDirectory'],
}).then((result) => {
if (result.canceled) {
return
}
const {ipcRenderer} = require('electron')
const initPath = result.filePaths[0]
if (isICloudPath(initPath)) {
let msg = '⚠️ This folder is under the iCloud sync path, please change another path'
if (isChinese(currentLang)) {
msg = '⚠️ 该文件夹位于 iCloud 同步路径下,请更换其他路径'
}
alert(msg)
return
}
if (isCloudDrivePath(initPath)) {
let msg = '⚠️ The folder path can not contain onedrive, dropbox, google drive, pcloud and 坚果云, please change another path'
if (isChinese(currentLang)) {
msg = '⚠️ 文件夹路径不能包含 onedrive、dropbox、google drive、pcloud 和 坚果云,请更换其他路径'
}
alert(msg)
return
}
let msg = '⚠️ Do not set the workspace under the path of a third-party sync disk, otherwise the data will be damaged (iCloud/OneDrive/Dropbox/Google Drive/Nutstore/Baidu Netdisk/Tencent Weiyun, etc.), continue?'
if (isChinese(currentLang)) {
msg = '⚠️ 请勿将工作空间设置在第三方同步盘路径下否则数据会被损坏iCloud/OneDrive/Dropbox/Google Drive/坚果云/百度网盘/腾讯微云等),是否继续?'
}
if (!confirm(msg)) {
return
}
if (!fs.existsSync(initPath)) {
fs.mkdirSync(initPath, {mode: 0o755, recursive: true})
}
ipcRenderer.send('siyuan-first-init', {
workspace: initPath,
lang: document.querySelector('.lang').value
})
})
})
})
const isCloudDrivePath = (absPath) => {
const absPathLower = absPath.toLowerCase()
return -1 < absPathLower.indexOf("onedrive") || -1 < absPathLower.indexOf("dropbox") ||
-1 < absPathLower.indexOf("google drive") || -1 < absPathLower.indexOf("pcloud") ||
-1 < absPathLower.indexOf("坚果云")
}
const isICloudPath = (absPath) => {
const os = require('os')
if ('darwin' !== os.platform()) {
return false
}
// macOS 端对工作空间放置在 iCloud 路径下做检查 https://github.com/siyuan-note/siyuan/issues/7747
const path = require('path')
const iCloudRoot = path.join(decodeURIComponent(getSearch('home')), 'Library', 'Mobile Documents')
const allFiles = walk(iCloudRoot)
const absPathLower = absPath.toLowerCase()
for (const file of allFiles) {
if (-1 < absPathLower.indexOf(file.toLowerCase())) {
return true
}
}
return false
}
const walk = (dir, files = []) => {
let dirFiles;
const fs = require('fs')
try {
if (!fs.existsSync(dir)) {
console.log("dir [" + dir + "] not exists")
return files
}
dirFiles = fs.readdirSync(dir)
} catch (e) {
console.error("read dir [" + dir + "] failed: ", e)
return files
}
const path = require('path')
for (const f of dirFiles) {
let stat = fs.lstatSync(dir + path.sep + f)
if (stat.isSymbolicLink()) {
files.push(fs.readlinkSync(dir + path.sep + f))
continue
}
if (stat.isDirectory()) {
// 如果已经遍历过则不再遍历
if (files.includes(dir + path.sep + f)) {
continue
}
walk(dir + path.sep + f, files)
} else {
files.push(dir + path.sep + f)
}
}
return files
}
</script>
</body>
</html>