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 10e53cb..3c65502 100644 Binary files a/.env.gpg and b/.env.gpg differ 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