2023-01-03 11:55:46 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Copyright 2021 Signal Messenger, LLC
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// SPDX-License-Identifier: AGPL-3.0-only
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-11-17 16:45:19 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import type { ReactElement } from 'react';
							 | 
						
					
						
							
								
									
										
										
										
											2021-10-26 14:15:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import React, { useRef, useState, useEffect } from 'react';
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import classNames from 'classnames';
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-09 10:38:57 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import type { VideoFrameSource } from '@signalapp/ringrtc';
							 | 
						
					
						
							
								
									
										
										
										
											2021-10-26 14:15:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import type { LocalizerType } from '../types/Util';
							 | 
						
					
						
							
								
									
										
										
										
											2021-09-28 11:37:03 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import type { GroupCallRemoteParticipantType } from '../types/Calling';
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import { GroupCallRemoteParticipant } from './GroupCallRemoteParticipant';
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-07 11:21:57 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import type { CallingImageDataCache } from './CallManager';
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const OVERFLOW_SCROLLED_TO_EDGE_THRESHOLD = 20;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const OVERFLOW_SCROLL_BUTTON_RATIO = 0.75;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// This should be an integer, as sub-pixel widths can cause performance issues.
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-25 06:40:22 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								export const OVERFLOW_PARTICIPANT_WIDTH = 107;
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-11 12:06:43 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								export type PropsType = {
							 | 
						
					
						
							
								
									
										
										
										
											2021-12-10 16:21:28 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  getFrameBuffer: () => Buffer;
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  i18n: LocalizerType;
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-07 11:21:57 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  imageDataCache: React.RefObject<CallingImageDataCache>;
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-16 13:58:51 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  isCallReconnecting: boolean;
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-01 14:12:49 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  joinedAt: number | null;
							 | 
						
					
						
							
								
									
										
										
										
											2023-12-11 07:10:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  onClickRaisedHand?: () => void;
							 | 
						
					
						
							
								
									
										
										
										
											2021-12-06 17:06:13 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  onParticipantVisibilityChanged: (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    demuxId: number,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    isVisible: boolean
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  ) => unknown;
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  overflowedParticipants: ReadonlyArray<GroupCallRemoteParticipantType>;
							 | 
						
					
						
							
								
									
										
										
										
											2022-05-18 20:28:51 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  remoteAudioLevels: Map<number, number>;
							 | 
						
					
						
							
								
									
										
										
										
											2023-03-22 10:53:13 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  remoteParticipantsCount: number;
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-14 12:07:05 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-11-17 16:45:19 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								export function GroupCallOverflowArea({
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  getFrameBuffer,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  getGroupCallVideoFrameSource,
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-07 11:21:57 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  imageDataCache,
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  i18n,
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-16 13:58:51 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  isCallReconnecting,
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-01 14:12:49 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  joinedAt,
							 | 
						
					
						
							
								
									
										
										
										
											2023-12-11 07:10:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  onClickRaisedHand,
							 | 
						
					
						
							
								
									
										
										
										
											2021-12-06 17:06:13 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  onParticipantVisibilityChanged,
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  overflowedParticipants,
							 | 
						
					
						
							
								
									
										
										
										
											2022-05-18 20:28:51 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  remoteAudioLevels,
							 | 
						
					
						
							
								
									
										
										
										
											2023-03-22 10:53:13 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  remoteParticipantsCount,
							 | 
						
					
						
							
								
									
										
										
										
											2022-11-17 16:45:19 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}: PropsType): JSX.Element | null {
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const overflowRef = useRef<HTMLDivElement | null>(null);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const [overflowScrollTop, setOverflowScrollTop] = useState(0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // This assumes that these values will change along with re-renders. If that's not true,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  //   we should add these values to the component's state.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  let visibleHeight: number;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  let scrollMax: number;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (overflowRef.current) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    visibleHeight = overflowRef.current.clientHeight;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    scrollMax = overflowRef.current.scrollHeight - visibleHeight;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    visibleHeight = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    scrollMax = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const hasOverflowedParticipants = Boolean(overflowedParticipants.length);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  useEffect(() => {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // If there aren't any overflowed participants, we want to clear the scroll position
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    //   so we don't hold onto stale values.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (!hasOverflowedParticipants) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      setOverflowScrollTop(0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }, [hasOverflowedParticipants]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (!hasOverflowedParticipants) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return null;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const isScrolledToTop =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    overflowScrollTop < OVERFLOW_SCROLLED_TO_EDGE_THRESHOLD;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const isScrolledToBottom =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    overflowScrollTop > scrollMax - OVERFLOW_SCROLLED_TO_EDGE_THRESHOLD;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  return (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    <div
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      className="module-ongoing-call__participants__overflow"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      style={{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // This width could live in CSS but we put it here to avoid having to keep two
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        //   values in sync.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        width: OVERFLOW_PARTICIPANT_WIDTH,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      }}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    >
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      <OverflowAreaScrollMarker
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        i18n={i18n}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        isHidden={isScrolledToTop}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        onClick={() => {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          const el = overflowRef.current;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          if (!el) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          el.scrollTo({
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            top: Math.max(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              el.scrollTop - visibleHeight * OVERFLOW_SCROLL_BUTTON_RATIO,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            ),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            left: 0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            behavior: 'smooth',
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        placement="top"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      />
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      <div
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        className="module-ongoing-call__participants__overflow__inner"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ref={overflowRef}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        onScroll={() => {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          // Ideally this would use `event.target.scrollTop`, but that does not seem to be
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          //   available, so we use the ref.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          const el = overflowRef.current;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          if (!el) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          setOverflowScrollTop(el.scrollTop);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      >
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {overflowedParticipants.map(remoteParticipant => (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          <GroupCallRemoteParticipant
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            key={remoteParticipant.demuxId}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            getFrameBuffer={getFrameBuffer}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-07 11:21:57 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            imageDataCache={imageDataCache}
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            i18n={i18n}
							 | 
						
					
						
							
								
									
										
										
										
											2022-05-18 20:28:51 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            audioLevel={remoteAudioLevels.get(remoteParticipant.demuxId) ?? 0}
							 | 
						
					
						
							
								
									
										
										
										
											2023-12-11 07:10:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            onClickRaisedHand={onClickRaisedHand}
							 | 
						
					
						
							
								
									
										
										
										
											2021-12-06 17:06:13 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            onVisibilityChanged={onParticipantVisibilityChanged}
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            width={OVERFLOW_PARTICIPANT_WIDTH}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            height={Math.floor(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              OVERFLOW_PARTICIPANT_WIDTH / remoteParticipant.videoAspectRatio
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            )}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            remoteParticipant={remoteParticipant}
							 | 
						
					
						
							
								
									
										
										
										
											2023-03-22 10:53:13 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            remoteParticipantsCount={remoteParticipantsCount}
							 | 
						
					
						
							
								
									
										
										
										
											2023-03-22 14:54:11 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            isActiveSpeakerInSpeakerView={false}
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-16 13:58:51 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            isCallReconnecting={isCallReconnecting}
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-25 06:50:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            isInOverflow
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-01 14:12:49 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            joinedAt={joinedAt}
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          />
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ))}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      </div>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      <OverflowAreaScrollMarker
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        i18n={i18n}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        isHidden={isScrolledToBottom}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        onClick={() => {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          const el = overflowRef.current;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          if (!el) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          el.scrollTo({
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            top: Math.min(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              el.scrollTop + visibleHeight * OVERFLOW_SCROLL_BUTTON_RATIO,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              scrollMax
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            ),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            left: 0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            behavior: 'smooth',
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        placement="bottom"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      />
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    </div>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							
								
									
										
										
										
											2022-11-17 16:45:19 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								function OverflowAreaScrollMarker({
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  i18n,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  isHidden,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  onClick,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  placement,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}: {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  i18n: LocalizerType;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  isHidden: boolean;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  onClick: () => void;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  placement: 'top' | 'bottom';
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}): ReactElement {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const baseClassName =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    'module-ongoing-call__participants__overflow__scroll-marker';
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  return (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    <div
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      className={classNames(baseClassName, `${baseClassName}--${placement}`, {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        [`${baseClassName}--hidden`]: isHidden,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      })}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    >
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      <button
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        type="button"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        className={`${baseClassName}__button`}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        onClick={onClick}
							 | 
						
					
						
							
								
									
										
										
										
											2023-03-28 11:26:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        aria-label={
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          placement === 'top'
							 | 
						
					
						
							
								
									
										
										
										
											2023-03-29 17:03:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            ? i18n('icu:calling__overflow__scroll-up')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            : i18n('icu:calling__overflow__scroll-down')
							 | 
						
					
						
							
								
									
										
										
										
											2023-03-28 11:26:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-08 12:58:28 -06:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      />
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    </div>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |