This commit is contained in:
parent
52814228b9
commit
57ade08618
10 changed files with 95 additions and 44 deletions
|
@ -10,7 +10,6 @@
|
|||
}
|
||||
|
||||
&__repo {
|
||||
background-color: var(--b3-theme-background);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
@ -25,16 +24,17 @@
|
|||
background: var(--b3-theme-background);
|
||||
}
|
||||
|
||||
&__diff {
|
||||
&__side {
|
||||
width: 256px;
|
||||
border-right: 1px solid var(--b3-border-color);
|
||||
padding: 8px 0;
|
||||
overflow: auto;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&__panel > .b3-list {
|
||||
width: 256px;
|
||||
user-select: none;
|
||||
&__resize {
|
||||
cursor: col-resize;
|
||||
box-shadow: 2px 0 0 0 var(--b3-theme-background) inset, 3px 0 0 0 var(--b3-border-color) inset;
|
||||
width: 5px;
|
||||
margin-left: -2px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,10 @@
|
|||
opacity: 0;
|
||||
transition: opacity 75ms linear, transform 150ms 0ms cubic-bezier(0, 0, .2, 1);
|
||||
border: 1px solid var(--b3-theme-surface-lighter);
|
||||
|
||||
&--theme {
|
||||
background-color: var(--b3-theme-background);
|
||||
}
|
||||
}
|
||||
|
||||
&__header {
|
||||
|
|
|
@ -71,8 +71,7 @@
|
|||
&__panel {
|
||||
flex-direction: column;
|
||||
|
||||
& > .b3-list,
|
||||
& > .history__diff {
|
||||
& > .history__side {
|
||||
height: 40%;
|
||||
overflow: auto;
|
||||
padding-bottom: 8px;
|
||||
|
|
|
@ -26,7 +26,8 @@ export class Dialog {
|
|||
disableClose?: boolean,
|
||||
hideCloseIcon?: boolean,
|
||||
disableAnimation?: boolean,
|
||||
resizeCallback?: (type: string) => void
|
||||
resizeCallback?: (type: string) => void,
|
||||
containerClassName?: string
|
||||
}) {
|
||||
this.disableClose = options.disableClose;
|
||||
this.id = genUUID();
|
||||
|
@ -49,7 +50,7 @@ export class Dialog {
|
|||
}
|
||||
this.element.innerHTML = `<div class="b3-dialog" style="z-index: ${++window.siyuan.zIndex};${typeof left === "string" ? "display:block" : ""}">
|
||||
<div class="b3-dialog__scrim"${options.transparent ? 'style="background-color:transparent"' : ""}></div>
|
||||
<div class="b3-dialog__container" style="width:${options.width || "auto"};height:${options.height || "auto"};left:${left};top:${top}">
|
||||
<div class="b3-dialog__container ${options.containerClassName}" style="width:${options.width || "auto"};height:${options.height || "auto"};left:${left};top:${top}">
|
||||
<svg ${(isMobile() && options.title) ? 'style="top:0;right:0;"' : ""} class="b3-dialog__close${(this.disableClose || options.hideCloseIcon) ? " fn__none" : ""}"><use xlink:href="#iconCloseRound"></use></svg>
|
||||
<div class="resize__move b3-dialog__header${options.title ? "" : " fn__none"}" onselectstart="return false;">${options.title || ""}</div>
|
||||
<div class="b3-dialog__body">${options.content}</div>
|
||||
|
|
|
@ -10,6 +10,7 @@ import {isMobile} from "../util/functions";
|
|||
import {App} from "../index";
|
||||
import {pathPosix} from "../util/pathName";
|
||||
import {renderAssetsPreview} from "../asset/renderAssets";
|
||||
import {resizeSide} from "./resizeSide";
|
||||
|
||||
const genItem = (data: [], data2?: { title: string, fileID: string }[]) => {
|
||||
if (!data || data.length === 0) {
|
||||
|
@ -31,7 +32,7 @@ const genItem = (data: [], data2?: { title: string, fileID: string }[]) => {
|
|||
let leftEditor: Protyle;
|
||||
let rightEditor: Protyle;
|
||||
const renderCompare = (app: App, element: HTMLElement) => {
|
||||
const listElement = hasClosestByClassName(element, "history__diff");
|
||||
const listElement = hasClosestByClassName(element, "history__side");
|
||||
if (!listElement) {
|
||||
return;
|
||||
}
|
||||
|
@ -39,8 +40,9 @@ const renderCompare = (app: App, element: HTMLElement) => {
|
|||
if (!dialogContainerElement) {
|
||||
return;
|
||||
}
|
||||
const leftElement = listElement.nextElementSibling.firstElementChild;
|
||||
const rightElement = listElement.nextElementSibling.lastElementChild;
|
||||
const editorsElement = dialogContainerElement.querySelector('[data-type="editors"]');
|
||||
const leftElement = editorsElement.firstElementChild;
|
||||
const rightElement = editorsElement.lastElementChild;
|
||||
if (!leftEditor) {
|
||||
leftEditor = new Protyle(app, leftElement.lastElementChild as HTMLElement, {
|
||||
blockId: "",
|
||||
|
@ -154,6 +156,7 @@ export const showDiff = (app: App, data: { id: string, time: string }[]) => {
|
|||
content: "",
|
||||
width: isMobile() ? "92vw" : "90vw",
|
||||
height: "80vh",
|
||||
containerClassName: "b3-dialog__container--theme",
|
||||
destroyCallback() {
|
||||
leftEditor = undefined;
|
||||
rightEditor = undefined;
|
||||
|
@ -162,7 +165,7 @@ export const showDiff = (app: App, data: { id: string, time: string }[]) => {
|
|||
dialog.element.setAttribute("data-key", Constants.DIALOG_HISTORYCOMPARE);
|
||||
dialog.element.addEventListener("click", (event) => {
|
||||
if (typeof event.detail === "string") {
|
||||
renderCompare(app, dialog.element.querySelector(".history__diff .b3-list-item--focus"));
|
||||
renderCompare(app, dialog.element.querySelector(".history__side .b3-list-item--focus"));
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
return;
|
||||
|
@ -179,7 +182,7 @@ export const showDiff = (app: App, data: { id: string, time: string }[]) => {
|
|||
if (target.classList.contains("b3-list-item--focus")) {
|
||||
return;
|
||||
}
|
||||
dialog.element.querySelector(".history__diff .b3-list-item--focus")?.classList.remove("b3-list-item--focus");
|
||||
dialog.element.querySelector(".history__side .b3-list-item--focus")?.classList.remove("b3-list-item--focus");
|
||||
target.classList.add("b3-list-item--focus");
|
||||
renderCompare(app, target);
|
||||
event.preventDefault();
|
||||
|
@ -223,7 +226,7 @@ const genHTML = (left: string, right: string, dialog: Dialog, direct: string) =>
|
|||
<span class="fn__flex-1"></span>
|
||||
</div>`;
|
||||
headElement.nextElementSibling.innerHTML = `<div class="fn__flex history__panel" style="height: 100%">
|
||||
<div class="history__diff">
|
||||
<div class="history__side" style="width: ${window.siyuan.storage[Constants.LOCAL_HISTORY].sideDiffWidth}">
|
||||
<ul class="b3-list b3-list--background">
|
||||
<li class="b3-list-item">
|
||||
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
||||
|
@ -255,7 +258,8 @@ const genHTML = (left: string, right: string, dialog: Dialog, direct: string) =>
|
|||
<ul class="fn__none">${genItem(response.data.removesRight)}</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="fn__flex-1 fn__flex">
|
||||
<div class="history__resize"></div>
|
||||
<div class="fn__flex-1 fn__flex" data-type="editors">
|
||||
<div class="fn__none fn__flex-1 fn__flex-column">
|
||||
<div class="history__date">${dayjs(response.data.left.created).format("YYYY-MM-DD HH:mm")}</div>
|
||||
<div class="ft__center"></div>
|
||||
|
@ -270,5 +274,6 @@ const genHTML = (left: string, right: string, dialog: Dialog, direct: string) =>
|
|||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
resizeSide(dialog.element.querySelector(".history__resize"), dialog.element.querySelector(".history__side"), "sideDiffWidth");
|
||||
});
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@ import * as dayjs from "dayjs";
|
|||
import {fetchPost} from "../util/fetch";
|
||||
import {isMobile} from "../util/functions";
|
||||
import {App} from "../index";
|
||||
import {resizeSide} from "./resizeSide";
|
||||
|
||||
let historyEditor: Protyle;
|
||||
let isLoading = false;
|
||||
|
@ -60,8 +61,16 @@ export const openDocHistory = (options: {
|
|||
notebookId: string,
|
||||
pathString: string
|
||||
}) => {
|
||||
const contentHTML = `<div class="fn__flex-column" style="height: 100%;">
|
||||
<div class="block__icons">
|
||||
const contentHTML = `<div class="fn__flex fn__flex-1 history__panel">
|
||||
<ul class="b3-list b3-list--background history__side" style="width: ${window.siyuan.storage[Constants.LOCAL_HISTORY].sideDocWidth}">
|
||||
<li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li>
|
||||
</ul>
|
||||
<div class="history__resize"></div>
|
||||
<textarea class="fn__flex-1 history__text fn__none" readonly data-type="mdPanel"></textarea>
|
||||
<div class="fn__flex-1 history__text fn__none" style="padding: 0" data-type="docPanel"></div>
|
||||
</div>`;
|
||||
const dialog = new Dialog({
|
||||
title:`<div class="block__icons">
|
||||
${isMobile() ? "" : options.pathString}
|
||||
<span class="fn__space"></span>
|
||||
<div class="fn__flex-1"></div>
|
||||
|
@ -82,19 +91,11 @@ export const openDocHistory = (options: {
|
|||
<span class="fn__space"></span>
|
||||
<span>1/1</span>
|
||||
${isMobile() ? '<span class="fn__space"></span><span data-type="close" class="block__icon block__icon--show"><svg><use xlink:href="#iconClose"></use></svg></span>' : ""}
|
||||
</div>
|
||||
<div class="fn__flex fn__flex-1 history__panel">
|
||||
<ul class="b3-list b3-list--background" style="overflow:auto;">
|
||||
<li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li>
|
||||
</ul>
|
||||
<textarea class="fn__flex-1 history__text fn__none" readonly data-type="mdPanel"></textarea>
|
||||
<div class="fn__flex-1 history__text fn__none" style="padding: 0" data-type="docPanel"></div>
|
||||
</div>
|
||||
</div>`;
|
||||
const dialog = new Dialog({
|
||||
</div>`,
|
||||
content: contentHTML,
|
||||
width: isMobile() ? "100vw" : "90vw",
|
||||
height: isMobile() ? "100vh" : "80vh",
|
||||
containerClassName: "b3-dialog__container--theme",
|
||||
destroyCallback() {
|
||||
historyEditor = undefined;
|
||||
}
|
||||
|
@ -182,6 +183,7 @@ export const openDocHistory = (options: {
|
|||
target = target.parentElement;
|
||||
}
|
||||
});
|
||||
resizeSide(dialog.element.querySelector(".history__resize"), dialog.element.querySelector(".history__side"), "sideDocWidth");
|
||||
};
|
||||
|
||||
const getHistoryPath = (target: Element, op: string, id: string, cb: (item: any) => void) => {
|
||||
|
|
|
@ -14,6 +14,7 @@ import {setStorageVal} from "../protyle/util/compatibility";
|
|||
import {openModel} from "../mobile/menu/model";
|
||||
import {closeModel} from "../mobile/util/closePanel";
|
||||
import {App} from "../index";
|
||||
import {resizeSide} from "./resizeSide";
|
||||
|
||||
let historyEditor: Protyle;
|
||||
|
||||
|
@ -65,11 +66,9 @@ const renderDoc = (element: HTMLElement, currentPage: number) => {
|
|||
opElement.querySelector('option[value="replace"]').classList.remove("fn__none");
|
||||
opElement.querySelector('option[value="outline"]').classList.remove("fn__none");
|
||||
}
|
||||
window.siyuan.storage[Constants.LOCAL_HISTORY] = {
|
||||
notebookId: notebookElement.value,
|
||||
type: parseInt(typeElement.value),
|
||||
operation: opElement.value
|
||||
};
|
||||
window.siyuan.storage[Constants.LOCAL_HISTORY].notebookId = notebookElement.value
|
||||
window.siyuan.storage[Constants.LOCAL_HISTORY].type = parseInt(typeElement.value)
|
||||
window.siyuan.storage[Constants.LOCAL_HISTORY].operation = opElement.value
|
||||
setStorageVal(Constants.LOCAL_HISTORY, window.siyuan.storage[Constants.LOCAL_HISTORY]);
|
||||
fetchPost("/api/history/searchHistory", {
|
||||
notebook: notebookElement.value,
|
||||
|
@ -276,7 +275,7 @@ const renderRepo = (element: Element, currentPage: number) => {
|
|||
previousElement.setAttribute("disabled", "disabled");
|
||||
}
|
||||
nextElement.setAttribute("disabled", "disabled");
|
||||
fetchPost(`/api/repo/${selectValue}`, { page: currentPage }, (response) => {
|
||||
fetchPost(`/api/repo/${selectValue}`, {page: currentPage}, (response) => {
|
||||
selectElement.disabled = false;
|
||||
if (currentPage < response.data.pageCount) {
|
||||
nextElement.removeAttribute("disabled");
|
||||
|
@ -355,7 +354,7 @@ export const openHistory = (app: App) => {
|
|||
</div>
|
||||
<div class="fn__flex-1 fn__flex" id="historyContainer">
|
||||
<div data-type="doc" class="history__repo fn__block" data-init="true">
|
||||
<div style="overflow:auto;">
|
||||
<div style="overflow:auto;border-bottom: 1px solid var(--b3-border-color);">
|
||||
<div class="block__icons">
|
||||
<span data-type="docprevious" class="block__icon block__icon--show b3-tooltips b3-tooltips__e" disabled="disabled" aria-label="${window.siyuan.languages.previousLabel}"><svg><use xlink:href='#iconLeft'></use></svg></span>
|
||||
<button class="b3-button b3-button--text ft__selectnone" data-type="jumpHistoryPage" data-totalpage="1">1</button>
|
||||
|
@ -394,9 +393,10 @@ export const openHistory = (app: App) => {
|
|||
</div>
|
||||
</div>
|
||||
<div class="fn__flex fn__flex-1 history__panel">
|
||||
<ul class="b3-list b3-list--background" style="overflow:auto;">
|
||||
<ul class="b3-list b3-list--background history__side" style="width: ${localHistory.sideWidth}">
|
||||
<li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li>
|
||||
</ul>
|
||||
<div class="history__resize"></div>
|
||||
<div class="fn__flex-1 history__text fn__none" data-type="assetPanel"></div>
|
||||
<textarea class="fn__flex-1 history__text fn__none" data-type="mdPanel"></textarea>
|
||||
<div class="fn__flex-1 history__text fn__none" style="padding: 0" data-type="docPanel"></div>
|
||||
|
@ -450,12 +450,14 @@ export const openHistory = (app: App) => {
|
|||
content: contentHTML,
|
||||
width: "90vw",
|
||||
height: "80vh",
|
||||
containerClassName: "b3-dialog__container--theme",
|
||||
destroyCallback() {
|
||||
historyEditor = undefined;
|
||||
}
|
||||
});
|
||||
dialog.element.setAttribute("data-key", Constants.DIALOG_HISTORY);
|
||||
bindEvent(app, dialog.element, dialog);
|
||||
resizeSide(dialog.element.querySelector(".history__resize"), dialog.element.querySelector(".history__side"), "sideWidth");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -666,7 +668,7 @@ const bindEvent = (app: App, element: Element, dialog?: Dialog) => {
|
|||
target.parentElement.querySelector(`.b3-list-item[data-id="${idJSON.splice(0, 1)[0].id}"]`)?.classList.remove("b3-list-item--focus");
|
||||
}
|
||||
}
|
||||
idJSON.push({ id, time: target.querySelector('[data-type="hCreated"]').textContent });
|
||||
idJSON.push({id, time: target.querySelector('[data-type="hCreated"]').textContent});
|
||||
}
|
||||
|
||||
if (idJSON.length === 2) {
|
||||
|
@ -738,7 +740,7 @@ const bindEvent = (app: App, element: Element, dialog?: Dialog) => {
|
|||
genRepoDialog.destroy();
|
||||
});
|
||||
btnsElement[1].addEventListener("click", () => {
|
||||
fetchPost("/api/repo/createSnapshot", { memo: textareaElement.value }, () => {
|
||||
fetchPost("/api/repo/createSnapshot", {memo: textareaElement.value}, () => {
|
||||
renderRepo(repoElement, 1);
|
||||
});
|
||||
genRepoDialog.destroy();
|
||||
|
@ -749,7 +751,7 @@ const bindEvent = (app: App, element: Element, dialog?: Dialog) => {
|
|||
} else if (type === "removeRepoTagSnapshot" || type === "removeCloudRepoTagSnapshot") {
|
||||
const tag = target.parentElement.getAttribute("data-tag");
|
||||
confirmDialog(window.siyuan.languages.deleteOpConfirm, `${window.siyuan.languages.confirmDelete} <i>${tag}</i>?`, () => {
|
||||
fetchPost("/api/repo/" + type, { tag }, () => {
|
||||
fetchPost("/api/repo/" + type, {tag}, () => {
|
||||
renderRepo(repoElement, 1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import {Dialog} from "../dialog";
|
||||
|
||||
export const historyKeydown = (event: KeyboardEvent, dialog: Dialog) => {
|
||||
let currentItem = dialog.element.querySelector(".history__diff .b3-list-item--focus");
|
||||
const items = Array.from(dialog.element.querySelectorAll(".history__diff .b3-list-item[data-id]"));
|
||||
let currentItem = dialog.element.querySelector(".history__side .b3-list-item--focus");
|
||||
const items = Array.from(dialog.element.querySelectorAll(".history__side .b3-list-item[data-id]"));
|
||||
if (items.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ export const historyKeydown = (event: KeyboardEvent, dialog: Dialog) => {
|
|||
currentItem.parentElement.previousElementSibling.querySelector("svg").classList.add("b3-list-item__arrow--open");
|
||||
}
|
||||
const currentItemRect = currentItem.getBoundingClientRect();
|
||||
const historyDiffElement = dialog.element.querySelector(".history__diff");
|
||||
const historyDiffElement = dialog.element.querySelector(".history__side");
|
||||
const historyDiffRect = historyDiffElement.getBoundingClientRect();
|
||||
if (currentItemRect.bottom > historyDiffRect.bottom) {
|
||||
currentItem.scrollIntoView(false);
|
||||
|
|
38
app/src/history/resizeSide.ts
Normal file
38
app/src/history/resizeSide.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
import {Constants} from "../constants";
|
||||
import {setStorageVal} from "../protyle/util/compatibility";
|
||||
import {hasClosestByClassName} from "../protyle/util/hasClosest";
|
||||
|
||||
export const resizeSide = (targetElement: HTMLElement, element: HTMLElement, key:string) => {
|
||||
targetElement.addEventListener("mousedown", (event: MouseEvent & { target: HTMLElement }) => {
|
||||
const dialogBodyElement = hasClosestByClassName(element, "b3-dialog__body");
|
||||
if (!dialogBodyElement) {
|
||||
return;
|
||||
}
|
||||
dialogBodyElement.style.userSelect = "none";
|
||||
|
||||
const documentSelf = document;
|
||||
documentSelf.ondragstart = () => false;
|
||||
|
||||
const x = event.clientX;
|
||||
const width = element.clientWidth;
|
||||
const maxWidth = dialogBodyElement.clientWidth - 256;
|
||||
documentSelf.onmousemove = (moveEvent: MouseEvent) => {
|
||||
const newWidth = width + (moveEvent.clientX - x);
|
||||
if (newWidth < 256 || newWidth > maxWidth) {
|
||||
return;
|
||||
}
|
||||
element.style.width = newWidth + "px";
|
||||
};
|
||||
|
||||
documentSelf.onmouseup = () => {
|
||||
dialogBodyElement.style.userSelect = "auto";
|
||||
documentSelf.onmousemove = null;
|
||||
documentSelf.onmouseup = null;
|
||||
documentSelf.ondragstart = null;
|
||||
documentSelf.onselectstart = null;
|
||||
documentSelf.onselect = null;
|
||||
window.siyuan.storage[Constants.LOCAL_HISTORY][key] = element.clientWidth + "px";
|
||||
setStorageVal(Constants.LOCAL_HISTORY, window.siyuan.storage[Constants.LOCAL_HISTORY]);
|
||||
};
|
||||
});
|
||||
};
|
|
@ -206,7 +206,7 @@ export const getLocalStorage = (cb: () => void) => {
|
|||
defaultStorage[Constants.LOCAL_FILEPOSITION] = {}; // {id: IScrollAttr}
|
||||
defaultStorage[Constants.LOCAL_DIALOGPOSITION] = {}; // {id: IPosition}
|
||||
defaultStorage[Constants.LOCAL_HISTORY] = {
|
||||
notebookId: "%", type: 0, operation: "all"
|
||||
notebookId: "%", type: 0, operation: "all", sideWidth: "256px", sideDocWidth: "256px", sideDiffWidth: "256px",
|
||||
};
|
||||
defaultStorage[Constants.LOCAL_FLASHCARD] = {
|
||||
fullscreen: false
|
||||
|
|
Loading…
Add table
Reference in a new issue