fix ports
This commit is contained in:
@@ -7,7 +7,11 @@
|
|||||||
const article = document.querySelector('[data-document-path]');
|
const article = document.querySelector('[data-document-path]');
|
||||||
const workspaceShell = article?.closest('.workspace-shell--document');
|
const workspaceShell = article?.closest('.workspace-shell--document');
|
||||||
const commentsAsideList = document.querySelector('[data-comments-aside-list]');
|
const commentsAsideList = document.querySelector('[data-comments-aside-list]');
|
||||||
|
const commentsAsideListMobile = document.querySelector('[data-comments-aside-list-mobile]');
|
||||||
const stripTrack = document.querySelector('[data-comments-strip-track]');
|
const stripTrack = document.querySelector('[data-comments-strip-track]');
|
||||||
|
const commentsAside = document.querySelector('[data-comments-aside]');
|
||||||
|
const commentsSheetToggle = document.querySelector('[data-toggle-comments]');
|
||||||
|
const commentsSheetClose = document.querySelector('[data-close-comments]');
|
||||||
const documentId = documentPath ? 'doc:' + documentPath.replace(/\.md$/, '') : null;
|
const documentId = documentPath ? 'doc:' + documentPath.replace(/\.md$/, '') : null;
|
||||||
const commentToggle = document.querySelector('[data-comment-toggle]');
|
const commentToggle = document.querySelector('[data-comment-toggle]');
|
||||||
const commentVisibilityKey = documentId ? `cairnquire:document-comments:${documentId}` : null;
|
const commentVisibilityKey = documentId ? `cairnquire:document-comments:${documentId}` : null;
|
||||||
@@ -165,20 +169,7 @@
|
|||||||
updateStripMarkers();
|
updateStripMarkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCommentsAside() {
|
function buildAsideItemFor(el) {
|
||||||
if (!commentsAsideList) return;
|
|
||||||
commentsAsideList.innerHTML = '';
|
|
||||||
|
|
||||||
const body = document.querySelector('.markdown-body');
|
|
||||||
if (!body) return;
|
|
||||||
|
|
||||||
const commentables = body.querySelectorAll('.commentable[data-has-comments="true"]');
|
|
||||||
if (!commentables.length) {
|
|
||||||
commentsAsideList.innerHTML = '<p class="document-comments-aside__empty">No comments yet.</p>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
commentables.forEach(el => {
|
|
||||||
const comments = [];
|
const comments = [];
|
||||||
el.querySelectorAll('.comment-item').forEach(item => {
|
el.querySelectorAll('.comment-item').forEach(item => {
|
||||||
const meta = item.querySelector('.comment-meta');
|
const meta = item.querySelector('.comment-meta');
|
||||||
@@ -189,7 +180,7 @@
|
|||||||
content: bodyEl?.textContent || '',
|
content: bodyEl?.textContent || '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (!comments.length) return;
|
if (!comments.length) return null;
|
||||||
|
|
||||||
const targetText = (el.textContent || '').replace(/\s+/g, ' ').trim().slice(0, 120);
|
const targetText = (el.textContent || '').replace(/\s+/g, ' ').trim().slice(0, 120);
|
||||||
const truncated = targetText.length > 120 ? targetText + '…' : targetText;
|
const truncated = targetText.length > 120 ? targetText + '…' : targetText;
|
||||||
@@ -216,9 +207,31 @@
|
|||||||
asideItem.appendChild(commentEl);
|
asideItem.appendChild(commentEl);
|
||||||
});
|
});
|
||||||
|
|
||||||
commentsAsideList.appendChild(asideItem);
|
return asideItem;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
function renderCommentsInto(container) {
|
||||||
|
if (!container) return;
|
||||||
|
container.innerHTML = '';
|
||||||
|
|
||||||
|
const body = document.querySelector('.markdown-body');
|
||||||
|
if (!body) return;
|
||||||
|
|
||||||
|
const commentables = body.querySelectorAll('.commentable[data-has-comments="true"]');
|
||||||
|
if (!commentables.length) {
|
||||||
|
container.innerHTML = '<p class="document-comments-aside__empty">No comments yet.</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
commentables.forEach(el => {
|
||||||
|
const item = buildAsideItemFor(el);
|
||||||
|
if (item) container.appendChild(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCommentsAside() {
|
||||||
|
renderCommentsInto(commentsAsideList);
|
||||||
|
renderCommentsInto(commentsAsideListMobile);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStripMarkers() {
|
function updateStripMarkers() {
|
||||||
@@ -326,6 +339,45 @@
|
|||||||
return d.toLocaleString();
|
return d.toLocaleString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function commentsSheetOpen() {
|
||||||
|
return commentsAside?.classList.contains('is-open');
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCommentsSheetOpen(open) {
|
||||||
|
if (!commentsAside) return;
|
||||||
|
commentsAside.classList.toggle('is-open', open);
|
||||||
|
if (commentsSheetToggle) {
|
||||||
|
commentsSheetToggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
||||||
|
commentsSheetToggle.setAttribute('aria-label', open ? 'Hide comments' : 'Show comments');
|
||||||
|
}
|
||||||
|
if (open) {
|
||||||
|
document.body.classList.add('drawer-open');
|
||||||
|
renderCommentsAside();
|
||||||
|
} else {
|
||||||
|
if (!pickerOpen() && !metaOpen()) {
|
||||||
|
document.body.classList.remove('drawer-open');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pickerOpen() {
|
||||||
|
return document.querySelector('[data-picker-drawer]')?.classList.contains('is-open');
|
||||||
|
}
|
||||||
|
|
||||||
|
function metaOpen() {
|
||||||
|
return document.querySelector('[data-meta-drawer]')?.classList.contains('is-open');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commentsSheetToggle) {
|
||||||
|
commentsSheetToggle.addEventListener('click', () => {
|
||||||
|
setCommentsSheetOpen(!commentsSheetOpen());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commentsSheetClose) {
|
||||||
|
commentsSheetClose.addEventListener('click', () => setCommentsSheetOpen(false));
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
const body = document.querySelector('.markdown-body');
|
const body = document.querySelector('.markdown-body');
|
||||||
if (!body) return;
|
if (!body) return;
|
||||||
|
|||||||
77
apps/server/internal/httpserver/static/mobile.js
Normal file
77
apps/server/internal/httpserver/static/mobile.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const backdrop = document.querySelector('[data-mobile-drawer-backdrop]');
|
||||||
|
const pickerDrawer = document.querySelector('[data-picker-drawer]');
|
||||||
|
const metaDrawer = document.querySelector('[data-meta-drawer]');
|
||||||
|
const commentsAside = document.querySelector('[data-comments-aside]');
|
||||||
|
const pickerToggle = document.querySelector('[data-toggle-picker]');
|
||||||
|
const metaToggle = document.querySelector('[data-toggle-meta]');
|
||||||
|
const pickerClose = document.querySelector('[data-close-picker]');
|
||||||
|
const metaClose = document.querySelector('[data-close-meta]');
|
||||||
|
|
||||||
|
function anyDrawerOpen() {
|
||||||
|
return Boolean(
|
||||||
|
pickerDrawer?.classList.contains('is-open') ||
|
||||||
|
metaDrawer?.classList.contains('is-open') ||
|
||||||
|
commentsAside?.classList.contains('is-open')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateBackdrop() {
|
||||||
|
document.body.classList.toggle('drawer-open', anyDrawerOpen());
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPickerOpen(open) {
|
||||||
|
if (!pickerDrawer) return;
|
||||||
|
pickerDrawer.classList.toggle('is-open', open);
|
||||||
|
if (pickerToggle) pickerToggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
||||||
|
updateBackdrop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMetaOpen(open) {
|
||||||
|
if (!metaDrawer) return;
|
||||||
|
metaDrawer.classList.toggle('is-open', open);
|
||||||
|
if (metaToggle) metaToggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
||||||
|
updateBackdrop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeAllDrawers() {
|
||||||
|
setPickerOpen(false);
|
||||||
|
setMetaOpen(false);
|
||||||
|
if (commentsAside) {
|
||||||
|
commentsAside.classList.remove('is-open');
|
||||||
|
const toggle = document.querySelector('[data-toggle-comments]');
|
||||||
|
if (toggle) toggle.setAttribute('aria-expanded', 'false');
|
||||||
|
}
|
||||||
|
updateBackdrop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pickerToggle) {
|
||||||
|
pickerToggle.addEventListener('click', () => {
|
||||||
|
const willOpen = !pickerDrawer?.classList.contains('is-open');
|
||||||
|
closeAllDrawers();
|
||||||
|
setPickerOpen(willOpen);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metaToggle) {
|
||||||
|
metaToggle.addEventListener('click', () => {
|
||||||
|
const willOpen = !metaDrawer?.classList.contains('is-open');
|
||||||
|
closeAllDrawers();
|
||||||
|
setMetaOpen(willOpen);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pickerClose) pickerClose.addEventListener('click', () => setPickerOpen(false));
|
||||||
|
if (metaClose) metaClose.addEventListener('click', () => setMetaOpen(false));
|
||||||
|
|
||||||
|
if (backdrop) {
|
||||||
|
backdrop.addEventListener('click', closeAllDrawers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close drawers on Escape key
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Escape') closeAllDrawers();
|
||||||
|
});
|
||||||
|
})();
|
||||||
@@ -111,6 +111,7 @@
|
|||||||
<script src="/static/auth.js" defer></script>
|
<script src="/static/auth.js" defer></script>
|
||||||
<script src="/static/render.js" defer></script>
|
<script src="/static/render.js" defer></script>
|
||||||
<script src="/static/comments.js" defer></script>
|
<script src="/static/comments.js" defer></script>
|
||||||
|
<script src="/static/mobile.js" defer></script>
|
||||||
<script src="/static/archive.js" defer></script>
|
<script src="/static/archive.js" defer></script>
|
||||||
<script src="/static/permissions.js" defer></script>
|
<script src="/static/permissions.js" defer></script>
|
||||||
<script src="/static/tags.js" defer></script>
|
<script src="/static/tags.js" defer></script>
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ services:
|
|||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- "$PORT:$PORT"
|
- "${PORT:-8080}:${PORT:-8080}"
|
||||||
depends_on:
|
depends_on:
|
||||||
- mailpit
|
- mailpit
|
||||||
environment:
|
environment:
|
||||||
|
PORT: "${PORT:-8080}"
|
||||||
CAIRNQUIRE_DATABASE_PATH: "/workspace/data/db.sqlite"
|
CAIRNQUIRE_DATABASE_PATH: "/workspace/data/db.sqlite"
|
||||||
CAIRNQUIRE_CONTENT_SOURCE_DIR: "/workspace/content"
|
CAIRNQUIRE_CONTENT_SOURCE_DIR: "/workspace/content"
|
||||||
CAIRNQUIRE_CONTENT_STORE_DIR: "/workspace/data/files"
|
CAIRNQUIRE_CONTENT_STORE_DIR: "/workspace/data/files"
|
||||||
@@ -20,7 +21,7 @@ services:
|
|||||||
- cairnquire_data:/workspace/data
|
- cairnquire_data:/workspace/data
|
||||||
- ./content:/workspace/content
|
- ./content:/workspace/content
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "--fail", "http://127.0.0.1:${PORT}/healthz"]
|
test: ["CMD", "curl", "--fail", "http://127.0.0.1:${PORT:-8080}/healthz"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
|||||||
Reference in New Issue
Block a user