Skip to content

Commit

Permalink
fix: double tap reaction + keyboard staying in place when long press …
Browse files Browse the repository at this point in the history
…on message + fix for new SDK senderInboxId + many other stuff (#1401)

* more chat fixes

* fix back pod + yoga

* remove logs

* fix comments + more fixes

* fix tsc
  • Loading branch information
thierryskoda authored Dec 20, 2024
1 parent a4ada0c commit 3996b51
Show file tree
Hide file tree
Showing 44 changed files with 465 additions and 639 deletions.
8 changes: 4 additions & 4 deletions containers/GroupScreenMembersTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ export const GroupScreenMembersTable: FC<GroupScreenMembersTableProps> = memo(
const colorScheme = useColorScheme();
const currentAccount = useCurrentAccount() as string;
const styles = useStyles();
const { data: members } = useGroupMembersConversationScreenQuery(
currentAccount,
topic
);
const { data: members } = useGroupMembersConversationScreenQuery({
account: currentAccount,
topic,
});
const {
promoteToSuperAdmin,
promoteToAdmin,
Expand Down
120 changes: 0 additions & 120 deletions data/store/chatStore.ts
Original file line number Diff line number Diff line change
@@ -1,93 +1,9 @@
import logger from "@utils/logger";
import { RemoteAttachmentContent } from "@xmtp/react-native-sdk";
import isDeepEqual from "fast-deep-equal";
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
import { Nullable } from "../../types/general";
import { zustandMMKVStorage } from "../../utils/mmkv";

// Chat data for each user

type XmtpConversationContext = {
conversationId: string;
metadata: {
[k: string]: string;
};
};

type XmtpConversationShared = {
topic: string;
createdAt: number;
context?: XmtpConversationContext;
messages: Map<string, XmtpMessage>;
messagesIds: string[];
messageDraft?: string;
mediaPreview?: MessageAttachment;
readUntil: number; // UNUSED
hasOneMessageFromMe?: boolean;
pending: boolean;
version: string;
spamScore?: number;
lastNotificationsSubscribedPeriod?: number;
};

export type XmtpDMConversation = XmtpConversationShared & {
isGroup: false;
peerAddress: string;
groupMembers?: undefined;
groupAdmins?: undefined;
groupPermissionLevel?: undefined;
groupCreator?: undefined;
groupAddedBy?: undefined;
};

/**
* @deprecated - Use the conversation from query instead
*/
export type XmtpGroupConversation = XmtpConversationShared & {
isGroup: true;
peerAddress?: undefined;
groupMembers: string[];
groupPermissionLevel: "all_members" | "admin_only" | "custom_policy";
groupName?: string;
groupCreator?: string;
groupAddedBy?: string;
isActive?: boolean;
};

/**
* @deprecated - Use the conversation from query instead
*/
export type XmtpConversation = XmtpDMConversation | XmtpGroupConversation;

/**
* @deprecated - Use the conversation from query instead
*/
export type XmtpConversationWithUpdate = XmtpConversation & {
lastUpdateAt: number;
};

type XmtpProtocolMessage = {
id: string;
senderAddress: string;
sent: number;
content: string;
contentType: string;
topic: string;
};

/**
* @deprecated - Use DecodedMessageWithCodeca instead
*/
export type XmtpMessage = XmtpProtocolMessage & {
status: "delivered" | "error" | "seen" | "sending" | "sent" | "prepared";
reactions?: Map<string, XmtpMessage>;
contentFallback?: string;
referencedMessageId?: string;
lastUpdateAt?: number;
localMediaURI?: string;
};

export type TopicStatus = "deleted" | "unread" | "read";

export type TopicData = {
Expand All @@ -101,41 +17,10 @@ export type TopicsData = {
[topic: string]: TopicData | undefined;
};

export type MessageAttachmentPreview = {
mediaURI: string;
mimeType: Nullable<string>;
dimensions?: {
width: number;
height: number;
};
};

export type MessageAttachmentUploaded = MessageAttachmentPreview &
RemoteAttachmentContent;

export type MessageAttachment =
| MessageAttachmentPreview
| MessageAttachmentUploaded
| null;

export type MessageAttachmentTodo = {
loading: boolean;
error: boolean;
mediaType: "IMAGE" | "UNSUPPORTED" | undefined;
mediaURL: string | undefined;
filename: string;
mimeType: string;
contentLength: number;
imageSize: { height: number; width: number } | undefined;
};

export type ChatStoreType = {
/**
* @deprecated - Use the conversation from query instead
*/
conversations: {
[topic: string]: XmtpConversationWithUpdate;
};
pinnedConversationTopics: string[];
openedConversationTopic: string | null;
lastUpdateAt: number;
Expand All @@ -150,8 +35,6 @@ export type ChatStoreType = {
topicsData: TopicsData;
topicsDataFetchedOnce: boolean | undefined;

conversationsSortedOnce: boolean;

searchQuery: string;
setSearchQuery: (query: string) => void;
searchBarFocused: boolean;
Expand Down Expand Up @@ -191,15 +74,12 @@ export const initChatStore = (account: string) => {
persist(
(set) =>
({
conversations: {},
pinnedConversationTopics: [],
lastSyncedAt: 0,
lastSyncedTopics: [],
topicsData: {},
topicsDataFetchedOnce: false,
openedConversationTopic: "",
conversationsMapping: {},
conversationsSortedOnce: false,
lastUpdateAt: 0,
searchQuery: "",
setSearchQuery: (q) => set(() => ({ searchQuery: q })),
Expand Down
1 change: 1 addition & 0 deletions features/GroupInvites/joinGroup/JoinGroup.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {} from "../groupInvites.utils";
import { JoinGroupResult } from "./joinGroup.types";
import { ConversationListQueryData } from "@/queries/useConversationListQuery";
import { entify } from "@/queries/entify";
import { wait } from "@/utils/general";

const GROUP_JOIN_REQUEST_POLL_MAX_ATTEMPTS = 10;
const GROUP_JOIN_REQUEST_POLL_INTERVAL_MS = 1000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import {
isTransactionReferenceMessage,
useConversationMessageById,
} from "@/features/conversation/conversation-message/conversation-message.utils";
import { useCurrentAccountInboxId } from "@/hooks/use-current-account-inbox-id";
import { messageIsFromCurrentAccountInboxId } from "@/features/conversation/utils/message-is-from-current-user";
import { usePreferredInboxName } from "@/hooks/usePreferredInboxName";
import { DecodedMessageWithCodecsType } from "@/utils/xmtpRN/client.types";
import { HStack } from "@design-system/HStack";
import { Icon } from "@design-system/Icon/Icon";
import { IconButton } from "@design-system/IconButton/IconButton";
Expand All @@ -21,10 +22,8 @@ import { useMessageText } from "@features/conversation-list/hooks/useMessageText
import { SICK_DAMPING, SICK_STIFFNESS } from "@theme/animations";
import { useAppTheme } from "@theme/useAppTheme";
import { Haptics } from "@utils/haptics";
import { DecodedMessageWithCodecsType } from "@/utils/xmtpRN/client.types";
import {
DecodedMessage,
InboxId,
RemoteAttachmentCodec,
ReplyCodec,
StaticAttachmentCodec,
Expand All @@ -50,20 +49,17 @@ export const ReplyPreview = memo(function ReplyPreview() {

const composerStore = useConversationComposerStore();

const { data: currentAccountInboxId } = useCurrentAccountInboxId();
const topic = useCurrentConversationTopic();

const { message: replyMessage } = useConversationMessageById({
messageId: replyingToMessageId!, // ! because we have enabled in the query
topic,
});

const inboxName = usePreferredInboxName(
replyMessage?.senderInboxId as InboxId
);
const inboxName = usePreferredInboxName(replyMessage?.senderInboxId);

const replyingTo = replyMessage
? replyMessage.senderInboxId === currentAccountInboxId
? messageIsFromCurrentAccountInboxId({ message: replyMessage })
? `Replying to you`
: inboxName
? `Replying to ${inboxName}`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ConversationTitle } from "@/features/conversation/conversation-title";
import { ConversationHeaderTitle } from "@/features/conversation/conversation-header/conversation-header-title";
import { usePreferredInboxAddress } from "@/hooks/usePreferredInboxAddress";
import { useDmPeerInboxId } from "@/queries/useDmPeerInbox";
import { copyToClipboard } from "@/utils/clipboard";
Expand Down Expand Up @@ -47,7 +47,7 @@ export const DmConversationTitle = ({ topic }: DmConversationTitleProps) => {
if (!displayAvatar) return null;

return (
<ConversationTitle
<ConversationHeaderTitle
title={preferredName}
onLongPress={onLongPress}
onPress={onPress}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Text } from "@/design-system/Text";
import { ConversationTitle } from "@/features/conversation/conversation-title";
import { useGroupNameConvos } from "@/features/conversation/hooks/use-group-name-convos";
import { ConversationHeaderTitle } from "@/features/conversation/conversation-header/conversation-header-title";
import { useGroupName } from "@/hooks/useGroupName";
import { useGroupPendingRequests } from "@/hooks/useGroupPendingRequests";
import { useProfilesSocials } from "@/hooks/useProfilesSocials";
import {
Expand Down Expand Up @@ -33,14 +33,14 @@ export const GroupConversationTitle = memo(
topic,
});

const { data: members } = useGroupMembersQuery(currentAccount, topic!);
const { data: members } = useGroupMembersQuery({
account: currentAccount,
topic: topic!,
});

const { data: memberData } = useGroupMembersAvatarData({ topic });

const { groupName, isLoading: groupNameLoading } = useGroupNameConvos({
topic,
account: currentAccount,
});
const { groupName, isLoading: groupNameLoading } = useGroupName(topic);

const navigation = useRouter();

Expand Down Expand Up @@ -75,7 +75,7 @@ export const GroupConversationTitle = memo(
const displayMemberText = members?.ids.length;

return (
<ConversationTitle
<ConversationHeaderTitle
title={groupName ?? undefined}
onLongPress={onLongPress}
onPress={onPress}
Expand Down Expand Up @@ -109,10 +109,10 @@ type IMemberData = {
const useGroupMembersAvatarData = (args: { topic: ConversationTopic }) => {
const { topic } = args;
const currentAccount = useCurrentAccount()!;
const { data: members, ...query } = useGroupMembersConversationScreenQuery(
currentAccount,
topic
);
const { data: members, ...query } = useGroupMembersConversationScreenQuery({
account: currentAccount,
topic,
});

const memberAddresses = useMemo(() => {
if (!members?.ids) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConversationTitleDumbProps = {
onPress?: () => void;
};

export function ConversationTitle({
export function ConversationHeaderTitle({
avatarComponent,
title,
subtitle,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ConversationTitle } from "@/features/conversation/conversation-title";
import { ConversationHeaderTitle } from "@/features/conversation/conversation-header/conversation-header-title";
import Avatar from "@components/Avatar";
import { usePreferredAvatarUri } from "@hooks/usePreferredAvatarUri";
import { usePreferredName } from "@hooks/usePreferredName";
Expand Down Expand Up @@ -35,7 +35,7 @@ export const NewConversationTitle = ({
if (!displayAvatar) return null;

return (
<ConversationTitle
<ConversationHeaderTitle
title={preferredName}
onPress={onPress}
avatarComponent={
Expand Down
24 changes: 12 additions & 12 deletions features/conversation/conversation-keyboard-filler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@ export const KeyboardFiller = memo(function KeyboardFiller(
const isKeyboardShown = useKeyboardIsShown();

useEffect(() => {
// Context menu was hidden
if (!messageContextMenuIsOpen) {
// Reopen keyboard if it was open before context menu was shown
if (keyboardWasOpenRef.current) {
textInputRef.current?.focus();
}
}
// Context menu is shown
else {
if (messageContextMenuIsOpen) {
// If the keyboard is open, keep track of where it was because we need to open it again when the context menu is dismissed
if (isKeyboardShown) {
Keyboard.dismiss();
lastKeyboardHeight.value = keyboardHeight.value;
keyboardWasOpenRef.current = true;
} else {
}
}
// Context menu is hidden
else {
// Reopen keyboard if it was open before context menu was shown
if (keyboardWasOpenRef.current) {
textInputRef.current?.focus();
keyboardWasOpenRef.current = false;
}
}
Expand All @@ -62,7 +61,7 @@ export const KeyboardFiller = memo(function KeyboardFiller(
lastKeyboardHeight,
]);

const animatedStyle = useAnimatedStyle(() => {
const fillerAnimatedStyle = useAnimatedStyle(() => {
return {
height: Math.max(
Math.max(lastKeyboardHeight.value, keyboardHeight.value) -
Expand All @@ -74,7 +73,8 @@ export const KeyboardFiller = memo(function KeyboardFiller(

return (
<>
<AnimatedVStack style={animatedStyle} />
<AnimatedVStack style={fillerAnimatedStyle} />
{/* Need for focus on keyboard */}
<TextInput
ref={textInputRef}
style={{ height: 0, width: 0, opacity: 0, position: "absolute" }}
Expand Down
Loading

0 comments on commit 3996b51

Please sign in to comment.