about summary refs log tree commit diff
path: root/src/screens/Messages/Conversation/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/Messages/Conversation/index.tsx')
-rw-r--r--src/screens/Messages/Conversation/index.tsx142
1 files changed, 129 insertions, 13 deletions
diff --git a/src/screens/Messages/Conversation/index.tsx b/src/screens/Messages/Conversation/index.tsx
index 239425a2f..11044c213 100644
--- a/src/screens/Messages/Conversation/index.tsx
+++ b/src/screens/Messages/Conversation/index.tsx
@@ -1,12 +1,26 @@
-import React from 'react'
-import {View} from 'react-native'
+import React, {useCallback} from 'react'
+import {TouchableOpacity, View} from 'react-native'
+import {KeyboardProvider} from 'react-native-keyboard-controller'
+import {AppBskyActorDefs} from '@atproto/api'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
+import {useNavigation} from '@react-navigation/native'
 import {NativeStackScreenProps} from '@react-navigation/native-stack'
 
-import {CommonNavigatorParams} from '#/lib/routes/types'
+import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
 import {useGate} from '#/lib/statsig/statsig'
-import {ViewHeader} from '#/view/com/util/ViewHeader'
+import {BACK_HITSLOP} from 'lib/constants'
+import {isWeb} from 'platform/detection'
+import {ChatProvider, useChat} from 'state/messages'
+import {ConvoStatus} from 'state/messages/convo'
+import {PreviewableUserAvatar} from 'view/com/util/UserAvatar'
+import {CenteredView} from 'view/com/util/Views'
+import {MessagesList} from '#/screens/Messages/Conversation/MessagesList'
+import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {ConvoMenu} from '#/components/dms/ConvoMenu'
+import {ListMaybePlaceholder} from '#/components/Lists'
+import {Text} from '#/components/Typography'
 import {ClipClopGate} from '../gate'
 
 type Props = NativeStackScreenProps<
@@ -14,19 +28,121 @@ type Props = NativeStackScreenProps<
   'MessagesConversation'
 >
 export function MessagesConversationScreen({route}: Props) {
-  const chatId = route.params.conversation
-  const {_} = useLingui()
-
   const gate = useGate()
+  const convoId = route.params.conversation
+
   if (!gate('dms')) return <ClipClopGate />
 
   return (
-    <View>
-      <ViewHeader
-        title={_(msg`Chat with ${chatId}`)}
-        showOnDesktop
-        showBorder
-      />
+    <ChatProvider convoId={convoId}>
+      <Inner />
+    </ChatProvider>
+  )
+}
+
+function Inner() {
+  const chat = useChat()
+
+  if (
+    chat.status === ConvoStatus.Uninitialized ||
+    chat.status === ConvoStatus.Initializing
+  ) {
+    return <ListMaybePlaceholder isLoading />
+  }
+
+  if (chat.status === ConvoStatus.Error) {
+    // TODO error
+    return null
+  }
+
+  /*
+   * Any other chat states (atm) are "ready" states
+   */
+
+  return (
+    <KeyboardProvider>
+      <CenteredView style={{flex: 1}} sideBorders>
+        <Header profile={chat.recipients[0]} />
+        <MessagesList />
+      </CenteredView>
+    </KeyboardProvider>
+  )
+}
+
+let Header = ({
+  profile,
+}: {
+  profile: AppBskyActorDefs.ProfileViewBasic
+}): React.ReactNode => {
+  const t = useTheme()
+  const {_} = useLingui()
+  const {gtTablet} = useBreakpoints()
+  const navigation = useNavigation<NavigationProp>()
+  const chat = useChat()
+
+  const onPressBack = useCallback(() => {
+    if (isWeb) {
+      navigation.replace('Messages')
+    } else {
+      navigation.pop()
+    }
+  }, [navigation])
+
+  const onUpdateConvo = useCallback(() => {
+    // TODO eric update muted state
+  }, [])
+
+  return (
+    <View
+      style={[
+        t.atoms.bg,
+        t.atoms.border_contrast_low,
+        a.border_b,
+        a.flex_row,
+        a.justify_between,
+        a.align_start,
+        a.gap_lg,
+        a.px_lg,
+        a.py_sm,
+      ]}>
+      {!gtTablet ? (
+        <TouchableOpacity
+          testID="conversationHeaderBackBtn"
+          onPress={onPressBack}
+          hitSlop={BACK_HITSLOP}
+          style={{width: 30, height: 30}}
+          accessibilityRole="button"
+          accessibilityLabel={_(msg`Back`)}
+          accessibilityHint="">
+          <FontAwesomeIcon
+            size={18}
+            icon="angle-left"
+            style={{
+              marginTop: 6,
+            }}
+            color={t.atoms.text.color}
+          />
+        </TouchableOpacity>
+      ) : (
+        <View style={{width: 30}} />
+      )}
+      <View style={[a.align_center, a.gap_sm, a.flex_1]}>
+        <PreviewableUserAvatar size={32} profile={profile} />
+        <Text style={[a.text_lg, a.font_bold, a.text_center]}>
+          {profile.displayName}
+        </Text>
+      </View>
+      {chat.status === ConvoStatus.Ready ? (
+        <ConvoMenu
+          convo={chat.convo}
+          profile={profile}
+          onUpdateConvo={onUpdateConvo}
+          currentScreen="conversation"
+        />
+      ) : (
+        <View style={{width: 30}} />
+      )}
     </View>
   )
 }
+Header = React.memo(Header)