This commit is contained in:
Matthias Hochmeister
2026-03-13 15:42:15 +01:00
parent 3dda069611
commit 75c919c063
13 changed files with 926 additions and 30 deletions

View File

@@ -0,0 +1,101 @@
import React, { useState } from 'react';
import Box from '@mui/material/Box';
import Tooltip from '@mui/material/Tooltip';
import Chip from '@mui/material/Chip';
import IconButton from '@mui/material/IconButton';
import Popover from '@mui/material/Popover';
import AddReactionOutlinedIcon from '@mui/icons-material/AddReactionOutlined';
import { nextcloudApi } from '../../services/nextcloud';
const QUICK_REACTIONS = ['\u{1F44D}', '\u2764\uFE0F', '\u{1F602}', '\u{1F62E}', '\u{1F622}', '\u{1F389}'];
interface MessageReactionsProps {
token: string;
messageId: number;
reactions: Record<string, number>;
reactionsSelf: string[];
onReactionToggled: () => void;
}
const MessageReactions: React.FC<MessageReactionsProps> = ({
token,
messageId,
reactions,
reactionsSelf,
onReactionToggled,
}) => {
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
const [loading, setLoading] = useState<string | null>(null);
const handleToggle = async (emoji: string) => {
setLoading(emoji);
try {
if (reactionsSelf.includes(emoji)) {
await nextcloudApi.removeReaction(token, messageId, emoji);
} else {
await nextcloudApi.addReaction(token, messageId, emoji);
}
onReactionToggled();
} catch {
// ignore
} finally {
setLoading(null);
}
};
const hasReactions = Object.keys(reactions).length > 0;
return (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.25, mt: 0.25, alignItems: 'center' }}>
{hasReactions && Object.entries(reactions).map(([emoji, count]) => (
<Chip
key={emoji}
label={`${emoji} ${count}`}
size="small"
onClick={() => handleToggle(emoji)}
disabled={loading === emoji}
sx={{
height: 20,
fontSize: '0.75rem',
cursor: 'pointer',
border: '1px solid',
borderColor: reactionsSelf.includes(emoji) ? 'primary.main' : 'transparent',
bgcolor: reactionsSelf.includes(emoji) ? 'primary.light' : 'action.hover',
'& .MuiChip-label': { px: 0.5 },
}}
/>
))}
<Tooltip title="Reaktion hinzuf\u00FCgen">
<IconButton
size="small"
onClick={(e) => setAnchorEl(e.currentTarget)}
sx={{ width: 20, height: 20, opacity: 0.6, '&:hover': { opacity: 1 } }}
>
<AddReactionOutlinedIcon sx={{ fontSize: '0.85rem' }} />
</IconButton>
</Tooltip>
<Popover
open={Boolean(anchorEl)}
anchorEl={anchorEl}
onClose={() => setAnchorEl(null)}
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'bottom', horizontal: 'left' }}
>
<Box sx={{ display: 'flex', p: 0.5, gap: 0.25 }}>
{QUICK_REACTIONS.map((emoji) => (
<IconButton
key={emoji}
size="small"
onClick={() => { handleToggle(emoji); setAnchorEl(null); }}
sx={{ fontSize: '1rem', minWidth: 32, minHeight: 32 }}
>
{emoji}
</IconButton>
))}
</Box>
</Popover>
</Box>
);
};
export default MessageReactions;