Rocket.Chat.ReactNative/app/containers/CallHeader.tsx

108 lines
3.4 KiB
TypeScript
Raw Normal View History

feat: Add caller and ringer to video conf calls (#5046) * add expo camera and use camera on call init action sheet * fix permissions * set colors when calling * update @react-native-community/hooks lib * move to useWindowDimensions * create action to handle video-conf calls * create videoConf reducer * add typed-redux-saga lib * fix return * change videoConf saga to TS * fix TS target * update action and types * create actionSheetRef * add notifyUser api * export video conf types * add action prop * use new reducer prop * add videoConferenceCancel and add allowRinging to videoConferenceStart * temp-patch * add locales * add handler to videoconf message * fix rest types * add message types * path to remove component from dom * remove notification when is videoconf * create sound hook * create dots loader * update call translation * the end is near * move to confirmed * better code reading * fix call type * fix tests * update podfile * wip * fix call order * move colors * move to jsx * fix colors * add pt-br * remove patch and point * fix colors * fix expo camera * move to style * remove unused styles * update types and style * wip * rename IncomingCallComponent * add custom notification * wip * fix naming * fix styles * fix import * fix styles * change colors * fixa ringing * fix import * organize * fix sizes * use realName * fix spacing * fix icon size * fix header gap * changeColor * fix safeArea * set calling only on direct calls * change ringer to be a component * cancel call on swipe * remove join on direct calls * add props * update package
2023-07-04 00:03:39 +00:00
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Touchable from 'react-native-platform-touchable';
import { useAppSelector } from '../lib/hooks';
import { useTheme } from '../theme';
import sharedStyles from '../views/Styles';
import { CustomIcon } from './CustomIcon';
import { BUTTON_HIT_SLOP } from './message/utils';
import AvatarContainer from './Avatar';
import StatusContainer from './Status';
import DotsLoader from './DotsLoader';
type TCallHeader = {
mic: boolean;
cam: boolean;
setCam: Function;
setMic: Function;
title: string;
avatar: string;
uid: string;
name: string;
direct: boolean;
};
export const CallHeader = ({ mic, cam, setCam, setMic, title, avatar, uid, name, direct }: TCallHeader): React.ReactElement => {
const style = useStyle();
const { colors } = useTheme();
const calling = useAppSelector(state => state.videoConf.calling);
const handleColors = (enabled: boolean) => {
if (calling) {
if (enabled) return { button: colors.conferenceCallCallBackButton, icon: colors.gray300 };
return { button: 'transparent', icon: colors.gray100 };
}
if (enabled) return { button: colors.conferenceCallEnabledIconBackground, icon: colors.conferenceCallEnabledIcon };
return { button: 'transparent', icon: colors.conferenceCallDisabledIcon };
};
return (
<View>
<View style={style.actionSheetHeader}>
<View style={style.rowContainer}>
<Text style={style.actionSheetHeaderTitle}>{title}</Text>
{calling && direct ? <DotsLoader /> : null}
</View>
<View style={style.actionSheetHeaderButtons}>
<Touchable
onPress={() => setCam(!cam)}
style={[style.iconCallContainerRight, { backgroundColor: handleColors(cam).button }]}
hitSlop={BUTTON_HIT_SLOP}
disabled={calling}
>
<CustomIcon name={cam ? 'camera' : 'camera-disabled'} size={24} color={handleColors(cam).icon} />
</Touchable>
<Touchable
onPress={() => setMic(!mic)}
style={[style.iconCallContainer, { backgroundColor: handleColors(mic).button }]}
hitSlop={BUTTON_HIT_SLOP}
disabled={calling}
>
<CustomIcon name={mic ? 'microphone' : 'microphone-disabled'} size={24} color={handleColors(mic).icon} />
</Touchable>
</View>
</View>
<View style={style.actionSheetUsernameContainer}>
<AvatarContainer text={avatar} size={36} />
{direct ? <StatusContainer size={16} id={uid} style={style.statusContainerMargin} /> : null}
<Text style={{ ...style.actionSheetUsername, marginLeft: !direct ? 8 : 0 }} numberOfLines={1}>
{name}
</Text>
</View>
</View>
);
};
function useStyle() {
const { colors } = useTheme();
const style = StyleSheet.create({
actionSheetHeader: { flexDirection: 'row', alignItems: 'center' },
actionSheetHeaderTitle: {
fontSize: 14,
...sharedStyles.textBold,
color: colors.n900
},
actionSheetHeaderButtons: { flex: 1, alignItems: 'center', flexDirection: 'row', justifyContent: 'flex-end' },
iconCallContainer: {
padding: 6,
borderRadius: 4
},
iconCallContainerRight: {
padding: 6,
borderRadius: 4,
marginRight: 6
},
actionSheetUsernameContainer: { flexDirection: 'row', paddingTop: 8, alignItems: 'center' },
actionSheetUsername: {
fontSize: 16,
...sharedStyles.textBold,
color: colors.passcodePrimary,
flexShrink: 1
},
rowContainer: { flexDirection: 'row' },
statusContainerMargin: { marginLeft: 8, marginRight: 6 }
});
return style;
}