Vanessa 2022-06-05 00:48:29 +08:00
parent 64ae905921
commit ff3cd4d4e9
21 changed files with 117 additions and 85 deletions

View file

@ -1,22 +1,29 @@
.b3-snackbar { .b3-snackbar {
//transform: translate3d(0, -100px, 0);
//transition: opacity 0.15s cubic-bezier(0, 0, 0.2, 1) 0ms, transform 0.15s cubic-bezier(0, 0, 0.2, 1) 0ms;
margin-bottom: 16px;
position: relative;
&:last-child {
margin-bottom: 0;
}
&s {
position: fixed; position: fixed;
top: 0; right: -2px;
top: 16px;
z-index: 502; z-index: 502;
transform: translate3d(0, -100px, 0); max-height: calc(100vh - 32px);
opacity: 0;
transition: opacity 0.15s cubic-bezier(0, 0, 0.2, 1) 0ms, transform 0.15s cubic-bezier(0, 0, 0.2, 1) 0ms;
width: 100%;
align-items: center;
justify-content: center;
height: 0;
display: flex; display: flex;
flex-direction: column;
&--show { & > .fn__flex-1 {
transform: translate3d(0, 0, 0); padding: 0 18px;
opacity: 1;
.b3-snackbar__content { &::-webkit-scrollbar {
transform: none; display: none;
}
} }
} }
@ -33,13 +40,11 @@
font-size: inherit; font-size: inherit;
background-color: var(--b3-theme-primary); background-color: var(--b3-theme-primary);
box-sizing: border-box; box-sizing: border-box;
box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12); box-shadow: 0 3px 5px -1px rgb(0 0 0 / 20%), 0 6px 10px 0 rgb(0 0 0 / 14%), 0 1px 18px 0 rgb(0 0 0 / 12%);
transition: transform 0.15s cubic-bezier(0, 0, 0.2, 1) 0ms; transition: transform 0.15s cubic-bezier(0, 0, 0.2, 1) 0ms;
transform: scale(0.8);
top: 16px;
position: absolute;
word-break: break-word; word-break: break-word;
max-width: 80vw; width: 20vw;
min-width: 240px;
a { a {
color: var(--b3-theme-on-primary); color: var(--b3-theme-on-primary);
@ -54,9 +59,18 @@
&__close { &__close {
position: absolute; position: absolute;
cursor: pointer; cursor: pointer;
top: 8px; top: 10px;
right: -30px; right: 4px;
height: 14px; height: 8px;
width: 14px; width: 8px;
padding: 4px;
border-radius: 10px;
color: var(--b3-theme-background-light);
transition: var(--b3-transition);
&:hover {
color: var(--b3-theme-on-background);
background-color: var(--b3-theme-background-light);
}
} }
} }

View file

@ -22,6 +22,7 @@
<div id="dockBottom" class="dock"></div> <div id="dockBottom" class="dock"></div>
<div id="commonMenu" class="b3-menu fn__none"></div> <div id="commonMenu" class="b3-menu fn__none"></div>
<div id="dragBg" style="z-index:199;pointer-events: none;" class="b3-dialog__scrim fn__none"></div> <div id="dragBg" style="z-index:199;pointer-events: none;" class="b3-dialog__scrim fn__none"></div>
<div id="message" class="b3-snackbars fn__none"></div>
<script> <script>
setTimeout(() => { setTimeout(() => {
const refreshElement = document.getElementById("loadingRefresh") const refreshElement = document.getElementById("loadingRefresh")

View file

@ -20,5 +20,6 @@
<div id="dockBottom" class="dock"></div> <div id="dockBottom" class="dock"></div>
<div id="commonMenu" class="b3-menu fn__none"></div> <div id="commonMenu" class="b3-menu fn__none"></div>
<div id="dragBg" style="z-index:199;pointer-events: none;" class="b3-dialog__scrim fn__none"></div> <div id="dragBg" style="z-index:199;pointer-events: none;" class="b3-dialog__scrim fn__none"></div>
<div id="message" class="b3-snackbars fn__none"></div>
</body> </body>
</html> </html>

View file

@ -50,5 +50,6 @@
</div> </div>
<div id="commonMenu" class="b3-menu fn__none"></div> <div id="commonMenu" class="b3-menu fn__none"></div>
<div id="dragBg" style="z-index:199;pointer-events: none;" class="b3-dialog__scrim fn__none"></div> <div id="dragBg" style="z-index:199;pointer-events: none;" class="b3-dialog__scrim fn__none"></div>
<div id="message" class="b3-snackbars fn__none"></div>
</body> </body>
</html> </html>

View file

@ -299,8 +299,9 @@ ${window.siyuan.languages.account8}`;
userPassword: md5(userPasswordElement.value), userPassword: md5(userPasswordElement.value),
captcha: captchaElement.value.replace(/(^\s*)|(\s*$)/g, ""), captcha: captchaElement.value.replace(/(^\s*)|(\s*$)/g, ""),
}, (data) => { }, (data) => {
let messageId
if (data.code === 1) { if (data.code === 1) {
showMessage(data.msg); messageId = showMessage(data.msg);
if (data.data.needCaptcha) { if (data.data.needCaptcha) {
// 验证码 // 验证码
needCaptcha = data.data.needCaptcha; needCaptcha = data.data.needCaptcha;
@ -320,7 +321,7 @@ ${window.siyuan.languages.account8}`;
token = data.data.token; token = data.data.token;
return; return;
} }
hideMessage(); hideMessage(messageId);
fetchPost("/api/setting/getCloudUser", { fetchPost("/api/setting/getCloudUser", {
token: data.data.token, token: data.data.token,
}, response => { }, response => {

View file

@ -5,7 +5,7 @@ import {SaveDialogReturnValue, shell} from "electron";
import {afterExport} from "../protyle/export/util"; import {afterExport} from "../protyle/export/util";
/// #endif /// #endif
import {isBrowser} from "../util/functions"; import {isBrowser} from "../util/functions";
import {showMessage} from "../dialog/message"; import {hideMessage, showMessage} from "../dialog/message";
export const exportConfig = { export const exportConfig = {
element: undefined as Element, element: undefined as Element,
@ -162,10 +162,11 @@ export const exportConfig = {
properties: ["showOverwriteConfirmation"], properties: ["showOverwriteConfirmation"],
}).then((result: SaveDialogReturnValue) => { }).then((result: SaveDialogReturnValue) => {
if (!result.canceled) { if (!result.canceled) {
showMessage(window.siyuan.languages.exporting, -1); const id = showMessage(window.siyuan.languages.exporting, -1);
fetchPost("/api/export/exportDataInFolder", { fetchPost("/api/export/exportDataInFolder", {
folder: result.filePath folder: result.filePath
}, () => { }, () => {
hideMessage(id)
afterExport(result.filePath); afterExport(result.filePath);
}); });
} }

View file

@ -160,7 +160,6 @@ export const keymap = {
item.addEventListener("keydown", function (event) { item.addEventListener("keydown", function (event) {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
hideMessage();
let keymapStr = ""; let keymapStr = "";
if (event.ctrlKey && !event.metaKey && isMac()) { if (event.ctrlKey && !event.metaKey && isMac()) {
keymapStr += "⌃"; keymapStr += "⌃";

View file

@ -1,41 +1,56 @@
let timeoutId: number; import {genUUID} from "../util/genID";
export const initMessage = () => {
const messageElement = document.getElementById("message")
messageElement.innerHTML = `<div class="fn__flex-1"></div>
<div class="fn__hr fn__flex-shrink"></div>
<button class="fn__flex-center b3-button b3-button--cancel">
${window.siyuan.languages.close}
</button>`
messageElement.addEventListener("click", (event) => {
let target = event.target as HTMLElement
while (target && !target.isEqualNode(messageElement)) {
if (target.classList.contains("b3-snackbar__close")) {
hideMessage(target.parentElement.getAttribute("data-id"))
event.preventDefault();
break;
} else if (target.isSameNode(messageElement.lastElementChild)) {
target.parentElement.classList.add("fn__none");
target.parentElement.innerHTML = '';
event.preventDefault();
break;
}
target = target.parentElement;
}
})
}
export const showMessage = (message: string, timeout = 6000, type = "info") => { export const showMessage = (message: string, timeout = 6000, type = "info") => {
clearTimeout(timeoutId); const id = genUUID();
let messageHTML = `<div data-id="${id}" class="b3-snackbar${type === "error" ? " b3-snackbar--error" : ""}"><div class="b3-snackbar__content">${message}</div>`;
let messageElement = document.getElementById("message");
if (!messageElement) {
document.body.insertAdjacentHTML("beforeend", '<div class="b3-snackbar" id="message"></div>');
messageElement = document.getElementById("message");
}
if (type === "error") {
messageElement.classList.add("b3-snackbar--error");
} else {
messageElement.classList.remove("b3-snackbar--error");
}
if (timeout === 0) { if (timeout === 0) {
messageElement.innerHTML = `<div class="b3-snackbar__content">${message} messageHTML += '<svg class="b3-snackbar__close"><use xlink:href="#iconClose"></use></svg>';
<svg class="b3-snackbar__close fn__a"><use xlink:href="#iconClose"></use></svg></div>`; } else if (timeout !== -1) { // -1 时需等待请求完成后手动关闭
messageElement.querySelector(".b3-snackbar__close").addEventListener("click", () => { window.setTimeout(() => {
hideMessage(); hideMessage(id);
});
} else {
messageElement.innerHTML = `<div class="b3-snackbar__content">${message}</div>`;
if (timeout !== -1) {
timeoutId = window.setTimeout(() => {
hideMessage();
}, timeout); }, timeout);
} }
const messagesElement = document.getElementById("message").firstElementChild
if (messagesElement.childElementCount === 0) {
messagesElement.parentElement.classList.remove("fn__none")
} }
setTimeout(() => { messagesElement.insertAdjacentHTML("afterbegin", messageHTML + "</div>");
messageElement.classList.add("b3-snackbar--show"); messagesElement.scrollTop = 0;
}); return id;
}; };
export const hideMessage = () => { export const hideMessage = (id: string) => {
const messageElement = document.getElementById("message"); const messagesElement = document.getElementById("message").firstElementChild
const messageElement = messagesElement.querySelector(`[data-id="${id}"]`);
if (messageElement) { if (messageElement) {
messageElement.innerHTML = ""; messageElement.remove();
messageElement.classList.remove("b3-snackbar--show"); }
if (messagesElement.childElementCount === 0) {
messagesElement.parentElement.classList.add("fn__none")
} }
}; };

View file

@ -1,4 +1,4 @@
import {hideMessage, showMessage} from "../dialog/message"; import {showMessage} from "../dialog/message";
import {Dialog} from "../dialog"; import {Dialog} from "../dialog";
import {focusByRange} from "../protyle/util/selection"; import {focusByRange} from "../protyle/util/selection";
import {hasClosestBlock} from "../protyle/util/hasClosest"; import {hasClosestBlock} from "../protyle/util/hasClosest";
@ -11,7 +11,6 @@ import {fetchPost} from "../util/fetch";
import {escapeHtml} from "../util/escape"; import {escapeHtml} from "../util/escape";
export const validateName = (name: string) => { export const validateName = (name: string) => {
hideMessage();
if (/\r\n|\r|\n|\u2028|\u2029|\t|\//.test(name)) { if (/\r\n|\r|\n|\u2028|\u2029|\t|\//.test(name)) {
showMessage(window.siyuan.languages.fileNameRule); showMessage(window.siyuan.languages.fileNameRule);
return false; return false;

View file

@ -13,6 +13,7 @@ import {repos} from "./config/repos";
import {openFileById} from "./editor/util"; import {openFileById} from "./editor/util";
import {bootSync, downloadProgress, progressLoading, setTitle, transactionError} from "./dialog/processSystem"; import {bootSync, downloadProgress, progressLoading, setTitle, transactionError} from "./dialog/processSystem";
import {promiseTransactions} from "./protyle/wysiwyg/transaction"; import {promiseTransactions} from "./protyle/wysiwyg/transaction";
import {initMessage, showMessage} from "./dialog/message";
class App { class App {
constructor() { constructor() {
@ -87,6 +88,7 @@ class App {
dragElement.style.paddingRight = (dragElement.getBoundingClientRect().left - document.querySelector("#windowControls").clientWidth) + "px"; dragElement.style.paddingRight = (dragElement.getBoundingClientRect().left - document.querySelector("#windowControls").clientWidth) + "px";
} }
setTitle(window.siyuan.languages.siyuanNote); setTitle(window.siyuan.languages.siyuanNote);
initMessage();
}); });
}); });
}); });

View file

@ -602,7 +602,6 @@ export class Files extends Model {
} }
private onMount(data: { data: { box: INotebook, existed?: boolean }, callback?: string }) { private onMount(data: { data: { box: INotebook, existed?: boolean }, callback?: string }) {
hideMessage();
if (data.data.existed) { if (data.data.existed) {
return; return;
} }

View file

@ -639,11 +639,11 @@ export const exportMd = (id: string) => {
label: "Markdown", label: "Markdown",
icon: "iconMarkdown", icon: "iconMarkdown",
click: () => { click: () => {
showMessage(window.siyuan.languages.exporting, -1); const id = showMessage(window.siyuan.languages.exporting, -1);
fetchPost("/api/export/exportMd", { fetchPost("/api/export/exportMd", {
id, id,
}, response => { }, response => {
hideMessage(); hideMessage(id);
if (window.siyuan.config.system.container === "ios") { if (window.siyuan.config.system.container === "ios") {
window.location.href = response.data.zip; window.location.href = response.data.zip;
} else if (window.siyuan.config.system.container === "android" && window.JSAndroid) { } else if (window.siyuan.config.system.container === "android" && window.JSAndroid) {
@ -658,11 +658,11 @@ export const exportMd = (id: string) => {
label: "SiYuan .sy.zip", label: "SiYuan .sy.zip",
icon: "iconSiYuan", icon: "iconSiYuan",
click: () => { click: () => {
showMessage(window.siyuan.languages.exporting, -1); const id = showMessage(window.siyuan.languages.exporting, -1);
fetchPost("/api/export/exportSY", { fetchPost("/api/export/exportSY", {
id, id,
}, response => { }, response => {
hideMessage(); hideMessage(id);
if (window.siyuan.config.system.container === "ios") { if (window.siyuan.config.system.container === "ios") {
window.location.href = response.data.zip; window.location.href = response.data.zip;
} else if (window.siyuan.config.system.container === "android" && window.JSAndroid) { } else if (window.siyuan.config.system.container === "android" && window.JSAndroid) {

View file

@ -108,12 +108,12 @@ export const initNavigationMenu = (liElement: HTMLElement) => {
label: window.siyuan.languages.export, label: window.siyuan.languages.export,
icon: "iconUpload", icon: "iconUpload",
click: () => { click: () => {
showMessage(window.siyuan.languages.exporting, -1); const id = showMessage(window.siyuan.languages.exporting, -1);
fetchPost("/api/export/batchExportMd", { fetchPost("/api/export/batchExportMd", {
notebook: notebookId, notebook: notebookId,
path: "/" path: "/"
}, response => { }, response => {
hideMessage(); hideMessage(id);
window.open(response.data.zip); window.open(response.data.zip);
}); });
} }

View file

@ -14,6 +14,7 @@ import {initAssets, loadAssets} from "../util/assets";
import {openMobileFileById} from "./editor"; import {openMobileFileById} from "./editor";
import {promiseTransactions} from "../protyle/wysiwyg/transaction"; import {promiseTransactions} from "../protyle/wysiwyg/transaction";
import {bootSync} from "../dialog/processSystem"; import {bootSync} from "../dialog/processSystem";
import {initMessage} from "../dialog/message";
class App { class App {
constructor() { constructor() {
@ -58,6 +59,7 @@ class App {
} else if (window.siyuan.config.system.container === "android" && window.JSAndroid) { } else if (window.siyuan.config.system.container === "android" && window.JSAndroid) {
window.JSAndroid.changeStatusBarColor(getComputedStyle(document.body).getPropertyValue("--b3-theme-background"), window.siyuan.config.appearance.mode); window.JSAndroid.changeStatusBarColor(getComputedStyle(document.body).getPropertyValue("--b3-theme-background"), window.siyuan.config.appearance.mode);
} }
initMessage();
}); });
}); });
if (navigator.userAgent.indexOf("iPhone") > -1) { if (navigator.userAgent.indexOf("iPhone") > -1) {

View file

@ -496,7 +496,6 @@ export class MobileFiles extends Model {
} }
private onMount(data: { data: { box: INotebook, existed?: boolean }, callback?: string }) { private onMount(data: { data: { box: INotebook, existed?: boolean }, callback?: string }) {
hideMessage();
if (data.data.existed) { if (data.data.existed) {
return; return;
} }

View file

@ -166,6 +166,7 @@ export class Breadcrumb {
icon: "iconRecord", icon: "iconRecord",
label: this.mediaRecorder?.isRecording ? window.siyuan.languages.endRecord : window.siyuan.languages.startRecord, label: this.mediaRecorder?.isRecording ? window.siyuan.languages.endRecord : window.siyuan.languages.startRecord,
click: () => { click: () => {
let messageId = ''
if (!this.mediaRecorder) { if (!this.mediaRecorder) {
navigator.mediaDevices.getUserMedia({audio: true}).then((mediaStream: MediaStream) => { navigator.mediaDevices.getUserMedia({audio: true}).then((mediaStream: MediaStream) => {
this.mediaRecorder = new RecordMedia(mediaStream); this.mediaRecorder = new RecordMedia(mediaStream);
@ -180,7 +181,7 @@ export class Breadcrumb {
this.mediaRecorder.cloneChannelData(left, right); this.mediaRecorder.cloneChannelData(left, right);
}; };
this.mediaRecorder.startRecordingNewWavFile(); this.mediaRecorder.startRecordingNewWavFile();
showMessage(window.siyuan.languages.recording, 86400000); id = showMessage(window.siyuan.languages.recording, -1);
}).catch(() => { }).catch(() => {
showMessage(window.siyuan.languages["record-tip"]); showMessage(window.siyuan.languages["record-tip"]);
}); });
@ -189,12 +190,13 @@ export class Breadcrumb {
if (this.mediaRecorder.isRecording) { if (this.mediaRecorder.isRecording) {
this.mediaRecorder.stopRecording(); this.mediaRecorder.stopRecording();
hideMessage(); hideMessage(messageId);
const file: File = new File([this.mediaRecorder.buildWavFileBlob()], const file: File = new File([this.mediaRecorder.buildWavFileBlob()],
`record${(new Date()).getTime()}.wav`, {type: "video/webm"}); `record${(new Date()).getTime()}.wav`, {type: "video/webm"});
uploadFiles(protyle, [file]); uploadFiles(protyle, [file]);
} else { } else {
showMessage(window.siyuan.languages.recording, 86400000); hideMessage(messageId);
messageId = showMessage(window.siyuan.languages.recording, -1);
this.mediaRecorder.startRecordingNewWavFile(); this.mediaRecorder.startRecordingNewWavFile();
} }
} }

View file

@ -1,4 +1,4 @@
import {showMessage} from "../../dialog/message"; import {hideMessage, showMessage} from "../../dialog/message";
import {Constants} from "../../constants"; import {Constants} from "../../constants";
/// #if !BROWSER /// #if !BROWSER
import {PrintToPDFOptions, SaveDialogReturnValue} from "electron"; import {PrintToPDFOptions, SaveDialogReturnValue} from "electron";
@ -126,7 +126,7 @@ const getExportPath = (option: { type: string, id: string }, pdfOption?: PrintTo
properties: ["showOverwriteConfirmation"], properties: ["showOverwriteConfirmation"],
}).then((result: SaveDialogReturnValue) => { }).then((result: SaveDialogReturnValue) => {
if (!result.canceled) { if (!result.canceled) {
showMessage(window.siyuan.languages.exporting, -1); const id = showMessage(window.siyuan.languages.exporting, -1);
let url = "/api/export/exportHTML"; let url = "/api/export/exportHTML";
if (option.type === "htmlmd") { if (option.type === "htmlmd") {
url = "/api/export/exportMdHTML"; url = "/api/export/exportMdHTML";
@ -138,6 +138,7 @@ const getExportPath = (option: { type: string, id: string }, pdfOption?: PrintTo
pdf: option.type === "pdf", pdf: option.type === "pdf",
savePath: result.filePath savePath: result.filePath
}, exportResponse => { }, exportResponse => {
hideMessage(id);
if (option.type === "word") { if (option.type === "word") {
afterExport(result.filePath); afterExport(result.filePath);
} else { } else {

View file

@ -5,7 +5,7 @@ import {shell} from "electron";
import * as path from "path"; import * as path from "path";
export const afterExport = (exportPath: string) => { export const afterExport = (exportPath: string) => {
showMessage(`<div class="fn__flex"> const id = showMessage(`<div class="fn__flex">
<div class="fn__flex-center">${window.siyuan.languages.exported}${escapeHtml(exportPath)}</div> <div class="fn__flex-center">${window.siyuan.languages.exported}${escapeHtml(exportPath)}</div>
<div class="fn__space"></div> <div class="fn__space"></div>
<div class="fn__space"></div> <div class="fn__space"></div>
@ -13,7 +13,7 @@ export const afterExport = (exportPath: string) => {
</div>`, 6000); </div>`, 6000);
document.querySelector("#message button").addEventListener("click", () => { document.querySelector("#message button").addEventListener("click", () => {
shell.showItemInFolder(path.join(exportPath)); shell.showItemInFolder(path.join(exportPath));
hideMessage(); hideMessage(id);
}); });
}; };
/// #endif /// #endif

View file

@ -81,7 +81,6 @@ export class Background {
uploadFiles(protyle, event.target.files, event.target, (responseText) => { uploadFiles(protyle, event.target.files, event.target, (responseText) => {
const response = JSON.parse(responseText); const response = JSON.parse(responseText);
const style = `background-image:url(${response.data.succMap[Object.keys(response.data.succMap)[0]]})`; const style = `background-image:url(${response.data.succMap[Object.keys(response.data.succMap)[0]]})`;
hideMessage();
this.ial["title-img"] = Lute.EscapeHTMLStr(style); this.ial["title-img"] = Lute.EscapeHTMLStr(style);
this.render(this.ial, protyle.block.rootID); this.render(this.ial, protyle.block.rootID);
fetchPost("/api/attr/setBlockAttrs", { fetchPost("/api/attr/setBlockAttrs", {

View file

@ -17,7 +17,6 @@ export class Upload {
} }
const validateFile = (protyle: IProtyle, files: File[]) => { const validateFile = (protyle: IProtyle, files: File[]) => {
hideMessage();
const uploadFileList = []; const uploadFileList = [];
let errorTip = ""; let errorTip = "";
let uploadingStr = ""; let uploadingStr = "";
@ -94,8 +93,6 @@ const genUploadedLabel = (responseText: string, protyle: IProtyle) => {
if (errorTip) { if (errorTip) {
showMessage(errorTip); showMessage(errorTip);
} else {
hideMessage();
} }
let succFileText = ""; let succFileText = "";

View file

@ -8,7 +8,6 @@ export const processMessage = (response: IWebSocketData) => {
return false; return false;
} }
if ("cmsg" === response.cmd) { if ("cmsg" === response.cmd) {
hideMessage();
const progressElement = document.getElementById("progress"); const progressElement = document.getElementById("progress");
if (progressElement) { if (progressElement) {
progressElement.remove(); progressElement.remove();