diff --git a/app/routers/board.py b/app/routers/board.py index a4a1242..96a5980 100644 --- a/app/routers/board.py +++ b/app/routers/board.py @@ -864,8 +864,10 @@ def _render_file_viewer(page: dict, request: Request) -> HTMLResponse: # Build workspace_id from file_path parts = file_path.split("/") ws_id = "" - if len(parts) >= 3 and parts[2].startswith("workspace_"): - ws_id = parts[2].replace("workspace_", "") + for p in parts: + if p.startswith("workspace_"): + ws_id = p.replace("workspace_", "") + break filename = parts[-1] if parts else title file_url = f"/api/files/{ws_id}/{filename}" if ws_id else "" diff --git a/app/templates/local_workspace.html b/app/templates/local_workspace.html index 3b8366c..f2561bb 100644 --- a/app/templates/local_workspace.html +++ b/app/templates/local_workspace.html @@ -108,9 +108,9 @@ .search-clear:hover{color:var(--text);background:var(--bg-hover);} /* File preview tooltip */ -.file-preview{position:fixed;z-index:300;background:var(--bg);border:1px solid var(--border-strong);border-radius:10px;box-shadow:0 8px 30px rgba(0,0,0,.5);max-width:400px;min-width:200px;pointer-events:auto;} -.file-preview-header{padding:8px 12px;font-size:12px;font-weight:600;color:var(--text-secondary);border-bottom:1px solid var(--border);} -.file-preview-body{padding:10px 12px;margin:0;font-size:12px;line-height:1.5;color:var(--text);max-height:200px;overflow:auto;font-family:'Fira Code','Cascadia Code',monospace;white-space:pre-wrap;word-wrap:break-word;} +.file-preview{position:fixed;z-index:300;background:#1a1a1a;background:var(--bg,#1a1a1a);border:1px solid var(--border-strong,#333);border-radius:10px;box-shadow:0 8px 30px rgba(0,0,0,.5);max-width:400px;min-width:200px;pointer-events:auto;} +.file-preview-header{padding:8px 12px;font-size:12px;font-weight:600;color:var(--text-secondary,#888);border-bottom:1px solid var(--border,#333);} +.file-preview-body{padding:10px 12px;margin:0;font-size:12px;line-height:1.5;color:var(--text,#ddd);max-height:200px;overflow:auto;font-family:'Fira Code','Cascadia Code',monospace;white-space:pre-wrap;word-wrap:break-word;background:#141414;}
-

+    
@@ -423,16 +423,25 @@ document.addEventListener('alpine:init', function() { this.previewName = node.name; this.previewX = ev.clientX + 12; this.previewY = ev.clientY + 12; - this.previewContent = 'Loading...'; this.previewVisible = true; var self = this; var wsId = {{ workspace_id }} || 1; - fetch('/api/files/' + wsId + '/' + encodeURIComponent(node.name)) - .then(function(r) { return r.text(); }) - .then(function(t) { - self.previewContent = t.substring(0, 500); - }) - .catch(function() { self.previewContent = '(preview not available)'; }); + var url = '/api/files/' + wsId + '/' + encodeURIComponent(node.name); + // Check if image + var imgExts = ['.png','.jpg','.jpeg','.gif','.webp','.svg','.bmp','.ico']; + var isImg = false; + for (var i=0; i'; + } else { + this.previewContent = 'Loading...'; + fetch(url) + .then(function(r) { return r.text(); }) + .then(function(t) { self.previewContent = t.substring(0, 500); }) + .catch(function() { self.previewContent = '(preview not available)'; }); + } }, hidePreview() { this.previewVisible = false;