about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-04-30 15:04:17 -0700
committerGitHub <noreply@github.com>2024-04-30 15:04:17 -0700
commitdb968b7610e8f3f217093c7a0d59b2ce1f319776 (patch)
tree06c4ac83a87ada2d1f4f4319a2cf7b0e7df6ab10 /src
parent268e30d21af3c71ad3d3a71590ef681a21f69438 (diff)
downloadvoidsky-db968b7610e8f3f217093c7a0d59b2ce1f319776.tar.zst
[Clipclops] Header for chat (#3775)
* add temp `getchat` query

* properly get the other profile

* add basic header

* normalize layout on all devices

* remove unused imports, adjust style

* remove unnecessary log

* remove another log

* remove some more imports

* cleanup

* use `Button` instead in the header

* lint
Diffstat (limited to 'src')
-rw-r--r--src/screens/Messages/Conversation/index.tsx114
-rw-r--r--src/screens/Messages/Temp/query/query.ts24
-rw-r--r--src/screens/Messages/Temp/useDmServiceUrlStorage.tsx1
3 files changed, 128 insertions, 11 deletions
diff --git a/src/screens/Messages/Conversation/index.tsx b/src/screens/Messages/Conversation/index.tsx
index efa64f5f8..d06913857 100644
--- a/src/screens/Messages/Conversation/index.tsx
+++ b/src/screens/Messages/Conversation/index.tsx
@@ -1,13 +1,26 @@
 import React from 'react'
-import {msg} from '@lingui/macro'
+import {TouchableOpacity, View} from 'react-native'
+import {AppBskyActorDefs} from '@atproto/api'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+import {msg, Trans} 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 {useSession} from 'state/session'
+import {UserAvatar} from 'view/com/util/UserAvatar'
 import {CenteredView} from 'view/com/util/Views'
 import {MessagesList} from '#/screens/Messages/Conversation/MessagesList'
+import {useChatQuery} from '#/screens/Messages/Temp/query/query'
+import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {Button, ButtonIcon} from '#/components/Button'
+import {DotGrid_Stroke2_Corner0_Rounded} from '#/components/icons/DotGrid'
+import {ListMaybePlaceholder} from '#/components/Lists'
+import {Text} from '#/components/Typography'
 import {ClipClopGate} from '../gate'
 
 type Props = NativeStackScreenProps<
@@ -15,20 +28,101 @@ type Props = NativeStackScreenProps<
   'MessagesConversation'
 >
 export function MessagesConversationScreen({route}: Props) {
-  const chatId = route.params.conversation
-  const {_} = useLingui()
   const gate = useGate()
+  const chatId = route.params.conversation
+  const {currentAccount} = useSession()
+  const myDid = currentAccount?.did
+
+  const {data: chat, isError: isError} = useChatQuery(chatId)
+  const otherProfile = React.useMemo(() => {
+    return chat?.members?.find(m => m.did !== myDid)
+  }, [chat?.members, myDid])
 
   if (!gate('dms')) return <ClipClopGate />
 
+  if (!chat || !otherProfile) {
+    return (
+      <CenteredView style={{flex: 1}} sideBorders>
+        <ListMaybePlaceholder isLoading={true} isError={isError} />
+      </CenteredView>
+    )
+  }
+
   return (
     <CenteredView style={{flex: 1}} sideBorders>
-      <ViewHeader
-        title={_(msg`Chat with ${chatId}`)}
-        showOnDesktop
-        showBorder
-      />
+      <Header profile={otherProfile} />
       <MessagesList chatId={chatId} />
     </CenteredView>
   )
 }
+
+function Header({profile}: {profile: AppBskyActorDefs.ProfileViewBasic}) {
+  const t = useTheme()
+  const {_} = useLingui()
+  const {gtTablet} = useBreakpoints()
+  const navigation = useNavigation<NavigationProp>()
+
+  const onPressBack = React.useCallback(() => {
+    if (isWeb) {
+      navigation.replace('MessagesList')
+    } else {
+      navigation.pop()
+    }
+  }, [navigation])
+
+  return (
+    <View
+      style={[
+        t.atoms.bg,
+        t.atoms.border_contrast_low,
+        a.border_b,
+        a.flex_row,
+        a.justify_between,
+        a.gap_lg,
+        a.px_lg,
+        a.py_sm,
+      ]}>
+      {!gtTablet ? (
+        <TouchableOpacity
+          testID="viewHeaderDrawerBtn"
+          onPress={onPressBack}
+          hitSlop={BACK_HITSLOP}
+          style={{
+            width: 30,
+            height: 30,
+          }}
+          accessibilityRole="button"
+          accessibilityLabel={_(msg`Back`)}
+          accessibilityHint={_(msg`Access navigation links and settings`)}>
+          <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]}>
+        <UserAvatar size={32} avatar={profile.avatar} />
+        <Text style={[a.text_lg, a.font_bold]}>
+          <Trans>{profile.displayName}</Trans>
+        </Text>
+      </View>
+      <View>
+        <Button
+          label={_(msg`Chat settings`)}
+          color="secondary"
+          size="large"
+          variant="ghost"
+          style={[{height: 'auto', width: 'auto'}, a.px_sm, a.py_sm]}
+          onPress={() => {}}>
+          <ButtonIcon icon={DotGrid_Stroke2_Corner0_Rounded} />
+        </Button>
+      </View>
+    </View>
+  )
+}
diff --git a/src/screens/Messages/Temp/query/query.ts b/src/screens/Messages/Temp/query/query.ts
index a51929bca..a4d78e0bb 100644
--- a/src/screens/Messages/Temp/query/query.ts
+++ b/src/screens/Messages/Temp/query/query.ts
@@ -73,6 +73,8 @@ export function useChat(chatId: string) {
       const chatJson =
         (await chatResponse.json()) as TempDmChatGetChat.OutputSchema
 
+      queryClient.setQueryData(['chatQuery', chatId], chatJson.chat)
+
       const newChat = {
         chatId,
         messages: messagesJson.messages,
@@ -275,3 +277,25 @@ export function useListChats() {
     getNextPageParam: lastPage => lastPage.cursor,
   })
 }
+
+export function useChatQuery(chatId: string) {
+  const headers = useHeaders()
+  const {serviceUrl} = useDmServiceUrlStorage()
+
+  return useQuery({
+    queryKey: ['chatQuery', chatId],
+    queryFn: async () => {
+      const chatResponse = await fetch(
+        `${serviceUrl}/xrpc/temp.dm.getChat?chatId=${chatId}`,
+        {
+          headers,
+        },
+      )
+
+      if (!chatResponse.ok) throw new Error('Failed to fetch chat')
+
+      const json = (await chatResponse.json()) as TempDmChatGetChat.OutputSchema
+      return json.chat
+    },
+  })
+}
diff --git a/src/screens/Messages/Temp/useDmServiceUrlStorage.tsx b/src/screens/Messages/Temp/useDmServiceUrlStorage.tsx
index 3679858f4..d78128b5c 100644
--- a/src/screens/Messages/Temp/useDmServiceUrlStorage.tsx
+++ b/src/screens/Messages/Temp/useDmServiceUrlStorage.tsx
@@ -35,7 +35,6 @@ export function DmServiceUrlProvider({children}: {children: React.ReactNode}) {
   React.useEffect(() => {
     ;(async () => {
       const v = await getItem()
-      console.log(v)
       setServiceUrl(v ?? '')
     })()
   }, [getItem])