From: PhiTux Date: Sat, 20 Sep 2025 23:00:56 +0000 (+0200) Subject: huge css update (light/dark) X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=48ab261e528db8e80790102b6e010dea97bbbab7;p=DailyTxT.git huge css update (light/dark) --- diff --git a/frontend/src/lib/ALookBack.svelte b/frontend/src/lib/ALookBack.svelte index c225228..1c30cb8 100644 --- a/frontend/src/lib/ALookBack.svelte +++ b/frontend/src/lib/ALookBack.svelte @@ -2,6 +2,7 @@ import { marked } from 'marked'; import { selectedDate } from './calendarStore'; import { getTranslate } from '@tolgee/svelte'; + import { onMount } from 'svelte'; const { t } = getTranslate(); @@ -12,93 +13,39 @@ let { log } = $props(); - let preview; - let content; let modal; - let isModalOpen = $state(false); + let modalInstance; + + onMount(() => { + // Import Bootstrap Modal + import('bootstrap').then((bootstrap) => { + modalInstance = new bootstrap.Modal(modal, { + backdrop: true, + keyboard: true + }); + }); + }); function openModal() { - if (!preview || !modal || !content) return; - - const previewRect = preview.getBoundingClientRect(); - const targetWidth = Math.min(window.innerWidth * 0.8, 600); // Target width - - // Initial state for the animation - // Position and scale to match the button - content.style.left = `${previewRect.left}px`; - content.style.top = `${previewRect.top}px`; - content.style.width = `${previewRect.width}px`; - content.style.height = `${previewRect.height}px`; - content.style.transform = 'scale(1)'; // Start at button's scale - content.style.opacity = '0'; - - modal.style.display = 'flex'; - - void content.offsetWidth; - - // Target state for the animation - // Calculate scale factor to reach targetWidth from previewRect.width - const scaleX = targetWidth / previewRect.width; - - const targetLeft = (window.innerWidth - targetWidth) / 2; - const targetTop = window.innerHeight * 0.2; - - content.style.left = `${targetLeft}px`; // Position for final state - content.style.top = `${targetTop}px`; // Position for final state - content.style.width = `${targetWidth}px`; - // Height will be 'auto' or controlled by max-height in CSS - content.style.height = 'auto'; // Let CSS max-height handle this - content.style.transform = 'scale(1)'; // End at normal scale, but at new position/size - content.style.opacity = '1'; - - isModalOpen = true; - document.body.style.overflow = 'hidden'; - } - - function closeModal() { - if (!preview || !modal || !content) return; - - const previewRect = preview.getBoundingClientRect(); - - content.style.left = `${previewRect.left}px`; - content.style.top = `${previewRect.top}px`; - content.style.width = `${previewRect.width}px`; - content.style.height = `${previewRect.height}px`; - content.style.transform = 'scale(1)'; - content.style.opacity = '0'; - - setTimeout(() => { - if (!isModalOpen) { - modal.style.display = 'none'; - document.body.style.overflow = ''; - } - }, 400); - - isModalOpen = false; + if (modalInstance) { + modalInstance.show(); + } } - function handleKeydown(event) { - if (event.key === 'Escape' && isModalOpen) { - closeModal(); + function goToDate() { + $selectedDate = { year: log.year, month: log.month, day: log.day }; + if (modalInstance) { + modalInstance.hide(); } } - - - - - - +
{ - if (event.target === modal) { - closeModal(); - } - }} + class="modal fade" + tabindex="-1" + aria-labelledby="alookbackModalLabel" + aria-hidden="true" > -
-
- {$t('aLookBack.header_X_years_ago', { years_old: log?.years_old })} | {new Date( - log?.year, - log?.month - 1, - log?.day - ).toLocaleDateString('locale', { - weekday: 'long', - day: '2-digit', - month: '2-digit', - year: 'numeric' - })} - +
diff --git a/frontend/src/lib/Datepicker.svelte b/frontend/src/lib/Datepicker.svelte index 96a5c99..1735850 100644 --- a/frontend/src/lib/Datepicker.svelte +++ b/frontend/src/lib/Datepicker.svelte @@ -142,7 +142,7 @@ ]; -
+
@@ -311,8 +311,16 @@ font-weight: bold; padding: 8px 0; font-size: 0.9em; + } + + :global(body[data-bs-theme='light']) .day-header { color: #666; } + + :global(body[data-bs-theme='light']) .day-header { + color: #5c5c5c; + } + .day { height: 32px; width: 32px; @@ -327,19 +335,24 @@ user-select: none; --dot-color: rgb(250, 199, 58); } + :global(body[data-bs-theme='light']) .day { + color: #222; + } .day:hover { background: #f0f0f0; + color: black; } .day.mark-background { background-color: #00ad00; color: white; aspect-ratio: 1; } + .day.mark-background:hover { + background-color: #008a00; + } .day.mark-circle { - /* background-color: transparent;*/ border: 3px solid #f57c00; - /* color: #ff9224; */ } .day.mark-dot::after { diff --git a/frontend/src/lib/EmojiMart.svelte b/frontend/src/lib/EmojiMart.svelte index 82b673b..f1e1ed8 100644 --- a/frontend/src/lib/EmojiMart.svelte +++ b/frontend/src/lib/EmojiMart.svelte @@ -11,11 +11,6 @@ // Wait for darkMode and language to be initialized before creating picker $effect(() => { - console.log('EmojiMart effect:', { - darkMode: $darkMode, - emojiPickerEl: !!emojiPickerEl, - picker: !!picker - }); if ($darkMode !== undefined && emojiPickerEl && !picker) { createPicker(); } @@ -29,7 +24,6 @@ }); function createPicker() { - console.log('Creating emoji picker with theme:', $darkMode ? 'dark' : 'light'); picker = new Picker({ theme: $darkMode ? 'dark' : 'light', autoFocus: true, diff --git a/frontend/src/lib/Sidenav.svelte b/frontend/src/lib/Sidenav.svelte index 7a1649d..8fd780c 100644 --- a/frontend/src/lib/Sidenav.svelte +++ b/frontend/src/lib/Sidenav.svelte @@ -263,7 +263,7 @@ {/if} -
+
{#if $searchResults.length > 0} {#each $searchResults as result} @@ -562,7 +562,7 @@ diff --git a/frontend/src/routes/(authed)/read/+page.svelte b/frontend/src/routes/(authed)/read/+page.svelte index b694ff6..5c0af40 100644 --- a/frontend/src/routes/(authed)/read/+page.svelte +++ b/frontend/src/routes/(authed)/read/+page.svelte @@ -358,7 +358,7 @@ {#each logs as log (log.day)} {#if ('text' in log && log.text !== '') || log.tags?.length > 0 || log.files?.length > 0} -
+

{log.day}

@@ -446,10 +446,16 @@ } .log { - backdrop-filter: blur(10px) saturate(150%); - background-color: rgba(199, 199, 201, 0.329); border-radius: 15px; - border: 1px solid rgba(223, 221, 221, 0.658); + } + + :global(body[data-bs-theme='dark']) .glass { + background-color: rgba(68, 68, 68, 0.6) !important; + } + + :global(body[data-bs-theme='light']) .glass { + background-color: rgba(122, 122, 122, 0.6) !important; + color: rgb(19, 19, 19); } .dateNumber { diff --git a/frontend/src/routes/(authed)/write/+page.svelte b/frontend/src/routes/(authed)/write/+page.svelte index a0fc369..b009b7d 100644 --- a/frontend/src/routes/(authed)/write/+page.svelte +++ b/frontend/src/routes/(authed)/write/+page.svelte @@ -677,6 +677,64 @@ let filteredTags = $state([]); let selectedTags = $state([]); + // Action: portal dropdown to and position it under the input + function portalDropdown(node, params) { + let anchorEl; + + function getAnchor() { + if (params?.anchor) { + return typeof params.anchor === 'string' + ? document.querySelector(params.anchor) + : params.anchor; + } + return document.getElementById('tag-input'); + } + + function position() { + if (!anchorEl) return; + const rect = anchorEl.getBoundingClientRect(); + node.style.position = 'fixed'; + node.style.top = rect.bottom + 'px'; + node.style.left = rect.left + 'px'; + /* node.style.width = rect.width + 'px'; */ + // keep within viewport horizontally (basic guard) + const maxLeft = Math.max(8, Math.min(rect.left, window.innerWidth - node.offsetWidth - 8)); + node.style.left = maxLeft + 'px'; + } + + function attach() { + // move element into body so it's not clipped by ancestors and backdrop-filter works as expected + document.body.appendChild(node); + position(); + } + + function onScroll() { + position(); + } + function onResize() { + position(); + } + + anchorEl = getAnchor(); + attach(); + // use capture to react to scrolls on any ancestor + window.addEventListener('scroll', onScroll, true); + window.addEventListener('resize', onResize); + + return { + update(newParams) { + params = newParams; + anchorEl = getAnchor(); + position(); + }, + destroy() { + window.removeEventListener('scroll', onScroll, true); + window.removeEventListener('resize', onResize); + // Do not manually remove node; Svelte will detach it. + } + }; + } + // show the correct tags in the dropdown $effect(() => { if ($tags.length === 0) { @@ -1095,7 +1153,7 @@

-
+
{new Date( Date.UTC($selectedDate.year, $selectedDate.month - 1, $selectedDate.day) @@ -1200,7 +1258,7 @@
{#if showTagDropdown} -
+
{#if filteredTags.length === 0} {$t('tags.no_tags_found')} {:else} @@ -1773,10 +1831,6 @@ white-space: nowrap; } - .tag-item.selected { - background-color: #b2b4b6; - } - .selectedTags { margin-top: 0.5rem; gap: 0.5rem; @@ -1788,14 +1842,23 @@ #tagDropdown { position: absolute; - background-color: white; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); z-index: 1000; max-height: 200px; overflow-y: scroll; overflow-x: hidden; display: flex; flex-direction: column; + backdrop-filter: blur(10px) saturate(150%); + border-radius: 10px; + } + + :global(body[data-bs-theme='dark']) #tagDropdown { + background-color: rgba(87, 87, 87, 0.5); + } + + :global(body[data-bs-theme='light']) #tagDropdown { + background-color: rgba(196, 196, 196, 0.5); } .tag-item { @@ -1803,15 +1866,19 @@ padding: 5px; } + :global(body[data-bs-theme='dark']) .tag-item.selected { + background-color: #5f5f5f; + } + + :global(body[data-bs-theme='light']) .tag-item.selected { + background-color: #b9b9b9; + } + .tags { z-index: 10; padding: 0.5rem; margin-bottom: 2rem; - /* backdrop-filter: blur(8px) saturate(150%); - background-color: rgba(219, 219, 219, 0.45); - border: 1px solid #ececec77; */ border-radius: 10px; - /* color: #ececec; */ } .loadImageBtn { @@ -1822,19 +1889,18 @@ transition: all ease 0.2s; } - .modal-content { - backdrop-filter: blur(8px) saturate(150%); - background-color: rgba(219, 219, 219, 0.45); + .modal-header { + border-bottom: none; + } + + .modal-footer { + border-top: none; } .files { - /* margin-right: 2rem; */ margin-bottom: 1rem; border-radius: 10px; padding: 1rem; - /* backdrop-filter: blur(8px) saturate(150%); - background-color: rgba(219, 219, 219, 0.45); - border: 1px solid #ececec77; */ } :global(#uploadIcon) { @@ -1846,11 +1912,64 @@ } :global(.TMCommandBar) { - border-top: 1px solid #ccc; - border-left: 1px solid #ccc; - border-right: 1px solid #ccc; + border-top: none; + border-bottom: none; height: auto; flex-wrap: wrap; + padding-top: 2px; + padding-bottom: 3px; + } + + :global(body[data-bs-theme='dark'] .TMCommandBar) { + border-left: 1px solid #6a6a6a; + border-right: 1px solid #6a6a6a; + } + + :global(body[data-bs-theme='light'] .TMCommandBar) { + border-left: 1px solid #cccccc; + border-right: 1px solid #cccccc; + } + + :global(body[data-bs-theme='dark'] .TMCommandBar) { + background-color: rgba(70, 70, 70, 0.5); + } + + :global(body[data-bs-theme='light'] .TMCommandBar) { + background-color: rgba(202, 202, 202, 0.5); + } + + :global(body[data-bs-theme='dark'] .TMCommandButton_Inactive) { + background-color: transparent; + fill: #f0f0f0; + } + + :global(body[data-bs-theme='light'] .TMCommandButton_Inactive) { + background-color: transparent; + fill: #161616; + } + + :global(body[data-bs-theme='dark'] .TMCommandButton_Inactive:hover) { + background-color: rgba(180, 180, 180, 0.438); + } + + :global(body[data-bs-theme='light'] .TMCommandButton_Inactive:hover) { + background-color: rgba(180, 180, 180, 0.438); + } + + :global(.TMCommandButton) { + border-radius: 3px; + } + + :global(body[data-bs-theme='dark'] .TinyMDE) { + backdrop-filter: blur(8px) saturate(130%); + background-color: rgba(50, 50, 50, 0.8); + color: #f0f0f0; + } + + :global(body[data-bs-theme='light'] .TinyMDE) { + backdrop-filter: blur(8px) saturate(130%); + background-color: rgba(255, 255, 255, 0.7); + color: #1f1f1f; } #editor { diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 63cd5b1..6f44d6b 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -10,6 +10,7 @@ import * as bootstrap from 'bootstrap'; import { TolgeeProvider, Tolgee, DevTools, LanguageStorage } from '@tolgee/svelte'; import { FormatIcu } from '@tolgee/format-icu'; + import { darkMode } from '$lib/settingsStore.js'; const tolgee = Tolgee() .use(DevTools()) @@ -88,7 +89,13 @@ // if on login page, generate neon mesh if (page.url.pathname === '/login') { - generateNeonMesh(); + generateNeonMesh($darkMode); + } + }); + + $effect(() => { + if ($darkMode !== undefined) { + document.body.setAttribute('data-bs-theme', $darkMode ? 'dark' : 'light'); } }); @@ -160,24 +167,33 @@ background-color: rgba(0, 0, 0, 0.3) !important; } - :global(.modal-content) { + :global(body[data-bs-theme='dark'] .modal-content) { backdrop-filter: blur(20px) saturate(150%); - background-color: rgba(83, 83, 83, 0.85) !important; + background-color: rgba(70, 70, 70, 0.5) !important; border: 1px solid rgba(255, 255, 255, 0.2); color: #ececec; } + :global(body[data-bs-theme='light'] .modal-content) { + backdrop-filter: blur(20px) saturate(150%); + background-color: rgba(211, 211, 211, 0.5) !important; + border: 1px solid rgba(255, 255, 255, 0.2); + color: #161616; + } - :global(.glass) { + :global(body[data-bs-theme='dark'] .glass) { backdrop-filter: blur(14px) saturate(130%); - background-color: rgba(83, 83, 83, 0.8); + background-color: rgba(83, 83, 83, 0.4); border: 1px solid #62626278; color: #ececec; } + :global(body[data-bs-theme='light'] .glass) { + backdrop-filter: blur(14px) saturate(130%); + background-color: rgba(187, 187, 187, 0.3); + border: 1px solid #ccc; + color: #222; + } - :global(.glassLight) { - backdrop-filter: blur(8px) saturate(130%); - background-color: rgba(83, 83, 83, 0.445); - border: 1px solid #62626278; - color: #ececec; + :global(body[data-bs-theme='dark'] .popover-body > span) { + background-color: #444; } diff --git a/frontend/src/routes/login/+page.svelte b/frontend/src/routes/login/+page.svelte index d7a5490..06ba004 100644 --- a/frontend/src/routes/login/+page.svelte +++ b/frontend/src/routes/login/+page.svelte @@ -233,7 +233,7 @@