lostpaul_obsidian-folder-notes/src/functions/folderNoteFunctions.ts
2024-01-20 18:31:50 +01:00

283 lines
11 KiB
TypeScript

import FolderNotesPlugin from '../main';
import ExistingFolderNoteModal from '../modals/ExistingNote';
import { applyTemplate } from '../template';
import { TFolder, TFile, TAbstractFile, Keymap } from 'obsidian';
import DeleteConfirmationModal from '../modals/DeleteConfirmation';
import { addExcludedFolder, deleteExcludedFolder, getExcludedFolder, ExcludedFolder, updateExcludedFolder } from '../excludedFolder';
import { openExcalidrawView } from './excalidraw';
import { AskForExtensionModal } from 'src/modals/AskForExtension';
const defaultExcalidrawTemplate = `---
excalidraw-plugin: parsed
tags: [excalidraw]
---
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
%%
# Drawing
\`\`\`json
{"type":"excalidraw","version":2,"source":"https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/1.9.20","elements":[],"appState":{"gridSize":null,"viewBackgroundColor":"#ffffff"}}
\`\`\`
%%`;
export async function createFolderNote(plugin: FolderNotesPlugin, folderPath: string, openFile: boolean, extension?: string, useModal?: boolean, existingNote?: TFile) {
const leaf = plugin.app.workspace.getLeaf(false);
const folderName = plugin.getFolderNameFromPathString(folderPath);
const fileName = plugin.settings.folderNoteName.replace('{{folder_name}}', folderName);
let folderNoteType = extension ?? plugin.settings.folderNoteType;
if (folderNoteType === '.excalidraw') {
folderNoteType = '.md';
extension = '.excalidraw';
} else if (folderNoteType === '.ask') {
return new AskForExtensionModal(plugin, folderPath, openFile, folderNoteType, useModal, existingNote).open();
}
let path = '';
if (plugin.settings.storageLocation === 'parentFolder') {
const parentFolderPath = plugin.getFolderPathFromString(folderPath);
if (parentFolderPath.trim() === '') {
path = `${fileName}${folderNoteType}`;
} else {
path = `${parentFolderPath}/${fileName}${folderNoteType}`;
}
} else if (plugin.settings.storageLocation === 'vaultFolder') {
path = `${fileName}${folderNoteType}`;
} else {
path = `${folderPath}/${fileName}${folderNoteType}`;
}
let file: TFile;
if (!existingNote) {
let content = '';
if (extension !== '.md') {
if (plugin.settings.templatePath && folderNoteType.split('.').pop() == plugin.settings.templatePath.split('.').pop()) {
const templateFile = plugin.app.vault.getAbstractFileByPath(plugin.settings.templatePath);
if (templateFile instanceof TFile) {
if (['md', 'canvas', 'txt'].includes(templateFile.extension)) {
content = await plugin.app.vault.read(templateFile);
if (extension === '.excalidraw' && !content.includes('==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==')) {
content = defaultExcalidrawTemplate;
}
} else {
return plugin.app.vault.readBinary(templateFile).then(async (data) => {
file = await plugin.app.vault.createBinary(path, data);
if (openFile) {
await leaf.openFile(file);
}
});
}
}
} else if (plugin.settings.folderNoteType === '.excalidraw' || extension === '.excalidraw') {
content = defaultExcalidrawTemplate;
} else if (plugin.settings.folderNoteType === '.canvas') {
content = '{}'
}
}
file = await plugin.app.vault.create(path, content);
} else {
plugin.app.fileManager.renameFile(existingNote, path);
file = existingNote;
file.path = path;
}
if (openFile) {
await leaf.openFile(file);
if (plugin.settings.folderNoteType === '.excalidraw' || extension === '.excalidraw') {
openExcalidrawView(leaf);
}
}
const matchingExtension = extension?.split('.').pop() == plugin.settings.templatePath.split('.').pop();
if (file && !existingNote && matchingExtension && plugin.settings.folderNoteType !== '.excalidraw') {
applyTemplate(plugin, file, leaf, plugin.settings.templatePath);
}
const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
if (!(folder instanceof TFolder)) return;
plugin.addCSSClassToTitleEL(path, 'is-folder-note', true);
plugin.addCSSClassToTitleEL(folder.path, 'has-folder-note');
}
export async function turnIntoFolderNote(plugin: FolderNotesPlugin, file: TFile, folder: TFolder, folderNote?: TFile | null | TAbstractFile, skipConfirmation?: boolean) {
const extension = file.extension
if (folderNote) {
if (plugin.settings.showRenameConfirmation && !skipConfirmation) {
return new ExistingFolderNoteModal(plugin.app, plugin, file, folder, folderNote).open();
}
plugin.removeCSSClassFromEL(folderNote.path, 'is-folder-note');
let excludedFolder = getExcludedFolder(plugin, folder.path);
let excludedFolderExisted = true;
let disabledSync = false;
if (!excludedFolder) {
excludedFolderExisted = false;
excludedFolder = new ExcludedFolder(folder.path, plugin.settings.excludeFolders.length, plugin);
addExcludedFolder(plugin, excludedFolder);
} else if (!excludedFolder.disableSync) {
disabledSync = false;
excludedFolder.disableSync = true;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
}
const newPath = `${folder.path}/${folder.name} (${file.stat.ctime.toString().slice(10) + Math.floor(Math.random() * 1000)}).${extension}`;
plugin.app.fileManager.renameFile(folderNote, newPath).then(() => {
if (!excludedFolder) { return; }
if (!excludedFolderExisted) {
deleteExcludedFolder(plugin, excludedFolder);
} else if (!disabledSync) {
excludedFolder.disableSync = false;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
}
});
}
const folderName = folder.name;
const fileName = plugin.settings.folderNoteName.replace('{{folder_name}}', folderName);
let path = `${folder.path}/${fileName}.${extension}`;
if (plugin.settings.storageLocation === 'parentFolder') {
const parentFolderPath = folder.parent?.path;
if (!parentFolderPath) return;
if (parentFolderPath.trim() === '') {
path = `${fileName}.${extension}`;
} else {
path = `${parentFolderPath}/${fileName}.${extension}`;
}
}
await plugin.app.fileManager.renameFile(file, path);
plugin.addCSSClassToTitleEL(path, 'is-folder-note', true);
plugin.addCSSClassToTitleEL(folder.path, 'has-folder-note');
}
export async function openFolderNote(plugin: FolderNotesPlugin, file: TAbstractFile, evt?: MouseEvent) {
const path = file.path;
if (plugin.app.workspace.getActiveFile()?.path === path && !(Keymap.isModEvent(evt) == 'tab')) { return; }
const leaf = plugin.app.workspace.getLeaf(Keymap.isModEvent(evt) || plugin.settings.openInNewTab);
if (file instanceof TFile) {
await leaf.openFile(file);
}
}
export async function deleteFolderNote(plugin: FolderNotesPlugin, file: TFile) {
if (plugin.settings.showDeleteConfirmation) {
return new DeleteConfirmationModal(plugin.app, plugin, file).open();
}
const folder = getFolder(plugin, file);
if (!folder) return;
plugin.removeCSSClassFromEL(folder.path, 'has-folder-note');
await plugin.app.vault.delete(file);
}
export function extractFolderName(template: string, changedFileName: string) {
const [prefix, suffix] = template.split('{{folder_name}}');
if (prefix.trim() === '' && suffix.trim() === '') {
return changedFileName;
}
if (!changedFileName.startsWith(prefix) || !changedFileName.endsWith(suffix)) {
return null;
}
if (changedFileName.startsWith(prefix) && prefix.trim() !== '') {
return changedFileName.slice(prefix.length).replace(suffix, '');
} else if (changedFileName.endsWith(suffix) && suffix.trim() !== '') {
return changedFileName.slice(0, -suffix.length);
}
return null;
}
export function getFolderNote(plugin: FolderNotesPlugin, folderPath: string, storageLocation?: string, file?: TFile) {
if (!folderPath) return null;
const folder = {
path: folderPath,
name: plugin.getFolderNameFromPathString(folderPath),
};
let fileName = plugin.settings.folderNoteName.replace('{{folder_name}}', folder.name);
if (file) {
fileName = plugin.settings.folderNoteName.replace('{{folder_name}}', file.basename);
}
if ((plugin.settings.storageLocation === 'parentFolder' || storageLocation === 'parentFolder') && storageLocation !== 'insideFolder') {
folder.path = plugin.getFolderPathFromString(folderPath);
}
let path = `${folder.path}/${fileName}`;
if (folder.path.trim() === '') {
folder.path = fileName;
path = `${fileName}`;
}
let folderNoteType = plugin.settings.folderNoteType;
if (folderNoteType === '.excalidraw') {
folderNoteType = '.md';
}
let folderNote = plugin.app.vault.getAbstractFileByPath(path + folderNoteType);
if (folderNote instanceof TFile) {
return folderNote;
} else {
const supportedFileTypes = plugin.settings.supportedFileTypes.filter((type) => type !== plugin.settings.folderNoteType.replace('.', ''));
for (let type of supportedFileTypes) {
if (type === 'excalidraw' || type === '.excalidraw') {
type = '.md';
}
if (!type.startsWith('.')) {
type = '.' + type;
}
folderNote = plugin.app.vault.getAbstractFileByPath(path + type);
if (folderNote instanceof TFile) {
return folderNote;
}
}
}
}
export function getFolder(plugin: FolderNotesPlugin, file: TFile, storageLocation?: string) {
if (!file) return null;
let folderName = extractFolderName(plugin.settings.folderNoteName, file.basename);
if (plugin.settings.folderNoteName === file.basename && plugin.settings.storageLocation === 'insideFolder') {
folderName = file.parent?.name ?? '';
}
if (!folderName) return null;
let folderPath = plugin.getFolderPathFromString(file.path);
let folder: TFolder | TAbstractFile | null = null;
if ((plugin.settings.storageLocation === 'parentFolder' || storageLocation === 'parentFolder') && storageLocation !== 'insideFolder') {
if (folderPath.trim() === '') {
folderPath = folderName;
} else {
folderPath = `${folderPath}/${folderName}`;
}
folder = plugin.app.vault.getAbstractFileByPath(folderPath);
} else {
folder = plugin.app.vault.getAbstractFileByPath(folderPath);
}
if (!folder) { return null; }
return folder;
}
export function getFolderNoteFolder(plugin: FolderNotesPlugin, folderNote: TFile | string, fileName: string) {
if (!folderNote) return null;
let filePath = '';
if (typeof folderNote === 'string') {
filePath = folderNote;
} else {
fileName = folderNote.basename;
filePath = folderNote.path;
}
const folderName = extractFolderName(plugin.settings.folderNoteName, fileName);
if (!folderName) return null;
let folderPath = plugin.getFolderPathFromString(filePath);
if (plugin.settings.storageLocation === 'parentFolder') {
if (folderPath.trim() === '') {
folderPath = folderName;
} else {
folderPath = `${folderPath}/${folderName}`;
}
} else {
folderPath = plugin.getFolderPathFromString(filePath);
}
const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
if (!folder) { return null; }
return folder;
}