mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-09-22 00:20:47 +02:00
This commit is contained in:
parent
7b2e48d54e
commit
91626c8fb5
3 changed files with 114 additions and 56 deletions
|
@ -866,7 +866,7 @@ data-type="navigation-root" data-path="/">
|
||||||
}
|
}
|
||||||
window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: IFilesPath) => {
|
window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: IFilesPath) => {
|
||||||
item.openPaths.forEach((openPath) => {
|
item.openPaths.forEach((openPath) => {
|
||||||
this.selectItem(item.notebookId, openPath, undefined, false);
|
this.selectItem(item.notebookId, openPath, undefined, false, false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (!init) {
|
if (!init) {
|
||||||
|
@ -1081,7 +1081,11 @@ data-type="navigation-root" data-path="/">
|
||||||
}, 2);
|
}, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onLsSelect(data: { files: IFile[], box: string, path: string }, filePath: string, setStorage: boolean) {
|
private async onLsSelect(data: {
|
||||||
|
files: IFile[],
|
||||||
|
box: string,
|
||||||
|
path: string
|
||||||
|
}, filePath: string, setStorage: boolean, isSetCurrent: boolean) {
|
||||||
let fileHTML = "";
|
let fileHTML = "";
|
||||||
data.files.forEach((item: IFile) => {
|
data.files.forEach((item: IFile) => {
|
||||||
fileHTML += this.genFileHTML(item);
|
fileHTML += this.genFileHTML(item);
|
||||||
|
@ -1102,28 +1106,30 @@ data-type="navigation-root" data-path="/">
|
||||||
emojiElement.textContent = unicode2Emoji(window.siyuan.storage[Constants.LOCAL_IMAGES].folder);
|
emojiElement.textContent = unicode2Emoji(window.siyuan.storage[Constants.LOCAL_IMAGES].folder);
|
||||||
}
|
}
|
||||||
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`);
|
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`);
|
||||||
data.files.forEach((item: IFile) => {
|
let newLiElement;
|
||||||
|
for (let i = 0; i < data.files.length; i++) {
|
||||||
|
const item = data.files[i];
|
||||||
if (filePath === item.path) {
|
if (filePath === item.path) {
|
||||||
this.selectItem(data.box, filePath, undefined, setStorage);
|
newLiElement = await this.selectItem(data.box, filePath, undefined, setStorage, isSetCurrent);
|
||||||
} else if (filePath.startsWith(item.path.replace(".sy", ""))) {
|
} else if (filePath.startsWith(item.path.replace(".sy", ""))) {
|
||||||
fetchPost("/api/filetree/listDocsByPath", {
|
const response = await fetchSyncPost("/api/filetree/listDocsByPath", {
|
||||||
notebook: data.box,
|
notebook: data.box,
|
||||||
path: item.path
|
path: item.path
|
||||||
}, response => {
|
|
||||||
this.selectItem(response.data.box, filePath, response.data, setStorage);
|
|
||||||
});
|
});
|
||||||
|
newLiElement = await this.selectItem(response.data.box, filePath, response.data, setStorage, isSetCurrent);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
if (setStorage) {
|
|
||||||
this.setCurrent(this.element.querySelector(`ul[data-url="${data.box}"] li[data-path="${filePath}"]`));
|
|
||||||
}
|
}
|
||||||
|
if (isSetCurrent) {
|
||||||
|
this.setCurrent(newLiElement);
|
||||||
|
}
|
||||||
|
return newLiElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private setCurrent(target: HTMLElement, isScroll = true) {
|
public setCurrent(target: HTMLElement, isScroll = true) {
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.element.querySelectorAll("li").forEach((liItem) => {
|
this.element.querySelectorAll("li.b3-list-item--focus").forEach((liItem) => {
|
||||||
liItem.classList.remove("b3-list-item--focus");
|
liItem.classList.remove("b3-list-item--focus");
|
||||||
});
|
});
|
||||||
target.classList.add("b3-list-item--focus");
|
target.classList.add("b3-list-item--focus");
|
||||||
|
@ -1155,11 +1161,11 @@ data-type="navigation-root" data-path="/">
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public selectItem(notebookId: string, filePath: string, data?: {
|
public async selectItem(notebookId: string, filePath: string, data?: {
|
||||||
files: IFile[],
|
files: IFile[],
|
||||||
box: string,
|
box: string,
|
||||||
path: string
|
path: string
|
||||||
}, setStorage = true) {
|
}, setStorage = true, isSetCurrent = true) {
|
||||||
const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`);
|
const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`);
|
||||||
if (!treeElement) {
|
if (!treeElement) {
|
||||||
// 有文件树和编辑器的布局初始化时,文件树还未挂载
|
// 有文件树和编辑器的布局初始化时,文件树还未挂载
|
||||||
|
@ -1181,24 +1187,24 @@ data-type="navigation-root" data-path="/">
|
||||||
|
|
||||||
if (liElement.getAttribute("data-path") === filePath) {
|
if (liElement.getAttribute("data-path") === filePath) {
|
||||||
if (setStorage) {
|
if (setStorage) {
|
||||||
this.setCurrent(liElement);
|
|
||||||
this.getOpenPaths();
|
this.getOpenPaths();
|
||||||
} else {
|
|
||||||
this.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus");
|
|
||||||
}
|
}
|
||||||
return;
|
if (isSetCurrent) {
|
||||||
|
this.setCurrent(liElement);
|
||||||
|
}
|
||||||
|
return liElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data && data.path === currentPath) {
|
if (data && data.path === currentPath) {
|
||||||
this.onLsSelect(data, filePath, setStorage);
|
liElement = await this.onLsSelect(data, filePath, setStorage, isSetCurrent);
|
||||||
} else {
|
} else {
|
||||||
fetchPost("/api/filetree/listDocsByPath", {
|
const response = await fetchSyncPost("/api/filetree/listDocsByPath", {
|
||||||
notebook: notebookId,
|
notebook: notebookId,
|
||||||
path: currentPath
|
path: currentPath
|
||||||
}, response => {
|
|
||||||
this.onLsSelect(response.data, filePath, setStorage);
|
|
||||||
});
|
});
|
||||||
|
liElement = await this.onLsSelect(response.data, filePath, setStorage, isSetCurrent);
|
||||||
}
|
}
|
||||||
|
return liElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOpenPaths() {
|
private getOpenPaths() {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {Constants} from "../../constants";
|
||||||
import {getDisplayName, pathPosix, setNoteBook} from "../../util/pathName";
|
import {getDisplayName, pathPosix, setNoteBook} from "../../util/pathName";
|
||||||
import {initFileMenu, initNavigationMenu, sortMenu} from "../../menus/navigation";
|
import {initFileMenu, initNavigationMenu, sortMenu} from "../../menus/navigation";
|
||||||
import {showMessage} from "../../dialog/message";
|
import {showMessage} from "../../dialog/message";
|
||||||
import {fetchPost} from "../../util/fetch";
|
import {fetchPost, fetchSyncPost} from "../../util/fetch";
|
||||||
import {genUUID} from "../../util/genID";
|
import {genUUID} from "../../util/genID";
|
||||||
import {openMobileFileById} from "../editor";
|
import {openMobileFileById} from "../editor";
|
||||||
import {unicode2Emoji} from "../../emoji";
|
import {unicode2Emoji} from "../../emoji";
|
||||||
|
@ -361,7 +361,7 @@ export class MobileFiles extends Model {
|
||||||
}
|
}
|
||||||
window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: IFilesPath) => {
|
window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: IFilesPath) => {
|
||||||
item.openPaths.forEach((openPath) => {
|
item.openPaths.forEach((openPath) => {
|
||||||
this.selectItem(item.notebookId, openPath, undefined, false);
|
this.selectItem(item.notebookId, openPath, undefined, false, false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (!init) {
|
if (!init) {
|
||||||
|
@ -577,20 +577,14 @@ export class MobileFiles extends Model {
|
||||||
}, 2);
|
}, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onLsSelect(data: { files: IFile[], box: string, path: string }, filePath: string, setStorage: boolean) {
|
private async onLsSelect(data: {
|
||||||
|
files: IFile[],
|
||||||
|
box: string,
|
||||||
|
path: string
|
||||||
|
}, filePath: string, setStorage: boolean, isSetCurrent: boolean) {
|
||||||
let fileHTML = "";
|
let fileHTML = "";
|
||||||
data.files.forEach((item: IFile) => {
|
data.files.forEach((item: IFile) => {
|
||||||
fileHTML += this.genFileHTML(item);
|
fileHTML += this.genFileHTML(item);
|
||||||
if (filePath === item.path) {
|
|
||||||
this.selectItem(data.box, filePath, undefined, setStorage);
|
|
||||||
} else if (filePath.startsWith(item.path.replace(".sy", ""))) {
|
|
||||||
fetchPost("/api/filetree/listDocsByPath", {
|
|
||||||
notebook: data.box,
|
|
||||||
path: item.path
|
|
||||||
}, response => {
|
|
||||||
this.selectItem(response.data.box, filePath, response.data, setStorage);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (fileHTML === "") {
|
if (fileHTML === "") {
|
||||||
return;
|
return;
|
||||||
|
@ -600,26 +594,45 @@ export class MobileFiles extends Model {
|
||||||
// 文件展开时,刷新
|
// 文件展开时,刷新
|
||||||
liElement.nextElementSibling.remove();
|
liElement.nextElementSibling.remove();
|
||||||
}
|
}
|
||||||
liElement.querySelector(".b3-list-item__arrow").classList.add("b3-list-item__arrow--open");
|
const arrowElement = liElement.querySelector(".b3-list-item__arrow");
|
||||||
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`);
|
arrowElement.classList.add("b3-list-item__arrow--open");
|
||||||
if (setStorage) {
|
arrowElement.parentElement.classList.remove("fn__hidden");
|
||||||
this.setCurrent(this.element.querySelector(`ul[data-url="${data.box}"] li[data-path="${filePath}"]`));
|
const emojiElement = liElement.querySelector(".b3-list-item__icon");
|
||||||
|
if (emojiElement.textContent === unicode2Emoji(window.siyuan.storage[Constants.LOCAL_IMAGES].file)) {
|
||||||
|
emojiElement.textContent = unicode2Emoji(window.siyuan.storage[Constants.LOCAL_IMAGES].folder);
|
||||||
}
|
}
|
||||||
|
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`);
|
||||||
|
let newLiElement;
|
||||||
|
for (let i = 0; i < data.files.length; i++) {
|
||||||
|
const item = data.files[i];
|
||||||
|
if (filePath === item.path) {
|
||||||
|
newLiElement = await this.selectItem(data.box, filePath, undefined, setStorage, isSetCurrent);
|
||||||
|
} else if (filePath.startsWith(item.path.replace(".sy", ""))) {
|
||||||
|
const response = await fetchSyncPost("/api/filetree/listDocsByPath", {
|
||||||
|
notebook: data.box,
|
||||||
|
path: item.path
|
||||||
|
});
|
||||||
|
newLiElement = await this.selectItem(response.data.box, filePath, response.data, setStorage, isSetCurrent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isSetCurrent) {
|
||||||
|
this.setCurrent(newLiElement);
|
||||||
|
}
|
||||||
|
return newLiElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private setCurrent(target: HTMLElement) {
|
public setCurrent(target: HTMLElement, isScroll = true) {
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.element.querySelectorAll("li").forEach((liItem) => {
|
this.element.querySelectorAll("li.b3-list-item--focus").forEach((liItem) => {
|
||||||
liItem.classList.remove("b3-list-item--focus");
|
liItem.classList.remove("b3-list-item--focus");
|
||||||
});
|
});
|
||||||
target.classList.add("b3-list-item--focus");
|
target.classList.add("b3-list-item--focus");
|
||||||
const titleHeight = this.actionsElement.clientHeight;
|
|
||||||
if (target.offsetTop - titleHeight < this.element.scrollTop) {
|
if (isScroll) {
|
||||||
this.element.scrollTop = target.offsetTop - titleHeight;
|
const elementRect = this.element.getBoundingClientRect();
|
||||||
} else if (target.offsetTop - this.element.clientHeight - titleHeight + target.clientHeight > this.element.scrollTop) {
|
this.element.scrollTop = this.element.scrollTop + (target.getBoundingClientRect().top - (elementRect.top + elementRect.height / 2));
|
||||||
this.element.scrollTop = target.offsetTop - this.element.clientHeight - titleHeight + target.clientHeight;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,11 +657,11 @@ export class MobileFiles extends Model {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public selectItem(notebookId: string, filePath: string, data?: {
|
public async selectItem(notebookId: string, filePath: string, data?: {
|
||||||
files: IFile[],
|
files: IFile[],
|
||||||
box: string,
|
box: string,
|
||||||
path: string
|
path: string
|
||||||
}, setStorage = true) {
|
}, setStorage = true, isSetCurrent = true) {
|
||||||
const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`);
|
const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`);
|
||||||
if (!treeElement) {
|
if (!treeElement) {
|
||||||
// 有文件树和编辑器的布局初始化时,文件树还未挂载
|
// 有文件树和编辑器的布局初始化时,文件树还未挂载
|
||||||
|
@ -670,24 +683,24 @@ export class MobileFiles extends Model {
|
||||||
|
|
||||||
if (liElement.getAttribute("data-path") === filePath) {
|
if (liElement.getAttribute("data-path") === filePath) {
|
||||||
if (setStorage) {
|
if (setStorage) {
|
||||||
this.setCurrent(liElement);
|
|
||||||
this.getOpenPaths();
|
this.getOpenPaths();
|
||||||
} else {
|
|
||||||
this.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus");
|
|
||||||
}
|
}
|
||||||
return;
|
if (isSetCurrent) {
|
||||||
|
this.setCurrent(liElement);
|
||||||
|
}
|
||||||
|
return liElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data && data.path === currentPath) {
|
if (data && data.path === currentPath) {
|
||||||
this.onLsSelect(data, filePath, setStorage);
|
liElement = await this.onLsSelect(data, filePath, setStorage, isSetCurrent);
|
||||||
} else {
|
} else {
|
||||||
fetchPost("/api/filetree/listDocsByPath", {
|
const response = await fetchSyncPost("/api/filetree/listDocsByPath", {
|
||||||
notebook: notebookId,
|
notebook: notebookId,
|
||||||
path: currentPath
|
path: currentPath
|
||||||
}, response => {
|
|
||||||
this.onLsSelect(response.data, filePath, setStorage);
|
|
||||||
});
|
});
|
||||||
|
liElement = await this.onLsSelect(response.data, filePath, setStorage, isSetCurrent);
|
||||||
}
|
}
|
||||||
|
return liElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOpenPaths() {
|
private getOpenPaths() {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import {globalCommand} from "../boot/globalEvent/command/global";
|
||||||
import {exportLayout} from "../layout/util";
|
import {exportLayout} from "../layout/util";
|
||||||
import {saveScroll} from "../protyle/scroll/saveScroll";
|
import {saveScroll} from "../protyle/scroll/saveScroll";
|
||||||
import {hasClosestByClassName} from "../protyle/util/hasClosest";
|
import {hasClosestByClassName} from "../protyle/util/hasClosest";
|
||||||
|
import {Files} from "../layout/dock/Files";
|
||||||
|
|
||||||
let openTab;
|
let openTab;
|
||||||
let openWindow;
|
let openWindow;
|
||||||
|
@ -248,6 +249,43 @@ const getActiveEditor = (wndActive = true) => {
|
||||||
return editor;
|
return editor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const expandDocTree = async (options: {
|
||||||
|
id: string,
|
||||||
|
isSetCurrent?: boolean
|
||||||
|
}) => {
|
||||||
|
let isNotebook = false;
|
||||||
|
window.siyuan.notebooks.find(item => {
|
||||||
|
if (options.id === item.id) {
|
||||||
|
isNotebook = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let liElement: HTMLElement;
|
||||||
|
let notebookId = options.id;
|
||||||
|
const file = getModelByDockType("file") as Files;
|
||||||
|
if (typeof options.isSetCurrent === "undefined") {
|
||||||
|
options.isSetCurrent = true;
|
||||||
|
}
|
||||||
|
if (isNotebook) {
|
||||||
|
liElement = file.element.querySelector(`.b3-list[data-url="${options.id}"]`).firstElementChild as HTMLElement;
|
||||||
|
} else {
|
||||||
|
const response = await fetchSyncPost("api/block/getBlockInfo", {id: options.id});
|
||||||
|
notebookId = response.data.box;
|
||||||
|
liElement = await file.selectItem(response.data.box, response.data.path, undefined, undefined, options.isSetCurrent);
|
||||||
|
}
|
||||||
|
if (!liElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (options.isSetCurrent || typeof options.isSetCurrent === "undefined") {
|
||||||
|
file.setCurrent(liElement);
|
||||||
|
}
|
||||||
|
const toggleElement = liElement.querySelector(".b3-list-item__arrow");
|
||||||
|
if (toggleElement.classList.contains("b3-list-item__arrow--open")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
file.getLeaf(liElement, notebookId);
|
||||||
|
};
|
||||||
|
|
||||||
export const API = {
|
export const API = {
|
||||||
adaptHotkey: updateHotkeyTip,
|
adaptHotkey: updateHotkeyTip,
|
||||||
confirm: confirmDialog,
|
confirm: confirmDialog,
|
||||||
|
@ -281,4 +319,5 @@ export const API = {
|
||||||
openAttributePanel,
|
openAttributePanel,
|
||||||
saveLayout,
|
saveLayout,
|
||||||
globalCommand,
|
globalCommand,
|
||||||
|
expandDocTree
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue