Skip to content

Commit f9c8a5f

Browse files
committed
add toast notifications and switch offline download to a dismissible prompt
Ports the generic toast system (ToastProvider/useToast + ToastViewport) and prompt-driven offline-download UX that was drafted, uncommitted, on the old nextjs-migration worktree, reconciled with the data+pages caching fix already on main. - ToastProvider now wraps the app in layout.tsx, rendering a fixed bottom-center viewport (title/message/progress bar/actions) shared by any future notification, not just this one. - OfflineDownload no longer renders an always-visible control on the homepage; it prompts once via a toast (skipped if already downloaded/dismissed, tracked in localStorage) with Download/Not now actions, live progress, and a Retry action on failure. Moved into the root layout so it applies site-wide instead of only on "/". - Extracted the collect/count/download logic into src/lib/offline-cache.ts so the component stays focused on UI — keeping the existing "data" + "pages" cache split (the pages cache is what makes offline navigation to un-visited pages work; see the earlier runtimeCaching fix). - Extracted the repeated 9-slice card border-image rules into a `card-border` mixin (src/styles/_mixins.scss) so Card and the new Toast share the same frame styling, and picked up a few small visual refinements from the same worktree (list-page row padding to sit inside the card frame, blacksmith type-icon sizing, list-row gap). Verified with `tsc --noEmit`, a full `next build` export, and a browser check that the toast prompts, downloads, and reports progress/completion with no console errors.
1 parent eb24a6b commit f9c8a5f

12 files changed

Lines changed: 572 additions & 213 deletions

File tree

‎src/app/blacksmith/page.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default function BlacksmithPage() {
4646
href={`/blacksmith/${type}/`}
4747
className="list-row"
4848
>
49-
<Icon type={type} size="large" rarity={4} alt={name} />
49+
<Icon type={type} alt={name} />
5050
<p>{name}</p>
5151
</Link>
5252
);

‎src/app/globals.scss‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,9 @@ hr.border {
155155
align-items: center;
156156
display: flex;
157157
flex: 0 0 38px;
158+
gap: 10px;
158159
height: 38px;
159-
padding-left: 6px;
160+
padding: 0 16px;
160161

161162
&:hover {
162163
@include green-hover-gradient;

‎src/app/layout.tsx‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import type { Metadata } from "next";
22
import "modern-normalize/modern-normalize.css";
33
import "./globals.scss";
44
import GlobalSearch from "@/components/GlobalSearch";
5+
import OfflineDownload from "@/components/OfflineDownload";
56
import { SaveProvider } from "@/context/SaveContext";
67
import { PreferencesProvider } from "@/context/PreferencesContext";
8+
import { ToastProvider } from "@/context/ToastContext";
79

810
export const metadata: Metadata = {
911
metadataBase: new URL(
@@ -30,8 +32,11 @@ export default function RootLayout({
3032
<body>
3133
<PreferencesProvider>
3234
<SaveProvider>
33-
{children}
34-
<GlobalSearch />
35+
<ToastProvider>
36+
{children}
37+
<GlobalSearch />
38+
<OfflineDownload />
39+
</ToastProvider>
3540
</SaveProvider>
3641
</PreferencesProvider>
3742
</body>

‎src/app/page.tsx‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import Link from "next/link";
22
import styles from "./page.module.scss";
3-
import OfflineDownload from "@/components/OfflineDownload";
43

54
export default function Home() {
65
return (
@@ -33,8 +32,6 @@ export default function Home() {
3332
</ul>
3433
</div>
3534
</div>
36-
37-
<OfflineDownload />
3835
</main>
3936
);
4037
}

‎src/components/Card.module.scss‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1+
@use "../styles/mixins" as *;
2+
13
.card {
2-
border-image-outset: 0px 0px 0px 0px;
3-
border-image-repeat: round round;
4-
border-image-slice: 21 22 20 22 fill;
5-
border-image-source: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIcAAAA+CAYAAAABIgi3AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJoSURBVHgB7d1BTjJBEIbhGkLyJz87484Yd1zEA+hJXHoIl55ED+BF2BnDzugKt2MkAZvJfDQN1djTvM9GBdLdCZWqnmJsGjNr7XBN5Pmcc+Qae4hrdp1jZIBAcEAah38831/brm4eXmwfOefINfYQ1+wxB5kDEsEBaaye6EthW9KTx+47JuccucYubs0p7yuZAxLBAWlsDlJ2wyWMm3PsUta875VNiMwBSWaOlCi9e5rNDKWZ9j2Y8r6SOSARHJB+Ptk7+Fr8anpJWSnM6+xtagcic0AiOCB1bxhZl5jJZLL8eX5xRsmo0Pv8Y1l2FotF+PBGPJA5IBEckLbdh7gsMavy8oMSM2ziCkbGgMtnKynatv2/+r1pmi/7I6wjjrICKZo5wt3suZ0ZhivcInSuUnplKythukx5zS6pNSUVs479UVYgdTMHTbCKbbyXc1s1wcLP1jauXLKVlTC97ZJS+9KhRypOWYdKyTWtIwVlBRLBAekoTTCPHfQuaTk2D+tI0w2O9YZkvVGZ/96LyOZ02Kptn6dsxnL2BmpdRx/2HJBon5+QqtrnOXslTdv+W78mMlZN60hBWYFE+/yEDKp97tFSTlpTkMKjz4v5alpHDGUFEsEBqZj2ea40uVG6Yi8ejT4tk1LWkeLoHVKUIexzrC4+ur0Pygqkk8ocpdz6X9q/ICgcwVApjmBAVgQHpKMfjI/j42B8uCM4ILkcjP94Oz14ZwxfNw9v4nEOxocDlyZY7d96NPRvatoXmQMSwQHJ5WB8M75XNmHc3GNvnYOD8eGC4IDk8qmsUVZSxs09ttscZA5IBAekb1eiZU9JPLoUAAAAAElFTkSuQmCC");
6-
border-image-width: 20px 22px 20px 22px;
7-
border-style: solid;
4+
@include card-border;
85
display: flex;
96
flex-direction: column;
107
flex: 1 1 0%;
118
font-size: 2.6rem;
12-
image-rendering: -webkit-optimize-contrast;
13-
image-rendering: crisp-edges;
14-
image-rendering: pixelated;
159
overflow: hidden;
1610
padding: 2.6rem 2rem;
1711
position: relative;

0 commit comments

Comments
 (0)