Let group admins delete the group's picture

Task #37: Add a "Remove picture" action next to the camera icon in the
group chat header so admins can clear a group's avatar back to the
default Users icon, not just replace it.

Implementation:
- artifacts/teaboy-os/src/pages/chat.tsx: Added a small X button overlay
  on the chat header avatar (positioned at -top-1 -end-1, mirrored for
  RTL). It only renders when the conversation is a group, the current
  user is an admin, and the group has an avatar set. Clicking it sends
  PATCH /api/conversations/:id with { avatarUrl: null } via the existing
  useUpdateConversation hook and invalidates the conversations list so
  both the chat header and conversation list fall back to the default
  Users fallback icon.
- Reused existing locale keys chat.removeAvatar (EN: "Remove picture",
  AR: "إزالة الصورة"), so it works in Arabic and English with no
  locale changes required.
- Backend (artifacts/api-server/src/routes/conversations.ts) and the
  generated UpdateConversationBody schema already accept avatarUrl:
  null, so no API or codegen changes were needed.

Notes / deviations:
- Pre-existing TypeScript errors in chat.tsx (codegen drift around
  useUpdateConversation, isMuted, isArchived, avatarUrl, etc.) are
  unrelated to this change; my new code follows the same patterns
  already used in this file and the dev server runs fine.

Replit-Task-Id: 03db94ee-51ff-4695-8347-07fe7d962c5d
This commit is contained in:
riyadhafraa
2026-04-21 09:09:18 +00:00
parent 8e14846772
commit c1b53dea8d
+26
View File
@@ -546,6 +546,32 @@ export default function ChatPage() {
)} )}
</label> </label>
)} )}
{selectedConv.isGroup && isAdminOfSelected && selectedConv.avatarUrl && (
<button
type="button"
onClick={() => {
if (!selectedConvId) return;
updateConv.mutate(
{ id: selectedConvId, data: { avatarUrl: null } },
{
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: getListConversationsQueryKey() });
},
onError: (err: Error) => {
toast({ title: t("chat.settings.saveFailed"), description: err.message, variant: "destructive" });
},
},
);
}}
disabled={isUploadingHeaderAvatar || updateConv.isPending}
className="absolute -top-1 -end-1 w-5 h-5 rounded-full bg-white border border-slate-200 shadow-sm flex items-center justify-center text-slate-600 hover:text-destructive disabled:opacity-50"
aria-label={t("chat.removeAvatar")}
title={t("chat.removeAvatar")}
data-testid="button-remove-group-avatar"
>
<X size={10} />
</button>
)}
</div> </div>
) : ( ) : (
<MessageCircle size={20} className="text-green-400 shrink-0" /> <MessageCircle size={20} className="text-green-400 shrink-0" />