From bb6438a0b9252ecf515d1749a33cff0ee48d15df Mon Sep 17 00:00:00 2001 From: Matthias Hochmeister Date: Fri, 13 Mar 2026 15:59:21 +0100 Subject: [PATCH] update --- frontend/src/components/chat/ChatMessage.tsx | 39 ++++++++++++++++++-- sync/src/scraper.ts | 5 ++- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/chat/ChatMessage.tsx b/frontend/src/components/chat/ChatMessage.tsx index 7f1c52c..84e9047 100644 --- a/frontend/src/components/chat/ChatMessage.tsx +++ b/frontend/src/components/chat/ChatMessage.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useRef, useState } from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Paper from '@mui/material/Paper'; @@ -29,6 +29,35 @@ function hasPollParam(params?: Record): boolean { const ChatMessage: React.FC = ({ message, isOwnMessage, onReplyClick, onReactionToggled }) => { const [hovered, setHovered] = useState(false); + const longPressTimer = useRef | null>(null); + const hideTimer = useRef | null>(null); + + const handleTouchStart = () => { + longPressTimer.current = setTimeout(() => { + setHovered(true); + // Auto-hide after 4 seconds if the user doesn't interact + hideTimer.current = setTimeout(() => setHovered(false), 4000); + }, 500); + }; + + const handleTouchEnd = () => { + if (longPressTimer.current) { + clearTimeout(longPressTimer.current); + longPressTimer.current = null; + } + }; + + const handleTouchMove = () => { + if (longPressTimer.current) { + clearTimeout(longPressTimer.current); + longPressTimer.current = null; + } + if (hideTimer.current) { + clearTimeout(hideTimer.current); + hideTimer.current = null; + } + setHovered(false); + }; const time = new Date(message.timestamp * 1000).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', @@ -52,6 +81,7 @@ const ChatMessage: React.FC = ({ message, isOwnMessage, onRepl const reactions = message.reactions ?? {}; const reactionsSelf = message.reactionsSelf ?? []; + const hasReactions = Object.keys(reactions).length > 0; return ( = ({ message, isOwnMessage, onRepl }} onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} + onTouchStart={handleTouchStart} + onTouchEnd={handleTouchEnd} + onTouchMove={handleTouchMove} > {/* Reply button for own messages (shown on left) */} {isOwnMessage && onReplyClick && ( @@ -159,8 +192,8 @@ const ChatMessage: React.FC = ({ message, isOwnMessage, onRepl - {/* Reactions */} - {!message.systemMessage && ( + {/* Reactions — shown on hover or when reactions exist */} + {(hovered || hasReactions) && ( { - const browser = await chromium.launch({ headless: true }); + const browser = await chromium.launch({ + headless: true, + args: ['--disable-gpu', '--disable-software-rasterizer'], + }); const context = await browser.newContext({ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', });