Skip to content

Commit e537800

Browse files
overengineered view counter
1 parent ce926c0 commit e537800

File tree

14 files changed

+30
-54
lines changed

14 files changed

+30
-54
lines changed

app/Home.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { formatDate } from 'pliny/utils/formatDate'
55
import NewsletterForm from 'pliny/ui/NewsletterForm'
66
import { CoreContent } from 'pliny/utils/contentlayer'
77
import { Blog } from 'contentlayer/generated'
8+
import { PostViews } from '@/components/post-views'
89

910
export function Home({
1011
posts,
@@ -36,7 +37,7 @@ export function Home({
3637
<li key={slug} className="py-12">
3738
<article>
3839
<div className="space-y-2 xl:grid xl:grid-cols-4 xl:items-baseline xl:space-x-6 xl:space-y-0">
39-
<dl className="flex flex-row items-center justify-start gap-4 xl:flex-col xl:items-end xl:gap-3">
40+
<dl className="flex flex-row items-center justify-start gap-4 font-mono xl:flex-col xl:items-end xl:gap-3">
4041
<div className="">
4142
<dt className="sr-only">Published on</dt>
4243
<dd className="text-base font-medium text-muted-foreground">
@@ -47,7 +48,7 @@ export function Home({
4748
<div className="">
4849
<dt className="sr-only ">View count</dt>
4950
<dd className="flex flex-row items-center gap-1 text-base font-medium text-muted-foreground">
50-
{viewCount} views
51+
<PostViews slug={slug} prev={viewCount} />
5152
</dd>
5253
</div>
5354
)}

app/actions.ts

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,9 @@
11
'use server'
22

3-
import { unstable_cache } from 'next/cache'
3+
import { revalidateTag, unstable_cache, unstable_noStore } from 'next/cache'
44

55
import { db } from '@/lib/db'
66

7-
export async function upsertPost(slug: string) {
8-
if (!db) {
9-
return null
10-
}
11-
const result = await db.post.upsert({
12-
where: {
13-
slug,
14-
},
15-
create: {
16-
slug,
17-
views: 0,
18-
},
19-
update: {},
20-
})
21-
return result
22-
}
23-
24-
export async function updatePostViews({ slug }: { slug: string }) {
25-
if (!db) {
26-
return null
27-
}
28-
const result = await db.post.update({
29-
where: {
30-
slug: slug,
31-
},
32-
data: {
33-
views: {
34-
increment: 1,
35-
},
36-
},
37-
})
38-
return result.views
39-
}
40-
417
export async function upsertIncreasePostViews({ slug }: { slug: string }) {
428
if (!db) {
439
return null
@@ -56,6 +22,7 @@ export async function upsertIncreasePostViews({ slug }: { slug: string }) {
5622
},
5723
},
5824
})
25+
revalidateTag('post-views')
5926
return result
6027
}
6128

@@ -74,7 +41,6 @@ export async function getPostViews({ slug }: { slug: string }) {
7441

7542
export const getAllViews = unstable_cache(getAllViewsInternal, ['post-views'], {
7643
tags: ['post-views'],
77-
revalidate: 3600, // TODO: Fine tune views revalidation time for a better user experience
7844
})
7945

8046
async function getAllViewsInternal() {

app/blog/[...slug]/page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import siteMetadata from '@/data/siteMetadata'
1313
import { notFound } from 'next/navigation'
1414
import { getPostViews } from '@/app/actions'
1515

16+
export const experimental_ppr = true
17+
1618
const defaultLayout = 'PostLayout'
1719
const layouts = {
1820
PostSimple,

bun.lockb

4.47 KB
Binary file not shown.

components/navigation-events.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function NavigationEvents() {
88

99
useEffect(() => {
1010
// TODO: create simpler logic
11-
const slug = pathname?.split('/blog/').slice(1).join('/')
11+
const slug = pathname?.split('/blog/').slice(1).join('/').split('#')[0]
1212

1313
if (slug && process.env.NODE_ENV === 'production') {
1414
fetch('/api/posts/' + slug, {

components/post-views.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import { Suspense } from 'react'
22

33
import { getPostViews } from '@/app/actions'
4+
import { unstable_noStore } from 'next/cache'
45

5-
export function PostViews({ slug }: { slug: string }) {
6+
export function PostViews({ slug, prev }: { slug: string; prev: number }) {
67
return (
7-
<span title="views">
8-
<Suspense fallback={<>{'...'}</>}>
8+
<span>
9+
<Suspense fallback={<>{prev}</>}>
910
<ViewCount slug={slug} />
1011
</Suspense>{' '}
1112
views
1213
</span>
1314
)
1415
}
1516

16-
export async function ViewCount({ slug }: { slug: string }) {
17+
async function ViewCount({ slug }: { slug: string }) {
18+
unstable_noStore()
19+
// 1 sec delay to not switch abruptly on load
20+
await new Promise((resolve) => setTimeout(resolve, 1000))
1721
const count = await getPostViews({ slug })
1822
return <>{count != null ? count : '-'}</>
1923
}

layouts/ListLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export default function ListLayout({
117117
return (
118118
<li key={path} className="py-4">
119119
<article className="space-y-2 xl:grid xl:grid-cols-4 xl:items-baseline xl:space-y-0">
120-
<dl className=" flex flex-row items-center justify-start gap-4">
120+
<dl className="flex flex-row items-center justify-start gap-4 font-mono">
121121
<dt className="sr-only">Published on</dt>
122122
<dd className="text-sm font-medium text-muted-foreground">
123123
<time dateTime={date} suppressHydrationWarning>

layouts/ListLayoutWithTags.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export default function ListLayoutWithTags({
125125
return (
126126
<li key={path} className="py-5">
127127
<article className="flex flex-col space-y-2">
128-
<dl className=" flex flex-row items-center justify-start gap-4">
128+
<dl className="flex flex-row items-center justify-start gap-4 font-mono">
129129
<dt className="sr-only">Published on</dt>
130130
<dd className="text-sm font-medium text-muted-foreground">
131131
<time dateTime={date} suppressHydrationWarning>

layouts/PostBanner.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ interface LayoutProps {
1717
prev?: { path: string; title: string }
1818
}
1919

20-
export default function PostMinimal({ content, next, prev, children }: LayoutProps) {
20+
export default function PostBanner({ content, next, prev, children }: LayoutProps) {
2121
const { slug, title, images } = content
2222
const displayImage =
2323
images && images.length > 0 ? images[0] : 'https://picsum.photos/seed/picsum/800/400'

layouts/PostLayout.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import Image from '@/components/Image'
99
import Tag from '@/components/Tag'
1010
import siteMetadata from '@/data/siteMetadata'
1111
import ScrollTopAndComment from '@/components/ScrollTopAndComment'
12-
import { Eye } from 'lucide-react'
1312
import { formatDate } from 'pliny/utils/formatDate'
13+
import { PostViews } from '@/components/post-views'
1414

1515
const editUrl = (path) => `${siteMetadata.siteRepo}/blob/main/data/${path}`
1616
const discussUrl = (path) =>
@@ -41,7 +41,7 @@ export default function PostLayout({ content, authorDetails, next, prev, childre
4141
<div className="xl:divide-y xl:divide-border">
4242
<header className="pt-6 xl:pb-6">
4343
<div className="space-y-1 text-center">
44-
<dl className="mb-1 flex flex-row items-center justify-start gap-4">
44+
<dl className="mb-1 flex flex-row items-center justify-start gap-4 font-mono">
4545
<div className="">
4646
<dt className="sr-only">Published on</dt>
4747
<dd className="text-sm font-medium text-muted-foreground">
@@ -52,7 +52,7 @@ export default function PostLayout({ content, authorDetails, next, prev, childre
5252
<div className="">
5353
<dt className="sr-only ">View count</dt>
5454
<dd className="flex flex-row items-center gap-1 text-sm font-medium text-muted-foreground">
55-
{viewCount} views
55+
<PostViews slug={slug} prev={viewCount} />
5656
</dd>
5757
</div>
5858
)}

0 commit comments

Comments
 (0)