Files
obsidian-excalidraw-plugin/src/dialogs/PublishOutOfDateFiles.ts
zsviczian c440dd9cf0 2.0.0
2023-11-13 22:16:43 +01:00

130 lines
4.8 KiB
TypeScript

import { Modal, Setting, TFile } from "obsidian";
import ExcalidrawPlugin from "src/main";
import { getIMGFilename } from "src/utils/FileUtils";
import { addIframe } from "src/utils/Utils";
const haveLinkedFilesChanged = (depth: number, mtime: number, path: string, sourceList: Set<string>, plugin: ExcalidrawPlugin):boolean => {
if(depth++ > 5) return false;
sourceList.add(path);
const links = plugin.app.metadataCache.resolvedLinks[path];
if(!links) return false;
for(const link of Object.keys(links)) {
if(sourceList.has(link)) continue;
const file = plugin.app.vault.getAbstractFileByPath(link);
if(!file || !(file instanceof TFile)) continue;
console.log(path, {mtimeLinked: file.stat.mtime, mtimeSource: mtime, path: file.path});
if(file.stat.mtime > mtime) return true;
if(plugin.isExcalidrawFile(file)) {
if(haveLinkedFilesChanged(depth, mtime, file.path, sourceList, plugin)) return true;
}
}
return false;
}
const listOfOutOfSyncImgExports = async(plugin: ExcalidrawPlugin, recursive: boolean, statusEl: HTMLParagraphElement):Promise<TFile[]> => {
const app = plugin.app;
const publish = app.internalPlugins.plugins["publish"].instance;
if(!publish) return;
const list = await app.internalPlugins.plugins["publish"].instance.apiList();
if(!list || !list.files) return;
const outOfSyncFiles = new Set<TFile>();
const allFiles = list.files.filter((f:any)=>(f.path.endsWith(".svg") || f.path.endsWith(".png")))
const totalCount = allFiles.length;
allFiles.forEach((f:any, idx:number)=>{
const maybeExcalidraFilePath = getIMGFilename(f.path,"md");
const imgFile = app.vault.getAbstractFileByPath(f.path);
const excalidrawFile = app.vault.getAbstractFileByPath(maybeExcalidraFilePath);
statusEl.innerText = `Status: ${idx+1}/${totalCount} ${imgFile ? imgFile.name : f.path}`;
if(!excalidrawFile || !imgFile || !(excalidrawFile instanceof TFile) || !(imgFile instanceof TFile)) return;
if(excalidrawFile.stat.mtime <= imgFile.stat.mtime) {
if(!recursive) return;
if(!haveLinkedFilesChanged(0, excalidrawFile.stat.mtime, excalidrawFile.path, new Set<string>(), plugin)) return;
}
outOfSyncFiles.add(excalidrawFile);
});
return Array.from(outOfSyncFiles);
}
export class PublishOutOfDateFilesDialog extends Modal {
constructor(
private plugin: ExcalidrawPlugin,
) {
super(plugin.app);
}
async onClose() {}
onOpen() {
this.containerEl.classList.add("excalidraw-release");
this.titleEl.setText(`Out of Date SVG Files`);
this.createForm(false);
}
async createForm(recursive: boolean) {
const detailsEl = this.contentEl.createEl("details");
detailsEl.createEl("summary", {
text: "Video about Obsidian Publish support",
});
detailsEl.createEl("br");
addIframe(detailsEl, "JC1E-jeiWhI");
const p = this.contentEl.createEl("p",{text: "Collecting data..."});
const statusEl = this.contentEl.createEl("p", {text: "Status: "});
const files = await listOfOutOfSyncImgExports(this.plugin, recursive, statusEl);
statusEl.style.display = "none";
if(!files || files.length === 0) {
p.innerText = "No out of date files found.";
const div = this.contentEl.createDiv({cls: "excalidraw-prompt-buttons-div"});
const bClose = div.createEl("button", { text: "Close", cls: "excalidraw-prompt-button"});
bClose.onclick = () => {
this.close();
};
if(!recursive) {
const bRecursive = div.createEl("button", { text: "Check Recursive", cls: "excalidraw-prompt-button"});
bRecursive.onclick = () => {
this.contentEl.empty();
this.createForm(true);
};
}
return;
}
const filesMap = new Map<TFile,boolean>();
p.innerText = "Select files to open.";
files.forEach((f:TFile) => {
filesMap.set(f,true);
new Setting(this.contentEl)
.setName(f.path)
.addToggle(toggle => toggle
.setValue(true)
.onChange(value => {
filesMap.set(f,value);
})
)
});
const div = this.contentEl.createDiv({cls: "excalidraw-prompt-buttons-div"});
const bClose = div.createEl("button", { text: "Close", cls: "excalidraw-prompt-button"});
bClose.onclick = () => {
this.close();
};
if(!recursive) {
const bRecursive = div.createEl("button", { text: "Check Recursive", cls: "excalidraw-prompt-button"});
bRecursive.onclick = () => {
this.contentEl.empty();
this.createForm(true);
};
}
const bOpen = div.createEl("button", { text: "Open Selected", cls: "excalidraw-prompt-button" });
bOpen.onclick = () => {
filesMap.forEach((value:boolean,key:TFile) => {
if(value) {
this.plugin.openDrawing(key,"new-tab",true);
}
});
this.close();
};
}
}