Page MenuHomePhorge

D15354.1765044589.diff
No OneTemporary

Size
24 KB
Referenced Files
None
Subscribers
None

D15354.1765044589.diff

diff --git a/lib/hooks/input-state-container-hooks.js b/lib/hooks/input-state-container-hooks.js
--- a/lib/hooks/input-state-container-hooks.js
+++ b/lib/hooks/input-state-container-hooks.js
@@ -1,5 +1,6 @@
// @flow
+import invariant from 'invariant';
import * as React from 'react';
import {
@@ -11,6 +12,7 @@
import { useProcessBlobHolders } from '../actions/holder-actions.js';
import { useSendComposableDMOperation } from '../shared/dm-ops/process-dm-ops.js';
import { useSendFarcasterTextMessage } from '../shared/farcaster/farcaster-api.js';
+import { useFetchConversation } from '../shared/farcaster/farcaster-hooks.js';
import { useMessageCreationSideEffectsFunc } from '../shared/message-utils.js';
import { threadSpecs } from '../shared/threads/thread-specs.js';
import { messageTypes } from '../types/message-types-enum.js';
@@ -21,7 +23,6 @@
} from '../types/message-types.js';
import type { RawTextMessageInfo } from '../types/messages/text.js';
import type { ThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
-import { useCurrentUserFID } from '../utils/farcaster-utils.js';
import { useSelector, useDispatch } from '../utils/redux-utils.js';
function useInputStateContainerSendTextMessage(): (
@@ -35,7 +36,10 @@
const sendFarcasterTextMessage = useSendFarcasterTextMessage();
const sideEffectsFunction =
useMessageCreationSideEffectsFunc<RawTextMessageInfo>(messageTypes.TEXT);
- const currentUserFID = useCurrentUserFID();
+ const auxUserStore = useSelector(state => state.auxUserStore);
+ const viewerID = useSelector(state => state.currentUserInfo?.id);
+ const farcasterFetchConversation = useFetchConversation();
+ const threadInfos = useSelector(state => state.threadStore.threadInfos);
return React.useCallback(
(
@@ -43,8 +47,9 @@
threadInfo: ThreadInfo,
parentThreadInfo: ?ThreadInfo,
sidebarCreation: boolean,
- ) =>
- threadSpecs[threadInfo.type].protocol().sendTextMessage(
+ ) => {
+ invariant(viewerID, 'Viewer ID should be present');
+ return threadSpecs[threadInfo.type].protocol().sendTextMessage(
{
messageInfo,
threadInfo,
@@ -54,17 +59,24 @@
{
sendKeyserverTextMessage,
sendComposableDMOperation,
- sideEffectsFunction,
sendFarcasterTextMessage,
- currentUserFID,
+ viewerID,
+ sideEffectsFunction,
+ auxUserStore,
+ farcasterFetchConversation,
+ threadInfos,
},
- ),
+ );
+ },
[
- sendComposableDMOperation,
sendKeyserverTextMessage,
- sideEffectsFunction,
+ sendComposableDMOperation,
sendFarcasterTextMessage,
- currentUserFID,
+ viewerID,
+ sideEffectsFunction,
+ auxUserStore,
+ farcasterFetchConversation,
+ threadInfos,
],
);
}
@@ -84,7 +96,10 @@
const dispatch = useDispatch();
const sendFarcasterTextMessage = useSendFarcasterTextMessage();
- const currentUserFID = useCurrentUserFID();
+
+ const auxUserStore = useSelector(state => state.auxUserStore);
+ const viewerID = useSelector(state => state.currentUserInfo?.id);
+ const farcasterFetchConversation = useFetchConversation();
return React.useCallback(
async (
@@ -93,6 +108,7 @@
isLegacy: boolean,
) => {
const threadInfo = threadInfos[messageInfo.threadID];
+ invariant(viewerID, 'Viewer ID should be present');
return threadSpecs[threadInfo.type].protocol().sendMultimediaMessage(
{
messageInfo,
@@ -107,21 +123,26 @@
reassignThickThreadMedia,
processHolders,
dispatch,
- currentUserFID,
+ viewerID,
sendFarcasterTextMessage,
+ auxUserStore,
+ farcasterFetchConversation,
+ threadInfos,
},
);
},
[
- dispatch,
+ threadInfos,
+ sendMultimediaMessage,
legacySendMultimediaMessage,
- processHolders,
- reassignThickThreadMedia,
sendComposableDMOperation,
- sendMultimediaMessage,
- threadInfos,
- currentUserFID,
+ reassignThickThreadMedia,
+ processHolders,
+ dispatch,
+ viewerID,
sendFarcasterTextMessage,
+ auxUserStore,
+ farcasterFetchConversation,
],
);
}
diff --git a/lib/shared/farcaster/farcaster-api.js b/lib/shared/farcaster/farcaster-api.js
--- a/lib/shared/farcaster/farcaster-api.js
+++ b/lib/shared/farcaster/farcaster-api.js
@@ -29,7 +29,7 @@
+groupId: string,
+message: string,
}
- | { +recipientFid: string, +message: string };
+ | { +recipientFid: number, +message: string };
type SendFarcasterMessageResultData = {
+messageId: string,
diff --git a/lib/shared/threads/protocols/farcaster-thread-protocol.js b/lib/shared/threads/protocols/farcaster-thread-protocol.js
--- a/lib/shared/threads/protocols/farcaster-thread-protocol.js
+++ b/lib/shared/threads/protocols/farcaster-thread-protocol.js
@@ -1,6 +1,7 @@
// @flow
import invariant from 'invariant';
+import uuid from 'uuid';
import {
changeThreadMemberRolesActionTypes,
@@ -12,6 +13,7 @@
import { getFarcasterRolePermissionsBlobs } from '../../../permissions/farcaster-permissions.js';
import type { RolePermissionBlobs } from '../../../permissions/thread-permissions.js';
import type { SetThreadUnreadStatusPayload } from '../../../types/activity-types.js';
+import type { AuxUserStore } from '../../../types/aux-user-types.js';
import type {
CreateEntryPayload,
DeleteEntryResult,
@@ -20,6 +22,7 @@
import { messageTypes } from '../../../types/message-types-enum.js';
import {
defaultNumberPerThread,
+ messageTruncationStatus,
type SendMessagePayload,
type SendMultimediaMessagePayload,
} from '../../../types/message-types.js';
@@ -44,17 +47,22 @@
import type {
ChangeThreadSettingsPayload,
ClientDBThreadInfo,
+ RawThreadInfos,
ThreadJoinPayload,
} from '../../../types/thread-types.js';
import { updateTypes } from '../../../types/update-types-enum.js';
import { messageIDToCompoundReactionID } from '../../../utils/convert-farcaster-message-to-comm-messages.js';
+import { createFarcasterRawThreadInfoPersonal } from '../../../utils/create-farcaster-raw-thread-info.js';
import { farcasterThreadIDRegExp } from '../../../utils/validation-utils.js';
import { generatePendingThreadColor } from '../../color-utils.js';
import { processFarcasterOpsActionType } from '../../farcaster/farcaster-actions.js';
-import {
- type ModifyFarcasterMembershipInput,
- type SendReactionInput,
+import type {
+ ModifyFarcasterMembershipInput,
+ SendReactionInput,
+ SendFarcasterMessageResult,
+ SendFarcasterTextMessageInput,
} from '../../farcaster/farcaster-api.js';
+import type { FarcasterConversation } from '../../farcaster/farcaster-conversation-types.js';
import {
conversationIDFromFarcasterThreadID,
extractFIDFromUserID,
@@ -98,13 +106,84 @@
ProtocolSendReactionInput,
SendReactionUtils,
} from '../thread-spec.js';
+import { threadTypeIsPersonal } from '../thread-specs.js';
+
+async function sendFarcasterMessage({
+ threadInfo,
+ viewerID,
+ auxUserStore,
+ text,
+ sendFarcasterTextMessage,
+ threadInfos,
+ farcasterFetchConversation,
+}: {
+ threadInfo: ThreadInfo | RawThreadInfo,
+ viewerID: string,
+ auxUserStore: AuxUserStore,
+ text: string,
+ sendFarcasterTextMessage: SendFarcasterTextMessageInput => Promise<SendFarcasterMessageResult>,
+ threadInfos: RawThreadInfos,
+ farcasterFetchConversation: (
+ conversationID: string,
+ ) => Promise<?FarcasterConversation>,
+}) {
+ const time = Date.now();
+
+ let request;
+ if (threadInfo.type === farcasterThreadTypes.FARCASTER_PERSONAL) {
+ const otherUser = getSingleOtherUser(threadInfo, viewerID);
+ invariant(
+ otherUser,
+ `Farcaster 1:1 conversation should have one more member except ${
+ viewerID ?? 'null'
+ }`,
+ );
+ const targetFid =
+ auxUserStore.auxUserInfos[otherUser]?.fid ??
+ extractFIDFromUserID(otherUser);
+
+ if (!targetFid) {
+ throw new Error('Missing target fid');
+ }
+
+ const recipientFid = parseInt(targetFid, 10);
+ request = {
+ recipientFid,
+ message: text,
+ };
+ } else {
+ const conversationID = conversationIDFromFarcasterThreadID(threadInfo.id);
+ request = {
+ groupId: conversationID,
+ message: text,
+ };
+ }
+
+ const result = await sendFarcasterTextMessage(request);
+
+ if (
+ threadInfo.type === farcasterThreadTypes.FARCASTER_PERSONAL &&
+ !threadInfos[threadInfo.id]
+ ) {
+ await farcasterFetchConversation(
+ conversationIDFromFarcasterThreadID(threadInfo.id),
+ );
+ }
+ return { time, result };
+}
const farcasterThreadProtocol: ThreadProtocol<MemberInfoSansPermissions> = {
sendTextMessage: async (
message: ProtocolSendTextMessageInput,
utils: SendTextMessageUtils,
): Promise<SendMessagePayload> => {
- const { sendFarcasterTextMessage, currentUserFID } = utils;
+ const {
+ sendFarcasterTextMessage,
+ viewerID,
+ auxUserStore,
+ farcasterFetchConversation,
+ threadInfos,
+ } = utils;
const { messageInfo, threadInfo } = message;
const { localID } = messageInfo;
invariant(
@@ -112,35 +191,20 @@
'localID should be set',
);
- const time = Date.now();
-
- let request;
- if (threadInfo.type === farcasterThreadTypes.FARCASTER_PERSONAL) {
- const otherUser = getSingleOtherUser(threadInfo, currentUserFID);
- invariant(
- otherUser,
- `Farcaster 1:1 conversation should have one more member except ${
- currentUserFID ?? 'null'
- }`,
- );
- request = {
- recipientFid: otherUser,
- message: messageInfo.text,
- };
- } else {
- const conversationID = conversationIDFromFarcasterThreadID(threadInfo.id);
- request = {
- groupId: conversationID,
- message: messageInfo.text,
- };
- }
-
- const result = await sendFarcasterTextMessage(request);
+ const { time, result } = await sendFarcasterMessage({
+ threadInfo,
+ viewerID,
+ auxUserStore,
+ text: messageInfo.text,
+ sendFarcasterTextMessage,
+ threadInfos,
+ farcasterFetchConversation,
+ });
return {
localID,
serverID: result.result.messageId,
- threadID: messageInfo.threadID,
+ threadID: threadInfo.id,
time: time,
};
},
@@ -150,15 +214,19 @@
utils: SendMultimediaMessageUtils,
): Promise<SendMultimediaMessagePayload> => {
const { messageInfo, threadInfo } = message;
- const { sendFarcasterTextMessage, currentUserFID } = utils;
+ const {
+ sendFarcasterTextMessage,
+ viewerID,
+ auxUserStore,
+ farcasterFetchConversation,
+ threadInfos,
+ } = utils;
const { localID, media } = messageInfo;
invariant(
localID !== null && localID !== undefined,
'localID should be set',
);
- const time = Date.now();
-
const messageText = media
.map(m => {
if (m.type === 'photo' || m.type === 'video') {
@@ -169,28 +237,15 @@
.filter(Boolean)
.join('\n');
- let request;
- if (threadInfo.type === farcasterThreadTypes.FARCASTER_PERSONAL) {
- const otherUser = getSingleOtherUser(threadInfo, currentUserFID);
- invariant(
- otherUser,
- `Farcaster 1:1 conversation should have one more member except ${
- currentUserFID ?? 'null'
- }`,
- );
- request = {
- recipientFid: otherUser,
- message: messageText,
- };
- } else {
- const conversationID = conversationIDFromFarcasterThreadID(threadInfo.id);
- request = {
- groupId: conversationID,
- message: messageText,
- };
- }
-
- const result = await sendFarcasterTextMessage(request);
+ const { time, result } = await sendFarcasterMessage({
+ threadInfo,
+ viewerID,
+ auxUserStore,
+ text: messageText,
+ sendFarcasterTextMessage,
+ threadInfos,
+ farcasterFetchConversation,
+ });
return {
result: {
@@ -751,6 +806,7 @@
createFarcasterGroup,
viewerID,
auxUserStore,
+ dispatch,
} = params;
if (!threadIsPending(threadInfo.id)) {
return {
@@ -758,6 +814,7 @@
threadType: threadInfo.type,
};
}
+ invariant(viewerID, 'Viewer ID should be present');
const name =
threadInfo.name ??
@@ -773,6 +830,47 @@
.filter(Boolean)
.map(id => parseInt(id, 10));
+ if (threadTypeIsPersonal(threadInfo.type)) {
+ const viewerFid =
+ auxUserStore.auxUserInfos[viewerID]?.fid ??
+ extractFIDFromUserID(viewerID);
+
+ const otherUserFid = otherMembersFIDs[0];
+
+ // We can deterministically generate a future conversation ID for 1:1
+ const conversationID = [viewerFid, otherUserFid].sort().join('-');
+
+ // We construct a thread here to make it work with our design.
+ // When sending a message, the thread is going to be fetched,
+ // so Farcaster remains the source of truth
+ const threadID = farcasterThreadIDFromConversationID(conversationID);
+ dispatch({
+ type: processFarcasterOpsActionType,
+ payload: {
+ rawMessageInfos: [],
+ updateInfos: [
+ {
+ type: updateTypes.JOIN_THREAD,
+ id: uuid.v4(),
+ time: Date.now(),
+ threadInfo: createFarcasterRawThreadInfoPersonal({
+ ...threadInfo,
+ id: threadID,
+ }),
+ rawMessageInfos: [],
+ truncationStatus: messageTruncationStatus.UNCHANGED,
+ rawEntryInfos: [],
+ },
+ ],
+ },
+ });
+
+ return {
+ threadID,
+ threadType: threadInfo.type,
+ };
+ }
+
let input = {
participantFids: otherMembersFIDs,
name: name.substring(0, 32),
diff --git a/lib/shared/threads/thread-spec.js b/lib/shared/threads/thread-spec.js
--- a/lib/shared/threads/thread-spec.js
+++ b/lib/shared/threads/thread-spec.js
@@ -80,6 +80,7 @@
LeaveThreadPayload,
NewThickThreadRequest,
NewThreadResult,
+ RawThreadInfos,
ThreadJoinPayload,
UpdateThreadRequest,
} from '../../types/thread-types.js';
@@ -127,8 +128,13 @@
+sendKeyserverTextMessage: SendTextMessageInput => Promise<SendMessageResult>,
+sendComposableDMOperation: OutboundComposableDMOperationSpecification => Promise<ProcessOutboundP2PMessagesResult>,
+sendFarcasterTextMessage: SendFarcasterTextMessageInput => Promise<SendFarcasterMessageResult>,
- +currentUserFID: ?string,
+ +viewerID: string,
+sideEffectsFunction: CreationSideEffectsFunc<RawTextMessageInfo>,
+ +auxUserStore: AuxUserStore,
+ +farcasterFetchConversation: (
+ conversationID: string,
+ ) => Promise<?FarcasterConversation>,
+ +threadInfos: RawThreadInfos,
};
export type ProtocolSendMultimediaMessageInput = {
@@ -144,8 +150,13 @@
+reassignThickThreadMedia: MediaMetadataReassignmentAction,
+processHolders: ProcessHolders,
+dispatch: Dispatch,
+ +viewerID: string,
+sendFarcasterTextMessage: SendFarcasterTextMessageInput => Promise<SendFarcasterMessageResult>,
- +currentUserFID: ?string,
+ +auxUserStore: AuxUserStore,
+ +farcasterFetchConversation: (
+ conversationID: string,
+ ) => Promise<?FarcasterConversation>,
+ +threadInfos: RawThreadInfos,
};
export type ProtocolEditTextMessageInput = {
@@ -341,6 +352,7 @@
conversationID: string,
) => Promise<?FarcasterConversation>,
+auxUserStore: AuxUserStore,
+ +dispatch: Dispatch,
};
export type ProtocolDeleteMessageInput = {
diff --git a/lib/utils/create-farcaster-raw-thread-info.js b/lib/utils/create-farcaster-raw-thread-info.js
--- a/lib/utils/create-farcaster-raw-thread-info.js
+++ b/lib/utils/create-farcaster-raw-thread-info.js
@@ -1,6 +1,9 @@
// @flow
-import { getFarcasterRolePermissionsBlobsFromConversation } from '../permissions/farcaster-permissions.js';
+import {
+ getFarcasterRolePermissionsBlobs,
+ getFarcasterRolePermissionsBlobsFromConversation,
+} from '../permissions/farcaster-permissions.js';
import { specialRoles } from '../permissions/special-roles.js';
import {
getAllThreadPermissions,
@@ -14,6 +17,7 @@
FarcasterRawThreadInfo,
RoleInfo,
ThreadCurrentUserInfo,
+ ThreadInfo,
} from '../types/minimally-encoded-thread-permissions-types.js';
import {
minimallyEncodeRoleInfo,
@@ -34,17 +38,33 @@
);
}
-function createFarcasterRawThreadInfo(
- conversation: FarcasterConversation,
+type FarcasterThreadData = {
+ +threadID: string,
+ +isGroup: boolean,
+ +permissionBlobs: {
+ +Members: ThreadRolePermissionsBlob,
+ +Admins: ?ThreadRolePermissionsBlob,
+ },
+ +memberIDs: $ReadOnlyArray<string>,
+ +adminIDs: $ReadOnlySet<string>,
+ +viewerAccess: 'read' | 'read-write' | 'admin',
+ +muted: boolean,
+ +unread: boolean,
+ +name: string,
+ +description: string,
+ +createdAt: number,
+ +pinnedCount: number,
+ +avatar: ?ClientAvatar,
+};
+
+function innerCreateFarcasterRawThreadInfo(
+ threadData: FarcasterThreadData,
): FarcasterRawThreadInfo {
- const threadID = farcasterThreadIDFromConversationID(
- conversation.conversationId,
- );
- const threadType = conversation.isGroup
+ const threadID = threadData.threadID;
+ const threadType = threadData.isGroup
? farcasterThreadTypes.FARCASTER_GROUP
: farcasterThreadTypes.FARCASTER_PERSONAL;
- const permissionBlobs =
- getFarcasterRolePermissionsBlobsFromConversation(conversation);
+ const permissionBlobs = threadData.permissionBlobs;
const membersRole: RoleInfo = {
...minimallyEncodeRoleInfo({
@@ -73,45 +93,74 @@
roles[adminsRole.id] = adminsRole;
}
- const removedUsers = new Set(conversation.removedFids);
- const userIDs = conversation.participants
- .filter(p => !removedUsers.has(p.fid))
- .map(p => `${p.fid}`);
- const adminIDs = new Set(conversation.adminFids.map(fid => `${fid}`));
-
- const members = userIDs.map(fid => ({
+ const members = threadData.memberIDs.map(fid => ({
id: fid,
// This flag was introduced for sidebars to show who replied to a thread.
// Now it doesn't seem to be used anywhere. Regardless, for Farcaster
// threads its value doesn't matter.
isSender: true,
minimallyEncoded: true,
- role: adminIDs.has(fid) && adminsRole ? adminsRole.id : membersRole.id,
+ role:
+ threadData.adminIDs.has(fid) && adminsRole
+ ? adminsRole.id
+ : membersRole.id,
}));
const currentUserRole =
- conversation.viewerContext.access === 'admin' && adminsRole
+ threadData.viewerAccess === 'admin' && adminsRole
? adminsRole
: membersRole;
const currentUser: ThreadCurrentUserInfo =
minimallyEncodeThreadCurrentUserInfo({
role: currentUserRole.id,
permissions: createPermissionsInfo(
- conversation.viewerContext.access === 'admin' && permissionBlobs.Admins
+ threadData.viewerAccess === 'admin' && permissionBlobs.Admins
? permissionBlobs.Admins
: permissionBlobs.Members,
threadID,
threadType,
),
subscription: {
- home: !conversation.viewerContext.muted,
- pushNotifs: !conversation.viewerContext.muted,
+ home: !threadData.muted,
+ pushNotifs: !threadData.muted,
},
- unread:
- conversation.viewerContext.unreadCount > 0 ||
- conversation.viewerContext.manuallyMarkedUnread,
+ unread: threadData.unread,
});
+ return {
+ farcaster: true,
+ id: threadData.threadID,
+ type: threadType,
+ name: threadData.name,
+ avatar: threadData.avatar,
+ description: threadData.description,
+ color: generatePendingThreadColor(threadData.memberIDs),
+ parentThreadID: null,
+ community: null,
+ creationTime: threadData.createdAt,
+ repliesCount: 0,
+ pinnedCount: threadData.pinnedCount,
+ minimallyEncoded: true,
+ members,
+ roles,
+ currentUser,
+ };
+}
+
+function createFarcasterRawThreadInfo(
+ conversation: FarcasterConversation,
+): FarcasterRawThreadInfo {
+ const threadID = farcasterThreadIDFromConversationID(
+ conversation.conversationId,
+ );
+ const removedUsers = new Set(conversation.removedFids);
+ const memberIDs = conversation.participants
+ .filter(p => !removedUsers.has(p.fid))
+ .map(p => `${p.fid}`);
+ const adminIDs = new Set(conversation.adminFids.map(fid => `${fid}`));
+ const unread =
+ conversation.unreadCount > 0 ||
+ conversation.viewerContext.manuallyMarkedUnread;
let avatar: ?ClientAvatar;
if (conversation.isGroup) {
avatar = conversation.photoUrl
@@ -121,9 +170,8 @@
const uri = conversation.viewerContext.counterParty?.pfp?.url;
avatar = uri ? { type: 'image', uri } : null;
}
-
- let name = conversation.name;
- let description = conversation.description;
+ let name = conversation.name ?? '';
+ let description = conversation.description ?? '';
if (!conversation.isGroup) {
// For a 1-1 conversation, follow the Farcaster approach and show user's
// name as the conversation name
@@ -134,25 +182,56 @@
name = otherUserName;
description = `Your Direct Cast with ${otherUserName}`;
}
+ const threadData: FarcasterThreadData = {
+ threadID,
+ isGroup: conversation.isGroup,
+ permissionBlobs:
+ getFarcasterRolePermissionsBlobsFromConversation(conversation),
+ memberIDs,
+ adminIDs,
+ viewerAccess: conversation.viewerContext.access,
+ muted: conversation.viewerContext.muted,
+ unread,
+ createdAt: conversation.createdAt,
+ pinnedCount: conversation.pinnedMessages.length,
+ avatar,
+ name,
+ description,
+ };
- return {
- farcaster: true,
- id: threadID,
- type: threadType,
+ return innerCreateFarcasterRawThreadInfo(threadData);
+}
+
+function createFarcasterRawThreadInfoPersonal(
+ threadInfo: ThreadInfo,
+): FarcasterRawThreadInfo {
+ const threadType = farcasterThreadTypes.FARCASTER_PERSONAL;
+ const permissionBlobs = getFarcasterRolePermissionsBlobs(
+ threadType,
+ false,
+ false,
+ );
+ const memberIDs = threadInfo.members.map(member => member.id);
+ const otherUser = threadInfo.members.find(user => !user.isViewer);
+ const name = otherUser?.username ?? 'anonymous';
+ const description = `Your Direct Cast with ${name}`;
+ const threadData: FarcasterThreadData = {
+ threadID: threadInfo.id,
+ isGroup: false,
+ permissionBlobs,
+ memberIDs,
+ adminIDs: new Set(),
+ viewerAccess: 'read-write',
+ muted: false,
+ unread: false,
name,
- avatar,
description,
- color: generatePendingThreadColor(userIDs),
- parentThreadID: null,
- community: null,
- creationTime: conversation.createdAt,
- repliesCount: 0,
- pinnedCount: conversation.pinnedMessages.length,
- minimallyEncoded: true,
- members,
- roles,
- currentUser,
+ createdAt: threadInfo.creationTime,
+ pinnedCount: threadInfo.pinnedCount ?? 0,
+ avatar: null,
};
+
+ return innerCreateFarcasterRawThreadInfo(threadData);
}
-export { createFarcasterRawThreadInfo };
+export { createFarcasterRawThreadInfo, createFarcasterRawThreadInfoPersonal };
diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js
--- a/native/input/input-state-container.react.js
+++ b/native/input/input-state-container.react.js
@@ -595,6 +595,7 @@
createFarcasterGroup: this.props.createFarcasterGroup,
farcasterFetchConversation: this.props.fetchConversation,
auxUserStore: this.props.auxUserStore,
+ dispatch: this.props.dispatch,
});
this.pendingThreadCreations.set(threadInfo.id, threadCreationPromise);
}
diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js
--- a/web/input/input-state-container.react.js
+++ b/web/input/input-state-container.react.js
@@ -612,6 +612,7 @@
createFarcasterGroup: this.props.createFarcasterGroup,
farcasterFetchConversation: this.props.fetchConversation,
auxUserStore: this.props.auxUserStore,
+ dispatch: this.props.dispatch,
});
this.pendingThreadCreations.set(threadInfo.id, threadCreationPromise);
}

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 6, 6:09 PM (4 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5840013
Default Alt Text
D15354.1765044589.diff (24 KB)

Event Timeline