(frontend) add UI support for reaction limit on comments

Prevent users from adding more reactions once the per-message
limit has been exceeded. It Disables reaction buttons
when limit is reached

Signed-off-by: Mohamed El Amine BOUKERFA <boukerfa.ma@gmail.com>
This commit is contained in:
Mohamed El Amine BOUKERFA
2026-06-15 08:56:45 +02:00
committed by Manuel Raynaud
parent 867583a52a
commit 51364e3d3c
4 changed files with 27 additions and 5 deletions
+5 -3
View File
@@ -3234,9 +3234,11 @@ class CommentViewSet(
permission_classes = [permissions.CommentPermission]
pagination_class = Pagination
serializer_class = serializers.CommentSerializer
queryset = models.Comment.objects.select_related("user").prefetch_related(
"reactions__users"
).all()
queryset = (
models.Comment.objects.select_related("user")
.prefetch_related("reactions__users")
.all()
)
def get_queryset(self):
"""Override to filter on related resource."""
@@ -60,6 +60,7 @@ export interface ConfigResponse {
POSTHOG_HOST?: PostHogConf['host'];
RELEASE_VERSION: string;
SENTRY_DSN?: string;
REACTIONS_MAX_PER_COMMENT: number;
TRASHBIN_CUTOFF_DAYS?: number;
theme_customization?: ThemeCustomization;
}
@@ -6,6 +6,7 @@ export class DocsThreadStoreAuth extends ThreadStoreAuth {
constructor(
private readonly userId: string,
public canSee: boolean,
private readonly maxReactions: number,
) {
super();
}
@@ -67,13 +68,27 @@ export class DocsThreadStoreAuth extends ThreadStoreAuth {
}
if (!emoji) {
return true;
return comment.reactions.length < this.maxReactions;
}
return !comment.reactions.some(
const hasReactedWithEmoji = comment.reactions.some(
(reaction) =>
reaction.emoji === emoji && reaction.userIds.includes(this.userId),
);
if (hasReactedWithEmoji) {
return false;
}
const reactionExists = comment.reactions.some(
(reaction) => reaction.emoji === emoji,
);
if (reactionExists) {
return true;
}
return comment.reactions.length < this.maxReactions;
}
canDeleteReaction(comment: ClientCommentData, emoji?: string): boolean {
@@ -1,6 +1,7 @@
import { useCallback, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useConfig } from '@/core';
import { useCunninghamTheme } from '@/cunningham';
import { User, avatarUrlFromName } from '@/features/auth';
import { Doc, useProviderStore } from '@/features/docs/doc-management';
@@ -18,6 +19,7 @@ export function useComments(
const { t } = useTranslation();
const { themeTokens } = useCunninghamTheme();
const { setThreadStore } = useThreadStore();
const { data: config } = useConfig();
const threadStore = useMemo(() => {
return new DocsThreadStore(
@@ -26,6 +28,7 @@ export function useComments(
new DocsThreadStoreAuth(
encodeURIComponent(user?.full_name || ''),
canComment,
config?.REACTIONS_MAX_PER_COMMENT ?? 0,
),
provider?.document,
);
@@ -35,6 +38,7 @@ export function useComments(
provider?.awareness,
provider?.document,
user?.full_name,
config?.REACTIONS_MAX_PER_COMMENT,
]);
useEffect(() => {