@@ -690,7 +690,7 @@ const SLOW_SCROLL_FRAME_COUNT = 10; // Number of slow frames before warning
690690const elements = {
691691 logo: document.getElementById('logo') as HTMLImageElement,
692692 btnOpenFile: document.getElementById('btn-open-file') as HTMLButtonElement,
693- btnRecentFiles: document.getElementById('btn-recent-files') as HTMLSpanElement ,
693+ btnRecentFiles: document.getElementById('btn-recent-files') as HTMLButtonElement ,
694694 recentFilesPopup: document.getElementById('recent-files-popup') as HTMLDivElement,
695695 btnOpenWelcome: document.getElementById('btn-open-welcome') as HTMLButtonElement,
696696 btnSearch: document.getElementById('btn-search') as HTMLButtonElement,
@@ -725,6 +725,8 @@ const elements = {
725725 markdownPreview: document.getElementById('markdown-preview') as HTMLDivElement,
726726 foldersList: document.getElementById('folders-list') as HTMLDivElement,
727727 btnAddFolder: document.getElementById('btn-add-folder') as HTMLButtonElement,
728+ btnRecentFolders: document.getElementById('btn-recent-folders') as HTMLButtonElement,
729+ recentFoldersPopup: document.getElementById('recent-folders-popup') as HTMLDivElement,
728730 btnRefreshFolders: document.getElementById('btn-refresh-folders') as HTMLButtonElement, // May be null — per-folder refresh buttons used instead
729731 folderSearchInput: document.getElementById('folder-search-input') as HTMLInputElement,
730732 btnFolderSearch: document.getElementById('btn-folder-search') as HTMLButtonElement,
@@ -4237,6 +4239,74 @@ async function openFile(): Promise<void> {
42374239 await loadFile(filePath);
42384240}
42394241
4242+ async function toggleRecentFoldersPopup(): Promise<void> {
4243+ const popup = elements.recentFoldersPopup;
4244+ if (!popup.classList.contains('hidden')) {
4245+ popup.classList.add('hidden');
4246+ return;
4247+ }
4248+
4249+ const result = await window.api.listRecentFolders();
4250+ const folders = result.folders || [];
4251+
4252+ let html = `<div class="recent-files-header">Recent Folders</div>`;
4253+ if (folders.length === 0) {
4254+ html += `<div class="recent-files-empty">No recent folders</div>`;
4255+ } else {
4256+ html += `<div class="recent-files-list">`;
4257+ for (const f of folders) {
4258+ const parts = f.path.replace(/\\/g, '/').split('/');
4259+ const name = parts.pop() || f.path;
4260+ const parent = parts.join('/') || '/';
4261+ const ageMs = Date.now() - f.lastOpened;
4262+ let ageText: string;
4263+ if (ageMs < 60000) ageText = 'just now';
4264+ else if (ageMs < 3600000) ageText = `${Math.floor(ageMs / 60000)}m ago`;
4265+ else if (ageMs < 86400000) ageText = `${Math.floor(ageMs / 3600000)}h ago`;
4266+ else ageText = `${Math.floor(ageMs / 86400000)}d ago`;
4267+ html += `
4268+ <div class="recent-file-item" data-path="${escapeHtml(f.path)}" title="${escapeHtml(f.path)}">
4269+ <span class="recent-file-name">${escapeHtml(name)}</span>
4270+ <span class="recent-file-meta">${escapeHtml(parent)} · ${ageText}</span>
4271+ </div>`;
4272+ }
4273+ html += `</div>`;
4274+ html += `<div class="recent-files-footer"><button class="recent-files-clear-btn">Clear history</button></div>`;
4275+ }
4276+
4277+ popup.innerHTML = html;
4278+
4279+ const btnRect = elements.btnRecentFolders.getBoundingClientRect();
4280+ popup.style.top = `${btnRect.bottom + 4}px`;
4281+ popup.style.left = `${btnRect.left}px`;
4282+ popup.classList.remove('hidden');
4283+
4284+ popup.querySelectorAll('.recent-file-item').forEach(item => {
4285+ item.addEventListener('click', async () => {
4286+ const folderPath = (item as HTMLElement).dataset.path;
4287+ if (!folderPath) return;
4288+ popup.classList.add('hidden');
4289+ if (state.folders.some(f => f.path === folderPath)) return;
4290+ const res = await window.api.readFolder(folderPath);
4291+ if (res.success && res.files) {
4292+ const folderName = folderPath.replace(/\\/g, '/').split('/').pop() || folderPath;
4293+ state.folders.push({
4294+ path: folderPath,
4295+ name: folderName,
4296+ files: mapFolderEntries(res.files),
4297+ collapsed: false,
4298+ });
4299+ renderFolderTree();
4300+ updateFolderSearchState();
4301+ }
4302+ });
4303+ });
4304+ popup.querySelector('.recent-files-clear-btn')?.addEventListener('click', async () => {
4305+ await window.api.clearRecentFolders();
4306+ popup.classList.add('hidden');
4307+ });
4308+ }
4309+
42404310// === Folder Operations ===
42414311
42424312function mapFolderEntries(entries: any[]): LocalFolderFile[] {
@@ -13437,18 +13507,13 @@ function init(): void {
1343713507 elements.logo.style.cursor = 'pointer';
1343813508
1343913509 // File operations
13440- elements.btnOpenFile.addEventListener('click', (e) => {
13441- // Don't open file dialog if the recent files chevron was clicked
13442- if ((e.target as HTMLElement).id === 'btn-recent-files') return;
13443- openFile();
13444- });
13445- elements.btnRecentFiles.addEventListener('click', (e) => {
13446- e.stopPropagation();
13510+ elements.btnOpenFile.addEventListener('click', openFile);
13511+ elements.btnOpenFile.addEventListener('contextmenu', (e) => {
1344713512 e.preventDefault();
1344813513 toggleRecentFilesPopup();
1344913514 });
13450- elements.btnOpenFile .addEventListener('contextmenu ', (e) => {
13451- e.preventDefault ();
13515+ elements.btnRecentFiles .addEventListener('click ', (e) => {
13516+ e.stopPropagation ();
1345213517 toggleRecentFilesPopup();
1345313518 });
1345413519 document.addEventListener('click', (e) => {
@@ -13457,11 +13522,20 @@ function init(): void {
1345713522 !elements.btnRecentFiles.contains(e.target as Node)) {
1345813523 elements.recentFilesPopup.classList.add('hidden');
1345913524 }
13525+ if (!elements.recentFoldersPopup.classList.contains('hidden') &&
13526+ !elements.recentFoldersPopup.contains(e.target as Node) &&
13527+ !elements.btnRecentFolders.contains(e.target as Node)) {
13528+ elements.recentFoldersPopup.classList.add('hidden');
13529+ }
1346013530 });
1346113531 elements.btnOpenWelcome.addEventListener('click', openFile);
1346213532
1346313533 // Folder operations
1346413534 elements.btnAddFolder.addEventListener('click', openFolder);
13535+ elements.btnRecentFolders.addEventListener('click', (e) => {
13536+ e.stopPropagation();
13537+ toggleRecentFoldersPopup();
13538+ });
1346513539 elements.btnRefreshFolders?.addEventListener('click', refreshFolders);
1346613540
1346713541 // Folder search
0 commit comments