This commit is contained in:
Vanessa 2023-04-07 21:46:59 +08:00
parent c8765621ba
commit 57bc6db377
4 changed files with 232 additions and 103 deletions

View file

@ -5,10 +5,93 @@ import {fetchPost} from "../../util/fetch";
import {getIconByType} from "../../editor/getIcon";
import {preventScroll} from "../../protyle/scroll/preventScroll";
import {openModel} from "./model";
import {getNotebookName, movePathTo, pathPosix} from "../../util/pathName";
import {filterMenu, initCriteriaMenu, moreMenu, queryMenu} from "../../search/menu";
import {getDisplayName, getNotebookIcon, getNotebookName, movePathTo, pathPosix} from "../../util/pathName";
import {filterMenu, getKeyByLiElement, initCriteriaMenu, moreMenu, queryMenu} from "../../search/menu";
import {setStorageVal} from "../../protyle/util/compatibility";
import {escapeHtml} from "../../util/escape";
import {escapeGreat, escapeHtml} from "../../util/escape";
import {unicode2Emoji} from "../../emoji";
import {newFileByName} from "../../util/newFile";
import {showMessage} from "../../dialog/message";
import {reloadProtyle} from "../../protyle/util/reload";
const replace = (element: Element, config: ISearchOption, isAll: boolean) => {
if (config.method === 1 || config.method === 2) {
showMessage(window.siyuan.languages._kernel[132]);
return;
}
const searchListElement = element.querySelector("#searchList");
const replaceInputElement = element.querySelector("#toolbarReplace") as HTMLInputElement;
const loadElement = replaceInputElement.nextElementSibling;
if (!loadElement.classList.contains("fn__none")) {
return;
}
let currentLiElement: HTMLElement = searchListElement.querySelector(".b3-list-item--focus");
if (!currentLiElement) {
return;
}
loadElement.classList.remove("fn__none");
loadElement.nextElementSibling.classList.add("fn__none");
let ids: string[] = [];
if (isAll) {
searchListElement.querySelectorAll('.b3-list-item[data-type="search-item"]').forEach(item => {
ids.push(item.getAttribute("data-node-id"));
});
} else {
ids = [currentLiElement.getAttribute("data-node-id")];
}
fetchPost("/api/search/findReplace", {
k: config.method === 0 ? getKeyByLiElement(currentLiElement) : (document.querySelector("#toolbarSearch") as HTMLInputElement).value,
r: replaceInputElement.value,
ids,
types: config.types,
method: config.method,
}, (response) => {
loadElement.classList.add("fn__none");
loadElement.nextElementSibling.classList.remove("fn__none");
if (response.code === 1) {
showMessage(response.msg);
return;
}
if (ids.length > 1) {
return;
}
reloadProtyle(window.siyuan.mobile.editor.protyle);
if (currentLiElement.nextElementSibling) {
currentLiElement.nextElementSibling.classList.add("b3-list-item--focus");
} else if (currentLiElement.previousElementSibling) {
currentLiElement.previousElementSibling.classList.add("b3-list-item--focus");
}
if (config.group === 1) {
if (currentLiElement.nextElementSibling || currentLiElement.previousElementSibling) {
currentLiElement.remove();
} else {
const nextDocElement = currentLiElement.parentElement.nextElementSibling || currentLiElement.parentElement.previousElementSibling.previousElementSibling?.previousElementSibling;
if (nextDocElement) {
nextDocElement.nextElementSibling.firstElementChild.classList.add("b3-list-item--focus");
nextDocElement.nextElementSibling.classList.remove("fn__none");
nextDocElement.firstElementChild.firstElementChild.classList.add("b3-list-item__arrow--open");
}
currentLiElement.parentElement.previousElementSibling.remove();
currentLiElement.parentElement.remove();
}
} else {
currentLiElement.remove();
}
currentLiElement = searchListElement.querySelector(".b3-list-item--focus");
if (!currentLiElement) {
searchListElement.innerHTML = `<div class="b3-list--empty">${window.siyuan.languages.emptyContent}</div>`;
return;
}
if (searchListElement.scrollTop < currentLiElement.offsetTop - searchListElement.clientHeight + 30 ||
searchListElement.scrollTop > currentLiElement.offsetTop) {
searchListElement.scrollTop = currentLiElement.offsetTop - searchListElement.clientHeight + 30;
}
});
};
const updateConfig = (element: Element, newConfig: ISearchOption, config: ISearchOption) => {
newConfig.hPath = config.hPath;
@ -64,43 +147,84 @@ const updateConfig = (element: Element, newConfig: ISearchOption, config: ISearc
Object.assign(config, newConfig);
window.siyuan.storage[Constants.LOCAL_SEARCHDATA] = Object.assign({}, config);
setStorageVal(Constants.LOCAL_SEARCHDATA, window.siyuan.storage[Constants.LOCAL_SEARCHDATA]);
updateSearchResult(config);
updateSearchResult(config, element);
window.siyuan.menus.menu.remove();
};
const onRecentBlocks = (data: IBlock[], matchedRootCount?: number, matchedBlockCount?: number) => {
const listElement = document.querySelector("#searchList")
let resultHTML = "";
if (matchedBlockCount) {
resultHTML = '<div class="b3-list-item ft__smaller ft__on-surface">' + window.siyuan.languages.findInDoc.replace("${x}", matchedRootCount).replace("${y}", matchedBlockCount) + "</div>";
}
data.forEach((item: IBlock) => {
resultHTML += `<div class="b3-list-item b3-list-item--two" data-url="${item.box}" data-path="${item.path}" data-id="${item.id}">
<div class="b3-list-item__first">
<svg class="b3-list-item__graphic"><use xlink:href="#${getIconByType(item.type)}"></use></svg>
<span class="b3-list-item__text">${item.content}</span>
</div>
<div class="b3-list-item__meta">${Lute.EscapeHTMLStr(item.hPath)}</div>
data.forEach((item: IBlock, index: number) => {
const title = getNotebookName(item.box) + getDisplayName(item.hPath, false);
if (item.children) {
resultHTML += `<div class="b3-list-item">
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
<svg class="b3-list-item__arrow b3-list-item__arrow--open"><use xlink:href="#iconRight"></use></svg>
</span>
${unicode2Emoji(getNotebookIcon(item.box) || Constants.SIYUAN_IMAGE_NOTE, false, "b3-list-item__graphic", true)}
<span class="b3-list-item__text" style="color: var(--b3-theme-on-surface)">${escapeGreat(title)}</span>
</div><div>`;
item.children.forEach((childItem, childIndex) => {
resultHTML += `<div style="padding-left: 36px" data-type="search-item" class="b3-list-item${childIndex === 0 && index === 0 ? " b3-list-item--focus" : ""}" data-node-id="${childItem.id}">
<svg class="b3-list-item__graphic"><use xlink:href="#${getIconByType(childItem.type)}"></use></svg>
${unicode2Emoji(childItem.ial.icon, false, "b3-list-item__graphic", true)}
<span class="b3-list-item__text">${childItem.content}</span>
</div>`;
});
document.querySelector("#searchList").innerHTML = resultHTML;
resultHTML += "</div>";
} else {
resultHTML += `<div class="b3-list-item b3-list-item--two${index === 0 ? " b3-list-item--focus" : ""}" data-type="search-item" data-node-id="${item.id}">
<div class="b3-list-item__first">
<svg class="b3-list-item__graphic"><use xlink:href="#${getIconByType(item.type)}"></use></svg>
${unicode2Emoji(item.ial.icon, false, "b3-list-item__graphic", true)}
<span class="b3-list-item__text">${item.content}</span>
</div>
<span class="b3-list-item__meta b3-list-item__meta--ellipsis"">${escapeGreat(title)}</span>
</div>`;
}
});
listElement.innerHTML = resultHTML ||
`<div class="b3-list-item b3-list-item--focus" data-type="search-new">
<svg class="b3-list-item__graphic"><use xlink:href="#iconFile"></use></svg>
<span class="b3-list-item__text">
${window.siyuan.languages.newFile} <mark>${(document.querySelector("#toolbarSearch") as HTMLInputElement).value}</mark>
</span>
</div>`;
listElement.scrollTop = 0;
let countHTML = ""
if (matchedBlockCount) {
countHTML = `<div class="b3-list--empty">${window.siyuan.languages.findInDoc.replace("${x}", matchedRootCount).replace("${y}", matchedBlockCount)}</div>`;
}
listElement.previousElementSibling.innerHTML = countHTML;
};
let toolbarSearchTimeout = 0;
export const updateSearchResult = (config: ISearchOption) => {
export const updateSearchResult = (config: ISearchOption, element: Element) => {
clearTimeout(toolbarSearchTimeout);
toolbarSearchTimeout = window.setTimeout(() => {
const loadingElement = element.querySelector(".fn__loading--top");
loadingElement.classList.remove("fn__none");
const inputElement = document.getElementById("toolbarSearch") as HTMLInputElement;
if (inputElement.value === "") {
if (inputElement.value === "" && (!config.idPath || config.idPath.length === 0)) {
fetchPost("/api/block/getRecentUpdatedBlocks", {}, (response) => {
onRecentBlocks(response.data);
loadingElement.classList.add("fn__none");
});
} else {
fetchPost("/api/search/fullTextSearchBlock", {query: inputElement.value,}, (response) => {
fetchPost("/api/search/fullTextSearchBlock", {
query: inputElement.value,
method: config.method,
types: config.types,
paths: config.idPath || [],
groupBy: config.group,
orderBy: config.sort,
}, (response) => {
onRecentBlocks(response.data.blocks, response.data.matchedRootCount, response.data.matchedBlockCount);
loadingElement.classList.add("fn__none");
});
}
}, Constants.TIMEOUT_SEARCH);
return toolbarSearchTimeout
};
const initSearchEvent = (element: Element, config: ISearchOption) => {
@ -110,13 +234,13 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
if (event && event.isComposing) {
return;
}
updateSearchResult(config);
updateSearchResult(config, element);
});
searchInputElement.addEventListener("input", (event: InputEvent) => {
if (event && event.isComposing) {
return;
}
updateSearchResult(config);
updateSearchResult(config, element);
});
const replaceInputElement = element.querySelector(".toolbar .b3-text-field") as HTMLInputElement
replaceInputElement.value = config.r || ""
@ -124,6 +248,7 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
const criteriaData: ISearchOption[] = [];
initCriteriaMenu(element.querySelector("#criteria"), criteriaData);
const searchListElement = element.querySelector("#searchList") as HTMLElement;
element.addEventListener("click", (event: MouseEvent) => {
let target = event.target as HTMLElement;
while (target && !target.isSameNode(element)) {
@ -161,30 +286,30 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
config.idPath = [];
config.hPath = "";
element.querySelector("#searchPath").classList.add("fn__none")
toolbarSearchTimeout = updateSearchResult(config);
updateSearchResult(config, element);
const includeElement = element.querySelector('[data-type="include"]');
includeElement.classList.remove("toolbar__icon--active");
includeElement.setAttribute("disabled", "disabled");
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "searchExpand") {
// Array.from(searchPanelElement.children).forEach(item => {
// if (item.classList.contains("b3-list-item")) {
// item.querySelector(".b3-list-item__arrow").classList.add("b3-list-item__arrow--open");
// item.nextElementSibling.classList.remove("fn__none");
// }
// });
} else if (type === "expand") {
Array.from(searchListElement.children).forEach(item => {
if (item.classList.contains("b3-list-item")) {
item.querySelector(".b3-list-item__arrow").classList.add("b3-list-item__arrow--open");
item.nextElementSibling.classList.remove("fn__none");
}
});
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "searchCollapse") {
// Array.from(searchPanelElement.children).forEach(item => {
// if (item.classList.contains("b3-list-item")) {
// item.querySelector(".b3-list-item__arrow").classList.remove("b3-list-item__arrow--open");
// item.nextElementSibling.classList.add("fn__none");
// }
// });
} else if (type === "contract") {
Array.from(searchListElement.children).forEach(item => {
if (item.classList.contains("b3-list-item")) {
item.querySelector(".b3-list-item__arrow").classList.remove("b3-list-item__arrow--open");
item.nextElementSibling.classList.add("fn__none");
}
});
event.stopPropagation();
event.preventDefault();
break;
@ -207,9 +332,11 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
hPathList.push(...response.data);
}
config.hPath = hPathList.join(" ");
const searchPathElement = element.querySelector("#searchPath")
searchPathElement.classList.remove("fn__none");
element.querySelector("#searchPath").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) {
@ -217,28 +344,28 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
} else {
includeElement.setAttribute("disabled", "disabled");
}
toolbarSearchTimeout = updateSearchResult(config);
updateSearchResult(config, element);
});
}, [], undefined, window.siyuan.languages.specifyPath);
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "searchInclude") {
target.classList.toggle("b3-button--cancel");
if (target.classList.contains("b3-button--cancel")) {
config.idPath.forEach((item, index) => {
if (!item.endsWith(".sy") && item.split("/").length > 1) {
config.idPath[index] = item + ".sy";
}
});
} else {
} else if (type === "include") {
target.classList.toggle("toolbar__icon--active");
if (target.classList.contains("toolbar__icon--active")) {
config.idPath.forEach((item, index) => {
if (item.endsWith(".sy")) {
config.idPath[index] = item.replace(".sy", "");
}
});
} else {
config.idPath.forEach((item, index) => {
if (!item.endsWith(".sy") && item.split("/").length > 1) {
config.idPath[index] = item + ".sy";
}
// inputTimeout = inputEvent(element, config, inputTimeout, edit);
});
}
updateSearchResult(config, element);
event.stopPropagation();
event.preventDefault();
break;
@ -251,7 +378,7 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
break;
} else if (type === "more") {
moreMenu(config, criteriaData, element, () => {
updateSearchResult(config);
updateSearchResult(config, element);
}, () => {
updateConfig(element, {
removed: true,
@ -286,27 +413,27 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
break;
} else if (type === "filter") {
filterMenu(config, () => {
updateSearchResult(config)
updateSearchResult(config, element)
});
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "query") {
queryMenu(config, () => {
updateSearchResult(config)
updateSearchResult(config, element)
});
window.siyuan.menus.menu.element.style.zIndex = "220";
window.siyuan.menus.menu.fullscreen();
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "replaceAllBtn") {
// replace(element, config, edit, true);
} else if (type === "replace-all") {
replace(element, config, true);
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "replaceBtn") {
// replace(element, config, edit, false);
} else if (type === "replace") {
replace(element, config, false);
event.stopPropagation();
event.preventDefault();
break;
@ -317,15 +444,10 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
event.preventDefault();
break;
} else if (target.classList.contains("b3-list-item")) {
if (target.parentElement.id === "searchHistoryList") {
searchInputElement.value = target.textContent;
// inputTimeout = inputEvent(element, config, inputTimeout, edit);
} else if (target.parentElement.id === "replaceHistoryList") {
replaceInputElement.value = target.textContent;
} else if (target.getAttribute("data-type") === "search-new") {
// newEmptyFileByInput(searchInputElement.value);
if (target.getAttribute("data-type") === "search-new") {
newFileByName(searchInputElement.value);
} else if (target.getAttribute("data-type") === "search-item") {
const id = target.getAttribute("data-id");
const id = target.getAttribute("data-node-id");
if (window.siyuan.mobile.editor.protyle) {
preventScroll(window.siyuan.mobile.editor.protyle);
}
@ -365,14 +487,16 @@ export const popSearch = (config = window.siyuan.storage[Constants.LOCAL_SEARCHD
<div class="toolbar toolbar--border${config.hasReplace ? "" : " fn__none"}">
<svg class="toolbar__icon"><use xlink:href="#iconReplace"></use></svg>
<input id="toolbarReplace" class="b3-text-field fn__flex-1">
<svg class="fn__rotate fn__none toolbar__icon"><use xlink:href="#iconRefresh"></use></svg>
<div class="fn__space"></div>
<button class="b3-button b3-button--outline fn__flex-center">${window.siyuan.languages.replaceAll}</button>
<button data-type="replace-all" class="b3-button b3-button--outline fn__flex-center">${window.siyuan.languages.replaceAll}</button>
<div class="fn__space"></div>
<button class="b3-button b3-button--outline fn__flex-center">${window.siyuan.languages.replace}</button>
<button data-type="replace" class="b3-button b3-button--outline fn__flex-center">${window.siyuan.languages.replace}</button>
<div class="fn__space"></div>
</div>
<div id="criteria" style="background-color: var(--b3-theme-background);" class="b3-chips"></div>
<div id="searchList" style="overflow:auto;" class="fn__flex-1"></div>
<div style="background-color: var(--b3-theme-background);"></div>
<div id="searchList" style="overflow:auto;" class="fn__flex-1 b3-list b3-list--background"></div>
<div id="searchPath" class="b3-chips${config.hPath ? "" : " fn__none"}" style="background-color: var(--b3-theme-background);">
<div class="b3-chip b3-chip--middle">
${escapeHtml(config.hPath)}
@ -391,10 +515,11 @@ export const popSearch = (config = window.siyuan.storage[Constants.LOCAL_SEARCHD
<svg data-type="more" class="toolbar__icon"><use xlink:href="#iconMore"></use></svg>
<span class="fn__flex-1"></span>
</div>
<div class="fn__loading fn__loading--top"><img width="120px" src="/stage/loading-pure.svg"></div>
</div>`,
bindEvent(element) {
initSearchEvent(element.firstElementChild, config);
toolbarSearchTimeout = updateSearchResult(config);
updateSearchResult(config, element);
}
});
};

View file

@ -371,3 +371,11 @@ export const initCriteriaMenu = (element: HTMLElement, data: ISearchOption[]) =>
}
});
};
export const getKeyByLiElement = (element: HTMLElement) => {
const keys: string[] = [];
element.querySelectorAll("mark").forEach(item => {
keys.push(item.textContent);
});
return [...new Set(keys)].join(" ");
};

View file

@ -16,14 +16,11 @@ import {disabledProtyle, onGet} from "../protyle/util/onGet";
import {addLoading, setPadding} from "../protyle/ui/initUI";
import {getIconByType} from "../editor/getIcon";
import {unicode2Emoji} from "../emoji";
import {Dialog} from "../dialog";
import {hasClosestByClassName} from "../protyle/util/hasClosest";
import {setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility";
import {replaceFileName} from "../editor/rename";
import {hideElements} from "../protyle/ui/hideElements";
import {getNewFilePath} from "../util/newFile";
import {newFileByName} from "../util/newFile";
import {matchHotKey} from "../protyle/util/hotKey";
import {filterMenu, initCriteriaMenu, moreMenu, queryMenu} from "./menu";
import {filterMenu, getKeyByLiElement, initCriteriaMenu, moreMenu, queryMenu} from "./menu";
const saveKeyList = (type: "keys" | "replaceKeys", value: string) => {
let list: string[] = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS][type];
@ -82,23 +79,6 @@ export const openGlobalSearch = (text: string, replace: boolean) => {
setPanelFocus(tab.panelElement);
};
const newEmptyFileByInput = (value: string) => {
const newData = getNewFilePath(true);
fetchPost("/api/filetree/getHPathByPath", {
notebook: newData.notebookId,
path: newData.currentPath,
}, (responsePath) => {
fetchPost("/api/filetree/createDocWithMd", {
notebook: newData.notebookId,
path: pathPosix().join(responsePath.data, replaceFileName(value.trim()) || "Untitled"),
markdown: ""
}, response => {
hideElements(["dialog"]);
openFileById({id: response.data, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
});
});
};
// closeCB 不存在为页签搜索
export const genSearch = (config: ISearchOption, element: Element, closeCB?: () => void) => {
let methodText = window.siyuan.languages.keyword;
@ -621,7 +601,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
replaceInputElement.value = target.textContent;
replaceHistoryElement.classList.add("fn__none");
} else if (target.getAttribute("data-type") === "search-new") {
newEmptyFileByInput(searchInputElement.value);
newFileByName(searchInputElement.value);
} else if (target.getAttribute("data-type") === "search-item") {
if (event.detail === 1) {
clickTimeout = window.setTimeout(() => {
@ -644,7 +624,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
getArticle({
edit,
id: target.getAttribute("data-node-id"),
k: getKey(target)
k: getKeyByLiElement(target)
});
searchInputElement.focus();
} else if (target.classList.contains("b3-list-item--focus")) {
@ -706,14 +686,14 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
}
const focusIsNew = currentList.getAttribute("data-type") === "search-new";
if (focusIsNew && matchHotKey(window.siyuan.config.keymap.general.newFile.custom, event)) {
newEmptyFileByInput(searchInputElement.value);
newFileByName(searchInputElement.value);
event.preventDefault();
event.stopPropagation();
return;
}
if (event.key === "Enter") {
if (focusIsNew) {
newEmptyFileByInput(searchInputElement.value);
newFileByName(searchInputElement.value);
} else {
const id = currentList.getAttribute("data-node-id");
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
@ -755,7 +735,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
}
getArticle({
id: currentList.getAttribute("data-node-id"),
k: getKey(currentList),
k: getKeyByLiElement(currentList),
edit
});
event.preventDefault();
@ -781,7 +761,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
}
getArticle({
id: currentList.getAttribute("data-node-id"),
k: getKey(currentList),
k: getKeyByLiElement(currentList),
edit
});
event.preventDefault();
@ -877,14 +857,6 @@ const updateConfig = (element: Element, item: ISearchOption, config: ISearchOpti
window.siyuan.menus.menu.remove();
};
const getKey = (element: HTMLElement) => {
const keys: string[] = [];
element.querySelectorAll("mark").forEach(item => {
keys.push(item.textContent);
});
return [...new Set(keys)].join(" ");
};
const renderNextSearchMark = (options: {
id: string,
edit: Protyle,
@ -973,7 +945,7 @@ const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll:
rootIds = [currentList.getAttribute("data-root-id")];
}
fetchPost("/api/search/findReplace", {
k: config.method === 0 ? getKey(currentList) : (element.querySelector("#searchInput") as HTMLInputElement).value,
k: config.method === 0 ? getKeyByLiElement(currentList) : (element.querySelector("#searchInput") as HTMLInputElement).value,
r: replaceInputElement.value,
ids,
types: config.types,
@ -1027,7 +999,7 @@ const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll:
getArticle({
edit,
id: currentList.getAttribute("data-node-id"),
k: getKey(currentList)
k: getKeyByLiElement(currentList)
});
});
};
@ -1106,14 +1078,14 @@ ${unicode2Emoji(item.ial.icon, false, "b3-list-item__graphic", true)}
getArticle({
edit,
id: data[0].children[0].id,
k: getKey(contentElement),
k: getKeyByLiElement(contentElement),
});
} else {
contentElement.innerHTML = data[0].content;
getArticle({
edit,
id: data[0].id,
k: getKey(contentElement),
k: getKeyByLiElement(contentElement),
});
}
} else {

View file

@ -9,7 +9,10 @@ import {openFileById} from "../editor/util";
import {fetchPost} from "./fetch";
import {getDisplayName, getOpenNotebookCount, pathPosix} from "./pathName";
import {Constants} from "../constants";
import {validateName} from "../editor/rename";
import {replaceFileName, validateName} from "../editor/rename";
import {hideElements} from "../protyle/ui/hideElements";
import {isMobile} from "./functions";
import {openMobileFileById} from "../mobile/editor";
export const getNewFilePath = (useSavePath: boolean) => {
let notebookId = "";
@ -149,3 +152,24 @@ export const getSavePath = (pathString: string, notebookId: string, cb: (p: stri
}
});
};
export const newFileByName = (value: string) => {
const newData = getNewFilePath(true);
fetchPost("/api/filetree/getHPathByPath", {
notebook: newData.notebookId,
path: newData.currentPath,
}, (responsePath) => {
fetchPost("/api/filetree/createDocWithMd", {
notebook: newData.notebookId,
path: pathPosix().join(responsePath.data, replaceFileName(value.trim()) || "Untitled"),
markdown: ""
}, response => {
hideElements(["dialog"]);
if (isMobile()) {
openMobileFileById(response.data, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
} else {
openFileById({id: response.data, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
}
});
});
};