Vanessa 2024-09-13 21:25:02 +08:00
parent d9fd9f68d2
commit b490acfcfb
4 changed files with 139 additions and 20 deletions

View File

@ -117,6 +117,7 @@ export abstract class Constants {
public static readonly LOCAL_PLUGINTOPUNPIN = "local-plugintopunpin"; public static readonly LOCAL_PLUGINTOPUNPIN = "local-plugintopunpin";
public static readonly LOCAL_FLASHCARD = "local-flashcard"; public static readonly LOCAL_FLASHCARD = "local-flashcard";
public static readonly LOCAL_FILEPOSITION = "local-fileposition"; public static readonly LOCAL_FILEPOSITION = "local-fileposition";
public static readonly LOCAL_FILESPATHS = "local-filespaths";
public static readonly LOCAL_DIALOGPOSITION = "local-dialogposition"; public static readonly LOCAL_DIALOGPOSITION = "local-dialogposition";
public static readonly LOCAL_SESSION_FIRSTLOAD = "local-session-firstload"; public static readonly LOCAL_SESSION_FIRSTLOAD = "local-session-firstload";
public static readonly LOCAL_OUTLINE = "local-outline"; public static readonly LOCAL_OUTLINE = "local-outline";

View File

@ -14,13 +14,18 @@ import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {openEmojiPanel, unicode2Emoji} from "../../emoji"; import {openEmojiPanel, unicode2Emoji} from "../../emoji";
import {mountHelp, newNotebook} from "../../util/mount"; import {mountHelp, newNotebook} from "../../util/mount";
import {confirmDialog} from "../../dialog/confirmDialog"; import {confirmDialog} from "../../dialog/confirmDialog";
import {isNotCtrl, isOnlyMeta, updateHotkeyTip} from "../../protyle/util/compatibility"; import {isNotCtrl, isOnlyMeta, setStorageVal, updateHotkeyTip} from "../../protyle/util/compatibility";
import {openFileById} from "../../editor/util"; import {openFileById} from "../../editor/util";
import {hasClosestByAttribute, hasClosestByTag, hasTopClosestByTag} from "../../protyle/util/hasClosest"; import {hasClosestByAttribute, hasClosestByTag, hasTopClosestByTag} from "../../protyle/util/hasClosest";
import {isTouchDevice} from "../../util/functions"; import {isTouchDevice} from "../../util/functions";
import {App} from "../../index"; import {App} from "../../index";
import {refreshFileTree} from "../../dialog/processSystem"; import {refreshFileTree} from "../../dialog/processSystem";
type filesPath = {
notebookId: string,
openPaths: string[]
}
export class Files extends Model { export class Files extends Model {
public element: HTMLElement; public element: HTMLElement;
public parent: Tab; public parent: Tab;
@ -732,6 +737,11 @@ export class Files extends Model {
} else { } else {
counterElement.classList.add("fn__none"); counterElement.classList.add("fn__none");
} }
window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: filesPath) => {
item.openPaths.forEach((openPath) => {
this.selectItem(item.notebookId, openPath, undefined, false);
})
})
if (!init) { if (!init) {
return; return;
} }
@ -932,18 +942,18 @@ export class Files extends Model {
}, 2); }, 2);
} }
private onLsSelect(data: { files: IFile[], box: string, path: string }, filePath: string) { private onLsSelect(data: { files: IFile[], box: string, path: string }, filePath: string, setStorage: 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) { if (filePath === item.path) {
this.selectItem(data.box, filePath); this.selectItem(data.box, filePath, undefined, setStorage);
} else if (filePath.startsWith(item.path.replace(".sy", ""))) { } else if (filePath.startsWith(item.path.replace(".sy", ""))) {
fetchPost("/api/filetree/listDocsByPath", { fetchPost("/api/filetree/listDocsByPath", {
notebook: data.box, notebook: data.box,
path: item.path path: item.path
}, response => { }, response => {
this.selectItem(response.data.box, filePath, response.data); this.selectItem(response.data.box, filePath, response.data, setStorage);
}); });
} }
}); });
@ -963,7 +973,9 @@ export class Files extends Model {
emojiElement.textContent = unicode2Emoji(Constants.SIYUAN_IMAGE_FOLDER); emojiElement.textContent = unicode2Emoji(Constants.SIYUAN_IMAGE_FOLDER);
} }
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`); liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`);
this.setCurrent(this.element.querySelector(`ul[data-url="${data.box}"] li[data-path="${filePath}"]`)); if (setStorage) {
this.setCurrent(this.element.querySelector(`ul[data-url="${data.box}"] li[data-path="${filePath}"]`));
}
} }
private setCurrent(target: HTMLElement, isScroll = true) { private setCurrent(target: HTMLElement, isScroll = true) {
@ -989,6 +1001,7 @@ export class Files extends Model {
if (toggleElement.classList.contains("b3-list-item__arrow--open")) { if (toggleElement.classList.contains("b3-list-item__arrow--open")) {
toggleElement.classList.remove("b3-list-item__arrow--open"); toggleElement.classList.remove("b3-list-item__arrow--open");
liElement.nextElementSibling?.remove(); liElement.nextElementSibling?.remove();
this.getOpenPaths();
return; return;
} }
fetchPost("/api/filetree/listDocsByPath", { fetchPost("/api/filetree/listDocsByPath", {
@ -1000,10 +1013,15 @@ export class Files extends Model {
return; return;
} }
this.onLsHTML(response.data); this.onLsHTML(response.data);
this.getOpenPaths();
}); });
} }
public selectItem(notebookId: string, filePath: string, data?: { files: IFile[], box: string, path: string }) { public selectItem(notebookId: string, filePath: string, data?: {
files: IFile[],
box: string,
path: string
}, setStorage = true) {
const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`); const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`);
if (!treeElement) { if (!treeElement) {
// 有文件树和编辑器的布局初始化时,文件树还未挂载 // 有文件树和编辑器的布局初始化时,文件树还未挂载
@ -1024,22 +1042,62 @@ export class Files extends Model {
} }
if (liElement.getAttribute("data-path") === filePath) { if (liElement.getAttribute("data-path") === filePath) {
this.setCurrent(liElement); if (setStorage) {
this.setCurrent(liElement);
this.getOpenPaths();
} else {
this.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus");
}
return; return;
} }
if (data && data.path === currentPath) { if (data && data.path === currentPath) {
this.onLsSelect(data, filePath); this.onLsSelect(data, filePath, setStorage);
} else { } else {
fetchPost("/api/filetree/listDocsByPath", { fetchPost("/api/filetree/listDocsByPath", {
notebook: notebookId, notebook: notebookId,
path: currentPath path: currentPath
}, response => { }, response => {
this.onLsSelect(response.data, filePath); this.onLsSelect(response.data, filePath, setStorage);
}); });
} }
} }
private getOpenPaths() {
const filesPaths: filesPath[] = [];
this.element.querySelectorAll('.b3-list[data-url]').forEach((item: HTMLElement) => {
const notebookPaths: filesPath = {
notebookId: item.getAttribute("data-url"),
openPaths: []
}
item.querySelectorAll(".b3-list-item__arrow--open").forEach((openItem) => {
const liElement = hasClosestByTag(openItem, "LI");
if (liElement) {
notebookPaths.openPaths.push(liElement.getAttribute("data-path"));
}
})
if (notebookPaths.openPaths.length > 0) {
for (let i = 0; i < notebookPaths.openPaths.length; i++) {
for (let j = i + 1; j < notebookPaths.openPaths.length; j++) {
if (notebookPaths.openPaths[j].startsWith(notebookPaths.openPaths[i].replace(".sy", ""))) {
notebookPaths.openPaths.splice(i, 1);
j--;
}
}
}
notebookPaths.openPaths.forEach((openPath, index) => {
const nextPath = this.element.querySelector(`[data-url="${notebookPaths.notebookId}"] li[data-path="${openPath}"]`)?.nextElementSibling?.firstElementChild?.getAttribute("data-path");
if (nextPath) {
notebookPaths.openPaths[index] = nextPath;
}
});
filesPaths.push(notebookPaths);
}
});
window.siyuan.storage[Constants.LOCAL_FILESPATHS] = filesPaths;
setStorageVal(Constants.LOCAL_FILESPATHS, filesPaths);
}
private genFileHTML = (item: IFile) => { private genFileHTML = (item: IFile) => {
let countHTML = ""; let countHTML = "";
if (item.count && item.count > 0) { if (item.count && item.count > 0) {

View File

@ -1,4 +1,4 @@
import {hasTopClosestByTag} from "../../protyle/util/hasClosest"; import {hasClosestByTag, hasTopClosestByTag} from "../../protyle/util/hasClosest";
import {escapeHtml} from "../../util/escape"; import {escapeHtml} from "../../util/escape";
import {Model} from "../../layout/Model"; import {Model} from "../../layout/Model";
import {Constants} from "../../constants"; import {Constants} from "../../constants";
@ -15,6 +15,12 @@ import {newFile} from "../../util/newFile";
import {MenuItem} from "../../menus/Menu"; import {MenuItem} from "../../menus/Menu";
import {App} from "../../index"; import {App} from "../../index";
import {refreshFileTree} from "../../dialog/processSystem"; import {refreshFileTree} from "../../dialog/processSystem";
import {setStorageVal} from "../../protyle/util/compatibility";
type filesPath = {
notebookId: string,
openPaths: string[]
}
export class MobileFiles extends Model { export class MobileFiles extends Model {
public element: HTMLElement; public element: HTMLElement;
@ -312,6 +318,11 @@ export class MobileFiles extends Model {
} else { } else {
counterElement.classList.add("fn__none"); counterElement.classList.add("fn__none");
} }
window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: filesPath) => {
item.openPaths.forEach((openPath) => {
this.selectItem(item.notebookId, openPath, undefined, false);
})
})
if (!init) { if (!init) {
return; return;
} }
@ -430,7 +441,7 @@ export class MobileFiles extends Model {
removeElement.remove(); removeElement.remove();
const counterElement = this.closeElement.querySelector(".counter"); const counterElement = this.closeElement.querySelector(".counter");
counterElement.textContent = (parseInt(counterElement.textContent) - 1).toString(); counterElement.textContent = (parseInt(counterElement.textContent) - 1).toString();
if (counterElement.textContent === "0") { if (counterElement.textContent === "0") {
counterElement.classList.add("fn__none"); counterElement.classList.add("fn__none");
} }
} }
@ -545,18 +556,18 @@ export class MobileFiles extends Model {
}, 2); }, 2);
} }
private onLsSelect(data: { files: IFile[], box: string, path: string }, filePath: string) { private onLsSelect(data: { files: IFile[], box: string, path: string }, filePath: string, setStorage: 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) { if (filePath === item.path) {
this.selectItem(data.box, filePath); this.selectItem(data.box, filePath, undefined, setStorage);
} else if (filePath.startsWith(item.path.replace(".sy", ""))) { } else if (filePath.startsWith(item.path.replace(".sy", ""))) {
fetchPost("/api/filetree/listDocsByPath", { fetchPost("/api/filetree/listDocsByPath", {
notebook: data.box, notebook: data.box,
path: item.path path: item.path
}, response => { }, response => {
this.selectItem(response.data.box, filePath, response.data); this.selectItem(response.data.box, filePath, response.data, setStorage);
}); });
} }
}); });
@ -570,7 +581,9 @@ export class MobileFiles extends Model {
} }
liElement.querySelector(".b3-list-item__arrow").classList.add("b3-list-item__arrow--open"); liElement.querySelector(".b3-list-item__arrow").classList.add("b3-list-item__arrow--open");
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`); liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`);
this.setCurrent(this.element.querySelector(`ul[data-url="${data.box}"] li[data-path="${filePath}"]`)); if (setStorage) {
this.setCurrent(this.element.querySelector(`ul[data-url="${data.box}"] li[data-path="${filePath}"]`));
}
} }
private setCurrent(target: HTMLElement) { private setCurrent(target: HTMLElement) {
@ -594,6 +607,7 @@ export class MobileFiles extends Model {
if (toggleElement.classList.contains("b3-list-item__arrow--open")) { if (toggleElement.classList.contains("b3-list-item__arrow--open")) {
toggleElement.classList.remove("b3-list-item__arrow--open"); toggleElement.classList.remove("b3-list-item__arrow--open");
liElement.nextElementSibling?.remove(); liElement.nextElementSibling?.remove();
this.getOpenPaths();
return; return;
} }
fetchPost("/api/filetree/listDocsByPath", { fetchPost("/api/filetree/listDocsByPath", {
@ -605,10 +619,15 @@ export class MobileFiles extends Model {
return; return;
} }
this.onLsHTML(response.data); this.onLsHTML(response.data);
this.getOpenPaths();
}); });
} }
public selectItem(notebookId: string, filePath: string, data?: { files: IFile[], box: string, path: string }) { public selectItem(notebookId: string, filePath: string, data?: {
files: IFile[],
box: string,
path: string
}, setStorage = true) {
const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`); const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`);
if (!treeElement) { if (!treeElement) {
// 有文件树和编辑器的布局初始化时,文件树还未挂载 // 有文件树和编辑器的布局初始化时,文件树还未挂载
@ -629,22 +648,62 @@ export class MobileFiles extends Model {
} }
if (liElement.getAttribute("data-path") === filePath) { if (liElement.getAttribute("data-path") === filePath) {
this.setCurrent(liElement); if (setStorage) {
this.setCurrent(liElement);
this.getOpenPaths();
} else {
this.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus");
}
return; return;
} }
if (data && data.path === currentPath) { if (data && data.path === currentPath) {
this.onLsSelect(data, filePath); this.onLsSelect(data, filePath, setStorage);
} else { } else {
fetchPost("/api/filetree/listDocsByPath", { fetchPost("/api/filetree/listDocsByPath", {
notebook: notebookId, notebook: notebookId,
path: currentPath path: currentPath
}, response => { }, response => {
this.onLsSelect(response.data, filePath); this.onLsSelect(response.data, filePath, setStorage);
}); });
} }
} }
private getOpenPaths() {
const filesPaths: filesPath[] = [];
this.element.querySelectorAll('.b3-list[data-url]').forEach((item: HTMLElement) => {
const notebookPaths: filesPath = {
notebookId: item.getAttribute("data-url"),
openPaths: []
}
item.querySelectorAll(".b3-list-item__arrow--open").forEach((openItem) => {
const liElement = hasClosestByTag(openItem, "LI");
if (liElement) {
notebookPaths.openPaths.push(liElement.getAttribute("data-path"));
}
})
if (notebookPaths.openPaths.length > 0) {
for (let i = 0; i < notebookPaths.openPaths.length; i++) {
for (let j = i + 1; j < notebookPaths.openPaths.length; j++) {
if (notebookPaths.openPaths[j].startsWith(notebookPaths.openPaths[i].replace(".sy", ""))) {
notebookPaths.openPaths.splice(i, 1);
j--;
}
}
}
notebookPaths.openPaths.forEach((openPath, index) => {
const nextPath = this.element.querySelector(`[data-url="${notebookPaths.notebookId}"] li[data-path="${openPath}"]`)?.nextElementSibling?.firstElementChild?.getAttribute("data-path");
if (nextPath) {
notebookPaths.openPaths[index] = nextPath;
}
});
filesPaths.push(notebookPaths);
}
});
window.siyuan.storage[Constants.LOCAL_FILESPATHS] = filesPaths;
setStorageVal(Constants.LOCAL_FILESPATHS, filesPaths);
}
private genFileHTML = (item: IFile) => { private genFileHTML = (item: IFile) => {
let countHTML = ""; let countHTML = "";
if (item.count && item.count > 0) { if (item.count && item.count > 0) {

View File

@ -231,6 +231,7 @@ export const getLocalStorage = (cb: () => void) => {
id: "", id: "",
}; };
defaultStorage[Constants.LOCAL_FONTSTYLES] = []; defaultStorage[Constants.LOCAL_FONTSTYLES] = [];
defaultStorage[Constants.LOCAL_FILESPATHS] = [];
defaultStorage[Constants.LOCAL_SEARCHDATA] = { defaultStorage[Constants.LOCAL_SEARCHDATA] = {
page: 1, page: 1,
sort: 0, sort: 0,
@ -265,7 +266,7 @@ export const getLocalStorage = (cb: () => void) => {
Constants.LOCAL_SEARCHDATA, Constants.LOCAL_ZOOM, Constants.LOCAL_LAYOUTS, Constants.LOCAL_AI, Constants.LOCAL_SEARCHDATA, Constants.LOCAL_ZOOM, Constants.LOCAL_LAYOUTS, Constants.LOCAL_AI,
Constants.LOCAL_PLUGINTOPUNPIN, Constants.LOCAL_SEARCHASSET, Constants.LOCAL_FLASHCARD, Constants.LOCAL_PLUGINTOPUNPIN, Constants.LOCAL_SEARCHASSET, Constants.LOCAL_FLASHCARD,
Constants.LOCAL_DIALOGPOSITION, Constants.LOCAL_SEARCHUNREF, Constants.LOCAL_HISTORY, Constants.LOCAL_DIALOGPOSITION, Constants.LOCAL_SEARCHUNREF, Constants.LOCAL_HISTORY,
Constants.LOCAL_OUTLINE, Constants.LOCAL_FILEPOSITION].forEach((key) => { Constants.LOCAL_OUTLINE, Constants.LOCAL_FILEPOSITION, Constants.LOCAL_FILESPATHS].forEach((key) => {
if (typeof response.data[key] === "string") { if (typeof response.data[key] === "string") {
try { try {
const parseData = JSON.parse(response.data[key]); const parseData = JSON.parse(response.data[key]);