Skip to content

Commit

Permalink
chore(rn-dogfood): add closed captions in the dogfood app (#1636)
Browse files Browse the repository at this point in the history
## Overview 

Closed captions in the dogfood app.

<img
src="https://github.com/user-attachments/assets/9def7a25-c338-41aa-ab82-12b06057dff8"
alt="ios-after" width="200" height="440"/>
  • Loading branch information
kristian-mkd authored Jan 9, 2025
1 parent 5dab0ba commit 1e78c96
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 30 deletions.
26 changes: 17 additions & 9 deletions sample-apps/react-native/dogfood/src/components/ActiveCall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
CallContent,
useTheme,
useIsInPiPMode,
useCallStateHooks,
useToggleCallRecording,
} from '@stream-io/video-react-native-sdk';
import { ActivityIndicator, StatusBar, StyleSheet, View } from 'react-native';
import { ParticipantsInfoList } from './ParticipantsInfoList';
Expand All @@ -12,9 +14,9 @@ import { useOrientation } from '../hooks/useOrientation';
import { Z_INDEX } from '../constants';
import { TopControls } from './CallControlls/TopControls';
import { useLayout } from '../contexts/LayoutContext';
import { useToggleCallRecording } from '@stream-io/video-react-bindings';
import { useAppGlobalStoreValue } from '../contexts/AppContext';
import DeviceInfo from 'react-native-device-info';
import { ClosedCaptions } from './ClosedCaptions';

type ActiveCallProps = {
onHangupCallHandler?: () => void;
Expand Down Expand Up @@ -52,17 +54,22 @@ export const ActiveCall = ({

const { toggleCallRecording, isAwaitingResponse, isCallRecordingInProgress } =
useToggleCallRecording();
const { useIsCallCaptioningInProgress } = useCallStateHooks();
const isCaptioningInProgress = useIsCallCaptioningInProgress();

const CustomBottomControls = useCallback(() => {
return (
<BottomControls
onParticipantInfoPress={onOpenCallParticipantsInfo}
onChatOpenHandler={onChatOpenHandler}
unreadCountIndicator={unreadCountIndicator}
toggleCallRecording={toggleCallRecording}
isCallRecordingInProgress={isCallRecordingInProgress}
isAwaitingResponse={isAwaitingResponse}
/>
<>
{isCaptioningInProgress && <ClosedCaptions />}
<BottomControls
onParticipantInfoPress={onOpenCallParticipantsInfo}
onChatOpenHandler={onChatOpenHandler}
unreadCountIndicator={unreadCountIndicator}
toggleCallRecording={toggleCallRecording}
isCallRecordingInProgress={isCallRecordingInProgress}
isAwaitingResponse={isAwaitingResponse}
/>
</>
);
}, [
onChatOpenHandler,
Expand All @@ -71,6 +78,7 @@ export const ActiveCall = ({
toggleCallRecording,
isAwaitingResponse,
isCallRecordingInProgress,
isCaptioningInProgress,
]);

const CustomTopControls = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, { useEffect, useRef, useState } from 'react';
import {
CallControlsButton,
OwnCapability,
useCall,
useCallStateHooks,
useTheme,
} from '@stream-io/video-react-native-sdk';
import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons';
Expand All @@ -16,6 +18,7 @@ import {
} from '../../contexts/AppContext';
import LightDark from '../../assets/LightDark';
import Stats from '../../assets/Stats';
import ClosedCaptions from '../../assets/ClosedCaptions';

/**
* The props for the More Actions Button in the Call Controls.
Expand Down Expand Up @@ -45,6 +48,13 @@ export const MoreActionsButton = ({
const themeMode = useAppGlobalStoreValue((store) => store.themeMode);
const call = useCall();
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const { useIsCallCaptioningInProgress, useHasPermissions } =
useCallStateHooks();
const isCaptioningInProgress = useIsCallCaptioningInProgress();
const canToggle = useHasPermissions(
OwnCapability.START_CLOSED_CAPTIONS_CALL,
OwnCapability.STOP_CLOSED_CAPTIONS_CALL,
);

useEffect(() => {
return () => {
Expand All @@ -71,6 +81,11 @@ export const MoreActionsButton = ({
return 'Light mode';
};

const getCaptionsLabel = () =>
isCaptioningInProgress
? 'Disable closed captions'
: 'Enable closed captions';

const options: DrawerOption[] = [
{
id: '1',
Expand Down Expand Up @@ -127,6 +142,30 @@ export const MoreActionsButton = ({
setIsDrawerVisible(false);
},
},
...(canToggle
? [
{
id: '4',
label: getCaptionsLabel(),
icon: (
<IconWrapper>
<ClosedCaptions
color={colors.iconPrimary}
size={variants.roundButtonSizes.sm}
/>
</IconWrapper>
),
onPress: () => {
if (isCaptioningInProgress) {
call?.stopClosedCaptions();
} else {
call?.startClosedCaptions();
}
setIsDrawerVisible(false);
},
},
]
: []),
];

const buttonColor = isDrawerVisible
Expand Down
48 changes: 27 additions & 21 deletions sample-apps/react-native/dogfood/src/components/ClosedCaptions.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import React, { useMemo } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { useCallStateHooks } from '@stream-io/video-react-native-sdk';
import { appTheme } from '../theme';
import { useCallStateHooks, useTheme } from '@stream-io/video-react-native-sdk';

export const ClosedCaptions = () => {
const { useCallClosedCaptions } = useCallStateHooks();
const closedCaptions = useCallClosedCaptions();
const styles = useStyles();
return (
<View style={styles.rootContainer}>
{closedCaptions.map(({ user, start_time, text }) => (
Expand All @@ -18,21 +18,27 @@ export const ClosedCaptions = () => {
);
};

const styles = StyleSheet.create({
rootContainer: {
backgroundColor: appTheme.colors.static_overlay,
paddingVertical: 6,
paddingHorizontal: 6,
height: 50,
},
closedCaptionItem: {
flexDirection: 'row',
gap: 8,
},
speakerName: {
color: appTheme.colors.light_gray,
},
closedCaption: {
color: appTheme.colors.static_white,
},
});
const useStyles = () => {
const { theme } = useTheme();
return useMemo(
() =>
StyleSheet.create({
rootContainer: {
backgroundColor: theme.colors.sheetPrimary,
padding: theme.variants.spacingSizes.md,
height: 55,
},
closedCaptionItem: {
flexDirection: 'row',
gap: theme.variants.spacingSizes.xs,
},
speakerName: {
color: theme.colors.textSecondary,
},
closedCaption: {
color: theme.colors.textPrimary,
},
}),
[theme],
);
};

0 comments on commit 1e78c96

Please sign in to comment.