Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: more chat fixes + message status + optimistic update for text message + refactor queries/mutations #1357

Merged
merged 6 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions components/Connecting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useDebugEnabled } from "./DebugButton";
import { useChatStore, useCurrentAccount } from "../data/store/accountsStore";
import { useAppStore } from "../data/store/appStore";
import { useSelect } from "../data/store/storeHelpers";
import { useV3ConversationListQuery } from "@/queries/useV3ConversationListQuery";
import { useConversationListQuery } from "@/queries/useConversationListQuery";

export const useShouldShowConnecting = () => {
const isInternetReachable = useAppStore((s) => s.isInternetReachable);
Expand Down Expand Up @@ -67,7 +67,7 @@ export const useShouldShowConnecting = () => {

export const useShouldShowConnectingOrSyncing = () => {
const currentAccount = useCurrentAccount();
const { isLoading } = useV3ConversationListQuery(currentAccount!);
const { isLoading } = useConversationListQuery({ account: currentAccount! });
const initialLoadDoneOnce = !isLoading;
const shouldShowConnecting = useShouldShowConnecting();

Expand Down
17 changes: 8 additions & 9 deletions components/PinnedConversations/PinnedConversations.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { View, ViewStyle } from "react-native";

import { PinnedV3Conversation } from "./PinnedV3Conversation";
import { useV3ConversationListQuery } from "@queries/useV3ConversationListQuery";
import { useCurrentAccount } from "@data/store/accountsStore";
import { useConversationListQuery } from "@/queries/useConversationListQuery";
import { ThemedStyle, useAppTheme } from "@/theme/useAppTheme";
import { useCurrentAccount } from "@data/store/accountsStore";
import { PinnedV3Conversation } from "./PinnedV3Conversation";

type Props = {
topics?: string[];
Expand All @@ -14,14 +13,14 @@ export const PinnedConversations = ({ topics }: Props) => {

const { themed } = useAppTheme();

const { isLoading } = useV3ConversationListQuery(
currentAccount!,
{
const { isLoading } = useConversationListQuery({
account: currentAccount!,
context: "PinnedConversations",
queryOptions: {
refetchOnWindowFocus: false,
refetchOnMount: false,
},
"PinnedConversations"
);
});

if (isLoading) return null;

Expand Down
36 changes: 18 additions & 18 deletions components/PinnedConversations/PinnedV3DMConversation.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { PinnedConversation } from "./PinnedConversation";
import { useCallback, useMemo } from "react";
import { navigate } from "@utils/navigation";
import Avatar from "@components/Avatar";
import { DmWithCodecsType } from "@utils/xmtpRN/client";
import { usePreferredInboxName } from "@hooks/usePreferredInboxName";
import { usePreferredInboxAvatar } from "@hooks/usePreferredInboxAvatar";
import { useDmPeerInboxOnConversationList } from "@queries/useDmPeerInboxOnConversationList";
import { useChatStore, useCurrentAccount } from "@data/store/accountsStore";
import { useSelect } from "@/data/store/storeHelpers";
import { VStack } from "@/design-system/VStack";
import {
resetConversationListContextMenuStore,
setConversationListContextMenuConversationData,
} from "@/features/conversation-list/ConversationListContextMenu.store";
import { translate } from "@i18n";
import { useToggleReadStatus } from "@/features/conversation-list/hooks/useToggleReadStatus";
import { useConversationIsUnread } from "@/features/conversation-list/hooks/useMessageIsUnread";
import { useHandleDeleteDm } from "@/features/conversation-list/hooks/useHandleDeleteDm";
import { useConversationIsUnread } from "@/features/conversation-list/hooks/useMessageIsUnread";
import { useToggleReadStatus } from "@/features/conversation-list/hooks/useToggleReadStatus";
import { useDmPeerInboxId } from "@/queries/useDmPeerInbox";
import { useAppTheme } from "@/theme/useAppTheme";
import { ContextMenuIcon, ContextMenuItem } from "../ContextMenuItems";
import Avatar from "@components/Avatar";
import { useChatStore, useCurrentAccount } from "@data/store/accountsStore";
import { usePreferredInboxAvatar } from "@hooks/usePreferredInboxAvatar";
import { usePreferredInboxName } from "@hooks/usePreferredInboxName";
import { translate } from "@i18n";
import { navigate } from "@utils/navigation";
import { DmWithCodecsType } from "@utils/xmtpRN/client";
import { useCallback, useMemo } from "react";
import { isTextMessage } from "../../features/conversation/conversation-message/conversation-message.utils";
import { VStack } from "@/design-system/VStack";
import { ContextMenuIcon, ContextMenuItem } from "../ContextMenuItems";
import { PinnedConversation } from "./PinnedConversation";
import { PinnedMessagePreview } from "./PinnedMessagePreview";

type PinnedV3DMConversationProps = {
Expand All @@ -37,10 +37,10 @@ export const PinnedV3DMConversation = ({

const topic = conversation.topic;

const { data: peerInboxId } = useDmPeerInboxOnConversationList(
currentAccount,
conversation
);
const { data: peerInboxId } = useDmPeerInboxId({
account: currentAccount!,
topic,
});

const preferredName = usePreferredInboxName(peerInboxId);

Expand Down
4 changes: 2 additions & 2 deletions components/StateHandlers/HydrationStateHandler.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { prefetchInboxIdQuery } from "@/queries/use-inbox-id-query";
import { fetchPersistedConversationListQuery } from "@/queries/useV3ConversationListQuery";
import { fetchPersistedConversationListQuery } from "@/queries/useConversationListQuery";
import logger from "@utils/logger";
import { useEffect } from "react";
import { getAccountsList } from "@data/store/accountsStore";
Expand Down Expand Up @@ -34,7 +34,7 @@ export default function HydrationStateHandler() {

const results = await Promise.allSettled([
getXmtpClient(account),
fetchPersistedConversationListQuery(account),
fetchPersistedConversationListQuery({ account }),
prefetchInboxIdQuery({ account }),
]);

Expand Down
54 changes: 27 additions & 27 deletions components/V3DMListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import { DmWithCodecsType } from "@utils/xmtpRN/client";
import { ConversationListItemDumb } from "./ConversationListItem/ConversationListItemDumb";
import { useCallback, useMemo, useRef } from "react";
import Avatar from "./Avatar";
import {
resetConversationListContextMenuStore,
setConversationListContextMenuConversationData,
} from "@/features/conversation-list/ConversationListContextMenu.store";
import { useHandleDeleteDm } from "@/features/conversation-list/hooks/useHandleDeleteDm";
import { useDmPeerInboxId } from "@/queries/useDmPeerInbox";
import { useAppTheme } from "@/theme/useAppTheme";
import { useChatStore, useCurrentAccount } from "@data/store/accountsStore";
import { AvatarSizes } from "@styles/sizes";
import { getMinimalDate } from "@utils/date";
import { useColorScheme } from "react-native";
import { useSelect } from "@data/store/storeHelpers";
import { IIconName } from "@design-system/Icon/Icon.types";
import { useDmPeerInboxOnConversationList } from "@queries/useDmPeerInboxOnConversationList";
import { usePreferredInboxName } from "@hooks/usePreferredInboxName";
import { usePreferredInboxAvatar } from "@hooks/usePreferredInboxAvatar";
import { usePreferredInboxName } from "@hooks/usePreferredInboxName";
import { translate } from "@i18n/index";
import { useRoute } from "@navigation/useNavigation";
import { AvatarSizes } from "@styles/sizes";
import { getMinimalDate } from "@utils/date";
import { Haptics } from "@utils/haptics";
import { navigate } from "@utils/navigation";
import { DmWithCodecsType } from "@utils/xmtpRN/client";
import { useCallback, useMemo, useRef } from "react";
import { useColorScheme } from "react-native";
import { Swipeable } from "react-native-gesture-handler";
import { useSelect } from "@data/store/storeHelpers";
import { Haptics } from "@utils/haptics";
import { runOnJS } from "react-native-reanimated";
import { translate } from "@i18n/index";
import { useToggleReadStatus } from "../features/conversation-list/hooks/useToggleReadStatus";
import { useMessageText } from "../features/conversation-list/hooks/useMessageText";
import { useRoute } from "@navigation/useNavigation";
import { useConversationIsUnread } from "../features/conversation-list/hooks/useMessageIsUnread";
import {
resetConversationListContextMenuStore,
setConversationListContextMenuConversationData,
} from "@/features/conversation-list/ConversationListContextMenu.store";
import { useHandleDeleteDm } from "@/features/conversation-list/hooks/useHandleDeleteDm";
import { useMessageText } from "../features/conversation-list/hooks/useMessageText";
import { useToggleReadStatus } from "../features/conversation-list/hooks/useToggleReadStatus";
import Avatar from "./Avatar";
import { ContextMenuIcon, ContextMenuItem } from "./ContextMenuItems";
import { useAppTheme } from "@/theme/useAppTheme";
import { ConversationListItemDumb } from "./ConversationListItem/ConversationListItemDumb";

type V3DMListItemProps = {
conversation: DmWithCodecsType;
Expand Down Expand Up @@ -58,10 +58,10 @@ export const V3DMListItem = ({ conversation }: V3DMListItemProps) => {
useSelect(["setPinnedConversations"])
);

const { data: peer } = useDmPeerInboxOnConversationList(
currentAccount!,
conversation
);
const { data: peerInboxId } = useDmPeerInboxId({
account: currentAccount!,
topic,
});

Comment on lines +61 to +64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for missing peerInboxId.

The hook usage should handle cases where peerInboxId data is undefined.

-  const { data: peerInboxId } = useDmPeerInboxId({
+  const { data: peerInboxId, error } = useDmPeerInboxId({
     account: currentAccount!,
     topic,
   });
+  
+  if (error) {
+    console.error('Failed to fetch peer inbox ID:', error);
+  }
+
+  if (!peerInboxId) {
+    // Handle missing data case
+    return null;
+  }

Committable suggestion skipped: line range outside the PR's diff.

const timestamp = conversation?.lastMessage?.sentNs ?? 0;
const timeToShow = getMinimalDate(timestamp);
Expand All @@ -79,8 +79,8 @@ export const V3DMListItem = ({ conversation }: V3DMListItemProps) => {
const { theme } = useAppTheme();

const messageText = useMessageText(conversation.lastMessage);
const preferredName = usePreferredInboxName(peer);
const avatarUri = usePreferredInboxAvatar(peer);
const preferredName = usePreferredInboxName(peerInboxId);
const avatarUri = usePreferredInboxAvatar(peerInboxId);

const toggleReadStatus = useToggleReadStatus({
topic,
Expand Down
15 changes: 9 additions & 6 deletions containers/GroupScreenAddition.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useGroupNameQuery } from "@/queries/useGroupNameQuery";
import { useChatStore, useCurrentAccount } from "@data/store/accountsStore";
import { useSelect } from "@data/store/storeHelpers";
import { Icon } from "@design-system/Icon/Icon";
import { useExistingGroupInviteLink } from "@hooks/useExistingGroupInviteLink";
import { useGroupDescription } from "@hooks/useGroupDescription";
import { useGroupMembers } from "@hooks/useGroupMembers";
import { useGroupName } from "@hooks/useGroupName";
import { useGroupPermissions } from "@hooks/useGroupPermissions";
import { useGroupPhoto } from "@hooks/useGroupPhoto";
import { translate } from "@i18n";
Expand All @@ -31,16 +31,16 @@ import {
Platform,
StyleSheet,
TouchableOpacity,
useColorScheme,
View,
useColorScheme,
} from "react-native";
import { Portal, Snackbar, Text } from "react-native-paper";
import {
saveGroupInviteLink,
deleteGroupInviteLink as deleteLinkFromStore,
saveInviteIdByGroupId,
deleteInviteIdByGroupId,
deleteGroupInviteLink as deleteLinkFromStore,
getInviteIdByGroupId,
saveGroupInviteLink,
saveInviteIdByGroupId,
} from "../features/GroupInvites/groupInvites.utils";

type GroupScreenAdditionProps = {
Expand Down Expand Up @@ -75,7 +75,10 @@ export const GroupScreenAddition: FC<GroupScreenAdditionProps> = ({
currentAccountIsAdmin,
currentAccountIsSuperAdmin
);
const { groupName } = useGroupName(topic);
const { data: groupName } = useGroupNameQuery({
account: currentAccount,
topic,
});
const { groupPhoto } = useGroupPhoto(topic);
const { groupDescription } = useGroupDescription(topic);

Expand Down
16 changes: 8 additions & 8 deletions containers/GroupScreenName.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useGroupName } from "@/hooks/useGroupName";
import { useCurrentAccount } from "@data/store/accountsStore";
import { useGroupMembers } from "@hooks/useGroupMembers";
import { useGroupName } from "@hooks/useGroupName";
import { useGroupPermissions } from "@hooks/useGroupPermissions";
import { textPrimaryColor } from "@styles/colors";
import {
Expand All @@ -13,12 +13,12 @@ import { formatGroupName } from "@utils/str";
import type { ConversationTopic } from "@xmtp/react-native-sdk";
import React, { FC, useCallback, useMemo, useState } from "react";
import {
Alert,
Pressable,
StyleSheet,
Text,
TextInput,
useColorScheme,
Text,
Alert,
Pressable,
} from "react-native";

type GroupScreenNameProps = {
Expand All @@ -28,9 +28,9 @@ type GroupScreenNameProps = {
export const GroupScreenName: FC<GroupScreenNameProps> = ({ topic }) => {
const styles = useStyles();
const { permissions } = useGroupPermissions(topic);
const { groupName, setGroupName } = useGroupName(topic);
const currentAccount = useCurrentAccount()!;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider safer type handling for currentAccount.

The non-null assertion (!) could lead to runtime errors if currentAccount is undefined. Consider adding a proper type check.

-const currentAccount = useCurrentAccount()!;
+const currentAccount = useCurrentAccount();
+if (!currentAccount) {
+  return null; // or handle the case appropriately
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const currentAccount = useCurrentAccount()!;
const currentAccount = useCurrentAccount();
if (!currentAccount) {
return null; // or handle the case appropriately
}

const { updateGroupName, groupName } = useGroupName(topic);
const formattedGroupName = formatGroupName(topic, groupName);
const currentAccount = useCurrentAccount() as string;
const { members } = useGroupMembers(topic);

const { currentAccountIsAdmin, currentAccountIsSuperAdmin } = useMemo(
Expand All @@ -49,12 +49,12 @@ export const GroupScreenName: FC<GroupScreenNameProps> = ({ topic }) => {
const handleNameChange = useCallback(async () => {
try {
setEditing(false);
await setGroupName(editedName);
await updateGroupName(editedName);
} catch (e) {
logger.error(e);
Alert.alert("An error occurred");
}
}, [editedName, setGroupName]);
}, [editedName, updateGroupName]);
const canEditGroupName = memberCanUpdateGroup(
permissions?.updateGroupNamePolicy,
currentAccountIsAdmin,
Expand Down
Loading
Loading