mirror of
				https://github.com/r-freeman/portfolio.git
				synced 2025-11-04 15:51:11 +00:00 
			
		
		
		
	More comment improvements
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build And Publish / BuildAndPublish (push) Successful in 3m13s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build And Publish / BuildAndPublish (push) Successful in 3m13s
				
			This commit is contained in:
		
							parent
							
								
									ed815cf9a3
								
							
						
					
					
						commit
						43d3f673a6
					
				@ -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=
 | 
			
		||||
 | 
			
		||||
@ -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}`
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
@ -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()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ export default function CommentFormProvider({children}: { children: ReactNode })
 | 
			
		||||
    const [replyTo, setReplyTo] = useState<Comment | null>(null)
 | 
			
		||||
    const [commentLength, setCommentLength] = useState<number>(0)
 | 
			
		||||
    const commentFormRef = useRef<HTMLTextAreaElement>(null)
 | 
			
		||||
    const commentMaxLength = 300
 | 
			
		||||
    const commentMaxLength = 500
 | 
			
		||||
 | 
			
		||||
    const focusCommentForm = () => {
 | 
			
		||||
        commentFormRef.current?.focus()
 | 
			
		||||
 | 
			
		||||
@ -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 (
 | 
			
		||||
        <>
 | 
			
		||||
            <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}
 | 
			
		||||
                       className={clsx('rounded-full', isReply ? 'size-8' : 'size-12')}/>
 | 
			
		||||
                <div className="flex-auto">
 | 
			
		||||
@ -87,8 +88,9 @@ Comments.List = function List({comments}: CommentsListProps) {
 | 
			
		||||
                        <React.Fragment key={comment.id}>
 | 
			
		||||
                            <Comments.Comment comment={comment}/>
 | 
			
		||||
                            {(typeof comment.replies !== 'undefined' && comment.replies.length > 0) ?
 | 
			
		||||
                                comment.replies.map(reply => (
 | 
			
		||||
                                    <Comments.Comment key={reply.id} comment={reply} isReply={true}/>
 | 
			
		||||
                                comment.replies.map((reply, i) => (
 | 
			
		||||
                                    <Comments.Comment key={reply.id} comment={reply} isReply={true}
 | 
			
		||||
                                                      className={`${i + 1 === comment.replies?.length ? 'mb-6' : ''}`}/>
 | 
			
		||||
                                )) : null
 | 
			
		||||
                            }
 | 
			
		||||
                        </React.Fragment>
 | 
			
		||||
 | 
			
		||||
@ -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]
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user