Vanessa 2025-12-01 18:51:58 +08:00
parent 0c6c90a82d
commit 12ebc120a0
10 changed files with 184 additions and 119 deletions

View file

@ -443,23 +443,42 @@ export const execByCommand = async (options: {
if (!isFileFocus) {
const nodeElement = hasClosestBlock(range.startContainer);
if (protyle.title?.editElement.contains(range.startContainer) || !nodeElement || window.siyuan.menus.menu.element.getAttribute("data-name") === Constants.MENU_TITLE) {
movePathTo((toPath, toNotebook) => {
moveToPath([protyle.path], toNotebook[0], toPath[0]);
}, [protyle.path], range);
movePathTo({
cb: (toPath, toNotebook) => {
moveToPath([protyle.path], toNotebook[0], toPath[0]);
},
paths: [protyle.path],
range,
flashcard: false,
rootIDs: [protyle.block.rootID]
});
} else if (nodeElement && range && protyle.element.contains(range.startContainer)) {
let selectElements = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
if (selectElements.length === 0) {
selectElements = [nodeElement];
}
movePathTo((toPath) => {
hintMoveBlock(toPath[0], selectElements, protyle);
movePathTo({
cb: (toPath) => {
hintMoveBlock(toPath[0], selectElements, protyle);
},
flashcard: false,
rootIDs: [protyle.block.rootID]
});
}
} else {
const paths = getTopPaths(fileLiElements);
movePathTo((toPath, toNotebook) => {
moveToPath(paths, toNotebook[0], toPath[0]);
}, paths);
const rootIDs: string[] = [];
fileLiElements.forEach(item => {
rootIDs.push(item.getAttribute("data-node-id"));
});
movePathTo({
cb: (toPath, toNotebook) => {
moveToPath(paths, toNotebook[0], toPath[0]);
},
paths,
rootIDs,
flashcard: false
});
}
break;
}

View file

@ -607,11 +607,15 @@ export const bindCardEvent = async (options: {
iconHTML: "",
label: window.siyuan.languages.fileTree,
click() {
movePathTo((toPath, toNotebook) => {
filterElement.setAttribute("data-id", toPath[0] === "/" ? toNotebook[0] : getDisplayName(toPath[0], true, true));
filterElement.setAttribute("data-cardtype", toPath[0] === "/" ? "notebook" : "doc");
fetchNewRound();
}, [], undefined, window.siyuan.languages.specifyPath, true);
movePathTo({
cb: (toPath, toNotebook) => {
filterElement.setAttribute("data-id", toPath[0] === "/" ? toNotebook[0] : getDisplayName(toPath[0], true, true));
filterElement.setAttribute("data-cardtype", toPath[0] === "/" ? "notebook" : "doc");
fetchNewRound();
},
title: window.siyuan.languages.specifyPath,
flashcard: true
});
}
}).element);
if (options.title || response.data.length > 0) {

View file

@ -312,7 +312,7 @@ ${data.shorthandContent}
if (!removeIds) {
removeIds = this.selectIds;
}
fetchPost("/api/inbox/removeShorthands", {ids:removeIds}, () => {
fetchPost("/api/inbox/removeShorthands", {ids: removeIds}, () => {
if (removeIds) {
this.back();
for (let i = this.selectIds.length - 1; i >= 0; i--) {
@ -329,26 +329,29 @@ ${data.shorthandContent}
}
private move(ids: string[]) {
movePathTo(async (toPath, toNotebook) => {
for (let i = 0; i < ids.length; i++) {
const idItem = ids[i];
const response = await fetchSyncPost("/api/inbox/getShorthand", {
id: idItem
});
this.data[response.data.oId] = response.data;
let md = response.data.shorthandMd;
if ("" === md && "" === response.data.shorthandContent && "" != response.data.shorthandURL) {
md = "[" + response.data.shorthandTitle + "](" + response.data.shorthandURL + ")";
movePathTo({
cb: async (toPath, toNotebook) => {
for (let i = 0; i < ids.length; i++) {
const idItem = ids[i];
const response = await fetchSyncPost("/api/inbox/getShorthand", {
id: idItem
});
this.data[response.data.oId] = response.data;
let md = response.data.shorthandMd;
if ("" === md && "" === response.data.shorthandContent && "" != response.data.shorthandURL) {
md = "[" + response.data.shorthandTitle + "](" + response.data.shorthandURL + ")";
}
await fetchSyncPost("/api/filetree/createDoc", {
notebook: toNotebook[0],
path: pathPosix().join(getDisplayName(toPath[0], false, true), Lute.NewNodeID() + ".sy"),
title: replaceFileName(response.data.shorthandTitle),
md,
listDocTree: true,
});
}
await fetchSyncPost("/api/filetree/createDoc", {
notebook: toNotebook[0],
path: pathPosix().join(getDisplayName(toPath[0], false, true), Lute.NewNodeID() + ".sy"),
title: replaceFileName(response.data.shorthandTitle),
md,
listDocTree: true,
});
}
this.remove(ids);
this.remove(ids);
},
flashcard: false
});
}

View file

@ -986,9 +986,18 @@ export const movePathToMenu = (paths: string[]) => {
icon: "iconMove",
accelerator: window.siyuan.config.keymap.general.move.custom,
click() {
movePathTo((toPath, toNotebook) => {
moveToPath(paths, toNotebook[0], toPath[0]);
}, paths);
const rootIDs: string[] = [];
paths.forEach(item => {
rootIDs.push(pathPosix().basename(item).replace(".sy", ""));
});
movePathTo({
cb: (toPath, toNotebook) => {
moveToPath(paths, toNotebook[0], toPath[0]);
},
paths,
flashcard: false,
rootIDs,
});
}
}).element;
};

View file

@ -477,40 +477,44 @@ const initSearchEvent = (app: App, element: Element, config: Config.IUILayoutTab
event.preventDefault();
break;
} else if (type === "path") {
movePathTo((toPath, toNotebook) => {
fetchPost("/api/filetree/getHPathsByPaths", {paths: toPath}, (response) => {
config.idPath = [];
const hPathList: string[] = [];
let enableIncludeChild = false;
toPath.forEach((item, index) => {
if (item === "/") {
config.idPath.push(toNotebook[index]);
hPathList.push(getNotebookName(toNotebook[index]));
} else {
enableIncludeChild = true;
config.idPath.push(pathPosix().join(toNotebook[index], item.replace(".sy", "")));
movePathTo({
cb: (toPath, toNotebook) => {
fetchPost("/api/filetree/getHPathsByPaths", {paths: toPath}, (response) => {
config.idPath = [];
const hPathList: string[] = [];
let enableIncludeChild = false;
toPath.forEach((item, index) => {
if (item === "/") {
config.idPath.push(toNotebook[index]);
hPathList.push(getNotebookName(toNotebook[index]));
} else {
enableIncludeChild = true;
config.idPath.push(pathPosix().join(toNotebook[index], item.replace(".sy", "")));
}
});
if (response.data) {
hPathList.push(...response.data);
}
config.hPath = hPathList.join(" ");
const searchPathElement = element.querySelector("#searchPath");
searchPathElement.classList.remove("fn__none");
searchPathElement.innerHTML = `<div class="b3-chip b3-chip--middle">${escapeHtml(config.hPath)}<svg data-type="remove-path" class="b3-chip__close"><use xlink:href="#iconCloseRound"></use></svg></div>`;
const includeElement = element.querySelector('[data-type="include"]');
includeElement.classList.add("toolbar__icon--active");
if (enableIncludeChild) {
includeElement.removeAttribute("disabled");
} else {
includeElement.setAttribute("disabled", "disabled");
}
config.page = 1;
updateSearchResult(config, element, true);
});
if (response.data) {
hPathList.push(...response.data);
}
config.hPath = hPathList.join(" ");
const searchPathElement = element.querySelector("#searchPath");
searchPathElement.classList.remove("fn__none");
searchPathElement.innerHTML = `<div class="b3-chip b3-chip--middle">${escapeHtml(config.hPath)}<svg data-type="remove-path" class="b3-chip__close"><use xlink:href="#iconCloseRound"></use></svg></div>`;
const includeElement = element.querySelector('[data-type="include"]');
includeElement.classList.add("toolbar__icon--active");
if (enableIncludeChild) {
includeElement.removeAttribute("disabled");
} else {
includeElement.setAttribute("disabled", "disabled");
}
config.page = 1;
updateSearchResult(config, element, true);
});
}, [], undefined, window.siyuan.languages.specifyPath);
},
flashcard: false,
title: window.siyuan.languages.specifyPath
});
event.stopPropagation();
event.preventDefault();
break;

View file

@ -816,8 +816,12 @@ export class Gutter {
accelerator: window.siyuan.config.keymap.general.move.custom,
icon: "iconMove",
click: () => {
movePathTo((toPath) => {
hintMoveBlock(toPath[0], selectsElement, protyle);
movePathTo({
cb: (toPath) => {
hintMoveBlock(toPath[0], selectsElement, protyle);
},
rootIDs: [protyle.block.rootID],
flashcard: false
});
}
}).element);
@ -1372,8 +1376,12 @@ export class Gutter {
label: window.siyuan.languages.move,
accelerator: window.siyuan.config.keymap.general.move.custom,
click: () => {
movePathTo((toPath) => {
hintMoveBlock(toPath[0], [nodeElement], protyle);
movePathTo({
cb: (toPath) => {
hintMoveBlock(toPath[0], [nodeElement], protyle);
},
flashcard: false,
rootIDs: [protyle.block.rootID],
});
}
}).element);

View file

@ -924,6 +924,13 @@ export const turnsIntoOneTransaction = (options: {
parentElement.setAttribute("data-node-id", id);
parentElement.setAttribute("data-type", "NodeBlockquote");
parentElement.innerHTML = '<div class="protyle-attr" contenteditable="false"></div>';
} else if (options.type === "Blocks2Callout") {
// TODO
parentElement = document.createElement("div");
parentElement.classList.add("bq");
parentElement.setAttribute("data-node-id", id);
parentElement.setAttribute("data-type", "NodeBlockquote");
parentElement.innerHTML = '<div class="protyle-attr" contenteditable="false"></div>';
} else if (options.type.endsWith("Ls")) {
parentElement = document.createElement("div");
parentElement.classList.add("list");

View file

@ -463,37 +463,41 @@ export const genSearch = (app: App, config: Config.IUILayoutTabSearchConfig, ele
event.preventDefault();
break;
} else if (target.id === "searchPath") {
movePathTo((toPath, toNotebook) => {
fetchPost("/api/filetree/getHPathsByPaths", {paths: toPath}, (response) => {
config.idPath = [];
const hPathList: string[] = [];
let enableIncludeChild = false;
toPath.forEach((item, index) => {
if (item === "/") {
config.idPath.push(toNotebook[index]);
hPathList.push(getNotebookName(toNotebook[index]));
} else {
enableIncludeChild = true;
config.idPath.push(pathPosix().join(toNotebook[index], item.replace(".sy", "")));
movePathTo({
cb: (toPath, toNotebook) => {
fetchPost("/api/filetree/getHPathsByPaths", {paths: toPath}, (response) => {
config.idPath = [];
const hPathList: string[] = [];
let enableIncludeChild = false;
toPath.forEach((item, index) => {
if (item === "/") {
config.idPath.push(toNotebook[index]);
hPathList.push(getNotebookName(toNotebook[index]));
} else {
enableIncludeChild = true;
config.idPath.push(pathPosix().join(toNotebook[index], item.replace(".sy", "")));
}
});
if (response.data) {
hPathList.push(...response.data);
}
config.hPath = hPathList.join(" ");
config.page = 1;
searchPathInputElement.innerHTML = `${escapeGreat(config.hPath)}<svg class="search__rmpath"><use xlink:href="#iconCloseRound"></use></svg>`;
searchPathInputElement.setAttribute("aria-label", escapeHtml(config.hPath));
const includeElement = element.querySelector("#searchInclude");
includeElement.firstElementChild.classList.add("ft__primary");
if (enableIncludeChild) {
includeElement.removeAttribute("disabled");
} else {
includeElement.setAttribute("disabled", "disabled");
}
inputEvent(element, config, edit, true);
});
if (response.data) {
hPathList.push(...response.data);
}
config.hPath = hPathList.join(" ");
config.page = 1;
searchPathInputElement.innerHTML = `${escapeGreat(config.hPath)}<svg class="search__rmpath"><use xlink:href="#iconCloseRound"></use></svg>`;
searchPathInputElement.setAttribute("aria-label", escapeHtml(config.hPath));
const includeElement = element.querySelector("#searchInclude");
includeElement.firstElementChild.classList.add("ft__primary");
if (enableIncludeChild) {
includeElement.removeAttribute("disabled");
} else {
includeElement.setAttribute("disabled", "disabled");
}
inputEvent(element, config, edit, true);
});
}, [], undefined, window.siyuan.languages.specifyPath);
},
title: window.siyuan.languages.specifyPath,
flashcard: false
});
event.stopPropagation();
event.preventDefault();
break;

View file

@ -12,7 +12,7 @@ interface ILuteNode {
type THintSource = "search" | "av" | "hint";
type TTurnIntoOne = "BlocksMergeSuperBlock" | "Blocks2ULs" | "Blocks2OLs" | "Blocks2TLs" | "Blocks2Blockquote"
type TTurnIntoOne = "BlocksMergeSuperBlock" | "Blocks2ULs" | "Blocks2OLs" | "Blocks2TLs" | "Blocks2Blockquote" | "Blocks2Callout"
type TTurnIntoOneSub = "row" | "col"

View file

@ -148,8 +148,14 @@ export const moveToPath = (fromPaths: string[], toNotebook: string, toPath: stri
});
};
export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
paths?: string[], range?: Range, title?: string, flashcard = false) => {
export const movePathTo = (options: {
cb: (toPath: string[], toNotebook: string[]) => void,
paths?: string[],
range?: Range,
title?: string,
flashcard: boolean
rootIDs?: string[],
}) => {
const exitDialog = window.siyuan.dialogs.find((item) => {
if (item.element.querySelector("#foldList")) {
item.destroy();
@ -161,7 +167,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
}
const dialog = new Dialog({
title: `<div style="padding: 8px;">
${title || window.siyuan.languages.move}
${options.title || window.siyuan.languages.move}
<div style="max-height: 16px;line-height: 14px;-webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, 0) 0, #000 6px);padding-bottom: 4px;margin-bottom: -4px" class="ft__smaller ft__on-surface fn__hidescrollbar"></div>
</div>`,
content: `<div class="b3-form__icon" style="margin: 8px">
@ -181,15 +187,15 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
width: isMobile() ? "92vw" : "50vw",
height: isMobile() ? "80vh" : "70vh",
destroyCallback() {
if (range) {
focusByRange(range);
if (options.range) {
focusByRange(options.range);
}
}
});
dialog.element.querySelector(".b3-dialog__header").setAttribute("style", "padding:0");
dialog.element.setAttribute("data-key", Constants.DIALOG_MOVEPATHTO);
if (paths && paths.length > 0) {
fetchPost("/api/filetree/getHPathsByPaths", {paths}, (response) => {
if (options.paths && options.paths.length > 0) {
fetchPost("/api/filetree/getHPathsByPaths", {paths: options.paths}, (response) => {
dialog.element.querySelector(".b3-dialog__header .ft__smaller").innerHTML = escapeHtml(response.data.join(" "));
});
}
@ -200,7 +206,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
notebooks.forEach((item) => {
if (!item.closed) {
let countHTML = "";
if (flashcard) {
if (options.flashcard) {
countHTML = `<span class="counter counter--right b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.flashcardNewCard}">${item.newFlashcardCount}</span>
<span class="counter counter--right b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.flashcardDueCard}">${item.dueFlashcardCount}</span>
<span class="counter counter--right b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.flashcardCard}">${item.flashcardCount}</span>`;
@ -217,7 +223,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
}
});
searchTreeElement.innerHTML = html;
}, flashcard);
}, options.flashcard);
const inputElement = dialog.element.querySelector(".b3-text-field") as HTMLInputElement;
inputElement.value = window.siyuan.storage[Constants.LOCAL_MOVE_PATH].k;
@ -238,7 +244,8 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
searchListElement.scrollTo(0, 0);
fetchPost("/api/filetree/searchDocs", {
k: inputElement.value,
flashcard,
flashcard: options.flashcard,
excludeIDs: options.rootIDs,
}, (data) => {
let fileHTML = "";
data.data.forEach((item: {
@ -251,7 +258,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
flashcardCount: string
}) => {
let countHTML = "";
if (flashcard) {
if (options.flashcard) {
countHTML = `<span class="fn__flex-1"></span>
<span class="counter counter--right b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.flashcardNewCard}">${item.newFlashcardCount}</span>
<span class="counter counter--right b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.flashcardDueCard}">${item.dueFlashcardCount}</span>
@ -383,7 +390,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
if (searchListElement.classList.contains("fn__none")) {
if ((event.key === "ArrowRight" && !currentItemElement.querySelector(".b3-list-item__arrow--open") && !currentItemElement.querySelector(".b3-list-item__toggle").classList.contains("fn__hidden")) ||
(event.key === "ArrowLeft" && currentItemElement.querySelector(".b3-list-item__arrow--open"))) {
getLeaf(currentItemElement, flashcard);
getLeaf(currentItemElement, options.flashcard);
event.preventDefault();
return;
}
@ -516,7 +523,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
pathList.push(item.getAttribute("data-path"));
notebookIdList.push(item.getAttribute("data-box"));
});
cb(pathList, notebookIdList);
options.cb(pathList, notebookIdList);
dialog.destroy();
event.preventDefault();
}
@ -525,7 +532,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
let target = event.target as HTMLElement;
while (target && !target.isEqualNode(dialog.element)) {
if (target.classList.contains("b3-list-item__toggle")) {
getLeaf(target.parentElement, flashcard);
getLeaf(target.parentElement, options.flashcard);
event.preventDefault();
event.stopPropagation();
break;
@ -546,7 +553,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
pathList.push(item.getAttribute("data-path"));
notebookIdList.push(item.getAttribute("data-box"));
});
cb(pathList, notebookIdList);
options.cb(pathList, notebookIdList);
dialog.destroy();
event.preventDefault();
event.stopPropagation();
@ -562,7 +569,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
if (currentItemElements.length === 0) {
return;
}
if (title === window.siyuan.languages.specifyPath && isOnlyMeta(event)) {
if (options.title === window.siyuan.languages.specifyPath && isOnlyMeta(event)) {
if (currentItemElements.length === 1 && currentItemElements[0] === target) {
// 至少需选中一个
} else {
@ -573,7 +580,7 @@ export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void,
target.classList.add("b3-list-item--focus");
}
if (target.getAttribute("data-path") === "/") {
getLeaf(target, flashcard);
getLeaf(target, options.flashcard);
}
event.preventDefault();
event.stopPropagation();