mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-22 11:15:41 +02:00
feat(frontend): small dashboard revamp (#26)
Add ⌘K search focus, URL-param'd search/tag/entry, persistent selection, extensions grid * feat(frontend): focus search input on ⌘K/Ctrl+K Add a global keydown handler that focuses (and selects) the search input when Meta+K or Ctrl+K is pressed. If the current view is not 'archive', switch to it first and focus the input after the next render frame via a pendingSearchFocus ref + requestAnimationFrame. The ⌘K hint badge in the toolbar was already present; this wires the behaviour behind it. * feat(frontend): persist search query and tag filter in URL params Extend parseLocation() to read ?q= and ?tag= search parameters. Initialise searchQuery and tagFilter from the URL on mount so that sharing or refreshing a filtered view restores the exact same results. - replaceState on every q/tag change (no extra history entries) - pushState on view navigation now preserves existing search params - popstate handler restores q and tag on back/forward - firstArchiveLoad ref prevents the archive-change effect from wiping URL-initialised filters on the first mount * feat(frontend): persist selected entry in URL params Extend parseLocation() to read ?entry= and initialise selectedEntryUid from it on mount. When entries load (or reload), a new effect checks whether selectedEntryUid is set without a corresponding selectedEntry object and restores it by finding the matching entry in the list. This covers page refresh, URL sharing, and back/forward navigation. The URL params sync effect now includes selectedEntryUid alongside q and tag, and the popstate handler restores all three. Also includes rebuilt frontend static assets. * fix(frontend): add cookies and extensions to settings URL routing SETTINGS_TABS was missing 'cookies' and 'extensions', so navigating to /settings/cookies or /settings/extensions silently fell back to the profile tab. Both tabs already existed in SettingsView; they just weren't recognised by parseLocation(). Includes rebuilt frontend static assets. * style(frontend): ext cards in auto-fill grid * fix(frontend): URL state regressions from Codex review Two issues: 1. Re-selection stall when popstate lands on the same entry UID. The restoration effect only had [entries, selectedEntryUid] as deps, so setting selectedEntry=null without changing either dep left the rail blank. Adding selectedEntry to the dep array lets the null→restore cycle complete. 2. tag/entry params leaking onto non-archive URLs. pushState on view changes carried window.location.search verbatim, so /settings?tag=foo was possible; reloading it triggered the tagFilter effect and force-switched back to archive. Fix: parseLocation() only extracts tag/entry when view=archive, and the params-sync effect only emits them on archive too.
This commit is contained in:
parent
72cf7ff642
commit
39765ef893
8 changed files with 187 additions and 107 deletions
|
|
@ -691,7 +691,7 @@ function ExtensionsTab() {
|
|||
const cookieExtEnabled = settings?.cookie_ext_enabled ?? true
|
||||
|
||||
return (
|
||||
<div style={{ maxWidth: 560 }}>
|
||||
<div>
|
||||
<div className="form-section">
|
||||
<h2>Extensions</h2>
|
||||
<p className="form-hint" style={{ marginBottom: 20 }}>
|
||||
|
|
@ -699,60 +699,62 @@ function ExtensionsTab() {
|
|||
accept cookie banners, and more. Changes take effect on the next capture.
|
||||
</p>
|
||||
|
||||
<div className="ext-card">
|
||||
<div className="ext-card-header">
|
||||
<div className="ext-card-info">
|
||||
<span className="ext-card-name">uBlock Origin Lite</span>
|
||||
<span className="ext-card-desc">
|
||||
Blocks ads, trackers, and other page clutter during archiving
|
||||
via Chrome’s declarativeNetRequest API (Manifest V3).
|
||||
</span>
|
||||
{!extAvailable && (
|
||||
<span className="ext-card-hint">
|
||||
Not configured — set <code>ARCHIVR_UBLOCK_EXT</code> to the
|
||||
unpacked extension directory to enable.
|
||||
<div className="ext-grid">
|
||||
<div className="ext-card">
|
||||
<div className="ext-card-header">
|
||||
<div className="ext-card-info">
|
||||
<span className="ext-card-name">uBlock Origin Lite</span>
|
||||
<span className="ext-card-desc">
|
||||
Blocks ads, trackers, and other page clutter during archiving
|
||||
via Chrome’s declarativeNetRequest API (Manifest V3).
|
||||
</span>
|
||||
)}
|
||||
{!extAvailable && (
|
||||
<span className="ext-card-hint">
|
||||
Not configured — set <code>ARCHIVR_UBLOCK_EXT</code> to the
|
||||
unpacked extension directory to enable.
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={extEnabled}
|
||||
className={`ext-toggle${extEnabled ? ' ext-toggle--on' : ''}`}
|
||||
onClick={() => toggleUblock(!extEnabled)}
|
||||
disabled={saving}
|
||||
aria-label="Toggle uBlock Origin Lite"
|
||||
>
|
||||
<span className="ext-toggle-knob" />
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={extEnabled}
|
||||
className={`ext-toggle${extEnabled ? ' ext-toggle--on' : ''}`}
|
||||
onClick={() => toggleUblock(!extEnabled)}
|
||||
disabled={saving}
|
||||
aria-label="Toggle uBlock Origin Lite"
|
||||
>
|
||||
<span className="ext-toggle-knob" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ext-card">
|
||||
<div className="ext-card-header">
|
||||
<div className="ext-card-info">
|
||||
<span className="ext-card-name">I Still Don’t Care About Cookies</span>
|
||||
<span className="ext-card-desc">
|
||||
Dismiss cookie consent banners during archiving.
|
||||
</span>
|
||||
{!cookieExtAvailable && (
|
||||
<span className="ext-card-hint">
|
||||
Not configured — set <code>ARCHIVR_COOKIE_EXT</code> to the
|
||||
unpacked extension directory to enable.
|
||||
<div className="ext-card">
|
||||
<div className="ext-card-header">
|
||||
<div className="ext-card-info">
|
||||
<span className="ext-card-name">I Still Don’t Care About Cookies</span>
|
||||
<span className="ext-card-desc">
|
||||
Dismiss cookie consent banners during archiving.
|
||||
</span>
|
||||
)}
|
||||
{!cookieExtAvailable && (
|
||||
<span className="ext-card-hint">
|
||||
Not configured — set <code>ARCHIVR_COOKIE_EXT</code> to the
|
||||
unpacked extension directory to enable.
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={cookieExtEnabled}
|
||||
className={`ext-toggle${cookieExtEnabled ? ' ext-toggle--on' : ''}`}
|
||||
onClick={() => toggleCookieExt(!cookieExtEnabled)}
|
||||
disabled={saving}
|
||||
aria-label="Toggle I Still Don't Care About Cookies"
|
||||
>
|
||||
<span className="ext-toggle-knob" />
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={cookieExtEnabled}
|
||||
className={`ext-toggle${cookieExtEnabled ? ' ext-toggle--on' : ''}`}
|
||||
onClick={() => toggleCookieExt(!cookieExtEnabled)}
|
||||
disabled={saving}
|
||||
aria-label="Toggle I Still Don't Care About Cookies"
|
||||
>
|
||||
<span className="ext-toggle-knob" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue