Bookmark buttons say 'محفوظ کریں', then 'محفوظ شدہ' with the accent colour

Owner request. Saved state: filled accent-coloured glyph, bold accent text and border, light accent
tint; the label follows the state on load and on click. The selection menu's phrase option and the
couplet bookmark's label use the same words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Anas Rashid 2026-10-09 00:07:53 +02:00
parent bf96002fa1
commit 9338c3dde0
4 changed files with 14 additions and 9 deletions

View File

@ -57,7 +57,7 @@ const fullTitle = title ? `${title} · دیوان` : 'دیوان · اردو ک
<div id="selmenu" class="selmenu" role="toolbar" aria-label="منتخب عبارت" hidden> <div id="selmenu" class="selmenu" role="toolbar" aria-label="منتخب عبارت" hidden>
<button type="button" data-act="meaning" title="معنی اور تلفظ">معنی</button> <button type="button" data-act="meaning" title="معنی اور تلفظ">معنی</button>
<button type="button" data-act="saveword" class="plus" title="ذخیرۂ الفاظ میں ڈالیں">ذخیرۂ الفاظ</button> <button type="button" data-act="saveword" class="plus" title="ذخیرۂ الفاظ میں ڈالیں">ذخیرۂ الفاظ</button>
<button type="button" data-act="bookmark" title="اس عبارت پر نشان لگائیں">نشان</button> <button type="button" data-act="bookmark" title="یہ عبارت محفوظ کریں">محفوظ کریں</button>
<button type="button" data-act="search" title="دیوان میں تلاش">تلاش</button> <button type="button" data-act="search" title="دیوان میں تلاش">تلاش</button>
<button type="button" data-act="copy" title="حوالے کے ساتھ کاپی">کاپی</button> <button type="button" data-act="copy" title="حوالے کے ساتھ کاپی">کاپی</button>
<button type="button" data-act="share" title="اس عبارت کا لنک">شیئر</button> <button type="button" data-act="share" title="اس عبارت کا لنک">شیئر</button>
@ -160,7 +160,10 @@ const fullTitle = title ? `${title} · دیوان` : 'دیوان · اردو ک
if (b.dataset.confirm && !confirm(b.dataset.confirm)) return; if (b.dataset.confirm && !confirm(b.dataset.confirm)) return;
const item = JSON.parse(b.dataset.save), d = await save(item); const item = JSON.parse(b.dataset.save), d = await save(item);
if (d && item.kind === 'phrase') location.reload(); // the highlight is drawn by the page if (d && item.kind === 'phrase') location.reload(); // the highlight is drawn by the page
else if (d) b.setAttribute('aria-pressed', String(d.saved)); else if (d) {
b.setAttribute('aria-pressed', String(d.saved));
if (b.classList.contains('save')) b.textContent = d.saved ? 'محفوظ شدہ' : 'محفوظ کریں';
}
}); });
const wordSave = (w) => { // sidebar button, with the word's saved state const wordSave = (w) => { // sidebar button, with the word's saved state
const b = el('button', 'wordbook', null, { type: 'button' }); const b = el('button', 'wordbook', null, { type: 'button' });
@ -336,7 +339,7 @@ const fullTitle = title ? `${title} · دیوان` : 'دیوان · اردو ک
switch (b.dataset.act) { switch (b.dataset.act) {
case 'meaning': showWord(oneWord(selText)); break; case 'meaning': showWord(oneWord(selText)); break;
case 'bookmark': save({ kind: 'phrase', poemId: source.poemId, couplet: source.couplet, phrase: selText }) case 'bookmark': save({ kind: 'phrase', poemId: source.poemId, couplet: source.couplet, phrase: selText })
.then((d) => d && (d.saved ? location.reload() : flash(b, 'نشان پہلے سے تھا، ہٹا دیا'))); break; .then((d) => d && (d.saved ? location.reload() : flash(b, 'پہلے سے محفوظ تھی، ہٹا دی'))); break;
case 'saveword': save({ kind: 'word', word: oneWord(selText), ...source }).then((d) => d && flash(b, d.saved ? 'ذخیرۂ الفاظ میں ڈال دیا' : 'ذخیرۂ الفاظ سے نکال دیا')); break; case 'saveword': save({ kind: 'word', word: oneWord(selText), ...source }).then((d) => d && flash(b, d.saved ? 'ذخیرۂ الفاظ میں ڈال دیا' : 'ذخیرۂ الفاظ سے نکال دیا')); break;
case 'search': location.href = `/search?q=${encodeURIComponent(q)}`; break; case 'search': location.href = `/search?q=${encodeURIComponent(q)}`; break;
case 'google': open(`https://www.google.com/search?q=${enc}`, '_blank', 'noopener'); break; case 'google': open(`https://www.google.com/search?q=${enc}`, '_blank', 'noopener'); break;

View File

@ -65,6 +65,7 @@ const lineMarks = (c: number, lines: string[]) => {
} }
return out; return out;
}; };
const label = (on: unknown) => (on ? 'محفوظ شدہ' : 'محفوظ کریں'); // bookmark buttons
const bookmark = (c: number) => JSON.stringify({ kind: 'couplet', poemId, couplet: c }); const bookmark = (c: number) => JSON.stringify({ kind: 'couplet', poemId, couplet: c });
const title = page.type === 'poem' ? page.poem.title : page.type === 'poet' ? page.poet.nickname : page.category.title; const title = page.type === 'poem' ? page.poem.title : page.type === 'poet' ? page.poet.nickname : page.category.title;
--- ---
@ -80,7 +81,7 @@ const title = page.type === 'poem' ? page.poem.title : page.type === 'poet' ? pa
{page.type === 'poet' && ( {page.type === 'poet' && (
<> <>
<h1>{page.poet.name}</h1> <h1>{page.poet.name}</h1>
<p class="center"><button type="button" class="save" data-save={JSON.stringify({ kind: 'poet', poetId })} aria-pressed={String(!!saved.poet)} title="اس شاعر پر نشان لگائیں">نشان</button></p> <p class="center"><button type="button" class="save" data-save={JSON.stringify({ kind: 'poet', poetId })} aria-pressed={String(!!saved.poet)} title="یہ شاعر محفوظ کریں">{label(saved.poet)}</button></p>
<p class="muted">{years(page.poet)}</p> <p class="muted">{years(page.poet)}</p>
{page.poet.description && <div class="intro">{page.poet.description}</div>} {page.poet.description && <div class="intro">{page.poet.description}</div>}
</> </>
@ -88,7 +89,7 @@ const title = page.type === 'poem' ? page.poem.title : page.type === 'poet' ? pa
{page.type === 'category' && ( {page.type === 'category' && (
<> <>
<h1>{page.category.title}</h1> <h1>{page.category.title}</h1>
<p class="center"><button type="button" class="save" data-save={JSON.stringify({ kind: 'category', categoryId: page.category.id })} aria-pressed={String(!!saved.category)} title="اس کتاب یا باب پر نشان لگائیں">نشان</button></p> <p class="center"><button type="button" class="save" data-save={JSON.stringify({ kind: 'category', categoryId: page.category.id })} aria-pressed={String(!!saved.category)} title="یہ کتاب یا باب محفوظ کریں">{label(saved.category)}</button></p>
</> </>
)} )}
@ -114,11 +115,11 @@ const title = page.type === 'poem' ? page.poem.title : page.type === 'poet' ? pa
«{hlq}» نمایاں · <a href={`/search?q=${encodeURIComponent(hlq)}`}>تلاش کے نتائج</a> · <a href={url}>نشان ہٹائیں</a> «{hlq}» نمایاں · <a href={`/search?q=${encodeURIComponent(hlq)}`}>تلاش کے نتائج</a> · <a href={url}>نشان ہٹائیں</a>
</p> </p>
)} )}
<p class="center"><button type="button" class="save" data-save={JSON.stringify({ kind: 'poem', poemId })} aria-pressed={String(!!saved.poem)} title="اس کلام پر نشان لگائیں">نشان</button></p> <p class="center"><button type="button" class="save" data-save={JSON.stringify({ kind: 'poem', poemId })} aria-pressed={String(!!saved.poem)} title="یہ کلام محفوظ کریں">{label(saved.poem)}</button></p>
{page.poem.radif != null && <p class="muted radif">{page.poem.radif ? `ردیف: ${page.poem.radif}` : 'غیر مردف'}</p>} {page.poem.radif != null && <p class="muted radif">{page.poem.radif ? `ردیف: ${page.poem.radif}` : 'غیر مردف'}</p>}
<article class="poem" data-cite={`${page.poet.nickname}، ${page.poem.title}`} data-poem={poemId}> <article class="poem" data-cite={`${page.poet.nickname}، ${page.poem.title}`} data-poem={poemId}>
{blocks.map((b) => { {blocks.map((b) => {
const bm = <button type="button" class="bm" data-save={bookmark(b.c)} aria-pressed={String(saved.couplets.includes(b.c))} aria-label="نشان لگائیں" />; const bm = <button type="button" class="bm" data-save={bookmark(b.c)} aria-pressed={String(saved.couplets.includes(b.c))} aria-label="شعر محفوظ کریں" />;
const lm = lineMarks(b.c, b.lines); const lm = lineMarks(b.c, b.lines);
return b.kind === 'couplet' ? <div class="couplet" id={`c${b.c}`} data-c={b.c} data-mark={b.mark}>{bm}{b.lines.map((l, i) => <p><Seg s={show(l, lm[i])} /></p>)}</div> return b.kind === 'couplet' ? <div class="couplet" id={`c${b.c}`} data-c={b.c} data-mark={b.mark}>{bm}{b.lines.map((l, i) => <p><Seg s={show(l, lm[i])} /></p>)}</div>
: b.kind === 'para' ? <p class="para" id={`c${b.c}`} data-c={b.c}>{bm}<Seg s={show(b.lines[0], lm[0])} /></p> : b.kind === 'para' ? <p class="para" id={`c${b.c}`} data-c={b.c}>{bm}<Seg s={show(b.lines[0], lm[0])} /></p>

View File

@ -33,7 +33,7 @@ const at = (item: any) => (item.poem ? `${item.poem.url}${item.poem.couplet != n
<p class="muted center">{ud(total)} نشانات</p> <p class="muted center">{ud(total)} نشانات</p>
{total === 0 && ( {total === 0 && (
<p class="muted center">ابھی کوئی نشان نہیں۔ کسی شاعر، کتاب، باب یا کلام پر "نشان" دبائیں، کسی شعر کے ساتھ نشان لگائیں، یا کوئی عبارت منتخب کر کے "نشان" لگائیں۔</p> <p class="muted center">ابھی کچھ محفوظ نہیں۔ کسی شاعر، کتاب، باب یا کلام پر "محفوظ کریں" دبائیں، کسی شعر کے ساتھ والا نشان دبائیں، یا کوئی عبارت منتخب کر کے "محفوظ کریں" دبائیں۔</p>
)} )}
{lib.poets.length > 0 && ( {lib.poets.length > 0 && (

View File

@ -225,7 +225,8 @@ h1 + .muted { text-align: center; margin-top: 0; }
background-color: var(--brand); -webkit-mask-image: var(--bm-filled); mask-image: var(--bm-filled); } background-color: var(--brand); -webkit-mask-image: var(--bm-filled); mask-image: var(--bm-filled); }
.save { font: inherit; font-size: .85rem; padding: 1px 14px; border: 1.5px solid var(--border); border-radius: 999px; background: var(--inner); color: var(--ink); cursor: pointer; } .save { font: inherit; font-size: .85rem; padding: 1px 14px; border: 1.5px solid var(--border); border-radius: 999px; background: var(--inner); color: var(--ink); cursor: pointer; }
.save::before { margin-inline-end: 4px; } .save::before { margin-inline-end: 4px; }
.save[aria-pressed='true'] { border-color: var(--brand); color: var(--brand); } .save[aria-pressed='true'] { border-color: var(--brand); color: var(--brand); font-weight: 700;
background: color-mix(in srgb, var(--brand) 12%, var(--inner)); } /* محفوظ شدہ: accent tint, filled glyph */
/* word book (ذخیرۂ الفاظ): + to add, ✓ when added (hearts are for poets and works) */ /* word book (ذخیرۂ الفاظ): + to add, ✓ when added (hearts are for poets and works) */
.wordbook { font: inherit; font-size: .85rem; padding: 1px 14px; margin-bottom: 6px; border: 1.5px solid var(--border); border-radius: 999px; background: var(--inner); color: var(--ink); cursor: pointer; } .wordbook { font: inherit; font-size: .85rem; padding: 1px 14px; margin-bottom: 6px; border: 1.5px solid var(--border); border-radius: 999px; background: var(--inner); color: var(--ink); cursor: pointer; }
.wordbook::before { content: '+ '; font-weight: 700; color: var(--gold); } .wordbook::before { content: '+ '; font-weight: 700; color: var(--gold); }