feat: add reminders, auto-delete, cross-device sync, dark mode, and rediscovery spotlight

- Rename extension from Shelf to "Read it later"
- Add reminder settings: highlight and pin overdue unarchived items
- Add auto-delete with a hard safety rule requiring its period to exceed the reminder period
- Add cross-device sync via chrome.storage.sync (lightweight per-item metadata, no thumbnails)
- Add light/dark/system theme support
- Fix list-view Archive/Delete button alignment (card-perf wasn't filling the row)
- Add "Worth a second look" spotlight: proactively resurfaces old, forgotten items with automatic backoff so repeatedly-ignored items are shown less often, never permanently
This commit is contained in:
2026-07-13 20:49:05 +10:00
parent d627e6bb44
commit c5bd7e38bf
7 changed files with 847 additions and 32 deletions
+64 -3
View File
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Shelf</title>
<title>Read it later</title>
<link rel="stylesheet" href="newtab.css" />
</head>
<body>
@@ -10,7 +10,7 @@
<header class="masthead">
<div class="masthead-title">
<span class="mark" aria-hidden="true">🔖</span>
<h1>Shelf</h1>
<h1>Read it later</h1>
</div>
<p class="tally"><span id="unreadCount">0</span> saved for later<span id="archivedNote"></span></p>
</header>
@@ -34,20 +34,81 @@
</div>
<button id="showArchivedBtn" class="ghost-btn">Show archived</button>
<div class="settings-wrap">
<button id="settingsBtn" class="toggle-btn" title="Settings" aria-haspopup="true" aria-expanded="false"></button>
<div id="settingsPanel" class="settings-panel" hidden>
<div class="settings-row settings-theme">
<label for="themeSelect">Theme</label>
<select id="themeSelect">
<option value="system">System</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
<hr class="settings-divider" />
<label class="settings-row">
<input type="checkbox" id="reminderEnabled" />
Remind me after
</label>
<div class="settings-row settings-period">
<input type="number" id="reminderAmount" min="1" max="999" value="7" />
<select id="reminderUnit">
<option value="days">days</option>
<option value="weeks">weeks</option>
<option value="months">months</option>
</select>
</div>
<p class="settings-hint">Overdue items are pinned to the top and highlighted.</p>
<hr class="settings-divider" />
<label class="settings-row">
<input type="checkbox" id="autoDeleteEnabled" />
Delete unarchived items after
</label>
<div class="settings-row settings-period">
<input type="number" id="autoDeleteAmount" min="1" max="999" value="30" />
<select id="autoDeleteUnit">
<option value="days">days</option>
<option value="weeks">weeks</option>
<option value="months">months</option>
</select>
</div>
<p class="settings-hint">Archive anything you want to keep — this only removes items you never got back to.</p>
<p class="settings-error" id="autoDeleteError" hidden>Must be longer than the reminder period above, so you're always warned first.</p>
<hr class="settings-divider" />
<label class="settings-row">
<input type="checkbox" id="spotlightEnabled" />
Worth a second look
</label>
<p class="settings-hint">Resurfaces a few old, forgotten items each time you open a new tab. The more you pass on one, the less often it comes back.</p>
</div>
</div>
</div>
<section id="spotlight" class="spotlight" hidden aria-label="Worth a second look">
<h2 class="spotlight-heading">Worth a second look</h2>
<div id="spotlightStrip" class="spotlight-strip"></div>
</section>
<main id="shelf" class="shelf" data-view="grid">
<!-- items injected here -->
</main>
<div id="emptyState" class="empty-state" hidden>
<p class="empty-title">Your shelf is empty.</p>
<p class="empty-sub">Click the Shelf icon in your toolbar, or right-click any page or link, to save something for later.</p>
<p class="empty-sub">Click the Read it later icon in your toolbar, or right-click any page or link, to save something for later.</p>
</div>
</div>
<div id="toast" class="toast" hidden></div>
<script src="sync.js"></script>
<script src="newtab.js"></script>
</body>
</html>