(() => loadRecent(Date.now()))
// Re-render each minute so "expires in …" stays true in a tab left open,
@@ -22,7 +22,7 @@ const R3drPage = () => {
return (
- } />
+ } />
r3dr
@@ -46,4 +46,4 @@ const R3drPage = () => {
)
}
-export default R3drPage
+export default IiliPage
diff --git a/src/apps/r3dr/recent.ts b/src/apps/iili/recent.ts
similarity index 85%
rename from src/apps/r3dr/recent.ts
rename to src/apps/iili/recent.ts
index ab59693..92b427b 100644
--- a/src/apps/r3dr/recent.ts
+++ b/src/apps/iili/recent.ts
@@ -8,7 +8,9 @@ export interface RecentLink {
expiresAt: number
}
-const KEY = 'r3dr.recent'
+const KEY = 'iili.recent'
+// Links saved before the rename; read once so nobody's list disappears.
+const LEGACY_KEY = 'r3dr.recent'
const MAX = 5
// Slugs are exactly 3, 6, or 11 base64url chars (the encoder's widths). A
@@ -18,7 +20,7 @@ const SLUG_SHAPE = /^(?:[A-Za-z0-9_-]{3}|[A-Za-z0-9_-]{6}|[A-Za-z0-9_-]{11})$/
export function loadRecent(now: number): RecentLink[] {
try {
- const raw = localStorage.getItem(KEY)
+ const raw = localStorage.getItem(KEY) ?? localStorage.getItem(LEGACY_KEY)
if (!raw) return []
const parsed: unknown = JSON.parse(raw)
if (!Array.isArray(parsed)) return []
@@ -43,6 +45,7 @@ export function addRecent(links: RecentLink[], link: RecentLink): RecentLink[] {
const next = [link, ...links.filter(l => l.slug !== link.slug)].slice(0, MAX)
try {
localStorage.setItem(KEY, JSON.stringify(next))
+ localStorage.removeItem(LEGACY_KEY)
} catch {
// storage unavailable; the in-memory list still renders
}
@@ -52,6 +55,7 @@ export function addRecent(links: RecentLink[], link: RecentLink): RecentLink[] {
export function clearRecent(): void {
try {
localStorage.removeItem(KEY)
+ localStorage.removeItem(LEGACY_KEY)
} catch {
// nothing to clear
}
diff --git a/src/apps/r3dr/urlInput.ts b/src/apps/iili/urlInput.ts
similarity index 100%
rename from src/apps/r3dr/urlInput.ts
rename to src/apps/iili/urlInput.ts
diff --git a/src/shared/components/Navigation.tsx b/src/shared/components/Navigation.tsx
index 72b3dab..df9c7cc 100644
--- a/src/shared/components/Navigation.tsx
+++ b/src/shared/components/Navigation.tsx
@@ -36,7 +36,7 @@ const MENU: MenuGroup[] = [
{ label: 'Posterize', to: '/posterize' },
{ label: 'Metrics', to: '/metrics' },
{ label: 'Wordchains', to: '/wordchains' },
- { label: 'r3dr', to: '/r3dr', description: 'URL shortener' },
+ { label: 'iili', to: '/iili', description: 'URL shortener' },
],
},
{
@@ -63,7 +63,7 @@ const MENU: MenuGroup[] = [
{ label: 'tty1', to: 'https://tty1.uk', external: true, description: 'Web terminal' },
{ label: '里に春が来ました', to: 'https://sato-ni-haru-ga-kimashita.uk', external: true, description: 'Japanese sentence breakdown' },
{ label: 'p2bx', to: 'https://p2bx.uk', external: true, description: 'Stone–Čech compactification' },
- { label: 'iili', to: 'https://iili.uk', external: true, description: 'URL shortener' },
+ { label: 'iili.uk', to: 'https://iili.uk', external: true, description: 'The shortener on its own domain' },
],
},
{
diff --git a/src/shared/components/__tests__/Navigation.test.tsx b/src/shared/components/__tests__/Navigation.test.tsx
index 961417b..388e3f6 100644
--- a/src/shared/components/__tests__/Navigation.test.tsx
+++ b/src/shared/components/__tests__/Navigation.test.tsx
@@ -46,7 +46,7 @@ describe('Navigation', () => {
[/^tty1\s?\(external site\)/, 'https://tty1.uk', 'Web terminal'],
[/^里に春が来ました\s?\(external site\)/, 'https://sato-ni-haru-ga-kimashita.uk', 'Japanese sentence breakdown'],
[/^p2bx\s?\(external site\)/, 'https://p2bx.uk', 'Stone–Čech compactification'],
- [/^iili\s?\(external site\)/, 'https://iili.uk', 'URL shortener'],
+ [/^iili\.uk\s?\(external site\)/, 'https://iili.uk', 'The shortener on its own domain'],
]
for (const [name, href, description] of expected) {
const link = group.getByRole('link', { name })
@@ -55,14 +55,12 @@ describe('Navigation', () => {
}
})
- // r3dr moved from Elsewhere to Projects when the page moved into this
- // site (#1359 chunk 2): internal now, description intact.
- it('links r3dr as an internal Projects page', () => {
+ it('links iili as an internal Projects page', () => {
renderWithRouter()
const groupEl = testingScreen.getByText('Projects').closest('li')
if (!groupEl) throw new Error('Projects nav group not found')
- const link = within(groupEl).getByRole('link', { name: /^r3dr/ })
- expect(link.getAttribute('href')).toBe('/r3dr')
+ const link = within(groupEl).getByRole('link', { name: /^iili/ })
+ expect(link.getAttribute('href')).toBe('/iili')
expect(link.textContent).not.toContain('(external site)')
expect(within(link).getByText('URL shortener')).toBeDefined()
})