fix: affichage images PNG + preview hover opaque + preview images
1. File viewer: ws_id parsing cassé (parts[2] au lieu de parts[1]). Corrigé avec une boucle qui trouve le segment 'workspace_*'. Les images s'affichent maintenant correctement. 2. Preview hover: background rendu opaque (fallback #1a1a1a si var(--bg) absent), texte lisible. Ajout support preview image (thumbnail). 3. Preview body: changé de <pre x-text> à <div x-html> pour supporter le HTML (nécessaire pour les <img>).
This commit is contained in:
@@ -864,8 +864,10 @@ def _render_file_viewer(page: dict, request: Request) -> HTMLResponse:
|
|||||||
# Build workspace_id from file_path
|
# Build workspace_id from file_path
|
||||||
parts = file_path.split("/")
|
parts = file_path.split("/")
|
||||||
ws_id = ""
|
ws_id = ""
|
||||||
if len(parts) >= 3 and parts[2].startswith("workspace_"):
|
for p in parts:
|
||||||
ws_id = parts[2].replace("workspace_", "")
|
if p.startswith("workspace_"):
|
||||||
|
ws_id = p.replace("workspace_", "")
|
||||||
|
break
|
||||||
filename = parts[-1] if parts else title
|
filename = parts[-1] if parts else title
|
||||||
|
|
||||||
file_url = f"/api/files/{ws_id}/{filename}" if ws_id else ""
|
file_url = f"/api/files/{ws_id}/{filename}" if ws_id else ""
|
||||||
|
|||||||
@@ -108,9 +108,9 @@
|
|||||||
.search-clear:hover{color:var(--text);background:var(--bg-hover);}
|
.search-clear:hover{color:var(--text);background:var(--bg-hover);}
|
||||||
|
|
||||||
/* File preview tooltip */
|
/* 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{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);border-bottom:1px solid var(--border);}
|
.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);max-height:200px;overflow:auto;font-family:'Fira Code','Cascadia Code',monospace;white-space:pre-wrap;word-wrap:break-word;}
|
.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;}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="ws-layout" x-data="wsInit()"
|
<div class="ws-layout" x-data="wsInit()"
|
||||||
@@ -278,7 +278,7 @@
|
|||||||
:style="{ left: previewX + 'px', top: previewY + 'px' }"
|
:style="{ left: previewX + 'px', top: previewY + 'px' }"
|
||||||
@mouseenter="previewVisible = true" @mouseleave="previewVisible = false">
|
@mouseenter="previewVisible = true" @mouseleave="previewVisible = false">
|
||||||
<div class="file-preview-header" x-text="previewName"></div>
|
<div class="file-preview-header" x-text="previewName"></div>
|
||||||
<pre class="file-preview-body" x-text="previewContent"></pre>
|
<div class="file-preview-body" x-html="previewContent"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -423,16 +423,25 @@ document.addEventListener('alpine:init', function() {
|
|||||||
this.previewName = node.name;
|
this.previewName = node.name;
|
||||||
this.previewX = ev.clientX + 12;
|
this.previewX = ev.clientX + 12;
|
||||||
this.previewY = ev.clientY + 12;
|
this.previewY = ev.clientY + 12;
|
||||||
this.previewContent = 'Loading...';
|
|
||||||
this.previewVisible = true;
|
this.previewVisible = true;
|
||||||
var self = this;
|
var self = this;
|
||||||
var wsId = {{ workspace_id }} || 1;
|
var wsId = {{ workspace_id }} || 1;
|
||||||
fetch('/api/files/' + wsId + '/' + encodeURIComponent(node.name))
|
var url = '/api/files/' + wsId + '/' + encodeURIComponent(node.name);
|
||||||
.then(function(r) { return r.text(); })
|
// Check if image
|
||||||
.then(function(t) {
|
var imgExts = ['.png','.jpg','.jpeg','.gif','.webp','.svg','.bmp','.ico'];
|
||||||
self.previewContent = t.substring(0, 500);
|
var isImg = false;
|
||||||
})
|
for (var i=0; i<imgExts.length; i++) {
|
||||||
.catch(function() { self.previewContent = '(preview not available)'; });
|
if ((node.name||'').toLowerCase().endsWith(imgExts[i])) { isImg = true; break; }
|
||||||
|
}
|
||||||
|
if (isImg) {
|
||||||
|
this.previewContent = '<img src="'+url+'" style="max-width:380px;max-height:180px;display:block;">';
|
||||||
|
} 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() {
|
hidePreview() {
|
||||||
this.previewVisible = false;
|
this.previewVisible = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user