Function MeetingProgressTimer

MeetingProgressTimer - A timer badge component for displaying meeting/session duration.

This component provides a visually prominent timer badge that displays the elapsed time of a meeting or session. It offers flexible positioning, styling customization, and render hooks for complete control over the timer's appearance and placement.

Key Features:

  • Corner Positioning: Four pre-configured positions (topLeft, topRight, bottomLeft, bottomRight)
  • Background Customization: Configurable background color for the timer badge
  • Text Styling: Full control over text appearance via textStyle prop
  • Visibility Control: Toggle timer visibility with showTimer flag
  • Render Hooks: Custom rendering for badge and container elements
  • HTML Attributes: Granular control over container, badge, and text elements
  • Absolute Positioning: Fixed position overlay that doesn't affect layout flow
  • Class Management: Smart className joining for clean CSS composition
  • Responsive Design: Adapts to content size with padding and border radius
  • Time Format Support: Displays any formatted time string (MM:SS, HH:MM:SS, etc.)
  • Z-Index Control: Positioned above other content for visibility
  • Accessible: Semantic HTML with proper span elements for time display

// Basic usage with auto-incrementing timer

import React, { useState, useEffect } from 'react';
import { MeetingProgressTimer } from 'mediasfu-reactjs';

const BasicMeetingTimer = () => {
const [elapsedTime, setElapsedTime] = useState('00:00');

useEffect(() => {
const startTime = Date.now();
const interval = setInterval(() => {
const elapsed = Math.floor((Date.now() - startTime) / 1000);
const minutes = Math.floor(elapsed / 60);
const seconds = elapsed % 60;
setElapsedTime(`${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`);
}, 1000);
return () => clearInterval(interval);
}, []);

return (
<MeetingProgressTimer
meetingProgressTime={elapsedTime}
initialBackgroundColor="#2ecc71"
position="topRight"
showTimer={true}
/>
);
};

// Custom styled with dynamic positioning

import React, { useState, useEffect } from 'react';
import { MeetingProgressTimer } from 'mediasfu-reactjs';

const CustomStyledTimer = () => {
const [elapsedTime, setElapsedTime] = useState('00:00:00');
const [position, setPosition] = useState<'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'>('topLeft');

useEffect(() => {
const startTime = Date.now();
const interval = setInterval(() => {
const elapsed = Math.floor((Date.now() - startTime) / 1000);
const hours = Math.floor(elapsed / 3600);
const minutes = Math.floor((elapsed % 3600) / 60);
const seconds = elapsed % 60;
setElapsedTime(
`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
);
}, 1000);
return () => clearInterval(interval);
}, []);

return (
<>
<select value={position} onChange={(e) => setPosition(e.target.value as any)}>
<option value="topLeft">Top Left</option>
<option value="topRight">Top Right</option>
<option value="bottomLeft">Bottom Left</option>
<option value="bottomRight">Bottom Right</option>
</select>
<MeetingProgressTimer
meetingProgressTime={elapsedTime}
initialBackgroundColor="#e74c3c"
position={position}
textStyle={{
fontSize: '18px',
fontWeight: 'bold',
fontFamily: 'monospace',
letterSpacing: '1px'
}}
badgeProps={{
style: {
padding: '12px 20px',
borderRadius: '8px',
border: '2px solid #c0392b',
boxShadow: '0 4px 8px rgba(0,0,0,0.3)'
}
}}
showTimer={true}
/>
</>
);
};

// Analytics tracking with custom badge rendering

import React, { useState, useEffect } from 'react';
import { MeetingProgressTimer } from 'mediasfu-reactjs';

const AnalyticsMeetingTimer = () => {
const [elapsedTime, setElapsedTime] = useState('00:00');
const [elapsedSeconds, setElapsedSeconds] = useState(0);

useEffect(() => {
const startTime = Date.now();
const interval = setInterval(() => {
const elapsed = Math.floor((Date.now() - startTime) / 1000);
setElapsedSeconds(elapsed);
const minutes = Math.floor(elapsed / 60);
const seconds = elapsed % 60;
setElapsedTime(`${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`);

// Track milestones
if (elapsed % 300 === 0 && elapsed > 0) { // Every 5 minutes
analytics.track('Meeting Milestone', {
duration: elapsed,
formatted: `${minutes}:${seconds}`
});
}
}, 1000);
return () => clearInterval(interval);
}, []);

return (
<MeetingProgressTimer
meetingProgressTime={elapsedTime}
initialBackgroundColor={elapsedSeconds > 3600 ? '#e67e22' : '#3498db'}
position="bottomRight"
showTimer={true}
renderBadge={({ defaultBadge, showTimer }) => {
useEffect(() => {
analytics.track('Timer Rendered', {
visible: showTimer,
elapsedSeconds
});
}, [showTimer, elapsedSeconds]);

return (
<div style={{ position: 'relative' }}>
{defaultBadge}
{elapsedSeconds > 3600 && (
<div style={{
position: 'absolute',
top: -8,
right: -8,
width: '16px',
height: '16px',
borderRadius: '50%',
backgroundColor: '#e74c3c',
border: '2px solid #fff',
animation: 'pulse 2s infinite'
}} />
)}
</div>
);
}}
/>
);
};

// Integration with MediasfuGeneric using uiOverrides

import React, { useState } from 'react';
import { MediasfuGeneric, MeetingProgressTimer } from 'mediasfu-reactjs';

const CustomTimerComponent = (props) => (
<MeetingProgressTimer
{...props}
renderContainer={({ defaultContainer }) => (
<div className="custom-timer-wrapper">
<div className="timer-label">Session Duration</div>
{defaultContainer}
<div className="timer-actions">
<button
onClick={() => console.log('Pause session')}
style={{
fontSize: '10px',
padding: '2px 6px',
marginTop: '4px'
}}
>
⏸️
</button>
</div>
</div>
)}
textStyle={{
fontSize: '16px',
fontWeight: '600',
color: '#fff'
}}
/>
);

const App = () => {
const [credentials] = useState({
apiUserName: 'user123',
apiKey: 'your-api-key'
});

return (
<MediasfuGeneric
credentials={credentials}
uiOverrides={{
MeetingProgressTimer: CustomTimerComponent
}}
/>
);
};

Properties

propTypes?: any

Ignored by React.

Only kept in types for backwards compatibility. Will be removed in a future major release.

displayName?: string

Used in debugging messages. You might want to set it explicitly if you want to display a different name for debugging purposes.


const MyComponent: FC = () => {
return <div>Hello!</div>
}

MyComponent.displayName = 'MyAwesomeComponent'