Skip to content

Commit

Permalink
feat: [FC-14] custom audio message
Browse files Browse the repository at this point in the history
  • Loading branch information
HuyDo committed Jul 8, 2024
1 parent 80f8da3 commit 35c11da
Show file tree
Hide file tree
Showing 23 changed files with 15,653 additions and 10,417 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,20 @@
]
},
"dependencies": {
"@react-native-community/slider": "^4.5.2",
"@react-native-firebase/app": "^20.1.0",
"@react-native-firebase/firestore": "^20.1.0",
"@react-native-firebase/storage": "^20.1.0",
"@types/uuid": "^9.0.8",
"randomcolor": "^0.6.2",
"react-native-aes-crypto": "^2.1.1",
"react-native-audio-recorder-player": "3.6.4",
"react-native-fast-image": "^8.6.3",
"react-native-fs": "^2.20.0",
"react-native-gifted-chat": "^2.4.0",
"react-native-image-picker": "^7.1.2",
"react-native-svg": "^15.3.0",
"react-native-uuid": "^2.0.2",
"react-native-video": "^6.2.0",
"react-native-vision-camera": "^4.1.0",
"uuid": "^10.0.0"
Expand Down
42 changes: 39 additions & 3 deletions src/chat/ChatScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
GiftedChat,
type GiftedChatProps,
Bubble,
Message,
} from 'react-native-gifted-chat';
import TypingIndicator from 'react-native-gifted-chat/lib/TypingIndicator';
import { FirestoreServices } from '../services/firebase';
Expand All @@ -35,6 +36,9 @@ import { CameraView, CameraViewRef } from '../chat_obs/components/CameraView';
import SelectedImageModal from './components/SelectedImage';
import { useCameraPermission } from 'react-native-vision-camera';
import { CustomBubble, CustomImageVideoBubbleProps } from './components/bubble';
import VoiceRecorderModal, {
VoiceRecorderModalRef,
} from './components/VoiceRecorderModal';

interface ChatScreenProps extends GiftedChatProps {
style?: StyleProp<ViewStyle>;
Expand Down Expand Up @@ -78,6 +82,14 @@ export const ChatScreen: React.FC<ChatScreenProps> = ({
const cameraViewRef = useRef<CameraViewRef>(null);
const [isImgVideoUrl, setImgVideoUrl] = useState('');
const { hasPermission, requestPermission } = useCameraPermission();
const voiceRef = useRef<VoiceRecorderModalRef>(null);

const [currentPlayingMessageId, setCurrentPlayingMessageId] = useState<
string | null
>(null);
const [selectedMessage, setSelectedMessage] = useState<MessageProps | null>(
null
);

const conversationRef = useRef<ConversationProps | undefined>(
conversationInfo
Expand Down Expand Up @@ -209,6 +221,7 @@ export const ChatScreen: React.FC<ChatScreenProps> = ({
hasCamera={props.hasCamera}
hasGallery={props.hasGallery}
{...inputToolbarProps}
voiceRef={voiceRef.current}
/>
);
},
Expand All @@ -222,20 +235,41 @@ export const ChatScreen: React.FC<ChatScreenProps> = ({
]
);

const handlePlayPause = (messageId: string) => {
setCurrentPlayingMessageId(
messageId === currentPlayingMessageId ? null : messageId
);
};

const renderBubble = (bubble: Bubble<MessageProps>['props']) => {
if (props.renderBubble) return props.renderBubble(bubble);
return (
<CustomBubble
bubbleMessage={bubble}
onSelectedMessage={() => {
//TODO: handle image/video press
}}
onSelectedMessage={setSelectedMessage}
customImageVideoBubbleProps={customImageVideoBubbleProps}
position={bubble.position}
onSetCurrentId={handlePlayPause}
isCurrentlyPlaying={
currentPlayingMessageId === bubble.currentMessage?.id
}
/>
);
};

const shouldUpdateMessage = (
currentProps: Message<MessageProps>['props'],
nextProps: Message<MessageProps>['props']
) => {
if (
currentProps.currentMessage?.type === 'voice' ||
nextProps.currentMessage?.type === 'voice'
) {
return true;
}
return false;
};

return (
<View style={[styles.container, style]}>
<KeyboardAvoidingView style={styles.container}>
Expand All @@ -253,6 +287,7 @@ export const ChatScreen: React.FC<ChatScreenProps> = ({
onLoadEarlier={onLoadEarlier}
renderComposer={inputToolbar}
renderBubble={renderBubble}
shouldUpdateMessage={shouldUpdateMessage}
{...props}
/>
</KeyboardAvoidingView>
Expand All @@ -261,6 +296,7 @@ export const ChatScreen: React.FC<ChatScreenProps> = ({
onClose={() => setImgVideoUrl('')}
/>
<CameraView onSend={onSend} userInfo={userInfo} ref={cameraViewRef} />
<VoiceRecorderModal onSend={onSend} userInfo={userInfo} ref={voiceRef} />
</View>
);
};
Expand Down
11 changes: 9 additions & 2 deletions src/chat/components/InputToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from 'react-native-image-picker';
import { MessageTypes } from '../../interfaces';
import { convertExtension } from '../../utilities';
import type { VoiceRecorderModalRef } from './VoiceRecorderModal';

const ImageURL = {
camera: require('../../images/camera.png'),
Expand All @@ -39,8 +40,13 @@ export interface IInputToolbar extends InputToolbarProps<any>, SendProps<any> {
galleryIcon?: string;
iconSend?: string;
iconStyle?: StyleProp<ImageStyle>;
renderLeftCustomView?: () => React.ReactNode;
renderLeftCustomView?: ({
voiceRef,
}: {
voiceRef: VoiceRecorderModalRef | null;
}) => React.ReactNode;
renderRightCustomView?: () => React.ReactNode;
voiceRef: VoiceRecorderModalRef | null;
}

const InputToolbar: React.FC<IInputToolbar> = ({
Expand All @@ -57,6 +63,7 @@ const InputToolbar: React.FC<IInputToolbar> = ({
iconStyle,
renderLeftCustomView,
renderRightCustomView,
voiceRef,
...props
}) => {
const { onSend, text } = props;
Expand Down Expand Up @@ -98,7 +105,7 @@ const InputToolbar: React.FC<IInputToolbar> = ({
return (
<View style={[styles.container, containerStyle]}>
<View>
{renderLeftCustomView && renderLeftCustomView()}
{renderLeftCustomView && renderLeftCustomView({ voiceRef })}
{hasCamera && (
<PressableIcon
icon={cameraIcon}
Expand Down
Loading

0 comments on commit 35c11da

Please sign in to comment.