@@ -354,6 +354,85 @@ export function useTimelineEventRenderer({
354354} : TimelineEventRendererOptions ) {
355355 const { t } = useTranslation ( ) ;
356356
357+ // Shared poll start renderer — used for both unstable and stable event types
358+ const renderPollStart = (
359+ mEventId : string ,
360+ mEvent : MatrixEvent ,
361+ item : number ,
362+ timelineSet : EventTimelineSet ,
363+ collapse : boolean
364+ ) => {
365+ const { getSender, getAssociatedStatus, isRedacted, getUnsigned } = mEvent ;
366+ const reactionRelations = getEventReactions ( timelineSet , mEventId ) ;
367+ const reactions = reactionRelations ?. getSortedAnnotationsByKey ( ) ;
368+ const hasReactions = reactions && reactions . length > 0 ;
369+ const highlighted = focusItem ?. index === item && focusItem . highlight ;
370+ const senderId = getSender . call ( mEvent ) ?? '' ;
371+ const senderDisplayName =
372+ getMemberDisplayName ( room , senderId , nicknames ) ?? getMxIdLocalPart ( senderId ) ?? senderId ;
373+ const myUserId = mx . getUserId ( ) ?? '' ;
374+ const canEnd = myUserId === senderId || canRedact ;
375+
376+ return (
377+ < Message
378+ key = { mEventId }
379+ data-message-item = { item }
380+ data-message-id = { mEventId }
381+ room = { room }
382+ mEvent = { mEvent }
383+ messageSpacing = { messageSpacing }
384+ messageLayout = { messageLayout }
385+ highlight = { highlighted }
386+ canDelete = { canRedact || ( canDeleteOwn && senderId === myUserId ) }
387+ canSendReaction = { canSendReaction }
388+ canPinEvent = { canPinEvent }
389+ imagePackRooms = { imagePackRooms }
390+ relations = { hasReactions ? reactionRelations : undefined }
391+ onUserClick = { onUserClick }
392+ onUsernameClick = { onUsernameClick }
393+ onReplyClick = { onReplyClick }
394+ onReactionToggle = { onReactionToggle }
395+ onEditId = { onEditId }
396+ senderId = { senderId }
397+ activeReplyId = { activeReplyId }
398+ senderDisplayName = { senderDisplayName }
399+ sendStatus = { getAssociatedStatus . call ( mEvent ) }
400+ onResend = { onResend }
401+ onDeleteFailedSend = { onDeleteFailedSend }
402+ collapse = { collapse }
403+ reactions = {
404+ reactionRelations ? (
405+ < Reactions
406+ style = { { marginTop : config . space . S200 } }
407+ room = { room }
408+ relations = { reactionRelations }
409+ mEventId = { mEventId }
410+ canSendReaction = { canSendReaction }
411+ canDeleteOwn = { canDeleteOwn }
412+ onReactionToggle = { onReactionToggle }
413+ />
414+ ) : undefined
415+ }
416+ hideReadReceipts = { hideReads }
417+ showDeveloperTools = { showDeveloperTools }
418+ memberPowerTag = { getMemberPowerTag ( senderId ) }
419+ hour24Clock = { hour24Clock }
420+ dateFormatString = { dateFormatString }
421+ >
422+ { isRedacted . call ( mEvent ) ? (
423+ < RedactedContent reason = { getUnsigned . call ( mEvent ) . redacted_because ?. content . reason } />
424+ ) : (
425+ < PollEvent
426+ room = { room }
427+ mEvent = { mEvent }
428+ canEnd = { canEnd }
429+ outlined = { messageLayout === MessageLayout . Bubble }
430+ />
431+ ) }
432+ </ Message >
433+ ) ;
434+ } ;
435+
357436 return useMatrixEventRenderer < [ string , MatrixEvent , number , EventTimelineSet , boolean ] > (
358437 {
359438 [ EventType . RoomMessage ] : ( mEventId , mEvent , item , timelineSet , collapse ) => {
@@ -1133,81 +1212,15 @@ export function useTimelineEventRenderer({
11331212 </ Event >
11341213 ) ;
11351214 } ,
1136- [ MessageEvent . PollStart ] : ( mEventId , mEvent , item , timelineSet , collapse ) => {
1137- const { getSender, getAssociatedStatus, isRedacted, getUnsigned } = mEvent ;
1138- const reactionRelations = getEventReactions ( timelineSet , mEventId ) ;
1139- const reactions = reactionRelations ?. getSortedAnnotationsByKey ( ) ;
1140- const hasReactions = reactions && reactions . length > 0 ;
1141- const highlighted = focusItem ?. index === item && focusItem . highlight ;
1142- const senderId = getSender . call ( mEvent ) ?? '' ;
1143- const senderDisplayName =
1144- getMemberDisplayName ( room , senderId , nicknames ) ?? getMxIdLocalPart ( senderId ) ?? senderId ;
1145- const myUserId = mx . getUserId ( ) ?? '' ;
1146- const canEnd = myUserId === senderId || canRedact ;
1147-
1148- return (
1149- < Message
1150- key = { mEventId }
1151- data-message-item = { item }
1152- data-message-id = { mEventId }
1153- room = { room }
1154- mEvent = { mEvent }
1155- messageSpacing = { messageSpacing }
1156- messageLayout = { messageLayout }
1157- highlight = { highlighted }
1158- canDelete = { canRedact || ( canDeleteOwn && senderId === myUserId ) }
1159- canSendReaction = { canSendReaction }
1160- canPinEvent = { canPinEvent }
1161- imagePackRooms = { imagePackRooms }
1162- relations = { hasReactions ? reactionRelations : undefined }
1163- onUserClick = { onUserClick }
1164- onUsernameClick = { onUsernameClick }
1165- onReplyClick = { onReplyClick }
1166- onReactionToggle = { onReactionToggle }
1167- onEditId = { onEditId }
1168- senderId = { senderId }
1169- activeReplyId = { activeReplyId }
1170- senderDisplayName = { senderDisplayName }
1171- sendStatus = { getAssociatedStatus . call ( mEvent ) }
1172- onResend = { onResend }
1173- onDeleteFailedSend = { onDeleteFailedSend }
1174- collapse = { collapse }
1175- reactions = {
1176- reactionRelations ? (
1177- < Reactions
1178- style = { { marginTop : config . space . S200 } }
1179- room = { room }
1180- relations = { reactionRelations }
1181- mEventId = { mEventId }
1182- canSendReaction = { canSendReaction }
1183- canDeleteOwn = { canDeleteOwn }
1184- onReactionToggle = { onReactionToggle }
1185- />
1186- ) : undefined
1187- }
1188- hideReadReceipts = { hideReads }
1189- showDeveloperTools = { showDeveloperTools }
1190- memberPowerTag = { getMemberPowerTag ( senderId ) }
1191- hour24Clock = { hour24Clock }
1192- dateFormatString = { dateFormatString }
1193- >
1194- { isRedacted . call ( mEvent ) ? (
1195- < RedactedContent reason = { getUnsigned . call ( mEvent ) . redacted_because ?. content . reason } />
1196- ) : (
1197- < PollEvent
1198- room = { room }
1199- mEvent = { mEvent }
1200- canEnd = { canEnd }
1201- outlined = { messageLayout === MessageLayout . Bubble }
1202- />
1203- ) }
1204- </ Message >
1205- ) ;
1206- } ,
1215+ [ MessageEvent . PollStart ] : renderPollStart ,
1216+ [ MessageEvent . StablePollStart ] : renderPollStart ,
12071217 // Poll response and end events are not rendered individually —
12081218 // they update the poll via RoomEvent.Timeline listeners in PollEvent.
12091219 [ MessageEvent . PollResponse ] : ( ) => null ,
12101220 [ MessageEvent . PollEnd ] : ( ) => null ,
1221+ // Stable poll type aliases (m.poll.*)
1222+ [ MessageEvent . StablePollResponse ] : ( ) => null ,
1223+ [ MessageEvent . StablePollEnd ] : ( ) => null ,
12111224 } ,
12121225 ( mEventId , mEvent , item , timelineSet , collapse ) => {
12131226 if ( ! showHiddenEvents ) return null ;
0 commit comments