update
This commit is contained in:
101
frontend/src/components/chat/MessageReactions.tsx
Normal file
101
frontend/src/components/chat/MessageReactions.tsx
Normal 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;
|
||||
Reference in New Issue
Block a user