diff --git a/app/routers/board.py b/app/routers/board.py
index 0234be0..3a887aa 100644
--- a/app/routers/board.py
+++ b/app/routers/board.py
@@ -946,9 +946,7 @@ async def delete_page(request: Request, page_id: int):
@router.get("/pages/{page_id}", response_class=HTMLResponse)
async def view_page(request: Request, page_id: int):
- """Render a page as HTML, or a file viewer for uploaded files.
- ?embed=1 — minimal mode for side peek (no sidebar/topbar)."""
- embed = request.query_params.get("embed") == "1"
+ """Render a page as HTML, or a file viewer for uploaded files."""
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader("app/templates"))
with get_conn() as conn:
@@ -1005,8 +1003,7 @@ async def view_page(request: Request, page_id: int):
"page_data": page_data,
"breadcrumb_items": nav_crumbs,
"nav_workspace_id": page.get("workspace_id") or 0,
- "nav_page_id": page_id,
- "embed_mode": embed}
+ "nav_page_id": page_id}
template = env.get_template("page_editor.html")
response = template.render(**ctx)
return HTMLResponse(content=response, headers={"Cache-Control": "no-store, max-age=0"})
diff --git a/app/templates/base.html b/app/templates/base.html
index 704a6be..d7dee33 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -88,18 +88,12 @@
font-size: 13px;
}
}
- /* Embed mode — hide sidebar + topbar for peek panels */
- body.embed-mode .sidebar, body.embed-mode .topbar, body.embed-mode .app-layout { display: block !important; }
- body.embed-mode .sidebar { display: none !important; }
- body.embed-mode .topbar { display: none !important; }
- body.embed-mode .app-layout { margin-left: 0 !important; padding-top: 0 !important; }
- body.embed-mode .sidebar-collapsed .app-layout { margin-left: 0 !important; }
-
+
diff --git a/app/templates/library.html b/app/templates/library.html
index 7529777..1f74989 100644
--- a/app/templates/library.html
+++ b/app/templates/library.html
@@ -407,7 +407,6 @@
-
-
+
+
Loading…
+
+
+
{{ fd_icon("file",32) }}
+
No preview available
+
@@ -1198,17 +1202,40 @@ function libraryPage() {
// ── Side peek ──
async openPeek(item) {
this.peekItem = item;
+ this.peekContent = '';
+ this.peekLoading = true;
this.peekFavorited = item.favorited || false;
- // Load editor in iframe
- var iframe = document.getElementById('lib-peek-iframe');
- if (iframe) iframe.src = '/pages/' + item.id + '?embed=1';
+ try {
+ var r = await fetch('/board/api/pages/' + item.id);
+ var d = await r.json();
+ var content = d.content || '';
+ // Simple preview
+ if (d.content_format === 'blocks') {
+ try {
+ var blocks = typeof content === 'string' ? JSON.parse(content) : content;
+ var preview = '';
+ var lines = Array.isArray(blocks) ? blocks.slice(0, 30) : ((blocks && blocks.blocks) ? blocks.blocks.slice(0, 30) : []);
+ for (var i = 0; i < lines.length; i++) {
+ var b = lines[i];
+ var txt = b.content || b.text || (typeof b === 'string' ? b : '');
+ if (txt && txt.trim()) preview += '
' + this._escHtml(String(txt)) + '
';
+ }
+ this.peekContent = preview || '
(empty page)
';
+ } catch(e) {
+ this.peekContent = '
' + this._escHtml(String(content).substring(0, 2000)) + '
';
+ }
+ } else {
+ this.peekContent = content ? '
' + this._escHtml(String(content).substring(0, 2000)) + '
' : '';
+ }
+ } catch(e) {
+ this.peekContent = '';
+ }
+ this.peekLoading = false;
},
closePeek() {
this.peekItem = null;
- // Clear iframe
- var iframe = document.getElementById('lib-peek-iframe');
- if (iframe) iframe.src = '';
+ this.peekContent = '';
},
async toggleFavoritePeek() {
@@ -1276,41 +1303,5 @@ function libraryPage() {
}
};
}
-// Init peek resize handle (vanilla JS)
-(function() {
- var panel = document.querySelector('.peek-overlay');
- var handle = document.getElementById('lib-peek-resize-handle');
- if (!panel || !handle) return;
- var startX, startWidth, dragging = false;
- handle.addEventListener('mousedown', function(e) {
- e.preventDefault();
- startX = e.clientX;
- startWidth = panel.offsetWidth;
- dragging = true;
- document.body.style.userSelect = 'none';
- });
- document.addEventListener('mousemove', function(e) {
- if (!dragging) return;
- var deltaX = startX - e.clientX;
- var newWidth = Math.max(300, Math.min(window.innerWidth * 0.9, startWidth + deltaX));
- panel.style.width = newWidth + 'px';
- });
- document.addEventListener('mouseup', function(e) {
- if (!dragging) return;
- document.body.style.userSelect = '';
- var moved = Math.abs(e.clientX - startX);
- if (moved < 3) {
- // Click — close via Alpine data
- var libData = document.querySelector('[x-data]')._x_dataStack[0];
- if (libData && libData.closePeek) libData.closePeek();
- }
- dragging = false;
- try { localStorage.setItem('fd_peek_width', panel.style.width); } catch(ex) {}
- });
- try {
- var saved = localStorage.getItem('fd_peek_width');
- if (saved) panel.style.width = saved;
- } catch(ex) {}
-})();
{% endblock %}
diff --git a/app/templates/local_workspace.html b/app/templates/local_workspace.html
index b44001e..1236bfb 100644
--- a/app/templates/local_workspace.html
+++ b/app/templates/local_workspace.html
@@ -631,44 +631,6 @@ window._wsInitData = (function() {
this.loadWorkspaceTags();
} catch(e) { console.error('Tree load error:', e); this.loaded = true; }
this._recompute();
- this._initResizeHandle();
- },
-
- _initResizeHandle() {
- var panel = document.getElementById('ws-preview-panel');
- var handle = document.getElementById('ws-preview-resize-handle');
- if (!panel || !handle) return;
- var startX, startWidth, dragging = false;
- handle.addEventListener('mousedown', function(e) {
- e.preventDefault();
- startX = e.clientX;
- startWidth = panel.offsetWidth;
- dragging = true;
- document.body.style.userSelect = 'none';
- });
- document.addEventListener('mousemove', function(e) {
- if (!dragging) return;
- var deltaX = startX - e.clientX;
- var newWidth = Math.max(300, Math.min(window.innerWidth * 0.9, startWidth + deltaX));
- panel.style.width = newWidth + 'px';
- });
- document.addEventListener('mouseup', function(e) {
- if (!dragging) return;
- document.body.style.userSelect = '';
- var moved = Math.abs(e.clientX - startX);
- if (moved < 3) {
- // Simple click — close panel
- window._wsData.closePreviewPanel();
- }
- dragging = false;
- // Save width preference
- try { localStorage.setItem('fd_peek_width', panel.style.width); } catch(ex) {}
- });
- // Restore saved width
- try {
- var saved = localStorage.getItem('fd_peek_width');
- if (saved) panel.style.width = saved;
- } catch(ex) {}
},
_recompute() {
@@ -834,7 +796,7 @@ window._wsInitData = (function() {
return null;
},
- // ── Preview panel (vanilla JS — loads /pages/{id}?embed=1 in iframe) ──
+ // ── Preview panel (vanilla JS — matches Library peek-overlay) ──
selectForPreview(node) {
var panel = document.getElementById('ws-preview-panel');
if (!panel) return;
@@ -857,9 +819,21 @@ window._wsInitData = (function() {
window.showToast('Failed to copy', 'error');
});
};
- // Load the full page editor in iframe (reuses /pages/{id} code)
- var iframe = document.getElementById('ws-preview-iframe');
- if (iframe) iframe.src = '/pages/' + node.id + '?embed=1';
+ // Body: meta info header + loading indicator
+ var meta = '
'
+ + '' + (node.is_folder ? 'Folder' : this._fileTypeLabel(node.name, node.content_format)) + ''
+ + '' + (node.size_display || '-') + ''
+ + '' + this._formatDate(node.updated_at) + ''
+ + '
';
+ if (node.tags && node.tags.length > 0) {
+ meta += '
';
+ for (var i = 0; i < node.tags.length; i++) {
+ var t = node.tags[i];
+ meta += '' + this._escHtml(t.name) + '';
+ }
+ meta += '
';
+ }
+ document.getElementById('ws-preview-body').innerHTML = meta + '
Loading...
';
// Show panel with slide-in
panel.style.display = 'flex';
requestAnimationFrame(function() {
@@ -867,6 +841,8 @@ window._wsInitData = (function() {
panel.style.transform = 'translateX(0)';
});
});
+ // Load content async
+ this._loadPreviewContentVanilla(node);
},
closePreviewPanel() {
@@ -876,9 +852,6 @@ window._wsInitData = (function() {
var self = this;
setTimeout(function() {
panel.style.display = 'none';
- // Clear iframe
- var iframe = document.getElementById('ws-preview-iframe');
- if (iframe) iframe.src = '';
self.previewItem = null;
}, 200);
},
@@ -2910,7 +2883,6 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
-