mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 03:05:24 -04:00
have hit counter start at zero during suspense, then count up
This commit is contained in:
parent
bbf6e9dc66
commit
0080c4925b
@ -4,6 +4,7 @@
|
||||
[](https://nextjs.org/)
|
||||
[](LICENSE)
|
||||
[](https://github.com/jakejarvis/jarv.is)
|
||||
[](https://jarv.is/api/hits)
|
||||
|
||||
My humble abode on the World Wide Web, created and deployed using [Next.js](https://nextjs.org/), [Vercel](https://vercel.com/), [Upstash Redis](https://upstash.com/), [Giscus](https://giscus.app/), [Umami](https://umami.is/), [and more](https://jarv.is/humans.txt).
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { connection } from "next/server";
|
||||
import commaNumber from "comma-number";
|
||||
import CountUp from "../../../components/CountUp";
|
||||
import redis from "../../../lib/helpers/redis";
|
||||
|
||||
const HitCounter = async ({ slug }: { slug: string }) => {
|
||||
@ -9,7 +10,11 @@ const HitCounter = async ({ slug }: { slug: string }) => {
|
||||
const hits = await redis.incr(slug);
|
||||
|
||||
// we have data!
|
||||
return <span title={`${commaNumber(hits)} ${hits === 1 ? "view" : "views"}`}>{commaNumber(hits)}</span>;
|
||||
return (
|
||||
<span title={`${commaNumber(hits)} ${hits === 1 ? "view" : "views"}`}>
|
||||
<CountUp start={0} end={hits} delay={0} duration={2.5} />
|
||||
</span>
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("[hit counter] fatal error:", error);
|
||||
|
||||
|
@ -17,10 +17,10 @@
|
||||
}
|
||||
|
||||
.meta .metaIcon {
|
||||
display: inline;
|
||||
display: inline-block;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
vertical-align: -0.2em;
|
||||
vertical-align: -0.25em;
|
||||
margin-right: 0.6em;
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,11 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
|
||||
}}
|
||||
>
|
||||
<EyeIcon size="1.2em" className={styles.metaIcon} />
|
||||
<Suspense fallback={<Loading boxes={3} width={20} />}>
|
||||
<Suspense
|
||||
// when this loads, the component will count up from zero to the actual number of hits, so we can simply
|
||||
// show a zero here as a "loading indicator"
|
||||
fallback={<span>0</span>}
|
||||
>
|
||||
<HitCounter slug={`notes/${frontmatter!.slug}`} />
|
||||
</Suspense>
|
||||
</div>
|
||||
|
5
components/CountUp/index.ts
Normal file
5
components/CountUp/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
"use client";
|
||||
|
||||
// marking the library as a proper client component so that react doesn't complain about hydration whenever we use it in
|
||||
// a server component.
|
||||
export { default } from "react-countup";
|
@ -1,6 +1,7 @@
|
||||
import { Redis } from "@upstash/redis";
|
||||
|
||||
// Initialize Redis
|
||||
// pulls credentials (prefixed with 'KV_REST_API_') set automatically by Vercel marketplace integration:
|
||||
// https://github.com/upstash/redis-js/blob/091e0a0949593d74b905f41f7cb409ada16f936f/platforms/nodejs.ts#L184
|
||||
const redis = Redis.fromEnv();
|
||||
|
||||
export default redis;
|
||||
|
@ -44,6 +44,7 @@
|
||||
"polished": "^4.3.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "19.0.0",
|
||||
"react-countup": "^6.5.3",
|
||||
"react-dom": "19.0.0",
|
||||
"react-error-boundary": "^5.0.0",
|
||||
"react-innertext": "^1.1.5",
|
||||
|
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@ -89,6 +89,9 @@ importers:
|
||||
react:
|
||||
specifier: 19.0.0
|
||||
version: 19.0.0
|
||||
react-countup:
|
||||
specifier: ^6.5.3
|
||||
version: 6.5.3(react@19.0.0)
|
||||
react-dom:
|
||||
specifier: 19.0.0
|
||||
version: 19.0.0(react@19.0.0)
|
||||
@ -1320,6 +1323,9 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
countup.js@2.8.0:
|
||||
resolution: {integrity: sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ==}
|
||||
|
||||
cross-env@7.0.3:
|
||||
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
|
||||
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
|
||||
@ -2910,6 +2916,11 @@ packages:
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
react-countup@6.5.3:
|
||||
resolution: {integrity: sha512-udnqVQitxC7QWADSPDOxVWULkLvKUWrDapn5i53HE4DPRVgs+Y5rr4bo25qEl8jSh+0l2cToJgGMx+clxPM3+w==}
|
||||
peerDependencies:
|
||||
react: '>= 16.3.0'
|
||||
|
||||
react-dom@19.0.0:
|
||||
resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
|
||||
peerDependencies:
|
||||
@ -4835,6 +4846,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
typescript: 5.8.2
|
||||
|
||||
countup.js@2.8.0: {}
|
||||
|
||||
cross-env@7.0.3:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
@ -6946,6 +6959,11 @@ snapshots:
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
react-countup@6.5.3(react@19.0.0):
|
||||
dependencies:
|
||||
countup.js: 2.8.0
|
||||
react: 19.0.0
|
||||
|
||||
react-dom@19.0.0(react@19.0.0):
|
||||
dependencies:
|
||||
react: 19.0.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user