import React, { useCallback, useReducer } from 'react'
import { ThemedView } from '@/components/ThemedView'
import { ThemedText } from '@/components/ThemedText'
import { Alert, Linking, Platform, StyleSheet } from 'react-native'
import { MaterialIcons } from '@expo/vector-icons'
import {
GiftedChat,
IMessage,
Send,
SendProps,
SystemMessage,
} from 'react-native-gifted-chat'
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'
import AccessoryBar from '@/components/chat/AccessoryBar'
import CustomActions from '@/components/chat/CustomActions'
import CustomView from '@/components/chat/CustomView'
import earlierMessages from '@/components/chat/data/earlierMessages'
import messagesData from '@/components/chat/data/messages'
import * as Clipboard from 'expo-clipboard'
//import NavBar from '@/components/chat/NavBar'
const user = {
_id: 1,
name: 'Developer',
}
interface IState {
messages: any[]
step: number
loadEarlier?: boolean
isLoadingEarlier?: boolean
isTyping: boolean
}
enum ActionKind {
SEND_MESSAGE = 'SEND_MESSAGE',
LOAD_EARLIER_MESSAGES = 'LOAD_EARLIER_MESSAGES',
LOAD_EARLIER_START = 'LOAD_EARLIER_START',
SET_IS_TYPING = 'SET_IS_TYPING',
// LOAD_EARLIER_END = 'LOAD_EARLIER_END',
}
// An interface for our actions
interface StateAction {
type: ActionKind
payload?: any
}
function reducer (state: IState, action: StateAction) {
switch (action.type) {
case ActionKind.SEND_MESSAGE: {
return {
...state,
step: state.step + 1,
messages: action.payload,
}
}
case ActionKind.LOAD_EARLIER_MESSAGES: {
return {
...state,
loadEarlier: true,
isLoadingEarlier: false,
messages: action.payload,
}
}
case ActionKind.LOAD_EARLIER_START: {
return {
...state,
isLoadingEarlier: true,
}
}
case ActionKind.SET_IS_TYPING: {
return {
...state,
isTyping: action.payload,
}
}
}
}
const App = () => {
const [state, dispatch] = useReducer(reducer, {
messages: messagesData,
step: 0,
loadEarlier: true,
isLoadingEarlier: false,
isTyping: false,
})
const onSend = useCallback(
(messages: any[]) => {
const sentMessages = [{ ...messages[0], sent: true, received: true }]
const newMessages = GiftedChat.append(
state.messages,
sentMessages,
Platform.OS !== 'web'
)
dispatch({ type: ActionKind.SEND_MESSAGE, payload: newMessages })
},
[dispatch, state.messages]
)
const onLoadEarlier = useCallback(() => {
dispatch({ type: ActionKind.LOAD_EARLIER_START })
setTimeout(() => {
const newMessages = GiftedChat.prepend(
state.messages,
earlierMessages() as IMessage[],
Platform.OS !== 'web'
)
dispatch({ type: ActionKind.LOAD_EARLIER_MESSAGES, payload: newMessages })
}, 1500) // simulating network
}, [dispatch, state.messages])
const parsePatterns = useCallback(() => {
return [
{
pattern: /#(\w+)/,
style: { textDecorationLine: 'underline', color: 'darkorange' },
onPress: () => Linking.openURL('https://gbrown.org'),
},
]
}, [])
const onLongPressAvatar = useCallback((pressedUser: any) => {
Alert.alert(JSON.stringify(pressedUser))
}, [])
const onPressAvatar = useCallback(() => {
Alert.alert('On avatar press')
}, [])
const handleLongPress = useCallback((context: unknown, currentMessage: object) => {
if (!currentMessage.text)
return
const options = [
'Copy text',
'Cancel',
]
const cancelButtonIndex = options.length - 1
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(context as any).actionSheet().showActionSheetWithOptions(
{
options,
cancelButtonIndex,
},
(buttonIndex: number) => {
switch (buttonIndex) {
case 0:
Clipboard.setStringAsync(currentMessage.text)
break
default:
break
}
}
)
}, [])
const onQuickReply = useCallback((replies: any[]) => {
const createdAt = new Date()
if (replies.length === 1)
onSend([
{
createdAt,
_id: Math.round(Math.random() * 1000000),
text: replies[0].title,
user,
},
])
else if (replies.length > 1)
onSend([
{
createdAt,
_id: Math.round(Math.random() * 1000000),
text: replies.map(reply => reply.title).join(', '),
user,
},
])
else
console.warn('replies param is not set correctly')
}, [])
const renderQuickReplySend = useCallback(() => {
return {' custom send =>'}
}, [])
const setIsTyping = useCallback(
(isTyping: boolean) => {
dispatch({ type: ActionKind.SET_IS_TYPING, payload: isTyping })
},
[dispatch]
)
const onSendFromUser = useCallback(
(messages: IMessage[] = []) => {
const createdAt = new Date()
const messagesToUpload = messages.map(message => ({
...message,
user,
createdAt,
_id: Math.round(Math.random() * 1000000),
}))
onSend(messagesToUpload)
},
[onSend]
)
const renderAccessory = useCallback(() => {
return (
setIsTyping(!state.isTyping)}
/>
)
}, [onSendFromUser, setIsTyping, state.isTyping])
const renderCustomActions = useCallback(
props =>
Platform.OS === 'web'
? null
: (
),
[onSendFromUser]
)
const renderSystemMessage = useCallback(props => {
return (
)
}, [])
const renderCustomView = useCallback(props => {
return
}, [])
const renderSend = useCallback((props: SendProps) => {
return (
)
}, [])
return (
)
}
const AppWrapper = () => {
return (
)
}
const styles = StyleSheet.create({
fill: {
flex: 1,
},
sendLine: {
}
})
export default AppWrapper