Home: Today shows only the five; categories behind mood selection; big view heading
- Today is just the day's five highlights (hero + four) — the preview lanes are gone; other categories appear only when their mood is selected. - Each view leads with a large serif heading (Today / Wonder / ...) and a subtitle, with a quiet sage rule — switching moods retitles the page. - Drop the now-unused Lane usage from the home. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
import { getJSON } from '$lib/api.js';
|
||||
import * as P from '$lib/prefs.js';
|
||||
import MoodNav from '$lib/components/MoodNav.svelte';
|
||||
import Lane from '$lib/components/Lane.svelte';
|
||||
import ArticleCard from '$lib/components/ArticleCard.svelte';
|
||||
import BoundariesPanel from '$lib/components/BoundariesPanel.svelte';
|
||||
|
||||
@@ -11,18 +10,25 @@
|
||||
let selected = $state('today');
|
||||
let brief = $state(null);
|
||||
let feed = $state([]);
|
||||
let lanes = $state([]);
|
||||
let userPrefs = $state(P.blank());
|
||||
let showBoundaries = $state(false);
|
||||
let loading = $state(true);
|
||||
let error = $state('');
|
||||
|
||||
let filtersOn = $derived(P.active(userPrefs));
|
||||
|
||||
const moodByKey = (k) => moods.find((m) => m.key === k);
|
||||
let current = $derived(moods.find((m) => m.key === selected));
|
||||
let viewLabel = $derived(current?.label ?? 'Today');
|
||||
let viewSubtitle = $derived(
|
||||
selected === 'today'
|
||||
? brief?.brief_date
|
||||
? `Five good things · ${brief.brief_date}`
|
||||
: 'Five good things today'
|
||||
: (current?.description ?? '')
|
||||
);
|
||||
|
||||
function feedUrl(moodKey, limit) {
|
||||
const merged = P.merge(userPrefs, moodByKey(moodKey)?.filter ?? {});
|
||||
const mood = moods.find((m) => m.key === moodKey);
|
||||
const merged = P.merge(userPrefs, mood?.filter ?? {});
|
||||
const q = P.param(merged);
|
||||
return `/api/feed?limit=${limit}${q ? '&' + q : ''}`;
|
||||
}
|
||||
@@ -31,23 +37,14 @@
|
||||
return `/api/brief?limit=5${q ? '&' + q : ''}`;
|
||||
}
|
||||
|
||||
async function loadToday() {
|
||||
brief = await getJSON(briefUrl());
|
||||
const keys = ['wonder', 'people-helping', 'solutions'];
|
||||
lanes = await Promise.all(
|
||||
keys.map(async (k) => ({ ...moodByKey(k), items: (await getJSON(feedUrl(k, 4))).items }))
|
||||
);
|
||||
}
|
||||
async function loadMood(key) {
|
||||
feed = (await getJSON(feedUrl(key, 24))).items;
|
||||
}
|
||||
|
||||
async function select(key) {
|
||||
selected = key;
|
||||
error = '';
|
||||
try {
|
||||
if (key === 'today') await loadToday();
|
||||
else await loadMood(key);
|
||||
// Today = just the day's highlights. Other moods reveal that category only
|
||||
// when chosen (categories live behind their selection, not on the home).
|
||||
if (key === 'today') brief = await getJSON(briefUrl());
|
||||
else feed = (await getJSON(feedUrl(key, 24))).items;
|
||||
} catch (e) {
|
||||
error = 'Something went quiet — could not reach the feed.';
|
||||
}
|
||||
@@ -94,43 +91,39 @@
|
||||
<p class="muted center pad">Gathering the good news…</p>
|
||||
{:else if error}
|
||||
<p class="muted center pad">{error}</p>
|
||||
{:else if selected === 'today'}
|
||||
{#if brief?.items?.length}
|
||||
<section class="rise">
|
||||
<h2 class="kicker">{brief.title ?? 'Five Good Things Today'}</h2>
|
||||
<ArticleCard article={brief.items[0]} hero onaction={applyAction} />
|
||||
{#if brief.items.length > 1}
|
||||
<div class="grid rest">
|
||||
{#each brief.items.slice(1) as a (a.id)}
|
||||
<ArticleCard article={a} onaction={applyAction} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
{:else}
|
||||
<p class="muted center pad">No brief yet today — try a calmer filter, or check back soon.</p>
|
||||
{/if}
|
||||
|
||||
{#each lanes as lane (lane.key)}
|
||||
<Lane title={lane.label} description={lane.description} items={lane.items}
|
||||
onaction={applyAction} onmore={() => select(lane.key)} />
|
||||
{/each}
|
||||
|
||||
<p class="endcap rise">✦ that's the good news for today ✦</p>
|
||||
{:else}
|
||||
<section class="rise">
|
||||
<h2 class="kicker">{moodByKey(selected)?.label}</h2>
|
||||
<p class="muted lede">{moodByKey(selected)?.description}</p>
|
||||
{#if feed.length}
|
||||
<div class="grid">
|
||||
{#key selected}
|
||||
<header class="view-head rise">
|
||||
<h1>{viewLabel}</h1>
|
||||
{#if viewSubtitle}<p class="sub">{viewSubtitle}</p>{/if}
|
||||
</header>
|
||||
|
||||
{#if selected === 'today'}
|
||||
{#if brief?.items?.length}
|
||||
<section class="rise">
|
||||
<ArticleCard article={brief.items[0]} hero onaction={applyAction} />
|
||||
{#if brief.items.length > 1}
|
||||
<div class="grid rest">
|
||||
{#each brief.items.slice(1) as a (a.id)}
|
||||
<ArticleCard article={a} onaction={applyAction} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
<p class="endcap rise">✦ that's the good news for today ✦</p>
|
||||
{:else}
|
||||
<p class="muted center pad">No brief yet today — try a calmer filter, or check back soon.</p>
|
||||
{/if}
|
||||
{:else if feed.length}
|
||||
<div class="grid rise">
|
||||
{#each feed as a (a.id)}
|
||||
<ArticleCard article={a} onaction={applyAction} />
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<p class="muted center pad">Nothing in this lane right now — try another mood or ease a filter.</p>
|
||||
<p class="muted center pad">Nothing in this mood right now — try another, or ease a boundary.</p>
|
||||
{/if}
|
||||
</section>
|
||||
{/key}
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
@@ -141,11 +134,19 @@
|
||||
}
|
||||
.boundaries:hover { color: var(--sage-deep); }
|
||||
.boundaries.on { color: var(--sage-deep); font-weight: 600; }
|
||||
.kicker {
|
||||
font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.12em;
|
||||
color: var(--gold); margin: 22px 0 14px; font-family: var(--sans); font-weight: 700;
|
||||
|
||||
.view-head { margin: 20px 0 20px; }
|
||||
.view-head h1 {
|
||||
font-size: clamp(2.1rem, 5.5vw, 2.8rem);
|
||||
line-height: 1.05;
|
||||
}
|
||||
.lede { margin: -8px 0 18px; font-size: 1.05rem; }
|
||||
.view-head .sub { margin: 8px 0 0; color: var(--muted); font-size: 1.02rem; }
|
||||
/* a quiet sage rule under the heading */
|
||||
.view-head::after {
|
||||
content: ''; display: block; width: 46px; height: 3px;
|
||||
background: var(--sage); border-radius: 2px; margin-top: 14px; opacity: 0.8;
|
||||
}
|
||||
|
||||
.rest { margin-top: 18px; }
|
||||
.center { text-align: center; }
|
||||
.pad { padding: 48px 0; }
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
- Ability to silence some categories temporarily (Maybe a user doesn't even want to see health-related articles, even good ones, so they're not reminded of an ongoing medical issue -- a way to avoid something purposely for a bit)
|
||||
- Terms to avoid list (To filter even good news that you'd rather not hear about)
|
||||
| = tabled for now
|
||||
- = Yet to do
|
||||
* = completed item
|
||||
|
||||
|
||||
* Ability to silence some categories temporarily (Maybe a user doesn't even want to see health-related articles, even good ones, so they're not reminded of an ongoing medical issue -- a way to avoid something purposely for a bit) [done: pause topics/flavors in Boundaries]
|
||||
* Terms to avoid list (To filter even good news that you'd rather not hear about) [done: avoid words/phrases in Boundaries]
|
||||
- Favorite/save articles
|
||||
- Soothing background colors/gradients per each category as you scroll. Maybe a user preference.
|
||||
- I really like the coloring for the metadata highlighting in each card (The grading bubbles)
|
||||
- Some articles are behind paywalls.. what can we do?
|
||||
- After an article is read, can we add a refresh button to fetch a replacement for it in the list?
|
||||
* I want the top 5 to be tere, but I want the remaining categories to be hidden behing their selections. So the main screen should show just the current highlights, and then the other articles should only be visible when in that category. [done]
|
||||
* Title headings should be a little larger -- if you select Today, Today should look like a proper heading, bold and beautiful. Switching to Wondow should show "Wonder" all nice and whatnot. [done]
|
||||
Reference in New Issue
Block a user