mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-18 10:01:23 +01:00
Merge pull request #13 from n8k99/claude/fix-nested-folder-display-015Ytt8mSX9sfytMQC85P4gA
Claude/fix nested folder display 015 ytt8m sx9sfyt mqc85 p4g a
This commit is contained in:
commit
d47e3d0bb0
2 changed files with 132 additions and 5 deletions
|
|
@ -13,6 +13,16 @@ const ObsidianBridge = (() => {
|
||||||
vaultName: ""
|
vaultName: ""
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Cache for vault file list
|
||||||
|
let vaultFilesCache = {
|
||||||
|
files: null,
|
||||||
|
timestamp: null,
|
||||||
|
ttl: 5 * 60 * 1000 // 5 minutes cache
|
||||||
|
};
|
||||||
|
|
||||||
|
// Index: fmg-id → file path for fast lookups
|
||||||
|
let fmgIdIndex = {};
|
||||||
|
|
||||||
// Initialize from localStorage
|
// Initialize from localStorage
|
||||||
function init() {
|
function init() {
|
||||||
const stored = localStorage.getItem("obsidianConfig");
|
const stored = localStorage.getItem("obsidianConfig");
|
||||||
|
|
@ -24,6 +34,18 @@ const ObsidianBridge = (() => {
|
||||||
ERROR && console.error("Failed to load Obsidian config:", error);
|
ERROR && console.error("Failed to load Obsidian config:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load FMG ID index from localStorage
|
||||||
|
const storedIndex = localStorage.getItem("obsidianFmgIdIndex");
|
||||||
|
if (storedIndex) {
|
||||||
|
try {
|
||||||
|
fmgIdIndex = JSON.parse(storedIndex);
|
||||||
|
INFO && console.log(`Loaded FMG ID index with ${Object.keys(fmgIdIndex).length} entries`);
|
||||||
|
} catch (error) {
|
||||||
|
ERROR && console.error("Failed to load FMG ID index:", error);
|
||||||
|
fmgIdIndex = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save configuration
|
// Save configuration
|
||||||
|
|
@ -94,19 +116,65 @@ const ObsidianBridge = (() => {
|
||||||
return mdFiles;
|
return mdFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all markdown files from vault (recursively)
|
// Clear the vault files cache
|
||||||
async function getVaultFiles() {
|
function clearVaultCache() {
|
||||||
|
vaultFilesCache.files = null;
|
||||||
|
vaultFilesCache.timestamp = null;
|
||||||
|
INFO && console.log("Vault file cache cleared");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save FMG ID index to localStorage
|
||||||
|
function saveFmgIdIndex() {
|
||||||
|
try {
|
||||||
|
localStorage.setItem("obsidianFmgIdIndex", JSON.stringify(fmgIdIndex));
|
||||||
|
DEBUG && console.log(`Saved FMG ID index with ${Object.keys(fmgIdIndex).length} entries`);
|
||||||
|
} catch (error) {
|
||||||
|
ERROR && console.error("Failed to save FMG ID index:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add entry to FMG ID index
|
||||||
|
function addToFmgIdIndex(fmgId, filePath) {
|
||||||
|
if (!fmgId) return;
|
||||||
|
fmgIdIndex[fmgId] = filePath;
|
||||||
|
saveFmgIdIndex();
|
||||||
|
DEBUG && console.log(`Added to index: ${fmgId} → ${filePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get file path from FMG ID index
|
||||||
|
function getFromFmgIdIndex(fmgId) {
|
||||||
|
return fmgIdIndex[fmgId] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all markdown files from vault (recursively, with caching)
|
||||||
|
async function getVaultFiles(forceRefresh = false) {
|
||||||
if (!config.enabled) {
|
if (!config.enabled) {
|
||||||
throw new Error("Obsidian not connected");
|
throw new Error("Obsidian not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check cache
|
||||||
|
const now = Date.now();
|
||||||
|
const cacheValid = vaultFilesCache.files !== null &&
|
||||||
|
vaultFilesCache.timestamp !== null &&
|
||||||
|
(now - vaultFilesCache.timestamp) < vaultFilesCache.ttl;
|
||||||
|
|
||||||
|
if (cacheValid && !forceRefresh) {
|
||||||
|
INFO && console.log(`getVaultFiles: Using cached list (${vaultFilesCache.files.length} files)`);
|
||||||
|
return vaultFilesCache.files;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TIME && console.time("getVaultFiles");
|
TIME && console.time("getVaultFiles");
|
||||||
|
INFO && console.log("getVaultFiles: Scanning vault (cache miss or expired)...");
|
||||||
|
|
||||||
// Recursively scan all directories
|
// Recursively scan all directories
|
||||||
const mdFiles = await scanDirectory("");
|
const mdFiles = await scanDirectory("");
|
||||||
|
|
||||||
INFO && console.log(`getVaultFiles: Found ${mdFiles.length} markdown files (recursive scan)`);
|
// Update cache
|
||||||
|
vaultFilesCache.files = mdFiles;
|
||||||
|
vaultFilesCache.timestamp = now;
|
||||||
|
|
||||||
|
INFO && console.log(`getVaultFiles: Found ${mdFiles.length} markdown files (recursive scan, cached)`);
|
||||||
DEBUG && console.log("Sample files:", mdFiles.slice(0, 10));
|
DEBUG && console.log("Sample files:", mdFiles.slice(0, 10));
|
||||||
|
|
||||||
TIME && console.timeEnd("getVaultFiles");
|
TIME && console.timeEnd("getVaultFiles");
|
||||||
|
|
@ -344,9 +412,43 @@ const ObsidianBridge = (() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find note by FMG ID in frontmatter
|
// Find note by FMG ID in frontmatter (with index for fast lookup)
|
||||||
async function findNoteByFmgId(fmgId) {
|
async function findNoteByFmgId(fmgId) {
|
||||||
|
if (!fmgId) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// First, check the index for instant lookup
|
||||||
|
const indexedPath = getFromFmgIdIndex(fmgId);
|
||||||
|
if (indexedPath) {
|
||||||
|
INFO && console.log(`Found note in index: ${fmgId} → ${indexedPath}`);
|
||||||
|
try {
|
||||||
|
const content = await getNote(indexedPath);
|
||||||
|
const {frontmatter} = parseFrontmatter(content);
|
||||||
|
|
||||||
|
// Verify the fmg-id still matches (file might have been modified)
|
||||||
|
if (frontmatter["fmg-id"] === fmgId || frontmatter.fmgId === fmgId) {
|
||||||
|
return {
|
||||||
|
path: indexedPath,
|
||||||
|
name: indexedPath.replace(/\.md$/, "").split("/").pop(),
|
||||||
|
content,
|
||||||
|
frontmatter
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// Index is stale, remove the entry
|
||||||
|
WARN && console.warn(`Index entry stale for ${fmgId}, removing`);
|
||||||
|
delete fmgIdIndex[fmgId];
|
||||||
|
saveFmgIdIndex();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// File no longer exists, remove from index
|
||||||
|
WARN && console.warn(`Indexed file not found: ${indexedPath}, removing from index`);
|
||||||
|
delete fmgIdIndex[fmgId];
|
||||||
|
saveFmgIdIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not in index or index was stale, search all files
|
||||||
|
INFO && console.log(`Searching vault for fmg-id: ${fmgId}`);
|
||||||
const files = await getVaultFiles();
|
const files = await getVaultFiles();
|
||||||
const mdFiles = files.filter(f => f.endsWith(".md"));
|
const mdFiles = files.filter(f => f.endsWith(".md"));
|
||||||
|
|
||||||
|
|
@ -356,6 +458,10 @@ const ObsidianBridge = (() => {
|
||||||
const {frontmatter} = parseFrontmatter(content);
|
const {frontmatter} = parseFrontmatter(content);
|
||||||
|
|
||||||
if (frontmatter["fmg-id"] === fmgId || frontmatter.fmgId === fmgId) {
|
if (frontmatter["fmg-id"] === fmgId || frontmatter.fmgId === fmgId) {
|
||||||
|
// Found it! Add to index for next time
|
||||||
|
addToFmgIdIndex(fmgId, filePath);
|
||||||
|
INFO && console.log(`Found note and added to index: ${fmgId} → ${filePath}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
path: filePath,
|
path: filePath,
|
||||||
name: filePath.replace(/\.md$/, "").split("/").pop(),
|
name: filePath.replace(/\.md$/, "").split("/").pop(),
|
||||||
|
|
@ -520,6 +626,7 @@ Add your lore here...
|
||||||
saveConfig,
|
saveConfig,
|
||||||
testConnection,
|
testConnection,
|
||||||
getVaultFiles,
|
getVaultFiles,
|
||||||
|
clearVaultCache,
|
||||||
getNote,
|
getNote,
|
||||||
updateNote,
|
updateNote,
|
||||||
createNote,
|
createNote,
|
||||||
|
|
@ -529,7 +636,9 @@ Add your lore here...
|
||||||
generateNoteTemplate,
|
generateNoteTemplate,
|
||||||
searchNotes,
|
searchNotes,
|
||||||
listAllNotes,
|
listAllNotes,
|
||||||
listAllNotePaths
|
listAllNotePaths,
|
||||||
|
addToFmgIdIndex,
|
||||||
|
getFromFmgIdIndex
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,13 @@ async function promptCreateNewNote(elementId, elementType, coordinates) {
|
||||||
|
|
||||||
const {frontmatter} = ObsidianBridge.parseFrontmatter(template);
|
const {frontmatter} = ObsidianBridge.parseFrontmatter(template);
|
||||||
|
|
||||||
|
// Add to FMG ID index for instant future lookups
|
||||||
|
const fmgId = frontmatter["fmg-id"] || frontmatter.fmgId;
|
||||||
|
if (fmgId) {
|
||||||
|
ObsidianBridge.addToFmgIdIndex(fmgId, notePath);
|
||||||
|
INFO && console.log(`New note added to index: ${fmgId} → ${notePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
resolve({
|
resolve({
|
||||||
path: notePath,
|
path: notePath,
|
||||||
name,
|
name,
|
||||||
|
|
@ -590,6 +597,17 @@ async function saveObsidianNote() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ObsidianBridge.updateNote(path, content);
|
await ObsidianBridge.updateNote(path, content);
|
||||||
|
|
||||||
|
// Update the FMG ID index if this note has an fmg-id
|
||||||
|
if (elementId) {
|
||||||
|
const {frontmatter} = ObsidianBridge.parseFrontmatter(content);
|
||||||
|
const fmgId = frontmatter["fmg-id"] || frontmatter.fmgId;
|
||||||
|
if (fmgId) {
|
||||||
|
// Add to index using internal method
|
||||||
|
ObsidianBridge.addToFmgIdIndex(fmgId, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
showMarkdownEditor.originalContent = content;
|
showMarkdownEditor.originalContent = content;
|
||||||
// Update the editor to show the new frontmatter
|
// Update the editor to show the new frontmatter
|
||||||
byId("obsidianMarkdownEditor").value = content;
|
byId("obsidianMarkdownEditor").value = content;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue