2022-05-26 15:18:53 +08:00
|
|
|
import * as path from "path";
|
|
|
|
|
import {fetchPost, fetchSyncPost} from "./fetch";
|
|
|
|
|
import {Dialog} from "../dialog";
|
|
|
|
|
import {escapeHtml} from "./escape";
|
|
|
|
|
import {isMobile} from "./functions";
|
|
|
|
|
import {focusByRange} from "../protyle/util/selection";
|
|
|
|
|
import {hasClosestByClassName} from "../protyle/util/hasClosest";
|
|
|
|
|
import {unicode2Emoji} from "../emoji";
|
2022-08-15 11:44:11 +08:00
|
|
|
import {Constants} from "../constants";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
|
|
|
|
export const addBaseURL = () => {
|
|
|
|
|
let baseURLElement = document.getElementById("baseURL");
|
|
|
|
|
if (!baseURLElement) {
|
|
|
|
|
baseURLElement = document.createElement("base");
|
|
|
|
|
baseURLElement.id = "baseURL";
|
|
|
|
|
}
|
|
|
|
|
baseURLElement.setAttribute("href", location.origin);
|
|
|
|
|
document.getElementsByTagName("head")[0].appendChild(baseURLElement);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getDisplayName = (filePath: string, basename = true, removeSY = false) => {
|
|
|
|
|
let name = filePath;
|
|
|
|
|
if (basename) {
|
|
|
|
|
name = pathPosix().basename(filePath);
|
|
|
|
|
}
|
|
|
|
|
if (removeSY && name.endsWith(".sy")) {
|
|
|
|
|
name = name.substr(0, name.length - 3);
|
|
|
|
|
}
|
|
|
|
|
return name;
|
|
|
|
|
};
|
|
|
|
|
|
2022-07-16 11:14:21 +08:00
|
|
|
export const getAssetName = (assetPath: string) => {
|
2022-07-17 11:06:57 +08:00
|
|
|
return assetPath.substring(7, assetPath.length - pathPosix().extname(assetPath).length - 23);
|
|
|
|
|
};
|
2022-07-16 11:14:21 +08:00
|
|
|
|
2022-05-26 15:18:53 +08:00
|
|
|
export const isLocalPath = (link: string) => {
|
2022-06-01 23:52:22 +08:00
|
|
|
if (!link) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-09-27 15:31:48 +08:00
|
|
|
|
2022-09-28 12:14:18 +08:00
|
|
|
link = link.trim();
|
2022-09-27 15:31:48 +08:00
|
|
|
if (1 > link.length) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-28 12:14:18 +08:00
|
|
|
link = link.toLowerCase();
|
2022-09-27 15:31:48 +08:00
|
|
|
if (link.startsWith("assets/") || link.startsWith("file://") || link.startsWith("\\\\") /* Windows 网络共享路径 */) {
|
2022-09-28 12:14:18 +08:00
|
|
|
return true;
|
2022-09-27 15:31:48 +08:00
|
|
|
}
|
|
|
|
|
|
2022-09-28 12:14:18 +08:00
|
|
|
const colonIdx = link.indexOf(":");
|
|
|
|
|
return 1 === colonIdx; // 冒号前面只有一个字符认为是 Windows 盘符而不是网络协议
|
2022-05-26 15:18:53 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const pathPosix = () => {
|
|
|
|
|
if (path.posix) {
|
|
|
|
|
return path.posix;
|
|
|
|
|
}
|
|
|
|
|
return path;
|
|
|
|
|
};
|
|
|
|
|
|
2022-11-04 21:48:50 +08:00
|
|
|
export const getTopPaths = (liElements:Element[]) => {
|
|
|
|
|
const fromPaths:string[] = []
|
|
|
|
|
liElements.forEach((item: HTMLElement) => {
|
|
|
|
|
if (item.getAttribute("data-type") !== "navigation-root") {
|
|
|
|
|
const dataPath = item.getAttribute("data-path")
|
|
|
|
|
const isChild = fromPaths.find(item => {
|
|
|
|
|
if (dataPath.startsWith(item.replace(".sy", ""))) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
if (!isChild) {
|
|
|
|
|
fromPaths.push(dataPath)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return fromPaths
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const moveToPath = (fromPaths: string[], toNotebook: string, toPath: string, dialog: Dialog) => {
|
|
|
|
|
fetchPost("/api/filetree/moveDocs", {
|
|
|
|
|
toNotebook,
|
|
|
|
|
fromPaths,
|
|
|
|
|
toPath,
|
2022-05-26 15:18:53 +08:00
|
|
|
});
|
|
|
|
|
dialog.destroy();
|
|
|
|
|
};
|
|
|
|
|
|
2022-11-04 21:48:50 +08:00
|
|
|
export const movePathTo = async (paths: string[], focus = true) => {
|
2022-05-26 15:18:53 +08:00
|
|
|
const exitDialog = window.siyuan.dialogs.find((item) => {
|
|
|
|
|
if (item.element.querySelector("#foldList")) {
|
|
|
|
|
item.destroy();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (exitDialog) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-11-04 21:48:50 +08:00
|
|
|
const response = await fetchSyncPost("/api/filetree/getHPathsByPaths", {
|
|
|
|
|
paths
|
2022-05-26 15:18:53 +08:00
|
|
|
});
|
|
|
|
|
let range: Range;
|
|
|
|
|
if (getSelection().rangeCount > 0) {
|
|
|
|
|
range = getSelection().getRangeAt(0);
|
|
|
|
|
}
|
|
|
|
|
const dialog = new Dialog({
|
2022-11-04 21:48:50 +08:00
|
|
|
title: `${window.siyuan.languages.move} <span class="ft__smaller ft__on-surface">${escapeHtml(response.data.join(", "))}</span>`,
|
2022-05-26 15:18:53 +08:00
|
|
|
content: `<div class="b3-form__icon b3-form__space">
|
|
|
|
|
<svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
|
|
|
|
|
<input class="b3-text-field fn__block b3-form__icon-input" value="" placeholder="${window.siyuan.languages.search}">
|
|
|
|
|
</div>
|
2022-10-15 11:35:53 +08:00
|
|
|
<ul id="foldList" class="b3-list b3-list--background" style="height: 50vh;overflow: auto;position: relative"></ul>
|
|
|
|
|
<div class="fn__hr"></div>`,
|
2022-05-26 15:18:53 +08:00
|
|
|
width: isMobile() ? "80vw" : "50vw",
|
|
|
|
|
destroyCallback() {
|
|
|
|
|
if (range && focus) {
|
|
|
|
|
focusByRange(range);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const searchPanelElement = dialog.element.querySelector("#foldList");
|
|
|
|
|
const inputElement = dialog.element.querySelector(".b3-text-field") as HTMLInputElement;
|
|
|
|
|
inputElement.focus();
|
|
|
|
|
const inputEvent = (event?: InputEvent) => {
|
|
|
|
|
if (event && event.isComposing) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
fetchPost("/api/filetree/searchDocs", {
|
|
|
|
|
k: inputElement.value
|
|
|
|
|
}, (data) => {
|
|
|
|
|
let fileHTML = "";
|
2022-06-01 23:52:22 +08:00
|
|
|
data.data.forEach((item: { boxIcon: string, box: string, hPath: string, path: string }) => {
|
2022-11-04 21:48:50 +08:00
|
|
|
if (paths.includes(item.path)) {
|
2022-05-26 15:18:53 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
fileHTML += `<li class="b3-list-item${fileHTML === "" ? " b3-list-item--focus" : ""}" data-path="${item.path}" data-box="${item.box}">
|
2022-08-15 11:44:11 +08:00
|
|
|
<span class="b3-list-item__icon">${unicode2Emoji(item.boxIcon || Constants.SIYUAN_IMAGE_NOTE)}</span>
|
2022-05-26 15:18:53 +08:00
|
|
|
<span class="b3-list-item__showall">${escapeHtml(item.hPath)}</span>
|
|
|
|
|
</li>`;
|
|
|
|
|
});
|
|
|
|
|
searchPanelElement.innerHTML = fileHTML;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
inputEvent();
|
|
|
|
|
inputElement.addEventListener("compositionend", (event: InputEvent) => {
|
|
|
|
|
inputEvent(event);
|
|
|
|
|
});
|
|
|
|
|
inputElement.addEventListener("input", (event: InputEvent) => {
|
|
|
|
|
inputEvent(event);
|
|
|
|
|
});
|
|
|
|
|
const lineHeight = 28;
|
|
|
|
|
inputElement.addEventListener("keydown", (event: KeyboardEvent) => {
|
|
|
|
|
let currentList: HTMLElement = dialog.element.querySelector(".b3-list-item--focus");
|
|
|
|
|
if (!currentList) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (event.key === "ArrowDown") {
|
|
|
|
|
currentList.classList.remove("b3-list-item--focus");
|
|
|
|
|
if (!currentList.nextElementSibling) {
|
|
|
|
|
searchPanelElement.children[0].classList.add("b3-list-item--focus");
|
|
|
|
|
} else {
|
|
|
|
|
currentList.nextElementSibling.classList.add("b3-list-item--focus");
|
|
|
|
|
}
|
|
|
|
|
currentList = searchPanelElement.querySelector(".b3-list-item--focus");
|
|
|
|
|
if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight ||
|
|
|
|
|
searchPanelElement.scrollTop > currentList.offsetTop) {
|
|
|
|
|
searchPanelElement.scrollTop = currentList.offsetTop - searchPanelElement.clientHeight + lineHeight;
|
|
|
|
|
}
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
} else if (event.key === "ArrowUp") {
|
|
|
|
|
currentList.classList.remove("b3-list-item--focus");
|
|
|
|
|
if (!currentList.previousElementSibling) {
|
|
|
|
|
const length = searchPanelElement.children.length;
|
|
|
|
|
searchPanelElement.children[length - 1].classList.add("b3-list-item--focus");
|
|
|
|
|
} else {
|
|
|
|
|
currentList.previousElementSibling.classList.add("b3-list-item--focus");
|
|
|
|
|
}
|
|
|
|
|
currentList = searchPanelElement.querySelector(".b3-list-item--focus");
|
|
|
|
|
if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight ||
|
|
|
|
|
searchPanelElement.scrollTop > currentList.offsetTop - lineHeight * 2) {
|
|
|
|
|
searchPanelElement.scrollTop = currentList.offsetTop - lineHeight * 2;
|
|
|
|
|
}
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
} else if (event.key === "Enter") {
|
2022-11-04 21:48:50 +08:00
|
|
|
moveToPath(paths, currentList.getAttribute("data-box"), currentList.getAttribute("data-path"), dialog);
|
2022-05-26 15:18:53 +08:00
|
|
|
event.preventDefault();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
dialog.element.addEventListener("click", (event) => {
|
|
|
|
|
const target = event.target as HTMLElement;
|
|
|
|
|
const liElement = hasClosestByClassName(target, "b3-list-item");
|
|
|
|
|
if (liElement) {
|
2022-11-04 21:48:50 +08:00
|
|
|
moveToPath(paths, liElement.getAttribute("data-box"), liElement.getAttribute("data-path"), dialog);
|
2022-05-26 15:18:53 +08:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getNotebookName = (id: string) => {
|
|
|
|
|
let rootPath = "";
|
|
|
|
|
window.siyuan.notebooks.find((item) => {
|
|
|
|
|
if (item.id === id) {
|
|
|
|
|
rootPath = item.name;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return rootPath;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const setNotebookName = (id: string, name: string) => {
|
|
|
|
|
window.siyuan.notebooks.find((item) => {
|
|
|
|
|
if (item.id === id) {
|
|
|
|
|
item.name = name;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getOpenNotebookCount = () => {
|
|
|
|
|
let count = 0;
|
|
|
|
|
window.siyuan.notebooks.forEach(item => {
|
|
|
|
|
if (!item.closed) {
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return count;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const setNoteBook = (cb?: (notebook: INotebook[]) => void) => {
|
|
|
|
|
fetchPost("/api/notebook/lsNotebooks", {}, (response) => {
|
|
|
|
|
window.siyuan.notebooks = response.data.notebooks;
|
|
|
|
|
if (cb) {
|
|
|
|
|
cb(response.data.notebooks);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|