From 8dc0854de26d4d8d55f89ad668bd18a2c6e0d9ec Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Thu, 16 Jul 2026 16:39:37 +0200 Subject: [PATCH] fdas --- public/s/css/f0ckm.css | 3 +- public/s/js/settings.js | 52 ++++++++++++++++++------------- src/inc/locales/de.json | 3 ++ src/inc/locales/en.json | 3 ++ src/inc/locales/nl.json | 3 ++ src/inc/locales/zange.json | 3 ++ src/inc/routes/apiv2/settings.mjs | 2 +- views/settings.html | 13 ++++---- views/snippets/footer.html | 1 + 9 files changed, 53 insertions(+), 30 deletions(-) diff --git a/public/s/css/f0ckm.css b/public/s/css/f0ckm.css index d98fb9f..d3e229f 100644 --- a/public/s/css/f0ckm.css +++ b/public/s/css/f0ckm.css @@ -8925,7 +8925,7 @@ span.badge.badge-current { gap: 30px; background: var(--metadata-bg); border-radius: 8px; - margin-bottom: 20px; + padding-bottom: 20px; } @media (max-width: 768px) { @@ -13667,6 +13667,7 @@ i.iconset#a_oc { background: var(--nav-bg); position: relative; z-index: 1; + min-height: 140px; } .profile_head::before { diff --git a/public/s/js/settings.js b/public/s/js/settings.js index 4e69ff8..47032c2 100644 --- a/public/s/js/settings.js +++ b/public/s/js/settings.js @@ -390,8 +390,8 @@ const canvasWrapper = document.createElement('div'); canvasWrapper.style.cssText = ` width: 100%; - max-width: 600px; - aspect-ratio: 4 / 1; + max-width: 400px; + aspect-ratio: 400 / 140; position: relative; overflow: hidden; border: 1px solid var(--nav-border-color); @@ -402,8 +402,8 @@ `; const canvas = document.createElement('canvas'); - canvas.width = 1200; - canvas.height = 300; + canvas.width = 400; + canvas.height = 140; canvas.style.cssText = 'width:100%;height:100%;display:block;cursor:move;touch-action:none;pointer-events:auto !important;'; canvasWrapper.appendChild(canvas); @@ -472,7 +472,7 @@ const clamp = (val, min, max) => Math.min(Math.max(val, min), max); const draw = () => { - ctx.clearRect(0, 0, 1200, 300); + ctx.clearRect(0, 0, 400, 140); ctx.drawImage(img, panX, panY, img.naturalWidth * zoom, img.naturalHeight * zoom); // Update hint with live coords/zoom @@ -481,8 +481,8 @@ const getBounds = (z) => { return { - minX: 1200 - img.naturalWidth * z, - minY: 300 - img.naturalHeight * z + minX: 400 - img.naturalWidth * z, + minY: 140 - img.naturalHeight * z }; }; @@ -492,15 +492,15 @@ return; } - // Determine minimum zoom so the image fully covers 1200x400 canvas without black edges - minZoom = Math.max(1200 / img.naturalWidth, 300 / img.naturalHeight); + // Determine minimum zoom so the image fully covers 400x140 canvas without black edges + minZoom = Math.max(400 / img.naturalWidth, 140 / img.naturalHeight); maxZoom = minZoom * 4; if (existingConfig && existingConfig.bgSize && existingConfig.bgSize !== 'cover') { const match = existingConfig.bgSize.match(/([\d.]+)%/); if (match) { const pct = parseFloat(match[1]); - const iw = (pct / 100) * 1200; + const iw = (pct / 100) * 400; zoom = Math.max(minZoom, Math.min(maxZoom, iw / img.naturalWidth)); } else { zoom = minZoom; @@ -511,8 +511,8 @@ const iw = img.naturalWidth * zoom; const ih = img.naturalHeight * zoom; - const maxPanX = 1200 - iw; - const maxPanY = 300 - ih; + const maxPanX = 400 - iw; + const maxPanY = 140 - ih; if (existingConfig && existingConfig.bgPos && existingConfig.bgPos !== 'center') { const parts = existingConfig.bgPos.split(' '); @@ -543,13 +543,13 @@ const t = pct / 100; const newZoom = minZoom + (maxZoom - minZoom) * t; - const imgCenterX = (600 - panX) / oldZoom; - const imgCenterY = (150 - panY) / oldZoom; + const imgCenterX = (200 - panX) / oldZoom; + const imgCenterY = (70 - panY) / oldZoom; zoom = newZoom; const bounds = getBounds(zoom); - panX = Math.max(bounds.minX, Math.min(0, 600 - imgCenterX * zoom)); - panY = Math.max(bounds.minY, Math.min(0, 150 - imgCenterY * zoom)); + panX = Math.max(bounds.minX, Math.min(0, 200 - imgCenterX * zoom)); + panY = Math.max(bounds.minY, Math.min(0, 70 - imgCenterY * zoom)); draw(); }; @@ -626,13 +626,13 @@ const iw = img.naturalWidth * zoom; const ih = img.naturalHeight * zoom; - const maxPanX = 1200 - iw; + const maxPanX = 400 - iw; const posXPercent = maxPanX === 0 ? 50 : (panX / maxPanX) * 100; - const maxPanY = 300 - ih; + const maxPanY = 140 - ih; const posYPercent = maxPanY === 0 ? 50 : (panY / maxPanY) * 100; - const bgSize = `${(iw / 1200) * 100}% auto`; + const bgSize = `${(iw / 400) * 100}% auto`; const bgPos = `${posXPercent.toFixed(2)}% ${posYPercent.toFixed(2)}%`; cleanup(); @@ -700,7 +700,7 @@ const newDiv = document.createElement('div'); newDiv.id = 'banner-preview'; newDiv.className = 'banner-preview-img'; - newDiv.style.cssText = `width:100%;aspect-ratio:4/1;border-radius:4px;border:1px solid var(--nav-border-color);background-image:url('/a/${res.banner_file}?t=${Date.now()}');background-size:${payload.banner_size};background-position:${payload.banner_position};background-repeat:no-repeat;`; + newDiv.style.cssText = `width:100%;aspect-ratio:400/140;border-radius:4px;border:1px solid var(--nav-border-color);background-image:url('/a/${res.banner_file}?t=${Date.now()}');background-size:${payload.banner_size};background-position:${payload.banner_position};background-repeat:no-repeat;`; a.appendChild(newDiv); bannerPreview.replaceWith(a); } else { @@ -857,8 +857,8 @@ if (bannerPreview) { const ph = document.createElement('div'); ph.id = 'banner-preview'; ph.className = 'banner-preview-img banner-placeholder'; - ph.style.cssText = 'width:100%;aspect-ratio:4/1;display:flex;align-items:center;justify-content:center;border:1px dashed var(--nav-border-color);border-radius:4px;color:var(--text-muted);font-size:0.85em;'; - ph.textContent = 'No banner set'; + ph.style.cssText = 'width:100%;aspect-ratio:400/140;display:flex;align-items:center;justify-content:center;border:1px dashed var(--nav-border-color);border-radius:4px;color:var(--text-muted);font-size:0.85em;'; + ph.textContent = window.f0ckI18n?.settings_no_banner_set || 'No banner set'; // Replace the wrapper if it exists, otherwise just the preview element const parentA = bannerPreview.closest('a'); @@ -1753,6 +1753,10 @@ const data = await res.json(); if (data.success) { showAccountStatus(descriptionStatus, 'Description updated successfully!', 'success'); + const liveDesc = document.querySelector('.user-infobox-description'); + if (liveDesc) { + liveDesc.textContent = description || 'Welcome to my profile! This is a live preview.'; + } } else { alert(data.msg || 'Error saving description'); } @@ -1786,6 +1790,10 @@ const data = await res.json(); if (data.success) { showAccountStatus(descriptionStatus, 'Description cleared!', 'success'); + const liveDesc = document.querySelector('.user-infobox-description'); + if (liveDesc) { + liveDesc.textContent = 'Welcome to my profile! This is a live preview.'; + } } else { alert(data.msg || 'Error clearing description'); } diff --git a/src/inc/locales/de.json b/src/inc/locales/de.json index 22b485d..6902cfd 100644 --- a/src/inc/locales/de.json +++ b/src/inc/locales/de.json @@ -139,6 +139,9 @@ "no_file_selected": "Keine Datei ausgewählt", "upload_btn": "Hochladen", "remove_custom": "Eigenen entfernen", + "current_banner": "Aktuelles Banner", + "banner_hint": "Max. 5 MB. Erlaubt: gif, jpg, png, webp", + "no_banner_set": "Kein Banner gesetzt", "custom_description": "Eigene Beschreibung", "description_placeholder": "Beschreibung zum Profil hinzufügen", "save_description": "Beschreibung speichern", diff --git a/src/inc/locales/en.json b/src/inc/locales/en.json index 2a72881..7404bac 100644 --- a/src/inc/locales/en.json +++ b/src/inc/locales/en.json @@ -139,6 +139,9 @@ "no_file_selected": "No file selected", "upload_btn": "Upload", "remove_custom": "Remove Custom", + "current_banner": "Current Banner", + "banner_hint": "Max 5MB. Allowed: gif, jpg, png, webp", + "no_banner_set": "No banner set", "custom_description": "Custom Description", "description_placeholder": "Add a description to your profile", "save_description": "Save Description", diff --git a/src/inc/locales/nl.json b/src/inc/locales/nl.json index ac6194f..e7edd0b 100644 --- a/src/inc/locales/nl.json +++ b/src/inc/locales/nl.json @@ -139,6 +139,9 @@ "no_file_selected": "Geen bestand geselecteerd", "upload_btn": "Uploaden", "remove_custom": "Aangepaste Verwijderen", + "current_banner": "Huidige Banner", + "banner_hint": "Max 5MB. Toegestaan: gif, jpg, png, webp", + "no_banner_set": "Geen banner ingesteld", "custom_description": "Aangepaste Beschrijving", "description_placeholder": "Voeg een beschrijving toe aan je profiel", "save_description": "Beschrijving Opslaan", diff --git a/src/inc/locales/zange.json b/src/inc/locales/zange.json index 38cf679..2b50205 100644 --- a/src/inc/locales/zange.json +++ b/src/inc/locales/zange.json @@ -139,6 +139,9 @@ "no_file_selected": "Keine Datei ausgewählt", "upload_btn": "Aufladieren", "remove_custom": "Benutzerdefiniertes entfernen", + "current_banner": "Aktuelles Banner", + "banner_hint": "Max 5MB. Erlaubt: gif, jpg, png, webp", + "no_banner_set": "Kein Banner gesetzt", "custom_description": "Benutzerdefinierte Beschreibung", "description_placeholder": "Fügen Sie Ihrem Profil eine Beschreibung hinzu", "save_description": "Beschreibung speichern", diff --git a/src/inc/routes/apiv2/settings.mjs b/src/inc/routes/apiv2/settings.mjs index 74adc66..bf6d5b0 100644 --- a/src/inc/routes/apiv2/settings.mjs +++ b/src/inc/routes/apiv2/settings.mjs @@ -438,7 +438,7 @@ export default router => { return res.json({ success: false, msg: 'Invalid description format' }, 400); } - const cleanDescription = description ? description.trim().substring(0, 255) : null; + const cleanDescription = description ? description.trim().substring(0, 2000) : null; try { await db` diff --git a/views/settings.html b/views/settings.html index f4877cd..296b165 100644 --- a/views/settings.html +++ b/views/settings.html @@ -126,7 +126,7 @@ {{ t('settings.custom_description') }}
+ maxlength="2000">{!! session.description || '' !!}
@@ -141,21 +141,22 @@ Profile Banner
-
Current Banner
+
{{ t('settings.current_banner') }}
@if(banner_file)
- + @else - + @endif
+

{{ t('settings.banner_hint') }}

- - + +