settings
This commit is contained in:
1 parent
e6243701a3
commit
cd9dc3e5bc
6 files changed
+142
-31
No files matched your search
+11
-1
@@ -82,6 +82,16 @@ body::after {
|
||||
.upcoming-dismiss { background: none; border: none; color: var(--t-dim); cursor: pointer; padding: 2px; transition: color 0.12s; }
|
||||
.upcoming-dismiss:hover { color: var(--t-danger); }
|
||||
|
||||
/* Toggle switch */
|
||||
.toggle-row { display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 3px 0; }
|
||||
.toggle-row:hover .toggle-label { color: var(--t-bright); }
|
||||
.toggle-label { flex: 1; font-size: 12px; color: var(--t-muted); user-select: none; transition: color 0.1s; }
|
||||
.toggle-switch { position: relative; width: 32px; height: 18px; border-radius: 9px; background: var(--t-border); flex-shrink: 0; transition: background 0.2s; }
|
||||
.toggle-switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--t-bg); transition: left 0.2s; }
|
||||
.toggle-switch.on { background: var(--t-accent); }
|
||||
.toggle-switch.on::after { left: 16px; }
|
||||
#settings-panel-behavior select { width: 120px; }
|
||||
|
||||
/* Settings */
|
||||
.settings-tab { display: flex; align-items: center; gap: 8px; padding: 6px 16px; font-size: 11px; color: var(--t-muted); cursor: pointer; border: none; background: none; width: 100%; text-align: left; transition: color 0.1s, background 0.1s; border-left: 2px solid transparent; }
|
||||
.settings-tab:hover { color: var(--t-bright); background: var(--t-raised); }
|
||||
@@ -99,7 +109,7 @@ body::after {
|
||||
|
||||
/* Cards */
|
||||
.card-bar { image-rendering: pixelated; height: 3px; }
|
||||
.board-card { min-height: 180px; }
|
||||
.board-card { min-height: var(--card-min-h, 180px); }
|
||||
.card-layer { position: relative; z-index: 1; }
|
||||
.card-has-cover {
|
||||
background-size: cover;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
|
||||
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:"JetBrains Mono", monospace;--color-amber-400:oklch(82.8% .189 84.429);--color-green-400:oklch(79.2% .209 151.711);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-2xl:42rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-bold:700;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-sm:.25rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-pixel:"Silkscreen", cursive;--color-t-bg:var(--t-bg);--color-t-surface:var(--t-surface);--color-t-raised:var(--t-raised);--color-t-border:var(--t-border);--color-t-dim:var(--t-dim);--color-t-muted:var(--t-muted);--color-t-text:var(--t-text);--color-t-bright:var(--t-bright);--color-t-accent:var(--t-accent);--color-t-accent2:var(--t-accent2);--color-t-danger:var(--t-danger)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::fiLine truncated
|
||||
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:"JetBrains Mono", monospace;--color-amber-400:oklch(82.8% .189 84.429);--color-green-400:oklch(79.2% .209 151.711);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-2xl:42rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-bold:700;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-sm:.25rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-pixel:"Silkscreen", cursive;--color-t-bg:var(--t-bg);--color-t-surface:var(--t-surface);--color-t-raised:var(--t-raised);--color-t-border:var(--t-border);--color-t-dim:var(--t-dim);--color-t-muted:var(--t-muted);--color-t-text:var(--t-text);--color-t-bright:var(--t-bright);--color-t-accent:var(--t-accent);--color-t-accent2:var(--t-accent2);--color-t-danger:var(--t-danger)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::fiLine truncated
|
||||
+65
-12
@@ -1138,19 +1138,72 @@ if (str_starts_with($route, '/api/')) {
|
||||
</div>
|
||||
<div id="caldav-log" class="text-[10px] text-t-dim font-mono max-h-32 overflow-y-auto hidden border-t border-t-border pt-2"></div>
|
||||
</div>
|
||||
<div id="settings-panel-behavior" class="hidden space-y-4">
|
||||
<div class="font-pixel text-[9px] uppercase tracking-wider text-t-dim mb-2">current view</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<label class="text-xs text-t-muted">Show cards touched within</label>
|
||||
<select id="setting-current-days" class="bg-t-bg border border-t-border text-t-bright text-xs font-pixel px-2 py-1 rounded-sm focus:border-t-accent focus:outline-none cursor-pointer">
|
||||
<option value="1">1 day</option>
|
||||
<option value="2">2 days</option>
|
||||
<option value="3">3 days</option>
|
||||
<option value="7">1 week</option>
|
||||
<option value="14">2 weeks</option>
|
||||
</select>
|
||||
<div id="settings-panel-behavior" class="hidden space-y-5">
|
||||
<div>
|
||||
<div class="font-pixel text-[9px] uppercase tracking-wider text-t-dim mb-2"><i class="ph ph-lightning text-xs"></i> current view</div>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-3">
|
||||
<label class="text-xs text-t-muted flex-1">Show cards touched within</label>
|
||||
<select id="setting-current-days" class="bg-t-bg border border-t-border text-t-bright text-xs font-pixel px-2 py-1 rounded-sm focus:border-t-accent focus:outline-none cursor-pointer">
|
||||
<option value="1">1 day</option>
|
||||
<option value="2">2 days</option>
|
||||
<option value="3">3 days</option>
|
||||
<option value="7">1 week</option>
|
||||
<option value="14">2 weeks</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="toggle-row" data-toggle="setting-current-include-synced"><span class="toggle-label">Include sync-only updates</span><div class="toggle-switch" id="setting-current-include-synced"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-t-border pt-4">
|
||||
<div class="font-pixel text-[9px] uppercase tracking-wider text-t-dim mb-2"><i class="ph ph-squares-four text-xs"></i> board cards</div>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-3">
|
||||
<label class="text-xs text-t-muted flex-1">Card min height</label>
|
||||
<select id="setting-card-height" class="bg-t-bg border border-t-border text-t-bright text-xs font-pixel px-2 py-1 rounded-sm focus:border-t-accent focus:outline-none cursor-pointer">
|
||||
<option value="140">compact</option>
|
||||
<option value="180">normal</option>
|
||||
<option value="220">tall</option>
|
||||
<option value="280">large</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<label class="text-xs text-t-muted flex-1">Card width</label>
|
||||
<select id="setting-card-width" class="bg-t-bg border border-t-border text-t-bright text-xs font-pixel px-2 py-1 rounded-sm focus:border-t-accent focus:outline-none cursor-pointer">
|
||||
<option value="220">narrow</option>
|
||||
<option value="280">normal</option>
|
||||
<option value="340">wide</option>
|
||||
<option value="400">extra wide</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<label class="text-xs text-t-muted flex-1">Body preview lines</label>
|
||||
<select id="setting-body-lines" class="bg-t-bg border border-t-border text-t-bright text-xs font-pixel px-2 py-1 rounded-sm focus:border-t-accent focus:outline-none cursor-pointer">
|
||||
<option value="3">3 lines</option>
|
||||
<option value="5">5 lines</option>
|
||||
<option value="8">8 lines</option>
|
||||
<option value="0">hide body</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="toggle-row" data-toggle="setting-show-tags"><span class="toggle-label">Show tag chips on cards</span><div class="toggle-switch" id="setting-show-tags"></div></div>
|
||||
<div class="toggle-row" data-toggle="setting-show-thumbnails"><span class="toggle-label">Show image thumbnails</span><div class="toggle-switch" id="setting-show-thumbnails"></div></div>
|
||||
<div class="toggle-row" data-toggle="setting-show-done-badge"><span class="toggle-label">Show done badges</span><div class="toggle-switch" id="setting-show-done-badge"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-t-border pt-4">
|
||||
<div class="font-pixel text-[9px] uppercase tracking-wider text-t-dim mb-2"><i class="ph ph-cursor-click text-xs"></i> interactions</div>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-3">
|
||||
<label class="text-xs text-t-muted flex-1">Single click opens</label>
|
||||
<select id="setting-click-action" class="bg-t-bg border border-t-border text-t-bright text-xs font-pixel px-2 py-1 rounded-sm focus:border-t-accent focus:outline-none cursor-pointer">
|
||||
<option value="preview">preview</option>
|
||||
<option value="edit">editor</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="toggle-row" data-toggle="setting-confirm-delete"><span class="toggle-label">Confirm before delete</span><div class="toggle-switch" id="setting-confirm-delete"></div></div>
|
||||
<div class="toggle-row" data-toggle="setting-auto-save"><span class="toggle-label">Auto-save on close (editor)</span><div class="toggle-switch" id="setting-auto-save"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-[10px] text-t-dim leading-relaxed"><i class="ph ph-info text-xs"></i> "Current" shows cards you recently opened or edited. Sync-only updates (CalDAV/WebDAV) are excluded.</p>
|
||||
</div>
|
||||
<div id="settings-panel-notifications" class="hidden space-y-4">
|
||||
<div class="font-pixel text-[9px] uppercase tracking-wider text-t-dim mb-2">lookahead</div>
|
||||
|
||||
@@ -317,8 +317,9 @@ $('sort-toggle')?.addEventListener('click', () => {
|
||||
|
||||
export function renderCardHtml(c, inGroup = false, recent = []) {
|
||||
const loaded = c.body != null;
|
||||
const coverImg = loaded ? leadingImage(c.body) : null;
|
||||
const thumbImg = coverImg ? null : (loaded ? firstImage(c.body) : null);
|
||||
const showThumbs = localStorage.getItem('hyprcrd-show-thumbnails') !== '0';
|
||||
const coverImg = loaded && showThumbs ? leadingImage(c.body) : null;
|
||||
const thumbImg = coverImg ? null : (loaded && showThumbs ? firstImage(c.body) : null);
|
||||
const children = getChildren(c.id);
|
||||
const isGroup = !inGroup && children.length > 0;
|
||||
const todos = loaded ? getTodos(c.body) : null;
|
||||
@@ -337,7 +338,7 @@ export function renderCardHtml(c, inGroup = false, recent = []) {
|
||||
<div class="board-card ${isGroup ? 'card-group ' : ''}card-glow ${hasCover ? 'card-has-cover' : 'bg-t-surface'} border border-t-border cursor-pointer hover:border-t-muted transition-colors relative group"
|
||||
style="--glow-color:${cardColor}22;${hasCover ? `background-image:url('${coverImg}')` : ''};${overdue ? 'border-bottom:3px solid var(--t-danger)' : recent.includes(String(c.id)) ? 'border-bottom:3px solid ' + cardColor : ''}" draggable="true" data-id="${c.id}">
|
||||
${hasCover ? '<div class="card-cover-overlay"></div>' : ''}
|
||||
${tags.includes('done') ? '<div class="card-done-badge"><i class="ph ph-check"></i></div>' : ''}
|
||||
${tags.includes('done') && localStorage.getItem('hyprcrd-show-done-badge') !== '0' ? '<div class="card-done-badge"><i class="ph ph-check"></i></div>' : ''}
|
||||
<div class="card-bar w-full card-layer ${overdue ? 'card-bar-pulse' : ''}" style="background:${barColor}"></div>
|
||||
${isGroup ? `<div class="card-group-badge cursor-pointer hover:scale-110 transition-transform" style="background:${cardColor};color:#000" data-group="${c.id}">${children.length + 1}</div>` : ''}
|
||||
${thumbImg ? `<div class="card-thumb" style="background-image:url('${thumbImg}')"></div>` : ''}
|
||||
@@ -352,9 +353,9 @@ export function renderCardHtml(c, inGroup = false, recent = []) {
|
||||
<div class="todo-progress">${Array.from({length: todos.total}, (_, i) => `<div class="todo-seg" style="background:${i < todos.done ? cardColor : 'var(--t-border)'}"></div>`).join('')}</div>
|
||||
</div>` : ''}
|
||||
${loaded
|
||||
? `<p class="text-xs ${hasCover ? 'text-t-text' : 'text-t-muted'} leading-relaxed line-clamp-5 flex-1">${esc(stripMd(c.body))}</p>`
|
||||
? (localStorage.getItem('hyprcrd-body-lines') === '0' ? '' : `<p class="text-xs ${hasCover ? 'text-t-text' : 'text-t-muted'} leading-relaxed flex-1" style="-webkit-line-clamp:var(--card-body-lines,5);display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;">${esc(stripMd(c.body))}</p>`)
|
||||
: `<div class="flex-1 flex items-center justify-center py-2"><i class="ph ph-spinner card-spinner text-t-dim text-lg"></i></div>`}
|
||||
${tags.length ? `<div class="flex flex-wrap gap-1 mt-1.5 card-layer">${tags.slice(0, 5).map(t => tagChipHtml(t)).join('')}${tags.length > 5 ? `<span class="tag-chip tag-chip-more">+${tags.length - 5}</span>` : ''}</div>` : ''}
|
||||
${tags.length && localStorage.getItem('hyprcrd-show-tags') !== '0' ? `<div class="flex flex-wrap gap-1 mt-1.5 card-layer">${tags.slice(0, 5).map(t => tagChipHtml(t)).join('')}${tags.length > 5 ? `<span class="tag-chip tag-chip-more">+${tags.length - 5}</span>` : ''}</div>` : ''}
|
||||
<div class="mt-auto pt-2 flex items-center gap-2 text-[10px] ${hasCover ? 'text-t-text' : 'text-t-dim'} font-pixel">
|
||||
${c.due_date ? `<span class="due-pill" style="background:${overdue ? 'var(--t-danger)' : cardColor};"><i class="ph ph-clock-countdown" style="font-size:9px;"></i>${c.due_date}</span>` : `<span class="flex items-center gap-1"><i class="ph ph-clock text-xs"></i>${(c.updated_at || c.created_at || '').substring(0, 10)}</span>`}
|
||||
${c.bucket_name ? `<span class="flex items-center gap-1"><i class="ph ph-folder text-xs"></i>${esc(c.bucket_name)}</span>` : ''}
|
||||
@@ -384,8 +385,11 @@ export function renderBoard() {
|
||||
if (recent.includes(String(c.id))) return true;
|
||||
// Recently edited locally (not just synced — check synced_at vs updated_at)
|
||||
const updated = new Date(c.updated_at || c.created_at || 0).getTime();
|
||||
const synced = c.caldav_synced_at ? new Date(c.caldav_synced_at).getTime() : 0;
|
||||
if (synced && Math.abs(updated - synced) < 3000) return false; // sync-only update
|
||||
const includeSynced = localStorage.getItem('hyprcrd-current-include-synced') === '1';
|
||||
if (!includeSynced) {
|
||||
const synced = c.caldav_synced_at ? new Date(c.caldav_synced_at).getTime() : 0;
|
||||
if (synced && Math.abs(updated - synced) < 3000) return false;
|
||||
}
|
||||
return (now - updated) < freshMs;
|
||||
});
|
||||
cards.sort((a, b) => (b.updated_at || b.created_at || '').localeCompare(a.updated_at || a.created_at || ''));
|
||||
@@ -814,6 +818,10 @@ function bindCardEvents() {
|
||||
clickTimer = setTimeout(() => {
|
||||
clickTimer = null;
|
||||
if (boardSplitOpen) { showBoardPreview(id); }
|
||||
else if (localStorage.getItem('hyprcrd-click-action') === 'edit') {
|
||||
const card = state.cards.find(c => c.id == id);
|
||||
if (card) window._openModal(card);
|
||||
}
|
||||
else { window._openDetail(id); }
|
||||
}, 200);
|
||||
});
|
||||
|
||||
@@ -147,10 +147,8 @@ function openOrphanLightbox(file) {
|
||||
|
||||
overlay.querySelector('.orphan-lb-create').addEventListener('click', async () => {
|
||||
const name = file.url.split('/').pop().replace(/\.[^.]+$/, '');
|
||||
await api('api/cards', { method: 'POST', body: { title: name, body: ``, color: '#38bdf8', position: -1 } });
|
||||
await window._reloadAll();
|
||||
close();
|
||||
openGallery();
|
||||
window._openModal({ id: null, title: name, body: ``, color: '#38bdf8', bucket_id: null });
|
||||
});
|
||||
|
||||
overlay.querySelector('.orphan-lb-delete').addEventListener('click', async () => {
|
||||
|
||||
@@ -87,15 +87,57 @@ $('settings-pw-save')?.addEventListener('click', async () => {
|
||||
});
|
||||
|
||||
function initBehaviorSettings() {
|
||||
const sel = $('setting-current-days');
|
||||
if (sel) {
|
||||
sel.value = localStorage.getItem('hyprcrd-current-days') || '2';
|
||||
sel.onchange = () => {
|
||||
localStorage.setItem('hyprcrd-current-days', sel.value);
|
||||
window._renderBoard?.();
|
||||
};
|
||||
const selects = {
|
||||
'setting-current-days': { key: 'hyprcrd-current-days', def: '2' },
|
||||
'setting-card-height': { key: 'hyprcrd-card-height', def: '180' },
|
||||
'setting-card-width': { key: 'hyprcrd-card-width', def: '280' },
|
||||
'setting-body-lines': { key: 'hyprcrd-body-lines', def: '5' },
|
||||
'setting-click-action': { key: 'hyprcrd-click-action', def: 'preview' },
|
||||
};
|
||||
const toggles = {
|
||||
'setting-current-include-synced': { key: 'hyprcrd-current-include-synced', def: '0' },
|
||||
'setting-show-tags': { key: 'hyprcrd-show-tags', def: '1' },
|
||||
'setting-show-thumbnails': { key: 'hyprcrd-show-thumbnails', def: '1' },
|
||||
'setting-show-done-badge': { key: 'hyprcrd-show-done-badge', def: '1' },
|
||||
'setting-confirm-delete': { key: 'hyprcrd-confirm-delete', def: '1' },
|
||||
'setting-auto-save': { key: 'hyprcrd-auto-save', def: '0' },
|
||||
};
|
||||
for (const [id, cfg] of Object.entries(selects)) {
|
||||
const el = $(id);
|
||||
if (!el) continue;
|
||||
el.value = localStorage.getItem(cfg.key) || cfg.def;
|
||||
el.onchange = () => { localStorage.setItem(cfg.key, el.value); applyBehavior(); };
|
||||
}
|
||||
for (const [id, cfg] of Object.entries(toggles)) {
|
||||
const el = $(id);
|
||||
if (!el) continue;
|
||||
const isOn = (localStorage.getItem(cfg.key) ?? cfg.def) === '1';
|
||||
el.classList.toggle('on', isOn);
|
||||
const row = el.closest('.toggle-row');
|
||||
if (row) {
|
||||
row.onclick = () => {
|
||||
const nowOn = !el.classList.contains('on');
|
||||
el.classList.toggle('on', nowOn);
|
||||
localStorage.setItem(cfg.key, nowOn ? '1' : '0');
|
||||
applyBehavior();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyBehavior() {
|
||||
const board = $('board');
|
||||
if (board) {
|
||||
const w = localStorage.getItem('hyprcrd-card-width') || '280';
|
||||
board.style.gridTemplateColumns = `repeat(auto-fill, minmax(${w}px, 1fr))`;
|
||||
}
|
||||
document.documentElement.style.setProperty('--card-min-h', (localStorage.getItem('hyprcrd-card-height') || '180') + 'px');
|
||||
document.documentElement.style.setProperty('--card-body-lines', localStorage.getItem('hyprcrd-body-lines') || '5');
|
||||
window._renderBoard?.();
|
||||
}
|
||||
|
||||
// Apply on load
|
||||
applyBehavior();
|
||||
|
||||
// Apply saved theme on load
|
||||
window.applyTheme(localStorage.getItem('hyprcrd-theme') || 'slate');
|
||||
Reference in new issue
Block a user