| Commit message (Collapse) | Author | Age | Files | Lines | |
|---|---|---|---|---|---|
| * | fix(user): pass actual description to badge preview alt text | Fuwn | 2026-04-18 | 1 | -1/+1 |
| | | | | | | | | | | | The ParallaxImage alternativeText prop was passed as the literal string "selectedBadge.description" (quoted attribute syntax) instead of the expression, so every badge image rendered with that identifier name as its alt text. Switch to the expression form with a nullish-coalescing fallback so badges without a description render empty alt rather than the literal. | ||||
| * | fix(schedule): stop duplicating first page in season pagination | Fuwn | 2026-04-18 | 1 | -37/+18 |
| | | | | | | | | | | | | | | The seasonal schedule collector pushed page 1 outside the while-loop, then re-pushed the current page on every loop iteration. That meant every multi-page season duplicated its first page's media, and the same bug ran a second time when includeLastSeason was set. Restructure into a shared collectAllSchedulePages helper with a single push-then-check-hasNextPage loop, so each page is pushed exactly once. Verified against AniList for SPRING 2026 with includeLastSeason=true: 210 media, 0 duplicates. | ||||
| * | fix(cdn): preserve upstream headers alongside CORS and cache overrides | Fuwn | 2026-04-18 | 1 | -6/+8 |
| | | | | | | | | | | | | The response was built with `{ "Cache-Control": ..., "Access-Control- Allow-Origin": ..., ...response.headers }`. Spreading a Headers instance into a plain object does not expand into own properties, so upstream headers (including Content-Type) were dropped on the floor. Build a Headers copy of the upstream response and .set() the overrides on it, so Content-Type and friends survive alongside the locked-down CORS origin and long cache policy. | ||||
| * | fix(api): gate badge click-count on Origin and fix 401 response reuse | Fuwn | 2026-04-18 | 1 | -9/+11 |
| | | | | | | | | | | | | | | The PUT ?incrementClickCount path ran before any auth guard, letting unauthenticated callers spam-increment arbitrary badges. Require the request Origin to match appOrigin() so legitimate in-browser clicks (authenticated or not) still count while direct scripted calls are rejected. Also convert the shared `unauthorised` Response singleton into a factory. The singleton's body was consumed on first use, so subsequent 401 paths returned a `Response body is locked` error instead of the intended "Unauthorised" body. | ||||
| * | fix(api): encode subsplease timezone to prevent query-param injection | Fuwn | 2026-04-18 | 1 | -5/+6 |
| | | | | | | | | The `tz` query value was interpolated raw into the upstream URL, letting callers append arbitrary query segments (e.g. `tz=foo&f=hax`). Wrap the value in encodeURIComponent and rename the local variable away from the banned `tz` abbreviation. | ||||
| * | fix(utility): treat .localhost subdomains as private in appOrigin | Fuwn | 2026-04-18 | 1 | -0/+1 |
| | | |||||
| * | fix(dev): route portless .localhost URL through app origin and proxy CORS | Fuwn | 2026-04-18 | 2 | -1/+2 |
| | | |||||
| * | build(dev): use portless for named .localhost dev URL | Fuwn | 2026-04-18 | 2 | -1/+13 |
| | | |||||
| * | fix(ui): hide list count badge when no media is displayed | Fuwn | 2026-04-17 | 2 | -2/+2 |
| | | | | | | | Showing "0" in the list title next to a "No anime/manga to display" empty-state message duplicates information. Treat an empty media list the same as dummy mode and suppress the count. | ||||
| * | fix(ui): reset media list filter when its custom list disappears | Fuwn | 2026-04-17 | 2 | -0/+20 |
| | | | | | | | | | If a user's persisted filter references a custom list that no longer exists on any media (renamed or deleted on AniList), the select falls back to showing "All" but the underlying state still filters to an empty set. Detect the stale value and reset it, clearing the StateBin entry so the fix survives a reload. | ||||
| * | fix(ui): hide follow-fix toggle link until a username is entered | Fuwn | 2026-04-17 | 1 | -3/+5 |
| | | | | | | | Previously the link rendered "Toggle follow for ..." and was clickable with an empty submission. Only render once the input has content so there is no dead affordance. | ||||
| * | fix(ui): hide media roulette button when only one item is pickable | Fuwn | 2026-04-17 | 2 | -2/+2 |
| | | | | | | | Rouletting a single item is deterministic, so the affordance adds nothing. Require at least two items before showing the button on both anime and manga lists. | ||||
| * | fix(ui): hide media list filter when every list matches "All" | Fuwn | 2026-04-17 | 2 | -2/+10 |
| | | | | | | | If every custom list contains every displayed media item, each option yields the same result, so the picker is noise. Gate the select on a reactive check that any list excludes at least one item. | ||||
| * | Merge pull request #3 from Fuwn/feat/instant-cache-invalidation | Fuwn | 2026-04-14 | 11 | -34/+111 |
| |\ | | | | | feat(cache): instant list revalidation from command palette and debug menu | ||||
| | * | feat(cache): instant list revalidation from command palette and debug menu | Fuwn | 2026-04-15 | 11 | -52/+106 |
| | | | | | | | | | | | | | | | | | | | Replaces one-shot boolean revalidateAnime with a counter store so multiple components can subscribe without race conditions. Adds revalidateManga store and reactive refresh blocks to DueAnimeList and MangaListTemplate. Extracts shared invalidateListCaches function used by both the command palette action and the debug settings button. Renames palette item to "Refresh" and debug button to "Invalidate". | ||||
| | * | feat(command-palette): add clear anime and manga list caches action | Fuwn | 2026-04-15 | 1 | -0/+23 |
| |/ | |||||
| * | fix(ui): balance homepage media panels | Fuwn | 2026-04-12 | 1 | -62/+220 |
| | | |||||
| * | fix(settings): clarify data saver checkbox | Fuwn | 2026-04-02 | 4 | -0/+6 |
| | | |||||
| * | feat(settings): add checkbox tooltips | Fuwn | 2026-04-02 | 1 | -0/+5 |
| | | |||||
| * | fix(ui): stop roulette at intended duration | Fuwn | 2026-04-02 | 1 | -1/+2 |
| | | |||||
| * | fix(ui): correct manga list tooltip behavior | Fuwn | 2026-04-02 | 2 | -2/+8 |
| | | |||||
| * | fix(ui): polish media list title separators | Fuwn | 2026-04-02 | 1 | -0/+8 |
| | | |||||
| * | fix(ui): align media list title timings | Fuwn | 2026-04-02 | 1 | -2/+3 |
| | | |||||
| * | fix(ui): refine media list title counts | Fuwn | 2026-04-02 | 1 | -4/+17 |
| | | |||||
| * | feat(debug): add media list timing toggle | Fuwn | 2026-04-02 | 6 | -1/+12 |
| | | |||||
| * | revert(ui): remove april fools executive mode | Fuwn | 2026-04-02 | 11 | -250/+52 |
| | | |||||
| * | fix(ui): tune april fools notification copy | Fuwn | 2026-04-01 | 1 | -1/+1 |
| | | |||||
| * | fix(ui): simplify april fools controls | Fuwn | 2026-04-01 | 1 | -15/+52 |
| | | |||||
| * | feat(ui): add april fools executive mode | Fuwn | 2026-04-01 | 11 | -52/+213 |
| | | |||||
| * | fix(badges): hide outbound link notice | Fuwn | 2026-04-01 | 1 | -1/+1 |
| | | |||||
| * | fix(manga): show skeleton while list is loading | Fuwn | 2026-03-30 | 1 | -1/+1 |
| | | |||||
| * | perf(manga): progressively hydrate native chapter counts | Fuwn | 2026-03-29 | 4 | -28/+200 |
| | | |||||
| * | fix(proxy): improve native chapter source routing | Fuwn | 2026-03-29 | 2 | -50/+117 |
| | | |||||
| * | fix(anilist): restore completed list query semantics | Fuwn | 2026-03-28 | 5 | -7/+7 |
| | | |||||
| * | fix(state): restore persisted list UI state | Fuwn | 2026-03-28 | 4 | -35/+68 |
| | | |||||
| * | fix(filters): apply list filter changes immediately | Fuwn | 2026-03-28 | 2 | -8/+16 |
| | | |||||
| * | fix(cache): restore instant filters and shared AniList cache | Fuwn | 2026-03-28 | 4 | -12/+30 |
| | | |||||
| * | fix(anilist): restore completed list filters | Fuwn | 2026-03-28 | 5 | -26/+61 |
| | | |||||
| * | fix(anilist): fall back to persisted media list cache | Fuwn | 2026-03-28 | 1 | -0/+56 |
| | | |||||
| * | fix(anilist): avoid leaking settings subscriptions | Fuwn | 2026-03-28 | 1 | -4/+1 |
| | | |||||
| * | fix(manga): avoid poisoning native chapter cache | Fuwn | 2026-03-28 | 1 | -7/+37 |
| | | |||||
| * | fix(cache): keep pre-hydration state changes | Fuwn | 2026-03-28 | 2 | -2/+26 |
| | | |||||
| * | fix(notifications): stabilize browser subscription identity | Fuwn | 2026-03-28 | 2 | -16/+30 |
| | | |||||
| * | fix(notifications): prune dead push endpoints | Fuwn | 2026-03-28 | 1 | -16/+53 |
| | | |||||
| * | fix(notifications): support per-device push subscriptions | Fuwn | 2026-03-28 | 4 | -7/+50 |
| | | |||||
| * | fix(cache): preserve hydrated client state | Fuwn | 2026-03-28 | 4 | -10/+28 |
| | | |||||
| * | fix(preferences): preserve partial preference updates | Fuwn | 2026-03-28 | 1 | -44/+26 |
| | | |||||
| * | fix(auth): ignore malformed user cookies | Fuwn | 2026-03-28 | 11 | -33/+113 |
| | | |||||
| * | fix(cache): respect AniList media list recache windows | Fuwn | 2026-03-28 | 8 | -65/+153 |
| | | |||||
| * | feat(manga): allow forcing automatic refresh | Fuwn | 2026-03-28 | 1 | -1/+5 |
| | | |||||