From b6c7dbdd71c4dcced3861db0b3a08181bb674107 Mon Sep 17 00:00:00 2001 From: Ryan Freeman Date: Sat, 26 Apr 2025 13:41:29 +0100 Subject: [PATCH] More comment improvements --- .env.example | 1 + .env.gpg | Bin 951 -> 961 bytes app/actions/comments.ts | 19 ++++++------------- app/context/CommentFormProvider.tsx | 2 +- components/ui/Comments.tsx | 10 ++++++---- lib/getComments.ts | 11 +++++------ lib/github.ts | 4 ++++ 7 files changed, 23 insertions(+), 24 deletions(-) diff --git a/.env.example b/.env.example index ac3f5b9..3c0509e 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,7 @@ SPOTIFY_CLIENT_SECRET= SPOTIFY_REFRESH_TOKEN= NEXT_PUBLIC_SITE_URL= GITHUB_ACCESS_TOKEN= +GITHUB_USER_ID= GITHUB_USERNAME= GITHUB_CLIENT_ID= GITHUB_SECRET= diff --git a/.env.gpg b/.env.gpg index 10e53cb0dda06b65ed42a5c83bc366ced97545ae..3c65502f29bbd61c971fd277700b6874b9437879 100644 GIT binary patch literal 961 zcmV;y13vtW4Fm@R0-JzcD6#;AukzCA0a^OlB}OM*k&#ACdc?IlZ(MD`2-rl=h#deer!Uc_M$m9rT$)B5-*Q zt?9t%cUUq-7d~f4SNat`Krb*Wci-l7(de=1efzP;W8z#V8=ZhCgx7+>Ol9OYe~-0g zJzconD1Sw2vCtK5j`0Yxgn9^CX{c)J)PzolKQ-M6?e#H&OMnUsK77bh>ySo8#Sf8^ zr1+$^`XO%DqA1TI_m4w;JrAZ~o+K(c&+t;t(heK^Tc}9BbGL@(8=~!|A!=1vzy0cS z8#)+JO82=1YJF!jq>!RUw3RAWI;nPH5bMx7(t)sk?y_vlkLG9X;=a<@pCn#S9M*Ju zCu9x8xI#L)ZrO)%xL$E$l)frT%P7nseqsqi6}DQ=9q5(oFrEK3PSR4n(s%0Cw%yg?OdGw z^i%|jX+)OKgS-Q-XxWViu!xL^zuwO9oP^zVP%68oIC^+7H670ayGbex;?$@H{Oqr2 z#$N)<83~{Z&OQsV$B`&%!0z>&aCMS2nDwwMnK}f-p>Q|&@(=HIgWMd->9aFU zS@~H%)@#7}z)hK-wK|+X6}o<#FkSC{9WamqDsx>@6bm*)9|J9kJ_Dt4b6@bW%cyK&v`oH0gQ=NbYU59WTv3g7 zm7WHB1v_xHfnLLq%R1NPHoT{C^OR_}r;q+@fFPZZ>E+eTDZbc_ta^gW< j8?qpZnv&h#(1Uw+Gwkd5JINV@9K`;}Hq}&46FD0{kXHkfvFDVS1ZW1ACz^5-)F6%YnVy{L<1eCRnTC4bm~Tt?Lj_BK3E+K(As@#+X#wi#?_o{Mrz z9Ip|v*|d&XUa;Ah&f3O}oTdQu_u0~S*OXxUSbJ7F^!1!Lo98QlP)>W(pTjV$!dg?} z6Rl+UPz9P&#S&0^s%sH+Rbqg3Hz$gh^Ru}c)iWex>FR7yd94w<7*jHL`gC?jx|$UB zUQ+3yu9PqC&A)jT5wN)gnw%=}kr`>Bdj&y&WKPRP`!d_nV%d&Px6BC}Dd_1pPin~t?`m{u|#^659_lJ zr=z4dnLp+(o4Ipbrmxn#4;3`SNyB)N0J{D~+hz19(Yl;Lw(>a?HM#iLNPJ zh2VTJ2-8hCdW}k2pa2H>z~met_@QP2m84gclf;2gq2b8;iaz+xY+h diff --git a/app/actions/comments.ts b/app/actions/comments.ts index 0c6bf9b..f0b8792 100644 --- a/app/actions/comments.ts +++ b/app/actions/comments.ts @@ -4,6 +4,7 @@ import {auth, signIn} from '@/auth' import {createClient} from '@/lib/supabase/server' import {z} from 'zod' import {sendNotification} from '@/lib/ntfy' +import {extractUserId} from '@/lib/github' export async function loginWithGitHub() { await signIn('github') @@ -22,15 +23,6 @@ const notificationBody = (comment: { id: number, content: string }, user: { name headers: { Authorization: `Bearer ${process.env.NTFY_TOKEN}` } - }, - { - action: 'http', - label: 'Delete comment', - url: `${process.env.NEXT_PUBLIC_SITE_URL}/api/comments/moderate/${comment.id}`, - method: 'DELETE', - headers: { - Authorization: `Bearer ${process.env.NTFY_TOKEN}` - } } ] } @@ -43,7 +35,7 @@ export async function addComment(prevState: { message: string }, formData: FormD const success_message = 'Your comment was submitted and is awaiting approval.' const schema = z.object({ - comment: z.string().min(1).max(300), + comment: z.string().min(1).max(500), slug: z.string(), parent_id: z.string().optional() }) @@ -54,7 +46,7 @@ export async function addComment(prevState: { message: string }, formData: FormD parent_id: formData.get('parent_id') } - const parse = schema.safeParse({comment, slug, parent_id}); + const parse = schema.safeParse({comment, slug, parent_id}) if (!parse.success) { return {message: validation_error} } @@ -64,6 +56,7 @@ export async function addComment(prevState: { message: string }, formData: FormD try { const supabase = await createClient() const session = await auth() + const isMe = process.env.GITHUB_USER_ID === extractUserId(session?.user?.image ?? '') if (!session?.user) { return {message: authorisation_error} @@ -78,7 +71,7 @@ export async function addComment(prevState: { message: string }, formData: FormD const {data: newComment, error} = await supabase .from('comments') - .insert({content: comment, article_id: article?.id, user_id: user?.id, parent_id: parent_id}) + .insert({content: comment, article_id: article?.id, user_id: user?.id, parent_id: parent_id, published: isMe}) .select('*') .single() @@ -86,7 +79,7 @@ export async function addComment(prevState: { message: string }, formData: FormD return {message: server_error} } - if (process.env.NODE_ENV === 'production') { + if (process.env.NODE_ENV === 'production' && !isMe) { await sendNotification(notificationBody(newComment, user, article)) } diff --git a/app/context/CommentFormProvider.tsx b/app/context/CommentFormProvider.tsx index 7220f8e..d4a8916 100644 --- a/app/context/CommentFormProvider.tsx +++ b/app/context/CommentFormProvider.tsx @@ -19,7 +19,7 @@ export default function CommentFormProvider({children}: { children: ReactNode }) const [replyTo, setReplyTo] = useState(null) const [commentLength, setCommentLength] = useState(0) const commentFormRef = useRef(null) - const commentMaxLength = 300 + const commentMaxLength = 500 const focusCommentForm = () => { commentFormRef.current?.focus() diff --git a/components/ui/Comments.tsx b/components/ui/Comments.tsx index 6201a05..7651bde 100644 --- a/components/ui/Comments.tsx +++ b/components/ui/Comments.tsx @@ -44,14 +44,15 @@ Comments.ReplyButton = function ReplyButton({comment}: ReplyButton) { ) } -Comments.Comment = function Comment({comment, isReply = false}: { +Comments.Comment = function Comment({comment, isReply = false, className}: { comment: Comment, isReply?: boolean + className?: string }) { return ( <>
+ className={clsx('flex gap-x-4 py-5', `${className ?? ''}`, isReply && 'ml-[66px] border-l border-zinc-100 pl-6 dark:border-zinc-700/40')}> {comment.user.name}
@@ -87,8 +88,9 @@ Comments.List = function List({comments}: CommentsListProps) { {(typeof comment.replies !== 'undefined' && comment.replies.length > 0) ? - comment.replies.map(reply => ( - + comment.replies.map((reply, i) => ( + )) : null } diff --git a/lib/getComments.ts b/lib/getComments.ts index c7d7e9e..c976e22 100644 --- a/lib/getComments.ts +++ b/lib/getComments.ts @@ -1,5 +1,6 @@ import {createClient} from '@/lib/supabase/client' import {QueryData} from '@supabase/supabase-js' +import type {Comment} from '@/types' export async function getComments(slug: string) { try { @@ -27,23 +28,21 @@ export async function getComments(slug: string) { // @ts-ignore acc[comment.id] = {...comment, replies: []} return acc - }, {}); + }, {}) return comments?.reduce((nested, comment) => { if (typeof commentMap !== 'undefined') { if (comment.parent_id !== null) { - const parent = commentMap[comment.parent_id]; + const parent: Comment = commentMap[comment.parent_id] if (parent) { - // @ts-ignore parent.replies?.push(commentMap[comment.id]) - // @ts-ignore parent.replies?.sort((a, b) => a.id - b.id) } } else { - nested.push(commentMap[comment.id]); + nested.push(commentMap[comment.id]) } } - return nested; + return nested }, []) } catch (error) { console.error(error) diff --git a/lib/github.ts b/lib/github.ts index 5ab3dc8..8f5fdda 100644 --- a/lib/github.ts +++ b/lib/github.ts @@ -46,4 +46,8 @@ export async function getPinnedRepos() { }) as PinnedReposResponse return response.data.user.pinnedItems.nodes +} + +export function extractUserId(avatarUrl: string) { + return new URL(avatarUrl).pathname.split('/')[2] } \ No newline at end of file