Improve bookmark logo variation and documentation screenshot #55
No files matched your search
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@directory/web': patch
|
||||
---
|
||||
|
||||
Vary generated bookmark logo backgrounds by link rather than group, keeping colors stable when titles or groups change.
|
||||
@@ -116,7 +116,7 @@ describe('prepared bookmark logos with the current Initials renderer', () => {
|
||||
).toBe('BF');
|
||||
});
|
||||
|
||||
it('keys separate slugs independently while sharing a named group color', () => {
|
||||
it('uses per-link colors even within the same named group', () => {
|
||||
const logos = renderBookmarkLogos(
|
||||
configuration({
|
||||
photos: { title: 'Photos', group: 'Family' },
|
||||
@@ -126,7 +126,7 @@ describe('prepared bookmark logos with the current Initials renderer', () => {
|
||||
expect(Object.keys(logos)).toEqual(['photos', 'backup']);
|
||||
expect(letters(logos.photos!)).toBe('PH');
|
||||
expect(letters(logos.backup!)).toBe('BF');
|
||||
expect(background(logos.photos!)).toBe(background(logos.backup!));
|
||||
expect(background(logos.photos!)).not.toBe(background(logos.backup!));
|
||||
});
|
||||
|
||||
it('keeps colors stable through group insertion, declaration reordering and accent changes', () => {
|
||||
@@ -148,6 +148,19 @@ describe('prepared bookmark logos with the current Initials renderer', () => {
|
||||
for (const id of Object.keys(original)) expect(updated[id]).toBe(original[id]);
|
||||
});
|
||||
|
||||
it('keeps a link color stable through title edits, regrouping and ungrouping', () => {
|
||||
const original = renderBookmarkLogos(
|
||||
configuration({ photos: { title: 'Photos', group: 'Family' } })
|
||||
).photos!;
|
||||
for (const group of ['Another group', undefined]) {
|
||||
const updated = renderBookmarkLogos(
|
||||
configuration({ photos: { title: 'Picture library', ...(group ? { group } : {}) } })
|
||||
).photos!;
|
||||
expect(background(updated)).toBe(background(original));
|
||||
expect(letters(updated)).toBe('PL');
|
||||
}
|
||||
});
|
||||
|
||||
it('uses a varied flat palette with opaque high-contrast colors and intrinsic 64px dimensions', () => {
|
||||
const config = configuration(
|
||||
Object.fromEntries(
|
||||
|
||||
@@ -9,8 +9,7 @@ const backgrounds = ['#dbeafe', '#dcfce7', '#fef3c7', '#fce7f3', '#ede9fe', '#cf
|
||||
export function renderBookmarkLogos(config: DirectoryConfiguration): Record<string, string> {
|
||||
return Object.fromEntries(
|
||||
Object.entries(config.links).map(([id, link]) => {
|
||||
const identity = link.group === undefined ? `link:${id}` : `named:${link.group}`;
|
||||
const colorIndex = createHash('sha256').update(identity).digest().readUInt32BE(0);
|
||||
const colorIndex = createHash('sha256').update(`link:${id}`).digest().readUInt32BE(0);
|
||||
const background = backgrounds[colorIndex % backgrounds.length]!;
|
||||
const svg = new Avatar(style, {
|
||||
seed: initialsSeed(link.title, id),
|
||||
@@ -27,7 +26,6 @@ export function renderBookmarkLogos(config: DirectoryConfiguration): Record<stri
|
||||
}
|
||||
|
||||
function initialsSeed(title: string, id: string): string {
|
||||
// DiceBear limits seeds to 1,024 Unicode characters and ignores text after @.
|
||||
const titleSeed = Array.from(title.split('@', 1)[0]!).slice(0, 1024).join('');
|
||||
if (/\p{L}/u.test(titleSeed)) return titleSeed;
|
||||
const slugSeed = Array.from(id).slice(0, 1024).join('');
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
# yaml-language-server: $schema=../../packages/config/src/config.schema.json
|
||||
# Local demo only: replace these known credentials before exposing the directory.
|
||||
# Runtime auth still needs a unique generated AUTH_SECRET and matching ORIGIN/AUTH_URL.
|
||||
# See demo/README.md for a preview that leaves operator configuration untouched.
|
||||
version: 1
|
||||
site:
|
||||
title: Home Server
|
||||
description: Useful things running at home.
|
||||
footer: Something not working? Ask your household maintainer.
|
||||
|
||||
appearance:
|
||||
primary_light_color: '#0f766e'
|
||||
primary_dark_color: '#5eead4'
|
||||
|
||||
auth:
|
||||
credentials:
|
||||
username: admin
|
||||
password: directory
|
||||
|
||||
# Reserved example.com destinations are placeholders, not live integrations.
|
||||
# All bookmarks use generated logos; site branding uses the bundled default.
|
||||
links:
|
||||
photos:
|
||||
title: Photos
|
||||
url: https://photos.example.com
|
||||
description: |
|
||||
Family photos and videos, all in one place.
|
||||
Install your photo service's mobile app for automatic uploads.
|
||||
tags: [photos, videos, memories]
|
||||
group: Photos & files
|
||||
requires_auth: true
|
||||
files:
|
||||
title: Files
|
||||
url: https://files.example.com
|
||||
description: Shared documents, school projects and household paperwork.
|
||||
tags: [documents, sharing, storage]
|
||||
group: Photos & files
|
||||
backups:
|
||||
title: Backups
|
||||
url: https://backups.example.com
|
||||
description: |
|
||||
Check the latest backup status before you need a restore.
|
||||
Ask your household maintainer for help recovering a file.
|
||||
tags: [backup, recovery, storage]
|
||||
group: Photos & files
|
||||
scans:
|
||||
title: Paperwork inbox
|
||||
url: https://scans.example.com
|
||||
description: Sort recent scans into searchable bills, receipts and warranties.
|
||||
tags: [scans, documents, receipts]
|
||||
group: Photos & files
|
||||
archive:
|
||||
title: Family history archive
|
||||
url: https://archive.example.com
|
||||
description: Old letters, digitized albums and notes about the family tree.
|
||||
tags: [history, memories, documents]
|
||||
group: Photos & files
|
||||
albums:
|
||||
title: Shared albums
|
||||
url: https://albums.example.com
|
||||
description: Choose a photo collection to share with visiting relatives.
|
||||
tags: [photos, albums, sharing]
|
||||
group: Photos & files
|
||||
transfers:
|
||||
title: File drop
|
||||
url: https://transfers.example.com
|
||||
description: Temporary space for large files moving between household devices.
|
||||
tags: [transfer, sharing, storage]
|
||||
group: Photos & files
|
||||
internal_only: true
|
||||
notebooks:
|
||||
title: Household notebooks
|
||||
url: https://notebooks.example.com
|
||||
description: Shared notes for school, travel plans and everyday reference.
|
||||
tags: [notes, writing, planning]
|
||||
group: Photos & files
|
||||
sync:
|
||||
title: Device sync status
|
||||
url: https://sync.example.com
|
||||
description: Check whether laptop folders have reached the home server.
|
||||
tags: [sync, devices, storage]
|
||||
group: Photos & files
|
||||
internal_only: true
|
||||
keepsakes:
|
||||
title: DigitalKeepsakesAndSchoolProjectCollections
|
||||
url: https://keepsakes.example.com
|
||||
description: Finished school projects and small creations worth keeping.
|
||||
tags: [school, archive, memories]
|
||||
group: Photos & files
|
||||
music:
|
||||
title: Music
|
||||
url: https://music.example.com
|
||||
description: Albums, playlists and a soundtrack for dinner.
|
||||
tags: [music, audio, playlists]
|
||||
group: Entertainment
|
||||
movies:
|
||||
title: Movies
|
||||
url: https://movies.example.com
|
||||
description: Browse the family movie and television library.
|
||||
tags: [movies, television, streaming]
|
||||
group: Entertainment
|
||||
books:
|
||||
title: Books
|
||||
url: https://books.example.com
|
||||
description: Find your next ebook or audiobook for the commute.
|
||||
tags: [books, reading, audiobooks]
|
||||
group: Entertainment
|
||||
radio:
|
||||
title: Radio
|
||||
url: https://radio.example.com
|
||||
description: Saved station links and recordings from the community radio club.
|
||||
tags: [radio, audio, recordings]
|
||||
group: Entertainment
|
||||
podcasts:
|
||||
title: Podcast queue
|
||||
url: https://podcasts.example.com
|
||||
description: Episodes downloaded for the next long drive.
|
||||
tags: [podcasts, audio, travel]
|
||||
group: Entertainment
|
||||
reading:
|
||||
title: Weekend reading list
|
||||
url: https://reading.example.com
|
||||
description: Saved articles and reading suggestions from around the household.
|
||||
tags: [reading, articles, bookmarks]
|
||||
group: Entertainment
|
||||
requests:
|
||||
title: Library requests
|
||||
url: https://requests.example.com
|
||||
description: Suggest something for the household media collection.
|
||||
tags: [library, requests, media]
|
||||
group: Entertainment
|
||||
requires_auth: true
|
||||
home-automation:
|
||||
title: Home automation
|
||||
url: https://home.example.com
|
||||
description: |
|
||||
Lights, room temperatures and everyday routines.
|
||||
Connect to the home network or VPN before opening this service.
|
||||
tags: [home, lights, routines]
|
||||
group: Everyday tools
|
||||
internal_only: true
|
||||
recipes:
|
||||
title: Recipes
|
||||
url: https://recipes.example.com
|
||||
description: Favorite meals, shopping lists and this week's dinner plan.
|
||||
tags: [cooking, meals, shopping]
|
||||
group: Everyday tools
|
||||
calendar:
|
||||
title: Family calendar
|
||||
url: https://calendar.example.com
|
||||
description: Appointments, school events and reminders for bin collection.
|
||||
tags: [calendar, reminders, planning]
|
||||
group: Everyday tools
|
||||
groceries:
|
||||
title: Shopping list
|
||||
url: https://groceries.example.com
|
||||
description: Add groceries before the next trip to the shops.
|
||||
tags: [shopping, groceries, pantry]
|
||||
group: Everyday tools
|
||||
weather:
|
||||
title: Garden weather station
|
||||
url: https://weather.example.com
|
||||
description: Local rainfall and temperature readings from the garden sensors.
|
||||
tags: [weather, garden, sensors]
|
||||
group: Everyday tools
|
||||
energy:
|
||||
title: Energy
|
||||
url: https://energy.example.com
|
||||
description: Household electricity trends and daily solar production.
|
||||
tags: [energy, solar, sensors]
|
||||
group: Everyday tools
|
||||
internal_only: true
|
||||
guides:
|
||||
title: Workshop guides
|
||||
url: https://guides.example.com
|
||||
description: Repair notes and instructions for frequently used tools.
|
||||
tags: [workshop, repair, guides]
|
||||
group: Workshop
|
||||
printer:
|
||||
title: 3D printer
|
||||
url: https://printer.example.com
|
||||
description: Check the current print before starting another job.
|
||||
tags: [printing, workshop, projects]
|
||||
group: Workshop
|
||||
internal_only: true
|
||||
inventory:
|
||||
title: Parts inventory
|
||||
url: https://inventory.example.com
|
||||
description: Find spare cables, screws and electronic components.
|
||||
tags: [parts, storage, workshop]
|
||||
group: Workshop
|
||||
projects:
|
||||
title: Works in progress
|
||||
url: https://projects.example.com
|
||||
description: Sketches, task lists and progress photos for household projects.
|
||||
tags: [projects, planning, workshop]
|
||||
group: Workshop
|
||||
manuals:
|
||||
title: Appliance manuals and warranty notes
|
||||
url: https://manuals.example.com
|
||||
description: Setup instructions and service records for household appliances.
|
||||
tags: [manuals, warranties, repair]
|
||||
group: Workshop
|
||||
router:
|
||||
title: Router
|
||||
url: https://router.example.com
|
||||
description: Manage the home network; leave changes to your household maintainer.
|
||||
tags: [network, router, maintenance]
|
||||
group: Behind the scenes
|
||||
requires_auth: true
|
||||
internal_only: true
|
||||
admin_only: true
|
||||
monitoring:
|
||||
title: Server health
|
||||
url: https://monitoring.example.com
|
||||
description: Storage capacity, temperatures and service availability.
|
||||
tags: [monitoring, maintenance, server]
|
||||
group: Behind the scenes
|
||||
internal_only: true
|
||||
admin_only: true
|
||||
containers:
|
||||
title: Container console
|
||||
url: https://containers.example.com
|
||||
description: Maintenance console for the services running on the home server.
|
||||
tags: [containers, maintenance, server]
|
||||
group: Behind the scenes
|
||||
requires_auth: true
|
||||
internal_only: true
|
||||
admin_only: true
|
||||
dns:
|
||||
title: Local name service
|
||||
url: https://dns.example.com
|
||||
description: Household DNS records and local network filtering settings.
|
||||
tags: [network, dns, maintenance]
|
||||
group: Behind the scenes
|
||||
internal_only: true
|
||||
admin_only: true
|
||||
@@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<rect width="64" height="64" rx="16" fill="#0f766e"/>
|
||||
<path d="M16 30 32 16l16 14v19H36V36h-8v13H16Z" fill="#f0fdfa"/>
|
||||
<circle cx="32" cy="27" r="3" fill="#0f766e"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 240 B |
@@ -1,6 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-labelledby="title">
|
||||
<title id="title">Files</title>
|
||||
<rect width="64" height="64" rx="12" fill="#1e3a8a"/>
|
||||
<path d="M13 24v-6h15l6 6h17v25H13Z" fill="none" stroke="#fff" stroke-width="3" stroke-linejoin="round"/>
|
||||
<path d="M13 28h38M23 36h18M23 42h12" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 432 B |
@@ -1,6 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-labelledby="title">
|
||||
<title id="title">Home automation</title>
|
||||
<rect width="64" height="64" rx="12" fill="#7c2d12"/>
|
||||
<path d="m11 29 21-17 21 17M18 25v26h28V25" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="m34 28-8 11h7l-3 9 10-13h-8Z" fill="#fff"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 419 B |
@@ -1,7 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-labelledby="title">
|
||||
<title id="title">Music</title>
|
||||
<rect width="64" height="64" rx="12" fill="#581c87"/>
|
||||
<path d="M27 43V20l22-5v23M27 27l22-5" fill="none" stroke="#fff" stroke-width="3" stroke-linejoin="round"/>
|
||||
<ellipse cx="21" cy="44" rx="7" ry="5" fill="#fff"/>
|
||||
<ellipse cx="43" cy="39" rx="7" ry="5" fill="#fff"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 436 B |
@@ -1,7 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-labelledby="title">
|
||||
<title id="title">Photos</title>
|
||||
<rect width="64" height="64" rx="12" fill="#14532d"/>
|
||||
<rect x="12" y="15" width="40" height="34" rx="3" fill="none" stroke="#fff" stroke-width="3"/>
|
||||
<circle cx="40" cy="25" r="4" fill="#fff"/>
|
||||
<path d="m15 44 12-16 10 12 6-6 6 10Z" fill="#fff"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 415 B |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 54 KiB |