More comment improvements
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m9s

This commit is contained in:
Ryan Freeman 2025-04-26 13:41:29 +01:00
parent ed815cf9a3
commit 7024f5a362
6 changed files with 15 additions and 15 deletions

View File

@ -3,6 +3,7 @@ SPOTIFY_CLIENT_SECRET=
SPOTIFY_REFRESH_TOKEN= SPOTIFY_REFRESH_TOKEN=
NEXT_PUBLIC_SITE_URL= NEXT_PUBLIC_SITE_URL=
GITHUB_ACCESS_TOKEN= GITHUB_ACCESS_TOKEN=
GITHUB_USER_ID=
GITHUB_USERNAME= GITHUB_USERNAME=
GITHUB_CLIENT_ID= GITHUB_CLIENT_ID=
GITHUB_SECRET= GITHUB_SECRET=

BIN
.env.gpg

Binary file not shown.

View File

@ -4,6 +4,7 @@ import {auth, signIn} from '@/auth'
import {createClient} from '@/lib/supabase/server' import {createClient} from '@/lib/supabase/server'
import {z} from 'zod' import {z} from 'zod'
import {sendNotification} from '@/lib/ntfy' import {sendNotification} from '@/lib/ntfy'
import {extractUserId} from '@/lib/github'
export async function loginWithGitHub() { export async function loginWithGitHub() {
await signIn('github') await signIn('github')
@ -22,15 +23,6 @@ const notificationBody = (comment: { id: number, content: string }, user: { name
headers: { headers: {
Authorization: `Bearer ${process.env.NTFY_TOKEN}` 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}`
}
} }
] ]
} }
@ -64,6 +56,7 @@ export async function addComment(prevState: { message: string }, formData: FormD
try { try {
const supabase = await createClient() const supabase = await createClient()
const session = await auth() const session = await auth()
const isMe = process.env.GITHUB_USER_ID === extractUserId(session?.user?.image ?? '')
if (!session?.user) { if (!session?.user) {
return {message: authorisation_error} return {message: authorisation_error}
@ -78,7 +71,7 @@ export async function addComment(prevState: { message: string }, formData: FormD
const {data: newComment, error} = await supabase const {data: newComment, error} = await supabase
.from('comments') .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('*') .select('*')
.single() .single()

View File

@ -19,7 +19,7 @@ export default function CommentFormProvider({children}: { children: ReactNode })
const [replyTo, setReplyTo] = useState<Comment | null>(null) const [replyTo, setReplyTo] = useState<Comment | null>(null)
const [commentLength, setCommentLength] = useState<number>(0) const [commentLength, setCommentLength] = useState<number>(0)
const commentFormRef = useRef<HTMLTextAreaElement>(null) const commentFormRef = useRef<HTMLTextAreaElement>(null)
const commentMaxLength = 300 const commentMaxLength = 500
const focusCommentForm = () => { const focusCommentForm = () => {
commentFormRef.current?.focus() commentFormRef.current?.focus()

View File

@ -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, comment: Comment,
isReply?: boolean isReply?: boolean
className?: string
}) { }) {
return ( return (
<> <>
<article <article
className={clsx('flex gap-x-4 py-5', isReply && 'ml-[66px] border-l border-zinc-100 pl-6 dark:border-zinc-700/40')}> className={clsx('flex gap-x-4 py-5', `${className ?? ''}`, isReply && 'ml-[66px] border-l border-zinc-100 pl-6 dark:border-zinc-700/40')}>
<Image src={comment.user.image} alt={comment.user.name} width={64} height={64} <Image src={comment.user.image} alt={comment.user.name} width={64} height={64}
className={clsx('rounded-full', isReply ? 'size-8' : 'size-12')}/> className={clsx('rounded-full', isReply ? 'size-8' : 'size-12')}/>
<div className="flex-auto"> <div className="flex-auto">
@ -87,8 +88,9 @@ Comments.List = function List({comments}: CommentsListProps) {
<React.Fragment key={comment.id}> <React.Fragment key={comment.id}>
<Comments.Comment comment={comment}/> <Comments.Comment comment={comment}/>
{(typeof comment.replies !== 'undefined' && comment.replies.length > 0) ? {(typeof comment.replies !== 'undefined' && comment.replies.length > 0) ?
comment.replies.map(reply => ( comment.replies.map((reply, i) => (
<Comments.Comment key={reply.id} comment={reply} isReply={true}/> <Comments.Comment key={reply.id} comment={reply} isReply={true}
className={`${i + 1 === comment.replies?.length && 'mb-6'}`}/>
)) : null )) : null
} }
</React.Fragment> </React.Fragment>

View File

@ -46,4 +46,8 @@ export async function getPinnedRepos() {
}) as PinnedReposResponse }) as PinnedReposResponse
return response.data.user.pinnedItems.nodes return response.data.user.pinnedItems.nodes
}
export function extractUserId(avatarUrl: string) {
return new URL(avatarUrl).pathname.split('/')[2]
} }