diff --git a/shared/chat/audio/audio-recorder.native.tsx b/shared/chat/audio/audio-recorder.native.tsx index 726ee55ccec9..7bb526791da9 100644 --- a/shared/chat/audio/audio-recorder.native.tsx +++ b/shared/chat/audio/audio-recorder.native.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Kb from '@/common-adapters' import {Portal} from '@/common-adapters/portal.native' @@ -364,7 +364,7 @@ const useRecorder = (p: {ampSV: SVN; setShowAudioSend: (s: boolean) => void; sho setStaged(false) setShowAudioSend(false) } - const setCommandStatusInfo = Chat.useChatUIContext(s => s.dispatch.setCommandStatusInfo) + const setCommandStatusInfo = ConvoState.useChatUIContext(s => s.dispatch.setCommandStatusInfo) const startRecording = () => { const checkPerms = async () => { @@ -420,7 +420,7 @@ const useRecorder = (p: {ampSV: SVN; setShowAudioSend: (s: boolean) => void; sho return } - const sendAudioRecording = Chat.useChatContext(s => s.dispatch.sendAudioRecording) + const sendAudioRecording = ConvoState.useChatContext(s => s.dispatch.sendAudioRecording) const sendRecording = () => { const impl = async () => { @@ -702,10 +702,16 @@ const CancelHint = (props: {fadeSV: SVN; dragXSV: SVN; lockedSV: SVN; onCancel: return ( <> - + - + {} ) } - const setConversationStatus = Chat.useChatContext(s => s.dispatch.blockConversation) + const setConversationStatus = ConvoState.useChatContext(s => s.dispatch.blockConversation) const setUserBlocks = (newBlocks: NewBlocksMap) => { // Convert our state block array to action payload. const blocks = [...newBlocks.entries()] diff --git a/shared/chat/blocking/invitation-to-block.tsx b/shared/chat/blocking/invitation-to-block.tsx index e7cf30ec7f34..5d2dacaac26b 100644 --- a/shared/chat/blocking/invitation-to-block.tsx +++ b/shared/chat/blocking/invitation-to-block.tsx @@ -1,28 +1,30 @@ import * as C from '@/constants' +import {isAssertion} from '@/constants/chat/helpers' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import {useCurrentUserState} from '@/stores/current-user' import {navToProfile} from '@/constants/router' const BlockButtons = () => { const navigateAppend = C.Router2.navigateAppend - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) - const team = Chat.useChatContext(s => s.meta.teamname) - const teamID = Chat.useChatContext(s => s.meta.teamID) + const team = ConvoState.useChatContext(s => s.meta.teamname) + const teamID = ConvoState.useChatContext(s => s.meta.teamID) const blockButtonInfo = Chat.useChatState(s => { const blockButtonsMap = s.blockButtonsMap return teamID ? blockButtonsMap.get(teamID) : undefined }) - const participantInfo = Chat.useChatContext(s => s.participants) + const participantInfo = ConvoState.useChatContext(s => s.participants) const currentUser = useCurrentUserState(s => s.username) - const dismissBlockButtons = Chat.useChatContext(s => s.dispatch.dismissBlockButtons) + const dismissBlockButtons = Chat.useChatState(s => s.dispatch.dismissBlockButtons) if (!blockButtonInfo) { return null } const adder = blockButtonInfo.adder const others = (team ? participantInfo.all : participantInfo.name).filter( - person => person !== currentUser && person !== adder && !Chat.isAssertion(person) + person => person !== currentUser && person !== adder && !isAssertion(person) ) const onViewProfile = () => navToProfile(adder) diff --git a/shared/chat/conversation/attachment-fullscreen/hooks.tsx b/shared/chat/conversation/attachment-fullscreen/hooks.tsx index 1ef9c6f81e42..d7790dd38f90 100644 --- a/shared/chat/conversation/attachment-fullscreen/hooks.tsx +++ b/shared/chat/conversation/attachment-fullscreen/hooks.tsx @@ -1,21 +1,23 @@ import * as React from 'react' import * as C from '@/constants' +import {clampImageSize} from '@/constants/chat/helpers' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' import {maxWidth, maxHeight} from '../messages/attachment/shared' import {useFSState} from '@/stores/fs' const blankMessage = Chat.makeMessageAttachment({}) export const useData = (initialOrdinal: T.Chat.Ordinal) => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const [ordinal, setOrdinal] = React.useState(initialOrdinal) - const message: T.Chat.MessageAttachment = Chat.useChatContext(s => { + const message: T.Chat.MessageAttachment = ConvoState.useChatContext(s => { const m = s.messageMap.get(ordinal) return m?.type === 'attachment' ? m : blankMessage }) - const loadNextAttachment = Chat.useChatContext(s => s.dispatch.loadNextAttachment) + const loadNextAttachment = ConvoState.useChatContext(s => s.dispatch.loadNextAttachment) const onSwitchAttachment = (backInTime: boolean) => { const f = async () => { if (conversationIDKey !== blankMessage.conversationIDKey) { @@ -37,11 +39,11 @@ export const useData = (initialOrdinal: T.Chat.Ordinal) => { s => s.dispatch.defer.openLocalPathInSystemFileManagerDesktop ) const navigateUp = C.Router2.navigateUp - const showInfoPanel = Chat.useChatContext(s => s.dispatch.showInfoPanel) - const attachmentDownload = Chat.useChatContext(s => s.dispatch.attachmentDownload) + const showInfoPanel = ConvoState.useChatContext(s => s.dispatch.showInfoPanel) + const attachmentDownload = ConvoState.useChatContext(s => s.dispatch.attachmentDownload) const {downloadPath, fileURL: path, fullHeight, fullWidth, fileType} = message const {previewHeight, previewURL: previewPath, previewWidth, title, transferProgress} = message - const {height: clampedHeight, width: clampedWidth} = Chat.clampImageSize( + const {height: clampedHeight, width: clampedWidth} = clampImageSize( previewWidth, previewHeight, maxWidth, diff --git a/shared/chat/conversation/attachment-get-titles.tsx b/shared/chat/conversation/attachment-get-titles.tsx index ea3cf94dee47..a617e0828db0 100644 --- a/shared/chat/conversation/attachment-get-titles.tsx +++ b/shared/chat/conversation/attachment-get-titles.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as React from 'react' import * as Kb from '@/common-adapters' @@ -40,8 +41,8 @@ const Container = (ownProps: OwnProps) => { const noDragDrop = ownProps.noDragDrop ?? false const selectConversationWithReason = ownProps.selectConversationWithReason const navigateUp = C.Router2.navigateUp - const navigateToThread = Chat.useChatContext(s => s.dispatch.navigateToThread) - const attachmentUploadCanceled = Chat.useChatContext(s => s.dispatch.attachmentUploadCanceled) + const navigateToThread = ConvoState.useChatContext(s => s.dispatch.navigateToThread) + const attachmentUploadCanceled = ConvoState.useChatContext(s => s.dispatch.attachmentUploadCanceled) const onCancel = () => { attachmentUploadCanceled( pathAndOutboxIDs.reduce((l: Array, {outboxID}) => { @@ -54,8 +55,8 @@ const Container = (ownProps: OwnProps) => { navigateUp() } const clearModals = C.Router2.clearModals - const attachmentsUpload = Chat.useChatContext(s => s.dispatch.attachmentsUpload) - const attachFromDragAndDrop = Chat.useChatContext(s => s.dispatch.attachFromDragAndDrop) + const attachmentsUpload = ConvoState.useChatContext(s => s.dispatch.attachmentsUpload) + const attachFromDragAndDrop = ConvoState.useChatContext(s => s.dispatch.attachFromDragAndDrop) const _onSubmit = (titles: Array, spoiler: boolean) => { tlfName || noDragDrop diff --git a/shared/chat/conversation/bot/confirm.tsx b/shared/chat/conversation/bot/confirm.tsx index 3a5e107eb485..35738967d1c7 100644 --- a/shared/chat/conversation/bot/confirm.tsx +++ b/shared/chat/conversation/bot/confirm.tsx @@ -1,8 +1,8 @@ import * as Kb from '@/common-adapters' import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' -import {useBotConversationIDKey} from './install' +import {useBotConversationIDKey, useRefreshBotMembershipOnSuccess} from './install' type Props = { botUsername: string @@ -10,16 +10,27 @@ type Props = { conversationIDKey?: T.Chat.ConversationIDKey } -const ConfirmBotRemoveImpl = (props: {botUsername: string}) => { - const {botUsername} = props +const ConfirmBotRemoveImpl = (props: {botUsername: string; teamID?: T.Teams.TeamID}) => { + const {botUsername, teamID} = props const clearModals = C.Router2.clearModals - const removeBotMember = Chat.useChatContext(s => s.dispatch.removeBotMember) + const error = C.Waiting.useAnyErrors(C.waitingKeyChatBotRemove) + const removeBotMember = ConvoState.useChatContext(s => s.dispatch.removeBotMember) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const onClose = () => { clearModals() } const onRemove = () => { removeBotMember(botUsername) } + useRefreshBotMembershipOnSuccess( + conversationIDKey, + teamID, + C.waitingKeyChatBotRemove, + error, + true, + {username: botUsername}, + clearModals + ) return ( { const {teamID, botUsername} = props const conversationIDKey = useBotConversationIDKey(props.conversationIDKey, teamID) return conversationIDKey ? ( - - - + + + ) : null } diff --git a/shared/chat/conversation/bot/install.tsx b/shared/chat/conversation/bot/install.tsx index fe61338060e9..cc89c5d4cc80 100644 --- a/shared/chat/conversation/bot/install.tsx +++ b/shared/chat/conversation/bot/install.tsx @@ -1,6 +1,7 @@ import * as C from '@/constants' +import * as ChatCommon from '@/constants/chat/common' import * as Meta from '@/constants/chat/meta' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as Teams from '@/stores/teams' import * as React from 'react' @@ -10,14 +11,70 @@ import {openURL} from '@/util/misc' import * as T from '@/constants/types' import {useAllChannelMetas} from '@/teams/common/channel-hooks' import {useFeaturedBot} from '@/util/featured-bots' +import type {RPCError} from '@/util/errors' const RestrictedItem = '---RESTRICTED---' +export const useRefreshBotMembershipOnSuccess = ( + conversationIDKey: T.Chat.ConversationIDKey | undefined, + teamID: T.Teams.TeamID | undefined, + waitingKey: string, + error: RPCError | undefined, + shouldRefreshMembership: boolean, + updatedBotMember: {role?: 'bot' | 'restrictedbot'; username: string} | undefined, + onSuccess: () => void +) => { + const waiting = C.Waiting.useAnyWaiting(waitingKey) + const wasWaitingRef = React.useRef(waiting) + const updateCachedBotMember = Teams.useTeamsState(s => s.dispatch.updateCachedBotMember) + const previewConversationByID = C.useRPC(T.RPCChat.localPreviewConversationByIDLocalRpcPromise) + const setParticipants = ConvoState.useChatContext(s => s.dispatch.setParticipants) + const teamIDToRefresh = teamID && teamID !== T.Teams.noTeamID ? teamID : undefined + + React.useEffect(() => { + if (!waiting && wasWaitingRef.current && !error) { + if (!shouldRefreshMembership) { + onSuccess() + } else if (!conversationIDKey) { + onSuccess() + } else { + previewConversationByID( + [{convID: T.Chat.keyToConversationID(conversationIDKey)}], + preview => { + setParticipants(ChatCommon.uiParticipantsToParticipantInfo(preview.conv.participants ?? [])) + if (teamIDToRefresh && updatedBotMember) { + updateCachedBotMember(teamIDToRefresh, updatedBotMember.username, updatedBotMember.role) + } + onSuccess() + }, + () => { + if (teamIDToRefresh && updatedBotMember) { + updateCachedBotMember(teamIDToRefresh, updatedBotMember.username, updatedBotMember.role) + } + onSuccess() + } + ) + } + } + wasWaitingRef.current = waiting + }, [ + conversationIDKey, + error, + onSuccess, + previewConversationByID, + setParticipants, + shouldRefreshMembership, + teamIDToRefresh, + updateCachedBotMember, + updatedBotMember, + waiting, + ]) +} + export const useBotConversationIDKey = (inConvIDKey?: T.Chat.ConversationIDKey, teamID?: T.Teams.TeamID) => { const cleanInConvIDKey = T.Chat.isValidConversationIDKey(inConvIDKey ?? '') ? inConvIDKey : undefined const [conversationIDKey, setConversationIDKey] = React.useState(cleanInConvIDKey) const findGeneralConvIDFromTeamID = C.useRPC(T.RPCChat.localFindGeneralConvFromTeamIDRpcPromise) - const metasReceived = Chat.useChatState(s => s.dispatch.metasReceived) const requestIDRef = React.useRef(0) React.useEffect(() => { @@ -40,7 +97,7 @@ export const useBotConversationIDKey = (inConvIDKey?: T.Chat.ConversationIDKey, if (!meta) { return } - metasReceived([meta]) + ConvoState.metasReceived([meta]) setConversationIDKey(meta.conversationIDKey) }, () => {} @@ -50,7 +107,7 @@ export const useBotConversationIDKey = (inConvIDKey?: T.Chat.ConversationIDKey, requestIDRef.current += 1 } } - }, [cleanInConvIDKey, findGeneralConvIDFromTeamID, metasReceived, teamID]) + }, [cleanInConvIDKey, findGeneralConvIDFromTeamID, teamID]) return conversationIDKey } @@ -67,9 +124,9 @@ const InstallBotPopupLoader = (props: LoaderProps) => { const conversationIDKey = useBotConversationIDKey(inConvIDKey, teamID) if (!conversationIDKey) return null return ( - + - + ) } @@ -93,22 +150,21 @@ const InstallBotPopup = (props: Props) => { const [disableDone, setDisableDone] = React.useState(false) const [botPublicCommands, setBotPublicCommands] = React.useState() - const meta = Chat.useChatContext(s => s.meta) - const commands = (() => { - const {botCommands} = meta - const commands = ( - botCommands.typ === T.RPCChat.ConversationCommandGroupsTyp.custom - ? botCommands.custom.commands || blankCommands - : blankCommands - ) - .filter(c => c.username === botUsername) - .map(c => c.name) - const convCommands = {commands, loadError: false} satisfies T.Chat.BotPublicCommands - return commands.length > 0 ? convCommands : botPublicCommands - })() + const meta = ConvoState.useChatContext(s => s.meta) + const commandsFromMeta = ( + meta.botCommands.typ === T.RPCChat.ConversationCommandGroupsTyp.custom + ? meta.botCommands.custom.commands || blankCommands + : blankCommands + ) + .filter(c => c.username === botUsername) + .map(c => c.name) + const commands = + commandsFromMeta.length > 0 + ? ({commands: commandsFromMeta, loadError: false} satisfies T.Chat.BotPublicCommands) + : botPublicCommands const featured = useFeaturedBot(botUsername) - const teamRole = Chat.useChatContext(s => s.botTeamRoleMap.get(botUsername)) + const teamRole = ConvoState.useChatContext(s => s.botTeamRoleMap.get(botUsername)) const inTeam = teamRole !== undefined ? !!teamRole : undefined const inTeamUnrestricted = inTeam && teamRole === 'bot' const isBot = teamRole === 'bot' || teamRole === 'restrictedbot' ? true : undefined @@ -116,20 +172,25 @@ const InstallBotPopup = (props: Props) => { const readOnly = Teams.useTeamsState(s => meta.teamname ? !Teams.getCanPerformByID(s, meta.teamID).manageBots : false ) - const settings = Chat.useChatContext(s => s.botSettings.get(botUsername) ?? undefined) + const settings = ConvoState.useChatContext(s => s.botSettings.get(botUsername) ?? undefined) let teamname: string | undefined let teamID: T.Teams.TeamID = T.Teams.noTeamID + let refreshTeamID: T.Teams.TeamID | undefined if (meta.teamname) { teamID = meta.teamID + refreshTeamID = meta.teamID teamname = meta.teamname } const {channelMetas} = useAllChannelMetas(teamID) + const mutationWaiting = C.Waiting.useAnyWaiting([C.waitingKeyChatBotAdd, C.waitingKeyChatBotRemove]) const error = C.Waiting.useAnyErrors([C.waitingKeyChatBotAdd, C.waitingKeyChatBotRemove]) + const mutationError = C.Waiting.useAnyErrors(C.waitingKeyChatBotAdd) // dispatch const clearModals = C.Router2.clearModals const navigateUp = C.Router2.navigateUp - const addBotMember = Chat.useChatContext(s => s.dispatch.addBotMember) + const addBotMember = ConvoState.useChatContext(s => s.dispatch.addBotMember) + const [pendingMutation, setPendingMutation] = React.useState<'add' | 'edit' | undefined>() const onLearn = () => { openURL('https://book.keybase.io/docs/chat/restricted-bots') } @@ -137,13 +198,17 @@ const InstallBotPopup = (props: Props) => { if (!conversationIDKey) { return } + dispatchClearWaiting([C.waitingKeyChatBotAdd, C.waitingKeyChatBotRemove]) + setPendingMutation('add') addBotMember(botUsername, installWithCommands, installWithMentions, installWithRestrict, installInConvs) } - const editBotSettings = Chat.useChatContext(s => s.dispatch.editBotSettings) + const editBotSettings = ConvoState.useChatContext(s => s.dispatch.editBotSettings) const onEdit = () => { if (!conversationIDKey) { return } + dispatchClearWaiting([C.waitingKeyChatBotAdd, C.waitingKeyChatBotRemove]) + setPendingMutation('edit') editBotSettings(botUsername, installWithCommands, installWithMentions, installInConvs) } const navigateAppend = C.Router2.navigateAppend @@ -153,15 +218,15 @@ const InstallBotPopup = (props: Props) => { } navigateAppend({ name: 'chatConfirmRemoveBot', - params: {botUsername, conversationIDKey}, + params: {botUsername, conversationIDKey, teamID: refreshTeamID}, }) } const onFeedback = () => { navigateAppend({name: 'feedback', params: {}}) } - const refreshBotSettings = Chat.useChatContext(s => s.dispatch.refreshBotSettings) - const refreshBotRoleInConv = Chat.useChatContext(s => s.dispatch.refreshBotRoleInConv) + const refreshBotSettings = ConvoState.useChatContext(s => s.dispatch.refreshBotSettings) + const refreshBotRoleInConv = ConvoState.useChatContext(s => s.dispatch.refreshBotRoleInConv) // lifecycle React.useEffect(() => { @@ -172,19 +237,39 @@ const InstallBotPopup = (props: Props) => { } } }, [refreshBotRoleInConv, refreshBotSettings, conversationIDKey, inTeam, botUsername]) - const noCommands = !commands?.commands + useRefreshBotMembershipOnSuccess( + conversationIDKey, + refreshTeamID, + C.waitingKeyChatBotAdd, + mutationError, + pendingMutation === 'add', + pendingMutation === 'add' + ? {role: installWithRestrict ? 'restrictedbot' : 'bot', username: botUsername} + : undefined, + () => { + setPendingMutation(undefined) + clearModals() + } + ) const dispatchClearWaiting = C.Waiting.useDispatchClearWaiting() const loadBotPublicCommands = C.useRPC(T.RPCChat.localListPublicBotCommandsLocalRpcPromise) const botPublicCommandsRequestIDRef = React.useRef(0) + const clearedWaitingForBotRef = React.useRef() + React.useEffect(() => { + setBotPublicCommands(undefined) + }, [botUsername]) + React.useEffect(() => { + if (!mutationWaiting && clearedWaitingForBotRef.current !== botUsername) { + clearedWaitingForBotRef.current = botUsername + dispatchClearWaiting([C.waitingKeyChatBotAdd, C.waitingKeyChatBotRemove]) + } + }, [botUsername, dispatchClearWaiting, mutationWaiting]) React.useEffect(() => { - dispatchClearWaiting([C.waitingKeyChatBotAdd, C.waitingKeyChatBotRemove]) botPublicCommandsRequestIDRef.current += 1 - if (!noCommands) { - setBotPublicCommands(undefined) + if (commandsFromMeta.length > 0) { return } - setBotPublicCommands(undefined) const requestID = botPublicCommandsRequestIDRef.current loadBotPublicCommands( [{username: botUsername}], @@ -207,7 +292,7 @@ const InstallBotPopup = (props: Props) => { botPublicCommandsRequestIDRef.current += 1 } } - }, [botUsername, dispatchClearWaiting, loadBotPublicCommands, noCommands]) + }, [botUsername, commandsFromMeta.length, loadBotPublicCommands]) const restrictedButton = ( diff --git a/shared/chat/conversation/bot/search.tsx b/shared/chat/conversation/bot/search.tsx index d00862fbab24..bb0db6ff60c1 100644 --- a/shared/chat/conversation/bot/search.tsx +++ b/shared/chat/conversation/bot/search.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as React from 'react' import debounce from 'lodash/debounce' @@ -29,7 +29,7 @@ type Item = type Section = Omit, 'title'> & {title: string} const SearchBotPopup = (props: Props) => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const teamID = props.teamID const [lastQuery, setLastQuery] = React.useState('') const [botSearchResults, setBotSearchResults] = React.useState( diff --git a/shared/chat/conversation/bottom-banner.tsx b/shared/chat/conversation/bottom-banner.tsx index c98694933a77..3227f5b0a68a 100644 --- a/shared/chat/conversation/bottom-banner.tsx +++ b/shared/chat/conversation/bottom-banner.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import type * as React from 'react' import {openSMS as _openSMS} from '@/util/misc' @@ -12,7 +12,7 @@ const installMessage = `I sent you encrypted messages on Keybase. You can instal const Invite = () => { const linkUrlProps = Kb.useClickURL('https://keybase.io/app') - const participantInfo = Chat.useChatContext(s => s.participants) + const participantInfo = ConvoState.useChatContext(s => s.participants) const participantInfoAll = participantInfo.all const users = participantInfoAll.filter(p => p.includes('@')) @@ -33,7 +33,7 @@ const Invite = () => { const usernameToContactName = participantInfo.contactName - const onDismiss = Chat.useChatContext(s => s.dispatch.dismissBottomBanner) + const onDismiss = ConvoState.useChatContext(s => s.dispatch.dismissBottomBanner) const theirName = users.length === 1 @@ -93,7 +93,7 @@ const Invite = () => { const Broken = () => { const following = useFollowerState(s => s.following) const infoMap = useUsersState(s => s.infoMap) - const participantInfo = Chat.useChatContext(s => s.participants) + const participantInfo = ConvoState.useChatContext(s => s.participants) const users = participantInfo.all.filter(p => following.has(p) && infoMap.get(p)?.broken) return } @@ -101,9 +101,9 @@ const Broken = () => { const BannerContainer = function BannerContainer() { const following = useFollowerState(s => s.following) const infoMap = useUsersState(s => s.infoMap) - const dismissed = Chat.useChatContext(s => s.dismissedInviteBanners) - const participantInfo = Chat.useChatContext(s => s.participants) - const type = Chat.useChatContext(s => { + const dismissed = ConvoState.useChatContext(s => s.dismissedInviteBanners) + const participantInfo = ConvoState.useChatContext(s => s.participants) + const type = ConvoState.useChatContext(s => { const teamType = s.meta.teamType if (teamType !== 'adhoc') { return 'none' diff --git a/shared/chat/conversation/command-markdown.tsx b/shared/chat/conversation/command-markdown.tsx index 751f669af955..43f4a2257bc2 100644 --- a/shared/chat/conversation/command-markdown.tsx +++ b/shared/chat/conversation/command-markdown.tsx @@ -1,8 +1,8 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' const CommandMarkdown = () => { - const md = Chat.useChatContext(s => s.commandMarkdown) + const md = ConvoState.useChatContext(s => s.commandMarkdown) const body = md?.body ?? '' const title = md?.title ?? undefined return ( diff --git a/shared/chat/conversation/command-status.tsx b/shared/chat/conversation/command-status.tsx index 83f56446412d..faa5bd2e2697 100644 --- a/shared/chat/conversation/command-status.tsx +++ b/shared/chat/conversation/command-status.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Kb from '@/common-adapters' import {useConfigState} from '@/stores/config' @@ -10,11 +10,11 @@ const empty = { } const Container = () => { - const info = Chat.useChatUIContext(s => s.commandStatus) + const info = ConvoState.useChatUIContext(s => s.commandStatus) const _info = info || empty const onOpenAppSettings = useConfigState(s => s.dispatch.defer.openAppSettings) - const setCommandStatusInfo = Chat.useChatUIContext(s => s.dispatch.setCommandStatusInfo) + const setCommandStatusInfo = ConvoState.useChatUIContext(s => s.dispatch.setCommandStatusInfo) const onCancel = () => { setCommandStatusInfo() } diff --git a/shared/chat/conversation/container.tsx b/shared/chat/conversation/container.tsx index f27584c978ed..8406c0a05c8d 100644 --- a/shared/chat/conversation/container.tsx +++ b/shared/chat/conversation/container.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import Normal from './normal/container' import NoConversation from './no-conversation' import Error from './error' @@ -8,7 +9,7 @@ import Rekey from './rekey/container' import type {ThreadSearchRouteProps} from './thread-search-route' const Conversation = function Conversation(_: ThreadSearchRouteProps) { - const type = Chat.useChatContext(s => { + const type = ConvoState.useChatContext(s => { const meta = s.meta switch (s.id) { case Chat.noConversationIDKey: diff --git a/shared/chat/conversation/error.tsx b/shared/chat/conversation/error.tsx index 80862bb4bb99..825d6cb1bd86 100644 --- a/shared/chat/conversation/error.tsx +++ b/shared/chat/conversation/error.tsx @@ -1,8 +1,8 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' const ConversationError = () => { - const text = Chat.useChatContext(s => s.meta.snippet ?? '') + const text = ConvoState.useChatContext(s => s.meta.snippet ?? '') return ( There was an error loading this conversation. diff --git a/shared/chat/conversation/fwd-msg.tsx b/shared/chat/conversation/fwd-msg.tsx index 04bb51e51c34..0896b04e2dc9 100644 --- a/shared/chat/conversation/fwd-msg.tsx +++ b/shared/chat/conversation/fwd-msg.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as React from 'react' import * as Kb from '@/common-adapters' import * as T from '@/constants/types' @@ -13,9 +14,9 @@ type Props = {ordinal: T.Chat.Ordinal} type PickerState = 'picker' | 'title' const TeamPicker = (props: Props) => { - const srcConvID = Chat.useChatContext(s => s.id) + const srcConvID = ConvoState.useChatContext(s => s.id) const ordinal = props.ordinal - const message = Chat.useChatContext(s => s.messageMap.get(ordinal)) + const message = ConvoState.useChatContext(s => s.messageMap.get(ordinal)) const [pickerState, setPickerState] = React.useState('picker') const [term, setTerm] = React.useState('') const dstConvIDRef = React.useRef(undefined) diff --git a/shared/chat/conversation/giphy/hooks.tsx b/shared/chat/conversation/giphy/hooks.tsx index 128cab51bb5e..232dd3013d2b 100644 --- a/shared/chat/conversation/giphy/hooks.tsx +++ b/shared/chat/conversation/giphy/hooks.tsx @@ -1,8 +1,8 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' export const useHooks = () => { - const giphy = Chat.useChatUIContext(s => s.giphyResult) - const onClick = Chat.useChatContext(s => s.dispatch.giphySend) + const giphy = ConvoState.useChatUIContext(s => s.giphyResult) + const onClick = ConvoState.useChatContext(s => s.dispatch.giphySend) return { galleryURL: giphy?.galleryUrl ?? '', onClick, diff --git a/shared/chat/conversation/header-area/index.native.tsx b/shared/chat/conversation/header-area/index.native.tsx index d2fac88cf09a..447322afcc59 100644 --- a/shared/chat/conversation/header-area/index.native.tsx +++ b/shared/chat/conversation/header-area/index.native.tsx @@ -1,5 +1,7 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import {chatStores} from '@/stores/convo-registry' +import * as ConvoState from '@/stores/convostate' import {getConvoState} from '@/stores/convostate' import * as Kb from '@/common-adapters' import type {HeaderBackButtonProps} from '@react-navigation/elements' @@ -12,9 +14,10 @@ import {useSafeAreaFrame} from 'react-native-safe-area-context' import {useUsersState} from '@/stores/users' import {useCurrentUserState} from '@/stores/current-user' import {navToProfile} from '@/constants/router' +import * as React from 'react' export const HeaderAreaRight = () => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const pendingWaiting = conversationIDKey === Chat.pendingWaitingConversationIDKey || conversationIDKey === Chat.pendingErrorConversationIDKey @@ -38,9 +41,9 @@ export const HeaderAreaRight = () => { // // ) : null - const showInfoPanel = Chat.useChatContext(s => s.dispatch.showInfoPanel) + const showInfoPanel = ConvoState.useChatContext(s => s.dispatch.showInfoPanel) const onShowInfoPanel = () => showInfoPanel(true, undefined) - const toggleThreadSearch = Chat.useChatContext(s => s.dispatch.toggleThreadSearch) + const toggleThreadSearch = ConvoState.useChatContext(s => s.dispatch.toggleThreadSearch) const onToggleThreadSearch = () => { // fix a race with the keyboard going away and coming back quickly Keyboard.dismiss() @@ -68,8 +71,8 @@ enum HeaderType { } const HeaderBranchContainer = function HeaderBranchContainer() { - const participantInfo = Chat.useChatContext(s => s.participants) - const type = Chat.useChatContext(s => { + const participantInfo = ConvoState.useChatContext(s => s.participants) + const type = ConvoState.useChatContext(s => { const meta = s.meta const teamName = meta.teamname if (teamName) { @@ -110,9 +113,9 @@ export const headerNavigationOptions = (route: {params?: {conversationIDKey?: st headerLeft: (props: HeaderBackButtonProps) => { const {labelStyle, ...rest} = props return ( - + - + ) }, } @@ -141,15 +144,15 @@ export const headerNavigationOptions = (route: {params?: {conversationIDKey?: st } : { headerRight: () => ( - + - + ), }), headerTitle: () => ( - + - + ), } } @@ -157,8 +160,19 @@ export const headerNavigationOptions = (route: {params?: {conversationIDKey?: st export const useBackBadge = () => { const visiblePath = C.Router2.getVisiblePath() const onTopOfInbox = visiblePath[visiblePath.length - 2]?.name === 'chatRoot' - const conversationIDKey = Chat.useChatContext(s => s.id) - const badgeNumber = Chat.useChatState(s => s.getBackCount(conversationIDKey)) + const conversationIDKey = ConvoState.useChatContext(s => s.id) + const badgeStateVersion = Chat.useChatState(s => s.badgeStateVersion) + const badgeNumber = React.useMemo(() => { + void badgeStateVersion + let count = 0 + for (const store of chatStores.values()) { + const {badge, id} = store.getState() + if (id !== conversationIDKey) { + count += badge + } + } + return count + }, [badgeStateVersion, conversationIDKey]) if (!onTopOfInbox) return 0 return badgeNumber } @@ -167,8 +181,8 @@ const shhIconColor = Kb.Styles.globalColors.black_20 const shhIconFontSize = 24 const ShhIcon = function ShhIcon() { - const isMuted = Chat.useChatContext(s => s.meta.isMuted) - const mute = Chat.useChatContext(s => s.dispatch.mute) + const isMuted = ConvoState.useChatContext(s => s.meta.isMuted) + const mute = ConvoState.useChatContext(s => s.dispatch.mute) const unMuteConversation = () => { mute(false) } @@ -191,7 +205,7 @@ const useMaxWidthStyle = () => { } const ChannelHeader = () => { - const {channelname, smallTeam, teamname, teamID} = Chat.useChatContext( + const {channelname, smallTeam, teamname, teamID} = ConvoState.useChatContext( C.useShallow(s => { const meta = s.meta const {channelname, teamname, teamType, teamID} = meta @@ -241,8 +255,8 @@ const emptyArray = new Array() const UsernameHeader = () => { const you = useCurrentUserState(s => s.username) const infoMap = useUsersState(s => s.infoMap) - const participantInfo = Chat.useChatContext(s => s.participants) - const {participants, theirFullname} = Chat.useChatContext( + const participantInfo = ConvoState.useChatContext(s => s.participants) + const {participants, theirFullname} = ConvoState.useChatContext( C.useShallow(s => { const meta = s.meta const participants = meta.teamname ? emptyArray : participantInfo.name @@ -290,8 +304,8 @@ const UsernameHeader = () => { } const PhoneOrEmailHeader = () => { - const participantInfo = Chat.useChatContext(s => s.participants) - const meta = Chat.useChatContext(s => s.meta) + const participantInfo = ConvoState.useChatContext(s => s.participants) + const meta = ConvoState.useChatContext(s => s.meta) const participants = (meta.teamname ? null : participantInfo.name) || emptyArray const phoneOrEmail = participants.find(s => s.endsWith('@phone') || s.endsWith('@email')) || '' const formattedPhoneOrEmail = assertionToDisplay(phoneOrEmail) diff --git a/shared/chat/conversation/info-panel/add-people.tsx b/shared/chat/conversation/info-panel/add-people.tsx index a24c97fbf8eb..57b274394c90 100644 --- a/shared/chat/conversation/info-panel/add-people.tsx +++ b/shared/chat/conversation/info-panel/add-people.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import {useTeamsState} from '@/stores/teams' import * as Kb from '@/common-adapters' @@ -9,9 +9,9 @@ type Props = { const AddPeople = (p: Props) => { const {isGeneralChannel, isAdmin} = p - const teamID = Chat.useChatContext(s => s.meta.teamID) + const teamID = ConvoState.useChatContext(s => s.meta.teamID) const startAddMembersWizard = useTeamsState(s => s.dispatch.startAddMembersWizard) - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onAddPeople = () => { startAddMembersWizard(teamID) } diff --git a/shared/chat/conversation/info-panel/add-to-channel.tsx b/shared/chat/conversation/info-panel/add-to-channel.tsx index 9993717cee83..535f988be09b 100644 --- a/shared/chat/conversation/info-panel/add-to-channel.tsx +++ b/shared/chat/conversation/info-panel/add-to-channel.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as React from 'react' import * as Teams from '@/stores/teams' import * as Kb from '@/common-adapters' @@ -15,7 +15,7 @@ type Props = {teamID: T.Teams.TeamID} const AddToChannel = (props: Props) => { const {teamID} = props const nav = useSafeNavigation() - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const [toAdd, setToAdd] = React.useState(new Set()) const [filter, setFilter] = React.useState('') @@ -80,9 +80,24 @@ const AddToChannel = (props: Props) => { title: `Add to #${channelname}`, }) return () => { - useModalHeaderState.setState({actionEnabled: false, actionWaiting: false, onAction: undefined, title: ''}) + useModalHeaderState.setState({ + actionEnabled: false, + actionWaiting: false, + onAction: undefined, + title: '', + }) } - }, [channelname, teamID, toAdd, toAdd.size, waiting, addToChannel, conversationIDKey, loadTeamChannelList, nav]) + }, [ + channelname, + teamID, + toAdd, + toAdd.size, + waiting, + addToChannel, + conversationIDKey, + loadTeamChannelList, + nav, + ]) return ( <> @@ -154,21 +169,16 @@ const AddToChannel = (props: Props) => { {Kb.Styles.isMobile ? null : ( - - - - + + + + )} diff --git a/shared/chat/conversation/info-panel/attachments.tsx b/shared/chat/conversation/info-panel/attachments.tsx index c05067a8d0e7..3042e9f05a6a 100644 --- a/shared/chat/conversation/info-panel/attachments.tsx +++ b/shared/chat/conversation/info-panel/attachments.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import {zoomImage} from '@/constants/chat/helpers' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import type {StylesTextCrossPlatform} from '@/common-adapters/text.shared' import * as T from '@/constants/types' @@ -435,8 +436,8 @@ export const useAttachmentSections = ( T.RPCChat.GalleryItemTyp.media ) const [lastSAV, setLastSAV] = React.useState(selectedAttachmentView) - const loadAttachmentView = Chat.useChatContext(s => s.dispatch.loadAttachmentView) - const loadMessagesCentered = Chat.useChatContext(s => s.dispatch.loadMessagesCentered) + const loadAttachmentView = ConvoState.useChatContext(s => s.dispatch.loadAttachmentView) + const loadMessagesCentered = ConvoState.useChatContext(s => s.dispatch.loadMessagesCentered) const clearModals = C.Router2.clearModals const jumpToAttachment = (messageID: T.Chat.MessageID) => { @@ -463,7 +464,7 @@ export const useAttachmentSections = ( } }, [lastSAV, loadAttachmentView, loadImmediately, selectedAttachmentView]) - const attachmentView = Chat.useChatContext(s => s.attachmentViewMap) + const attachmentView = ConvoState.useChatContext(s => s.attachmentViewMap) const attachmentInfo = attachmentView.get(selectedAttachmentView) const fromMsgID = attachmentInfo ? getFromMsgID(attachmentInfo) : undefined @@ -477,11 +478,11 @@ export const useAttachmentSections = ( loadAttachmentView(selectedAttachmentView) } - const attachmentPreviewSelect = Chat.useChatContext(s => s.dispatch.attachmentPreviewSelect) + const attachmentPreviewSelect = ConvoState.useChatContext(s => s.dispatch.attachmentPreviewSelect) const onMediaClick = (message: T.Chat.MessageAttachment) => attachmentPreviewSelect(message.ordinal) - const attachmentDownload = Chat.useChatContext(s => s.dispatch.attachmentDownload) - const messageAttachmentNativeShare = Chat.useChatContext(s => s.dispatch.messageAttachmentNativeShare) + const attachmentDownload = ConvoState.useChatContext(s => s.dispatch.attachmentDownload) + const messageAttachmentNativeShare = ConvoState.useChatContext(s => s.dispatch.messageAttachmentNativeShare) const onDocDownload = (message: T.Chat.MessageAttachment) => { if (Kb.Styles.isMobile) { @@ -581,7 +582,7 @@ export const useAttachmentSections = ( maxMediaThumbSize, width: thumb.width, }, - sizing: Chat.zoomImage(thumb.width, thumb.height, maxMediaThumbSize), + sizing: zoomImage(thumb.width, thumb.height, maxMediaThumbSize), thumb, })) const dataChunked = useFlexWrap ? [dataUnchunked] : chunk(dataUnchunked, rowSize) diff --git a/shared/chat/conversation/info-panel/bot.tsx b/shared/chat/conversation/info-panel/bot.tsx index 6bec1c7efa10..02d2d2eaa9b9 100644 --- a/shared/chat/conversation/info-panel/bot.tsx +++ b/shared/chat/conversation/info-panel/bot.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import * as Kb from '@/common-adapters' import * as React from 'react' @@ -35,8 +35,8 @@ type Section = Kb.SectionType const AddToChannel = (props: AddToChannelProps) => { const {conversationIDKey, username} = props - const settings = Chat.useChatContext(s => s.botSettings.get(username)) - const editBotSettings = Chat.useChatContext(s => s.dispatch.editBotSettings) + const settings = ConvoState.useChatContext(s => s.botSettings.get(username)) + const editBotSettings = ConvoState.useChatContext(s => s.dispatch.editBotSettings) return ( { const {ownerTeam, ownerUser} = props const {onClick, firstItem, isSelected} = props const {conversationIDKey, showChannelAdd, showTeamAdd} = props - const refreshBotSettings = Chat.useChatContext(s => s.dispatch.refreshBotSettings) + const refreshBotSettings = ConvoState.useChatContext(s => s.dispatch.refreshBotSettings) const primaryColor = isSelected ? Kb.Styles.globalColors.white : Kb.Styles.globalColors.black const secondaryColor = isSelected ? Kb.Styles.globalColors.white : undefined React.useEffect(() => { @@ -90,7 +90,12 @@ export const Bot = (props: BotProps) => { const lower = ( {description !== '' && ( - onClick(botUsername)}> + onClick(botUsername)} + > {description} )} @@ -181,9 +186,9 @@ type Props = { } const BotTab = (props: Props) => { - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const {teamID, teamname, teamType, botAliases} = meta - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const yourOperations = Teams.useTeamsState(s => (teamname ? Teams.getCanPerformByID(s, teamID) : undefined)) let canManageBots = false if (teamname) { @@ -192,7 +197,7 @@ const BotTab = (props: Props) => { canManageBots = true } const adhocTeam = teamType === 'adhoc' - const participantInfo = Chat.useChatContext(s => s.participants) + const participantInfo = ConvoState.useChatContext(s => s.participants) const teamMembers = Teams.useTeamsState(s => s.teamIDToMembers.get(teamID)) const participantsAll = participantInfo.all @@ -245,7 +250,7 @@ const BotTab = (props: Props) => { const botsInTeam: string[] = botUsernames.filter(b => !botsInConv.includes(b)) - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onBotAdd = () => { navigateAppend(conversationIDKey => ({name: 'chatSearchBots', params: {conversationIDKey}})) } diff --git a/shared/chat/conversation/info-panel/common.tsx b/shared/chat/conversation/info-panel/common.tsx index 0e3b9a65297f..c76caedace7b 100644 --- a/shared/chat/conversation/info-panel/common.tsx +++ b/shared/chat/conversation/info-panel/common.tsx @@ -1,9 +1,8 @@ -import type * as Chat from '@/stores/chat' +import type {ConvoState} from '@/stores/convostate' import {useTeamsState} from '@/stores/teams' -import * as React from 'react' import * as Styles from '@/styles' import type * as T from '@/constants/types' -import * as C from '@/constants' +import {useLoadTeamMembers} from '@/teams/team-members' export const infoPanelWidthElectron = 320 const infoPanelWidthPhone = Styles.dimensionWidth @@ -22,12 +21,7 @@ export function infoPanelWidth() { const isBot = (type: T.Teams.TeamRoleType) => type === 'bot' || type === 'restrictedbot' export const useTeamHumans = (teamID: T.Teams.TeamID) => { - const [lastTID, setLastTID] = React.useState('') - const getMembers = useTeamsState(s => s.dispatch.getMembers) - if (lastTID !== teamID) { - setLastTID(teamID) - C.ignorePromise(getMembers(teamID)) - } + useLoadTeamMembers(teamID, !!teamID) const teamMembers = useTeamsState(s => s.teamIDToMembers.get(teamID)) const bots = (() => { const ret = new Set() @@ -39,8 +33,8 @@ export const useTeamHumans = (teamID: T.Teams.TeamID) => { } export const useHumans = ( - participantInfo: Chat.ConvoState['participants'], - meta: Chat.ConvoState['meta'] + participantInfo: ConvoState['participants'], + meta: ConvoState['meta'] ) => { const {teamType, teamID} = meta const {bots, teamHumanCount} = useTeamHumans(teamID) diff --git a/shared/chat/conversation/info-panel/header.tsx b/shared/chat/conversation/info-panel/header.tsx index 4854c89f4bf9..20627e7a52f1 100644 --- a/shared/chat/conversation/info-panel/header.tsx +++ b/shared/chat/conversation/info-panel/header.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import * as Kb from '@/common-adapters' import InfoPanelMenu from './menu' @@ -8,11 +8,11 @@ import AddPeople from './add-people' const gearIconSize = Kb.Styles.isMobile ? 24 : 16 const TeamHeader = () => { - const conversationIDKey = Chat.useChatContext(s => s.id) - const meta = Chat.useChatContext(s => s.meta) + const conversationIDKey = ConvoState.useChatContext(s => s.id) + const meta = ConvoState.useChatContext(s => s.meta) const {teamname, teamID, channelname, descriptionDecorated: description, membershipType, teamType} = meta - const participants = Chat.useChatContext(s => s.participants) - const onJoinChannel = Chat.useChatContext(s => s.dispatch.joinConversation) + const participants = ConvoState.useChatContext(s => s.participants) + const onJoinChannel = ConvoState.useChatContext(s => s.dispatch.joinConversation) const {channelHumans, teamHumanCount} = InfoPanelCommon.useHumans(participants, meta) const yourOperations = Teams.useTeamsState(s => (teamname ? Teams.getCanPerformByID(s, teamID) : undefined)) @@ -28,7 +28,7 @@ const TeamHeader = () => { const makePopup = (p: Kb.Popup2Parms) => { const {attachTo, hidePopup} = p return ( - + { isSmallTeam={isSmallTeam} visible={true} /> - + ) } const {showPopup, popup, popupAnchor} = Kb.usePopup2(makePopup) @@ -139,7 +139,7 @@ const TeamHeader = () => { } export const AdhocHeader = () => { - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onShowNewTeamDialog = () => { navigateAppend(conversationIDKey => ({ name: 'chatShowNewTeamDialog', diff --git a/shared/chat/conversation/info-panel/index.tsx b/shared/chat/conversation/info-panel/index.tsx index 40c7683ac51d..0615a94923c5 100644 --- a/shared/chat/conversation/info-panel/index.tsx +++ b/shared/chat/conversation/info-panel/index.tsx @@ -1,4 +1,5 @@ import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as Teams from '@/stores/teams' import * as React from 'react' @@ -17,8 +18,8 @@ type Props = { const InfoPanelConnector = (ownProps: Props) => { const initialTab = ownProps.tab - const conversationIDKey = Chat.useChatContext(s => s.id) - const meta = Chat.useConvoState(conversationIDKey, s => s.meta) + const conversationIDKey = ConvoState.useChatContext(s => s.id) + const meta = ConvoState.useConvoState(conversationIDKey, s => s.meta) const shouldNavigateOut = meta.conversationIDKey === Chat.noConversationIDKey const yourRole = Teams.useTeamsState(s => Teams.getRole(s, meta.teamID)) const isPreview = meta.membershipType === 'youArePreviewing' @@ -28,8 +29,8 @@ const InfoPanelConnector = (ownProps: Props) => { const [selectedTab, onSelectTab] = React.useState(initialTab ?? 'members') const [lastSNO, setLastSNO] = React.useState(shouldNavigateOut) - const showInfoPanel = Chat.useChatContext(s => s.dispatch.showInfoPanel) - const clearAttachmentView = Chat.useConvoState(conversationIDKey, s => s.dispatch.clearAttachmentView) + const showInfoPanel = ConvoState.useChatContext(s => s.dispatch.showInfoPanel) + const clearAttachmentView = ConvoState.useConvoState(conversationIDKey, s => s.dispatch.clearAttachmentView) React.useEffect(() => { return () => { // Only call showInfoPanel(false) on mobile where the panel is a separate route. diff --git a/shared/chat/conversation/info-panel/members.tsx b/shared/chat/conversation/info-panel/members.tsx index 946dec8a5491..5d24907d0014 100644 --- a/shared/chat/conversation/info-panel/members.tsx +++ b/shared/chat/conversation/info-panel/members.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import {getBotsAndParticipants} from '@/constants/chat/helpers' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import * as React from 'react' import * as Kb from '@/common-adapters' @@ -30,9 +31,9 @@ type Item = type Section = Kb.SectionType const MembersTab = (props: Props) => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const infoMap = useUsersState(s => s.infoMap) - const {channelname, teamID, teamname} = Chat.useChatContext( + const {channelname, teamID, teamname} = ConvoState.useChatContext( C.useShallow(s => { const {meta} = s const {teamID, channelname, teamname} = meta @@ -44,9 +45,9 @@ const MembersTab = (props: Props) => { const isGeneral = channelname === 'general' const showAuditingBanner = isGeneral && !teamMembers const refreshParticipants = C.useRPC(T.RPCChat.localRefreshParticipantsRpcPromise) - const participantInfo = Chat.useChatContext(s => s.participants) - const participants = Chat.useChatContext( - C.useShallow(s => Chat.getBotsAndParticipants(s.meta, s.participants).participants) + const participantInfo = ConvoState.useChatContext(s => s.participants) + const participants = ConvoState.useChatContext( + C.useShallow(s => getBotsAndParticipants(s.meta, s.participants, teamMembers).participants) ) const [lastTeamName, setLastTeamName] = React.useState('') React.useEffect(() => { diff --git a/shared/chat/conversation/info-panel/menu.tsx b/shared/chat/conversation/info-panel/menu.tsx index b6af1a99e4e7..b43dfaffeb54 100644 --- a/shared/chat/conversation/info-panel/menu.tsx +++ b/shared/chat/conversation/info-panel/menu.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as Teams from '@/stores/teams' import type * as React from 'react' @@ -29,8 +30,8 @@ const useData = (p: {isSmallTeam: boolean; pteamID: string | undefined}) => { const {isSmallTeam, pteamID} = p const username = useCurrentUserState(s => s.username) const infoMap = useUsersState(s => s.infoMap) - const participantInfo = Chat.useChatContext(s => s.participants) - const meta = Chat.useChatContext(s => s.meta) + const participantInfo = ConvoState.useChatContext(s => s.participants) + const meta = ConvoState.useChatContext(s => s.meta) const teamMeta = Teams.useTeamsState(s => (pteamID ? Teams.getTeamMeta(s, pteamID) : undefined)) const manageChannelsTitle = isSmallTeam ? 'Create channels...' : 'Browse all channels' const manageChannelsSubtitle = isSmallTeam ? 'Turns this into a big team' : '' @@ -102,7 +103,7 @@ const InfoPanelMenuConnector = function InfoPanelMenuConnector(p: OwnProps) { const onAddPeople = () => { teamID && startAddMembersWizard(teamID) } - const chatNavigateAppend = Chat.useChatNavigateAppend() + const chatNavigateAppend = ConvoState.useChatNavigateAppend() const routerNavigateAppend = C.Router2.navigateAppend const onBlockConv = () => { chatNavigateAppend(conversationIDKey => ({ @@ -116,20 +117,20 @@ const InfoPanelMenuConnector = function InfoPanelMenuConnector(p: OwnProps) { })) } - const onJoinChannel = Chat.useChatContext(s => s.dispatch.joinConversation) - const onLeaveChannel = Chat.useChatContext(s => s.dispatch.leaveConversation) + const onJoinChannel = ConvoState.useChatContext(s => s.dispatch.joinConversation) + const onLeaveChannel = ConvoState.useChatContext(s => s.dispatch.leaveConversation) const onLeaveTeam = () => teamID && chatNavigateAppend(() => ({name: 'teamReallyLeaveTeam', params: {teamID}})) const onManageChannels = () => { manageChatChannels(teamID) addTeamWithChosenChannels(teamID) } const clearModals = C.Router2.clearModals - const markTeamAsRead = Chat.useChatContext(s => s.dispatch.markTeamAsRead) + const markTeamAsRead = ConvoState.useChatContext(s => s.dispatch.markTeamAsRead) const onMarkAsRead = () => { clearModals() markTeamAsRead(teamID) } - const setMarkAsUnread = Chat.useChatContext(s => s.dispatch.setMarkAsUnread) + const setMarkAsUnread = ConvoState.useChatContext(s => s.dispatch.setMarkAsUnread) const onMarkAsUnread = () => { clearModals() setMarkAsUnread() @@ -138,11 +139,11 @@ const InfoPanelMenuConnector = function InfoPanelMenuConnector(p: OwnProps) { clearModals() chatNavigateAppend(() => ({name: 'team', params: {teamID}})) } - const hideConversation = Chat.useChatContext(s => s.dispatch.hideConversation) + const hideConversation = ConvoState.useChatContext(s => s.dispatch.hideConversation) const onHideConv = () => { hideConversation(true) } - const onMuteConv = Chat.useChatContext(s => s.dispatch.mute) + const onMuteConv = ConvoState.useChatContext(s => s.dispatch.mute) const onUnhideConv = () => { hideConversation(false) } @@ -209,7 +210,7 @@ const InfoPanelMenuConnector = function InfoPanelMenuConnector(p: OwnProps) { ), } as const - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const hideItem = (() => { if (!conversationIDKey) { return null @@ -396,8 +397,8 @@ type AdhocHeaderProps = { } const AdhocHeader = (props: AdhocHeaderProps) => { - const meta = Chat.useChatContext(s => s.meta) - const participants = Chat.useChatContext(s => s.participants) + const meta = ConvoState.useChatContext(s => s.meta) + const participants = ConvoState.useChatContext(s => s.participants) const {channelHumans} = InfoPanelCommon.useHumans(participants, meta) return ( diff --git a/shared/chat/conversation/info-panel/settings/index.tsx b/shared/chat/conversation/info-panel/settings/index.tsx index 15c6c739bc64..dddc99e33694 100644 --- a/shared/chat/conversation/info-panel/settings/index.tsx +++ b/shared/chat/conversation/info-panel/settings/index.tsx @@ -1,5 +1,7 @@ import * as C from '@/constants' +import {isAssertion} from '@/constants/chat/helpers' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as Teams from '@/stores/teams' import * as T from '@/constants/types' @@ -14,7 +16,7 @@ type SettingsPanelProps = {isPreview: boolean} const SettingsPanel = (props: SettingsPanelProps) => { const {isPreview} = props const username = useCurrentUserState(s => s.username) - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const {status, teamname, teamType, channelname, teamID} = meta const yourOperations = Teams.useTeamsState(s => (teamname ? Teams.getCanPerformByID(s, teamID) : undefined)) const ignored = status === T.RPCChat.ConversationStatus.ignored @@ -33,17 +35,17 @@ const SettingsPanel = (props: SettingsPanelProps) => { } const teamMembers = Teams.useTeamsState(s => s.teamIDToMembers.get(teamID)) - const participantInfo = Chat.useChatContext(s => s.participants) + const participantInfo = ConvoState.useChatContext(s => s.participants) const membersForBlock = (teamMembers?.size ? [...teamMembers.keys()] : participantInfo.name).filter( - u => u !== username && !Chat.isAssertion(u) + u => u !== username && !isAssertion(u) ) - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onShowClearConversationDialog = () => { navigateAppend(conversationIDKey => ({name: 'chatDeleteHistoryWarning', params: {conversationIDKey}})) } - const hideConversation = Chat.useChatContext(s => s.dispatch.hideConversation) + const hideConversation = ConvoState.useChatContext(s => s.dispatch.hideConversation) const onHideConv = () => hideConversation(true) const onUnhideConv = () => hideConversation(false) const onShowBlockConversationDialog = () => { @@ -62,7 +64,7 @@ const SettingsPanel = (props: SettingsPanelProps) => { } } - const leaveConversation = Chat.useChatContext(s => s.dispatch.leaveConversation) + const leaveConversation = ConvoState.useChatContext(s => s.dispatch.leaveConversation) const onLeaveConversation = () => { leaveConversation() } @@ -75,7 +77,7 @@ const SettingsPanel = (props: SettingsPanelProps) => { } const showDangerZone = canDeleteHistory || entityType === 'adhoc' || entityType !== 'channel' - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) return ( { - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const {teamname, minWriterRole} = meta const canPerform = Teams.useTeamsState(s => (teamname ? Teams.getCanPerform(s, teamname) : undefined)) @@ -18,7 +18,7 @@ const MinWriterRole = () => { const [saving, setSaving] = React.useState(false) const [selected, setSelected] = React.useState(minWriterRole) - const setMinWriterRole = Chat.useChatContext(s => s.dispatch.setMinWriterRole) + const setMinWriterRole = ConvoState.useChatContext(s => s.dispatch.setMinWriterRole) const onSetNewRole = (role: T.Teams.TeamRoleType) => setMinWriterRole(role) const selectRole = (role: T.Teams.TeamRoleType) => { diff --git a/shared/chat/conversation/info-panel/settings/notifications.tsx b/shared/chat/conversation/info-panel/settings/notifications.tsx index ee8f9b909507..2490d81707a7 100644 --- a/shared/chat/conversation/info-panel/settings/notifications.tsx +++ b/shared/chat/conversation/info-panel/settings/notifications.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as React from 'react' import * as Kb from '@/common-adapters' import type * as T from '@/constants/types' @@ -101,14 +101,14 @@ const UnmutedNotificationPrefs = (props: UnmutedProps) => { } const Notifications = () => { - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const [channelWide, setChannelWide] = React.useState(meta.notificationsGlobalIgnoreMentions) const [desktop, setDesktop] = React.useState(meta.notificationsDesktop) const [mobile, setMobile] = React.useState(meta.notificationsMobile) const [muted, setMuted] = React.useState(meta.isMuted) const [saving, setSaving] = React.useState(false) const delayUnsave = Kb.useTimeout(() => setSaving(false), 100) - const updateNotificationSettings = Chat.useChatContext(s => s.dispatch.updateNotificationSettings) + const updateNotificationSettings = ConvoState.useChatContext(s => s.dispatch.updateNotificationSettings) const saveNotifications = ( desktop: T.Chat.NotificationsType, mobile: T.Chat.NotificationsType, @@ -118,7 +118,7 @@ const Notifications = () => { updateNotificationSettings(desktop, mobile, channelWide) delayUnsave() } - const mute = Chat.useChatContext(s => s.dispatch.mute) + const mute = ConvoState.useChatContext(s => s.dispatch.mute) const saveMuted = (muted: boolean) => { setSaving(true) mute(muted) diff --git a/shared/chat/conversation/input-area/container.tsx b/shared/chat/conversation/input-area/container.tsx index 4482b2915fb3..75e693925316 100644 --- a/shared/chat/conversation/input-area/container.tsx +++ b/shared/chat/conversation/input-area/container.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import {PerfProfiler} from '@/perf/react-profiler' import Normal from './normal' import Preview from './preview' @@ -7,9 +8,9 @@ import ThreadSearch from '../search' import {useThreadSearchRoute} from '../thread-search-route' const InputAreaContainer = () => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const showThreadSearch = !!useThreadSearchRoute() - const {membershipType, resetParticipants, wasFinalizedBy} = Chat.useChatContext( + const {membershipType, resetParticipants, wasFinalizedBy} = ConvoState.useChatContext( C.useShallow(s => { const {membershipType, resetParticipants, wasFinalizedBy} = s.meta return {membershipType, resetParticipants, wasFinalizedBy} diff --git a/shared/chat/conversation/input-area/location-popup.native.tsx b/shared/chat/conversation/input-area/location-popup.native.tsx index dd6d1e4cc65e..60cc11be84e9 100644 --- a/shared/chat/conversation/input-area/location-popup.native.tsx +++ b/shared/chat/conversation/input-area/location-popup.native.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as React from 'react' import {useConfigState} from '@/stores/config' import logger from '@/logger' @@ -11,7 +11,13 @@ import {requestLocationPermission} from '@/util/platform-specific' import * as ExpoLocation from 'expo-location' import {ignorePromise} from '@/constants/utils' -const LocationButton = (props: {disabled: boolean; label: string; onClick: () => void; subLabel?: string; primary?: boolean}) => ( +const LocationButton = (props: { + disabled: boolean + label: string + onClick: () => void + subLabel?: string + primary?: boolean +}) => ( style={styles.liveButton} > - {props.label} - {!!props.subLabel && {props.subLabel}} + + {props.label} + + {!!props.subLabel && ( + + {props.subLabel} + + )} ) @@ -39,7 +54,7 @@ const useWatchPosition = ( conversationIDKey: T.Chat.ConversationIDKey, setLocation: React.Dispatch> ) => { - const setCommandStatusInfo = Chat.useChatUIContext(s => s.dispatch.setCommandStatusInfo) + const setCommandStatusInfo = ConvoState.useChatUIContext(s => s.dispatch.setCommandStatusInfo) React.useEffect(() => { let unsub = () => {} logger.info('[location] perms check due to map') @@ -78,11 +93,11 @@ const useWatchPosition = ( } const LocationPopup = () => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const username = useCurrentUserState(s => s.username) const httpSrv = useConfigState(s => s.httpSrv) const [location, setLocation] = React.useState() - const locationDenied = Chat.useChatUIContext( + const locationDenied = ConvoState.useChatUIContext( s => s.commandStatus?.displayType === T.RPCChat.UICommandStatusDisplayTyp.error ) const [mapLoaded, setMapLoaded] = React.useState(false) @@ -91,7 +106,7 @@ const LocationPopup = () => { clearModals() } const onSettings = useConfigState(s => s.dispatch.defer.openAppSettings) - const sendMessage = Chat.useChatContext(s => s.dispatch.sendMessage) + const sendMessage = ConvoState.useChatContext(s => s.dispatch.sendMessage) const onLocationShare = (duration: string) => { onClose() sendMessage(duration ? `/location live ${duration}` : '/location') @@ -120,12 +135,33 @@ const LocationPopup = () => { setMapLoaded(true)} /> )} - - onLocationShare('15m')} subLabel="Live location" /> - onLocationShare('1h')} subLabel="Live location" /> - onLocationShare('8h')} subLabel="Live location" /> - onLocationShare('')} subLabel={mapLoaded ? `Accurate to ${location ? location.accuracy : 0} meters` : undefined} primary={true} /> - + + onLocationShare('15m')} + subLabel="Live location" + /> + onLocationShare('1h')} + subLabel="Live location" + /> + onLocationShare('8h')} + subLabel="Live location" + /> + onLocationShare('')} + subLabel={mapLoaded ? `Accurate to ${location ? location.accuracy : 0} meters` : undefined} + primary={true} + /> + ) diff --git a/shared/chat/conversation/input-area/normal/index.tsx b/shared/chat/conversation/input-area/normal/index.tsx index d61efe95e241..171da7ec3a7c 100644 --- a/shared/chat/conversation/input-area/normal/index.tsx +++ b/shared/chat/conversation/input-area/normal/index.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as React from 'react' import CommandMarkdown from '../../command-markdown' @@ -25,8 +26,8 @@ const useHintText = (p: { }) => { const {minWriterRole, isExploding, isEditing, cannotWrite} = p const username = useCurrentUserState(s => s.username) - const {teamType, teamname, channelname} = Chat.useChatContext(s => s.meta) - const participantInfoName = Chat.useChatContext(s => s.participants.name) + const {teamType, teamname, channelname} = ConvoState.useChatContext(s => s.meta) + const participantInfoName = ConvoState.useChatContext(s => s.participants.name) if (Kb.Styles.isMobile && isExploding) { return C.isLargeScreen ? `Write an exploding message` : 'Exploding message' } @@ -69,11 +70,11 @@ const useHintText = (p: { } const Input = function Input() { - const showGiphySearch = Chat.useChatUIContext(s => s.giphyWindow) - const showCommandMarkdown = Chat.useChatContext(s => !!s.commandMarkdown) - const showCommandStatus = Chat.useChatUIContext(s => !!s.commandStatus) - const replyTo = Chat.useChatUIContext(s => s.replyTo) - const showReplyTo = Chat.useChatContext(s => !!s.messageMap.get(replyTo)?.id) + const showGiphySearch = ConvoState.useChatUIContext(s => s.giphyWindow) + const showCommandMarkdown = ConvoState.useChatContext(s => !!s.commandMarkdown) + const showCommandStatus = ConvoState.useChatUIContext(s => !!s.commandStatus) + const replyTo = ConvoState.useChatUIContext(s => s.replyTo) + const showReplyTo = ConvoState.useChatContext(s => !!s.messageMap.get(replyTo)?.id) return ( {showReplyTo && } @@ -113,14 +114,14 @@ const ConnectedPlatformInput = function ConnectedPlatformInput() { const route = useRoute | RootRouteProps<'chatRoot'>>() const params = getRouteParamsFromRoute<'chatConversation' | 'chatRoot'>(route) const infoPanelShowing = !!(params && typeof params === 'object' && 'infoPanel' in params && params.infoPanel) - const uiData = Chat.useChatUIContext( + const uiData = ConvoState.useChatUIContext( C.useShallow(s => ({ editOrdinal: s.editing, replyTo: s.replyTo, unsentText: s.unsentText, })) ) - const data = Chat.useChatContext( + const data = ConvoState.useChatContext( C.useShallow(s => { const {meta, id: conversationIDKey, messageMap} = s const {sendMessage, jumpToRecent, setExplodingMode} = s.dispatch @@ -149,8 +150,8 @@ const ConnectedPlatformInput = function ConnectedPlatformInput() { const {suggestBotCommandsUpdateStatus, showReplyPreview} = data const {editOrdinal, unsentText} = uiData const isEditing = !!editOrdinal - const setEditing = Chat.useChatUIContext(s => s.dispatch.setEditing) - const updateUnsentText = Chat.useChatUIContext(s => s.dispatch.injectIntoInput) + const setEditing = ConvoState.useChatUIContext(s => s.dispatch.setEditing) + const updateUnsentText = ConvoState.useChatUIContext(s => s.dispatch.injectIntoInput) const [explodingModeSeconds, setExplodingModeSeconds] = React.useState(explodingModeSecondsRaw) const isExploding = explodingModeSeconds !== 0 @@ -177,7 +178,7 @@ const ConnectedPlatformInput = function ConnectedPlatformInput() { if (!text) return injectText('', true) sendMessage(text) - const cs = Chat.getConvoState(conversationIDKey) + const cs = ConvoState.getConvoState(conversationIDKey) if (cs.messageCenterOrdinal) { cs.dispatch.toggleThreadSearch(true) jumpToRecent() @@ -227,7 +228,7 @@ const ConnectedPlatformInput = function ConnectedPlatformInput() { React.useEffect(() => { const rows = [loadIDOnUnloadRef.current] return () => { - Chat.useChatState.getState().dispatch.unboxRows(rows) + ConvoState.unboxRows(rows) } }, [loadIDOnUnloadRef]) diff --git a/shared/chat/conversation/input-area/normal/input.desktop.tsx b/shared/chat/conversation/input-area/normal/input.desktop.tsx index 79fa47cea087..f8ac1c093399 100644 --- a/shared/chat/conversation/input-area/normal/input.desktop.tsx +++ b/shared/chat/conversation/input-area/normal/input.desktop.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Kb from '@/common-adapters' import * as React from 'react' @@ -112,8 +112,7 @@ export function Input(p: InputLowLevelProps) { if (rowsMax) { heightStyles.maxHeight = - rowsMax * - (textStyle.lineHeight === undefined ? 20 : maybeParseInt(textStyle.lineHeight, 10) || 20) + rowsMax * (textStyle.lineHeight === undefined ? 20 : maybeParseInt(textStyle.lineHeight, 10) || 20) } const paddingStyles = padding ? Kb.Styles.padding(Kb.Styles.globalMargins[padding]) : {} @@ -312,7 +311,7 @@ const EmojiButton = function EmojiButton(p: EmojiButtonProps) { } const GiphyButton = function GiphyButton() { - const toggleGiphyPrefill = Chat.useChatUIContext(s => s.dispatch.toggleGiphyPrefill) + const toggleGiphyPrefill = ConvoState.useChatUIContext(s => s.dispatch.toggleGiphyPrefill) const onGiphyToggle = toggleGiphyPrefill return ( @@ -326,12 +325,10 @@ const fileListToPaths = (f: FileList): Array => { return Array.from(f).map(f => getPathForFile?.(f) ?? '') } -const FileButton = function FileButton(p: { - setHtmlInputRef: (i: HTMLInputElement | null) => void -}) { +const FileButton = function FileButton(p: {setHtmlInputRef: (i: HTMLInputElement | null) => void}) { const {setHtmlInputRef} = p const htmlInputRef = React.useRef(null) - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const pickFile = () => { const paths = htmlInputRef.current?.files ? fileListToPaths(htmlInputRef.current.files) : undefined const pathAndOutboxIDs = paths?.reduce>((arr, path: string) => { @@ -389,7 +386,7 @@ const useKeyboard = (p: UseKeyboardProps) => { const {htmlInputRef, focusInput, isEditing, onKeyDown, onCancelEditing} = p const {onChangeText, onEditLastMessage, showReplyPreview} = p const lastText = React.useRef('') - const setReplyTo = Chat.useChatUIContext(s => s.dispatch.setReplyTo) + const setReplyTo = ConvoState.useChatUIContext(s => s.dispatch.setReplyTo) const {scrollDown, scrollUp} = React.useContext(ScrollContext) const onCancelReply = () => { setReplyTo(T.Chat.numberToOrdinal(0)) @@ -518,7 +515,7 @@ const PlatformInput = function PlatformInput(p: Props) { const focusInput = () => { inputRef.current?.focus() } - const setEditing = Chat.useChatUIContext(s => s.dispatch.setEditing) + const setEditing = ConvoState.useChatUIContext(s => s.dispatch.setEditing) const onEditLastMessage = () => { setEditing('last') } diff --git a/shared/chat/conversation/input-area/normal/input.native.tsx b/shared/chat/conversation/input-area/normal/input.native.tsx index 39d3bac7e964..6bfdadc638cc 100644 --- a/shared/chat/conversation/input-area/normal/input.native.tsx +++ b/shared/chat/conversation/input-area/normal/input.native.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as React from 'react' import AudioRecorder from '@/chat/audio/audio-recorder.native' @@ -235,7 +235,7 @@ const Buttons = function Buttons(p: ButtonsProps) { updatePickerMap(pickKey, undefined) }, [emojiStr, insertText, lastEmoji, updatePickerMap]) - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const openEmojiPicker = () => { navigateAppend(conversationIDKey => ({ name: 'chatChooseEmoji', @@ -351,9 +351,9 @@ type ChatFilePickerProps = { } const ChatFilePicker = (p: ChatFilePickerProps) => { const {attachTo, showingPopup, hidePopup} = p - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const filePickerError = useConfigState(s => s.dispatch.filePickerError) - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const launchNativeImagePicker = (mediaType: 'photo' | 'video' | 'mixed' | 'file', location: string) => { const f = async () => { const handleSelection = (result: ImagePicker.ImagePickerResult) => { @@ -576,7 +576,7 @@ const PlatformInput = (p: Props) => { ourShowMenu('exploding') } - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onPasteImage = (uri: Array) => { try { const pathAndOutboxIDs = uri.map(path => ({path})) diff --git a/shared/chat/conversation/input-area/normal/moremenu-popup.native.tsx b/shared/chat/conversation/input-area/normal/moremenu-popup.native.tsx index 5081785b30b5..8ad1b4eae3a8 100644 --- a/shared/chat/conversation/input-area/normal/moremenu-popup.native.tsx +++ b/shared/chat/conversation/input-area/normal/moremenu-popup.native.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' type Props = { @@ -8,8 +8,8 @@ type Props = { const MoreMenuPopup = (props: Props) => { const {onHidden, visible} = props - const injectIntoInput = Chat.useChatUIContext(s => s.dispatch.injectIntoInput) - const navigateAppend = Chat.useChatNavigateAppend() + const injectIntoInput = ConvoState.useChatUIContext(s => s.dispatch.injectIntoInput) + const navigateAppend = ConvoState.useChatNavigateAppend() const onLocationShare = () => { navigateAppend(conversationIDKey => ({name: 'chatLocationPreview', params: {conversationIDKey}})) } diff --git a/shared/chat/conversation/input-area/normal/set-explode-popup/hooks.tsx b/shared/chat/conversation/input-area/normal/set-explode-popup/hooks.tsx index 128a336397a0..8ffbeb7acd5e 100644 --- a/shared/chat/conversation/input-area/normal/set-explode-popup/hooks.tsx +++ b/shared/chat/conversation/input-area/normal/set-explode-popup/hooks.tsx @@ -1,4 +1,5 @@ import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' import type {Props} from '.' @@ -31,8 +32,8 @@ const makeItems = (meta: T.Chat.ConversationMeta) => { export default (p: Props) => { const {setExplodingMode, onHidden, visible, attachTo, onAfterSelect} = p - const _meta = Chat.useChatContext(s => s.meta) - const selected = Chat.useChatContext(s => s.explodingMode) + const _meta = ConvoState.useChatContext(s => s.meta) + const selected = ConvoState.useChatContext(s => s.explodingMode) const onSelect = (seconds: number) => { setTimeout(() => { setExplodingMode(seconds) diff --git a/shared/chat/conversation/input-area/normal/typing.tsx b/shared/chat/conversation/input-area/normal/typing.tsx index d1031d8ee82d..23d97cb2a21f 100644 --- a/shared/chat/conversation/input-area/normal/typing.tsx +++ b/shared/chat/conversation/input-area/normal/typing.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' const Names = (props: {names?: ReadonlySet}) => { @@ -44,8 +44,8 @@ const Names = (props: {names?: ReadonlySet}) => { const emptySet = new Set() const Typing = function Typing() { - const showGiphySearch = Chat.useChatUIContext(s => s.giphyWindow) - const names = Chat.useChatContext( + const showGiphySearch = ConvoState.useChatUIContext(s => s.giphyWindow) + const names = ConvoState.useChatContext( C.useShallow(s => { const names = s.typing if (!C.isMobile) return names diff --git a/shared/chat/conversation/input-area/preview.tsx b/shared/chat/conversation/input-area/preview.tsx index 3bf3c4e9756c..a3471dadff17 100644 --- a/shared/chat/conversation/input-area/preview.tsx +++ b/shared/chat/conversation/input-area/preview.tsx @@ -1,11 +1,11 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as React from 'react' import * as Kb from '@/common-adapters' const Preview = () => { - const meta = Chat.useChatContext(s => s.meta) - const onJoinChannel = Chat.useChatContext(s => s.dispatch.joinConversation) - const onLeaveChannel = Chat.useChatContext(s => s.dispatch.leaveConversation) + const meta = ConvoState.useChatContext(s => s.meta) + const onJoinChannel = ConvoState.useChatContext(s => s.dispatch.joinConversation) + const onLeaveChannel = ConvoState.useChatContext(s => s.dispatch.leaveConversation) const {channelname} = meta const [clicked, setClicked] = React.useState(undefined) diff --git a/shared/chat/conversation/input-area/suggestors/channels.tsx b/shared/chat/conversation/input-area/suggestors/channels.tsx index ef5ab6dc78a8..334347140aa4 100644 --- a/shared/chat/conversation/input-area/suggestors/channels.tsx +++ b/shared/chat/conversation/input-area/suggestors/channels.tsx @@ -1,5 +1,7 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' +import type {ConvoState as ConvoStateType} from '@/stores/convostate' import * as T from '@/constants/types' import * as Teams from '@/stores/teams' import * as Common from './common' @@ -42,7 +44,7 @@ const ItemRenderer = (p: Common.ItemRendererProps) => { const noChannel: Array<{channelname: string}> = [] const getChannelSuggestions = ( - s: Chat.ConvoState, + s: ConvoStateType, teamname: string, teamMeta: Teams.State['teamMeta'] ) => { @@ -79,8 +81,8 @@ const getChannelSuggestions = ( } const useDataSource = (filter: string) => { - const conversationIDKey = Chat.useChatContext(s => s.id) - const meta = Chat.useChatContext(s => s.meta) + const conversationIDKey = ConvoState.useChatContext(s => s.id) + const meta = ConvoState.useChatContext(s => s.meta) const {teamID} = meta const suggestChannelsLoading = C.Waiting.useAnyWaiting([ @@ -88,7 +90,7 @@ const useDataSource = (filter: string) => { C.waitingKeyChatMutualTeams(conversationIDKey), ]) const teamMeta = Teams.useTeamsState(s => s.teamMeta) - return Chat.useChatContext( + return ConvoState.useChatContext( C.useDeep(s => { const fil = filter.toLowerCase() // don't include 'small' here to ditch the single #general suggestion diff --git a/shared/chat/conversation/input-area/suggestors/commands.tsx b/shared/chat/conversation/input-area/suggestors/commands.tsx index 7b583f0ef240..4c07743aeee3 100644 --- a/shared/chat/conversation/input-area/suggestors/commands.tsx +++ b/shared/chat/conversation/input-area/suggestors/commands.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Common from './common' import * as Kb from '@/common-adapters' @@ -43,8 +44,8 @@ const blankCommands: Array = [] const ItemRenderer = (p: Common.ItemRendererProps) => { const {selected, item: command} = p const prefix = getCommandPrefix(command) - const botSettings = Chat.useChatContext(s => s.botSettings) - const enabled = Chat.useChatContext(s => { + const botSettings = ConvoState.useChatContext(s => s.botSettings) + const enabled = ConvoState.useChatContext(s => { const {botCommands} = s.meta const suggestBotCommands = botCommands.typ === T.RPCChat.ConversationCommandGroupsTyp.custom @@ -106,9 +107,9 @@ type UseDataSourceProps = { const useDataSource = (p: UseDataSourceProps) => { const {filter, inputRef, lastTextRef} = p const staticConfig = Chat.useChatState(s => s.staticConfig) - const showGiphySearch = Chat.useChatUIContext(s => s.giphyWindow) - const showCommandMarkdown = Chat.useChatContext(s => !!s.commandMarkdown) - return Chat.useChatContext( + const showGiphySearch = ConvoState.useChatUIContext(s => s.giphyWindow) + const showCommandMarkdown = ConvoState.useChatContext(s => !!s.commandMarkdown) + return ConvoState.useChatContext( C.useShallow(s => { if (showCommandMarkdown || showGiphySearch) { return [] diff --git a/shared/chat/conversation/input-area/suggestors/emoji.tsx b/shared/chat/conversation/input-area/suggestors/emoji.tsx index 2c427f4ee24b..efa61901057d 100644 --- a/shared/chat/conversation/input-area/suggestors/emoji.tsx +++ b/shared/chat/conversation/input-area/suggestors/emoji.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Common from './common' import * as Kb from '@/common-adapters' import {type EmojiData, RPCToEmojiData, emojiData} from '@/common-adapters/emoji' @@ -38,7 +38,7 @@ const emojiPrepass = /[a-z0-9_]{2,}(?!.*:)/i const empty = new Array() const useDataSource = (filter: string) => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const {emojis: userEmojis, loading: userEmojisLoading} = useUserEmoji({conversationIDKey}) if (!emojiPrepass.test(filter)) { diff --git a/shared/chat/conversation/input-area/suggestors/index.tsx b/shared/chat/conversation/input-area/suggestors/index.tsx index ea1c438ff82d..3ae75eaeaefa 100644 --- a/shared/chat/conversation/input-area/suggestors/index.tsx +++ b/shared/chat/conversation/input-area/suggestors/index.tsx @@ -1,5 +1,5 @@ import * as Channels from './channels' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Commands from './commands' import * as Emoji from './emoji' import * as Kb from '@/common-adapters' @@ -392,7 +392,7 @@ type PopupProps = { } const Popup = (p: PopupProps) => { const {children, suggestionOverlayStyle, setInactive, inputRef} = p - const conversationIdKey = Chat.useChatContext(s => s.id) + const conversationIdKey = ConvoState.useChatContext(s => s.id) const attachRef = inputRef as React.RefObject @@ -409,9 +409,9 @@ const Popup = (p: PopupProps) => { style={suggestionOverlayStyle} > {Kb.Styles.isMobile ? ( - + {children} - + ) : ( children )} diff --git a/shared/chat/conversation/input-area/suggestors/users.tsx b/shared/chat/conversation/input-area/suggestors/users.tsx index 5651f081784e..2e7c24840e85 100644 --- a/shared/chat/conversation/input-area/suggestors/users.tsx +++ b/shared/chat/conversation/input-area/suggestors/users.tsx @@ -1,10 +1,11 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' -import {useTeamsState} from '@/stores/teams' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Common from './common' import * as Kb from '@/common-adapters' import {useUsersState} from '@/stores/users' +import {useTeamMembers} from '@/teams/team-members' export const transformer = ( input: { @@ -139,27 +140,22 @@ const getTeams = (layout?: T.RPCChat.UIInboxLayout) => { const useDataUsers = () => { const infoMap = useUsersState(s => s.infoMap) - const participantInfo = Chat.useChatContext(s => s.participants) - return Chat.useChatContext( - C.useDeep(s => { - const {teamID, teamType} = s.meta - // TODO not reactive - const teamMembers = useTeamsState.getState().teamIDToMembers.get(teamID) - const usernames = teamMembers - ? [...teamMembers.values()].map(m => m.username).sort((a, b) => a.localeCompare(b)) - : participantInfo.all - const suggestions = usernames.map(username => ({ - fullName: infoMap.get(username)?.fullname || '', - username, - })) - if (teamType !== 'adhoc') { - const fullName = teamType === 'small' ? 'Everyone in this team' : 'Everyone in this channel' - suggestions.push({fullName, username: 'channel'}, {fullName, username: 'here'}) - } - // TODO this will thrash on every store change, TODO fix - return suggestions - }) + const {participantInfo, teamID, teamType} = ConvoState.useChatContext( + C.useShallow(s => ({participantInfo: s.participants, teamID: s.meta.teamID, teamType: s.meta.teamType})) ) + const teamMembers = useTeamMembers(teamID) + const usernames = teamMembers + ? [...teamMembers.values()].map(member => member.username).sort((a, b) => a.localeCompare(b)) + : participantInfo.all + const suggestions = usernames.map(username => ({ + fullName: infoMap.get(username)?.fullname || '', + username, + })) + if (teamType !== 'adhoc') { + const fullName = teamType === 'small' ? 'Everyone in this team' : 'Everyone in this channel' + suggestions.push({fullName, username: 'channel'}, {fullName, username: 'here'}) + } + return suggestions } const useDataTeams = () => { diff --git a/shared/chat/conversation/list-area/hooks.tsx b/shared/chat/conversation/list-area/hooks.tsx index 7001595ee7d1..dc9be90b2997 100644 --- a/shared/chat/conversation/list-area/hooks.tsx +++ b/shared/chat/conversation/list-area/hooks.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import JumpToRecent from './jump-to-recent' import type * as T from '@/constants/types' import logger from '@/logger' @@ -13,14 +14,14 @@ export const useActions = (p: {conversationIDKey: T.Chat.ConversationIDKey}) => return } // Force mark as read since this is triggered by navigation (user action) - Chat.getConvoState(conversationIDKey).dispatch.markThreadAsRead(true) + ConvoState.getConvoState(conversationIDKey).dispatch.markThreadAsRead(true) } return {markInitiallyLoadedThreadAsRead} } export const useJumpToRecent = (scrollToBottom: () => void, numOrdinals: number) => { - const data = Chat.useChatContext( + const data = ConvoState.useChatContext( C.useShallow(s => { const {loaded, moreToLoadForward} = s const {jumpToRecent, toggleThreadSearch} = s.dispatch diff --git a/shared/chat/conversation/list-area/index.desktop.tsx b/shared/chat/conversation/list-area/index.desktop.tsx index ba9d3df80fb6..1a9ca47bfaf1 100644 --- a/shared/chat/conversation/list-area/index.desktop.tsx +++ b/shared/chat/conversation/list-area/index.desktop.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as Hooks from './hooks' import * as React from 'react' @@ -35,7 +35,7 @@ const useScrolling = (p: { setListRef: (r: HTMLDivElement | null) => void centeredOrdinal: T.Chat.Ordinal | undefined }) => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const {listRef, setListRef: _setListRef, containsLatestMessage} = p const containsLatestMessageRef = React.useRef(containsLatestMessage) React.useEffect(() => { @@ -43,17 +43,14 @@ const useScrolling = (p: { }, [containsLatestMessage]) const {messageOrdinals, centeredOrdinal, loaded} = p const numOrdinals = messageOrdinals.length - const loadNewerMessagesDueToScroll = Chat.useChatContext(s => s.dispatch.loadNewerMessagesDueToScroll) - const loadNewerMessages = C.useThrottledCallback( - () => { - loadNewerMessagesDueToScroll(numOrdinals) - }, - 200 - ) + const loadNewerMessagesDueToScroll = ConvoState.useChatContext(s => s.dispatch.loadNewerMessagesDueToScroll) + const loadNewerMessages = C.useThrottledCallback(() => { + loadNewerMessagesDueToScroll(numOrdinals) + }, 200) // if we scroll up try and keep the position const scrollBottomOffsetRef = React.useRef(undefined) - const loadOlderMessages = Chat.useChatContext(s => s.dispatch.loadOlderMessagesDueToScroll) + const loadOlderMessages = ConvoState.useChatContext(s => s.dispatch.loadOlderMessagesDueToScroll) const {markInitiallyLoadedThreadAsRead} = Hooks.useActions({conversationIDKey}) // pixels away from top/bottom to load/be locked const listEdgeSlopBottom = 10 @@ -338,7 +335,7 @@ const useScrolling = (p: { }, [scrollDown, scrollToBottom, scrollUp, setScrollRef]) // go to editing message - const editingOrdinal = Chat.useChatUIContext(s => s.editing) + const editingOrdinal = ConvoState.useChatUIContext(s => s.editing) const lastEditingOrdinalRef = React.useRef(0) React.useEffect(() => { if (lastEditingOrdinalRef.current === editingOrdinal) return @@ -386,10 +383,7 @@ const useItems = (p: { )} > - + ) } @@ -475,8 +469,8 @@ const useItems = (p: { const noOrdinals = new Array() const ThreadWrapper = function ThreadWrapper() { - const editingOrdinal = Chat.useChatUIContext(s => s.editing) - const data = Chat.useChatContext( + const editingOrdinal = ConvoState.useChatUIContext(s => s.editing) + const data = ConvoState.useChatContext( C.useShallow(s => { const {id: conversationIDKey} = s const {messageCenterOrdinal: mco, messageOrdinals = noOrdinals, loaded} = s diff --git a/shared/chat/conversation/list-area/index.native.tsx b/shared/chat/conversation/list-area/index.native.tsx index 52d94423a5b2..62b4c6706133 100644 --- a/shared/chat/conversation/list-area/index.native.tsx +++ b/shared/chat/conversation/list-area/index.native.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Hooks from './hooks' import * as Kb from '@/common-adapters' @@ -42,7 +42,7 @@ const useScrolling = (p: { }) => { const {listRef, centeredOrdinal, messageOrdinals} = p const numOrdinals = messageOrdinals.length - const loadOlderMessages = Chat.useChatContext(s => s.dispatch.loadOlderMessagesDueToScroll) + const loadOlderMessages = ConvoState.useChatContext(s => s.dispatch.loadOlderMessagesDueToScroll) const [scrollToBottom] = React.useState(() => () => { listRef.current?.scrollToOffset({animated: false, offset: 0}) }) @@ -102,7 +102,7 @@ const ConversationList = function ConversationList() { ) : null - const listData = Chat.useChatContext( + const listData = ConvoState.useChatContext( C.useShallow(s => { const {id: conversationIDKey, loaded, messageCenterOrdinal} = s const centeredOrdinal = messageCenterOrdinal?.ordinal ?? T.Chat.numberToOrdinal(-1) @@ -134,12 +134,7 @@ const ConversationList = function ConversationList() { if (!ordinal) { return null } - return ( - - ) + return } const numOrdinals = messageOrdinals.length @@ -149,7 +144,7 @@ const ConversationList = function ConversationList() { if (!ordinal) { return 'null' } - const convoState = Chat.getConvoState(conversationIDKey) + const convoState = ConvoState.getConvoState(conversationIDKey) return convoState.rowRecycleTypeMap.get(ordinal) ?? convoState.messageTypeMap.get(ordinal) ?? 'text' }, [conversationIDKey] diff --git a/shared/chat/conversation/load-status.tsx b/shared/chat/conversation/load-status.tsx index 38030e6b6078..87732a956fde 100644 --- a/shared/chat/conversation/load-status.tsx +++ b/shared/chat/conversation/load-status.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as React from 'react' import * as Kb from '@/common-adapters' import * as T from '@/constants/types' @@ -31,8 +31,8 @@ const getBkgColor = (status: T.RPCChat.UIChatThreadStatusTyp) => { } const ThreadLoadStatus = () => { - const status = Chat.useChatContext(s => s.threadLoadStatus) - const conversationIDKey = Chat.useChatContext(s => s.id) + const status = ConvoState.useChatContext(s => s.threadLoadStatus) + const conversationIDKey = ConvoState.useChatContext(s => s.id) logger.info(`ThreadLoadStatus: convID: ${conversationIDKey} status: ${status}`) if (status === T.RPCChat.UIChatThreadStatusTyp.none) { diff --git a/shared/chat/conversation/messages/account-payment/container.tsx b/shared/chat/conversation/messages/account-payment/container.tsx index 9a2b95d34091..a5f7d2912c3d 100644 --- a/shared/chat/conversation/messages/account-payment/container.tsx +++ b/shared/chat/conversation/messages/account-payment/container.tsx @@ -1,4 +1,6 @@ import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' +import type {ConvoState as ConvoStateType} from '@/stores/convostate' import * as Kb from '@/common-adapters' import type * as T from '@/constants/types' import MarkdownMemo from '@/wallets/markdown-memo' @@ -45,7 +47,7 @@ type OwnProps = { } const getRequestMessageInfo = ( - accountsInfoMap: Chat.ConvoState['accountsInfoMap'], + accountsInfoMap: ConvoStateType['accountsInfoMap'], message: T.Chat.MessageRequestPayment ) => { const maybeRequestInfo = accountsInfoMap.get(message.id) @@ -62,7 +64,7 @@ const getRequestMessageInfo = ( const ConnectedAccountPayment = (ownProps: OwnProps) => { const you = useCurrentUserState(s => s.username) - const accountsInfoMap = Chat.useChatContext(s => s.accountsInfoMap) + const accountsInfoMap = ConvoState.useChatContext(s => s.accountsInfoMap) const stateProps = (() => { const youAreSender = ownProps.message.author === you diff --git a/shared/chat/conversation/messages/attachment/file.tsx b/shared/chat/conversation/messages/attachment/file.tsx index 223db9e84d87..38b7dad13bb9 100644 --- a/shared/chat/conversation/messages/attachment/file.tsx +++ b/shared/chat/conversation/messages/attachment/file.tsx @@ -1,6 +1,7 @@ import * as C from '@/constants' import * as CryptoRoutes from '@/constants/crypto' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' import {isPathSaltpack, isPathSaltpackEncrypted, isPathSaltpackSigned} from '@/util/path' import captialize from 'lodash/capitalize' @@ -19,7 +20,7 @@ type OwnProps = { function FileContainer(p: OwnProps) { const {isEditing, message, ordinal} = p - const {attachmentDownload, messageAttachmentNativeShare} = Chat.useChatContext( + const {attachmentDownload, messageAttachmentNativeShare} = ConvoState.useChatContext( C.useShallow(s => ({ attachmentDownload: s.dispatch.attachmentDownload, messageAttachmentNativeShare: s.dispatch.messageAttachmentNativeShare, diff --git a/shared/chat/conversation/messages/attachment/image/index.tsx b/shared/chat/conversation/messages/attachment/image/index.tsx index 6f433768822b..c6dc0d99a80e 100644 --- a/shared/chat/conversation/messages/attachment/image/index.tsx +++ b/shared/chat/conversation/messages/attachment/image/index.tsx @@ -1,6 +1,6 @@ import * as Kb from '@/common-adapters' import * as React from 'react' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' import ImageImpl from './imageimpl' import { @@ -23,7 +23,7 @@ type Props = { function Image(p: Props) { const {message, ordinal, showPopup} = p const {isCollapsed, title, transferProgress, transferState} = message - const attachmentPreviewSelect = Chat.useChatContext(s => s.dispatch.attachmentPreviewSelect) + const attachmentPreviewSelect = ConvoState.useChatContext(s => s.dispatch.attachmentPreviewSelect) const fileName = getAttachmentDisplayFileName(message) const showTitle = !!title const openFullscreen = () => { @@ -33,12 +33,13 @@ function Image(p: Props) { const containerStyle = styles.container const collapseIcon = useCollapseIcon(ordinal, isCollapsed, false) - const filename = Kb.Styles.isMobile || !fileName ? null : ( - - {fileName} - {collapseIcon} - - ) + const filename = + Kb.Styles.isMobile || !fileName ? null : ( + + {fileName} + {collapseIcon} + + ) const toastTargetRef = React.useRef(null) @@ -53,7 +54,7 @@ function Image(p: Props) { > : null} - + ) diff --git a/shared/chat/conversation/messages/attachment/shared.tsx b/shared/chat/conversation/messages/attachment/shared.tsx index 7d6f208f9687..317c20cd468b 100644 --- a/shared/chat/conversation/messages/attachment/shared.tsx +++ b/shared/chat/conversation/messages/attachment/shared.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import {clampImageSize} from '@/constants/chat/helpers' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as React from 'react' import * as T from '@/constants/types' @@ -79,7 +80,7 @@ export const TransferIcon = (p: { default: } } - const download = Chat.useChatContext(s => + const download = ConvoState.useChatContext(s => C.isMobile ? s.dispatch.messageAttachmentNativeSave : s.dispatch.attachmentDownload ) const onDownload = () => { @@ -173,7 +174,7 @@ export const getAttachmentPreviewSize = ( ) => { const {fileURL, previewHeight, previewWidth} = message let {previewURL} = message - let {height, width} = Chat.clampImageSize(previewWidth, previewHeight, maxWidth, maxHeight) + let {height, width} = clampImageSize(previewWidth, previewHeight, maxWidth, maxHeight) // This is mostly a sanity check and also allows us to handle HEIC even though the go side doesn't // understand. if (useSquareFallback && (height === 0 || width === 0)) { @@ -234,7 +235,7 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ })) const useCollapseAction = (ordinal: T.Chat.Ordinal) => { - const toggleMessageCollapse = Chat.useChatContext(s => s.dispatch.toggleMessageCollapse) + const toggleMessageCollapse = ConvoState.useChatContext(s => s.dispatch.toggleMessageCollapse) const onCollapse = () => { toggleMessageCollapse(T.Chat.numberToMessageID(T.Chat.ordinalToNumber(ordinal)), ordinal) } diff --git a/shared/chat/conversation/messages/attachment/video/index.tsx b/shared/chat/conversation/messages/attachment/video/index.tsx index 750be423ad16..835b7afcd1d6 100644 --- a/shared/chat/conversation/messages/attachment/video/index.tsx +++ b/shared/chat/conversation/messages/attachment/video/index.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import * as Kb from '@/common-adapters' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' import VideoImpl from './videoimpl' import { @@ -23,7 +23,7 @@ type Props = { function Video(p: Props) { const {message, ordinal, showPopup} = p const {isCollapsed, submitState, title, transferProgress, transferState} = message - const attachmentPreviewSelect = Chat.useChatContext(s => s.dispatch.attachmentPreviewSelect) + const attachmentPreviewSelect = ConvoState.useChatContext(s => s.dispatch.attachmentPreviewSelect) const fileName = getAttachmentDisplayFileName(message) const showTitle = !!title const openFullscreen = () => { @@ -33,12 +33,13 @@ function Video(p: Props) { const containerStyle = styles.container const collapseIcon = useCollapseIcon(ordinal, isCollapsed, false) - const filename = Kb.Styles.isMobile || !fileName ? null : ( - - {fileName} - {collapseIcon} - - ) + const filename = + Kb.Styles.isMobile || !fileName ? null : ( + + {fileName} + {collapseIcon} + + ) const toastTargetRef = React.useRef(null) @@ -54,7 +55,7 @@ function Video(p: Props) { > : null} - + ) return ( - + {isCollapsed ? : content} ) diff --git a/shared/chat/conversation/messages/cards/make-team.tsx b/shared/chat/conversation/messages/cards/make-team.tsx index e01b118a7144..b76026f0a6b4 100644 --- a/shared/chat/conversation/messages/cards/make-team.tsx +++ b/shared/chat/conversation/messages/cards/make-team.tsx @@ -1,8 +1,8 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' const MakeTeam = () => { - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onShowNewTeamDialog = () => navigateAppend(conversationIDKey => ({name: 'chatShowNewTeamDialog', params: {conversationIDKey}})) return ( diff --git a/shared/chat/conversation/messages/cards/team-journey/container.tsx b/shared/chat/conversation/messages/cards/team-journey/container.tsx index d4cab52cc24d..2e5842867319 100644 --- a/shared/chat/conversation/messages/cards/team-journey/container.tsx +++ b/shared/chat/conversation/messages/cards/team-journey/container.tsx @@ -1,5 +1,7 @@ import * as C from '@/constants' +import {isBigTeam as getIsBigTeam} from '@/constants/chat/helpers' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Teams from '@/stores/teams' import * as Kb from '@/common-adapters' @@ -13,16 +15,16 @@ const emptyJourney = Chat.makeMessageJourneycard({}) const TeamJourneyConnected = (ownProps: OwnProps) => { const {ordinal} = ownProps - const m = Chat.useChatContext(s => s.messageMap.get(ordinal)) + const m = ConvoState.useChatContext(s => s.messageMap.get(ordinal)) const message = m?.type === 'journeycard' ? m : emptyJourney - const conv = Chat.useChatContext(s => s.meta) + const conv = ConvoState.useChatContext(s => s.meta) const {cannotWrite, channelname, teamname, teamID} = conv const welcomeMessage = {display: '', raw: '', set: false} const canShowcase = Teams.useTeamsState(s => Teams.canShowcase(s, teamID)) - const isBigTeam = Chat.useChatState(s => Chat.isBigTeam(s, teamID)) + const isBigTeam = Chat.useChatState(s => getIsBigTeam(s.inboxLayout, teamID)) const navigateAppend = C.Router2.navigateAppend const _onAuthorClick = (teamID: T.Teams.TeamID) => navigateAppend({name: 'team', params: {teamID}}) - const dismissJourneycard = Chat.useChatContext(s => s.dispatch.dismissJourneycard) + const dismissJourneycard = ConvoState.useChatContext(s => s.dispatch.dismissJourneycard) const _onDismiss = (cardType: T.RPCChat.JourneycardType, ordinal: T.Chat.Ordinal) => dismissJourneycard(cardType, ordinal) const previewConversation = C.Router2.previewConversation @@ -42,7 +44,7 @@ const TeamJourneyConnected = (ownProps: OwnProps) => { const onGoToChannel = (channelName: string) => _onGoToChannel(channelName, teamname) const onPublishTeam = () => _onPublishTeam(teamID) - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const {cardType} = message let textComponent: React.ReactNode let image: Kb.IconType | undefined diff --git a/shared/chat/conversation/messages/emoji-row.tsx b/shared/chat/conversation/messages/emoji-row.tsx index 85fe9b007486..cb4bfcc59a06 100644 --- a/shared/chat/conversation/messages/emoji-row.tsx +++ b/shared/chat/conversation/messages/emoji-row.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as React from 'react' import {useOrdinal} from './ids-context' import * as Kb from '@/common-adapters' @@ -30,10 +31,10 @@ const useTopReacjis = () => function EmojiRowContainer(p: OwnProps) { const {className, hasUnfurls, messageType, onReact: onReactProp, onReply: onReplyProp, onShowingEmojiPicker, style} = p const ordinal = useOrdinal() - const setReplyTo = Chat.useChatUIContext(s => s.dispatch.setReplyTo) - const toggleMessageReaction = Chat.useChatContext(s => s.dispatch.toggleMessageReaction) + const setReplyTo = ConvoState.useChatUIContext(s => s.dispatch.setReplyTo) + const toggleMessageReaction = ConvoState.useChatContext(s => s.dispatch.toggleMessageReaction) const emojis = useTopReacjis() - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const _onForward = () => { navigateAppend(conversationIDKey => ({ name: 'chatForwardMsgPick', diff --git a/shared/chat/conversation/messages/message-popup/attachment.tsx b/shared/chat/conversation/messages/message-popup/attachment.tsx index 25db9e4b9033..b5a6f15773ad 100644 --- a/shared/chat/conversation/messages/message-popup/attachment.tsx +++ b/shared/chat/conversation/messages/message-popup/attachment.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as React from 'react' import type * as T from '@/constants/types' import {type Position, fileUIName, type StylesCrossPlatform} from '@/styles' @@ -21,7 +22,7 @@ const emptyMessage = Chat.makeMessageAttachment({}) const PopAttach = (ownProps: OwnProps) => { const {ordinal, attachTo, mode, onHidden, position, style, visible} = ownProps - const message = Chat.useChatContext(s => { + const message = ConvoState.useChatContext(s => { const m = s.messageMap.get(ordinal) const message = m?.type === 'attachment' ? m : emptyMessage return message @@ -36,7 +37,7 @@ const PopAttach = (ownProps: OwnProps) => { messageAttachmentNativeSave, messageAttachmentNativeShare, showInfoPanel, - } = Chat.useChatContext( + } = ConvoState.useChatContext( C.useShallow(s => { const { attachmentDownload, diff --git a/shared/chat/conversation/messages/message-popup/hooks.tsx b/shared/chat/conversation/messages/message-popup/hooks.tsx index 1fef4cca632e..b261fede1208 100644 --- a/shared/chat/conversation/messages/message-popup/hooks.tsx +++ b/shared/chat/conversation/messages/message-popup/hooks.tsx @@ -1,6 +1,7 @@ import type * as T from '@/constants/types' import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import {useConfigState} from '@/stores/config' import {useCurrentUserState} from '@/stores/current-user' @@ -45,19 +46,19 @@ const getConversationLabel = ( } export const useItems = (ordinal: T.Chat.Ordinal, onHidden: () => void) => { - const message = Chat.useChatContext(s => { + const message = ConvoState.useChatContext(s => { return s.messageMap.get(ordinal) ?? emptyText }) const isAttach = message.type === 'attachment' const {author, id, deviceName, timestamp, deviceRevokedAt} = message - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const {teamID, teamname} = meta - const participantInfo = Chat.useChatContext(s => s.participants) - const toggleMessageReaction = Chat.useChatContext(s => s.dispatch.toggleMessageReaction) + const participantInfo = ConvoState.useChatContext(s => s.participants) + const toggleMessageReaction = ConvoState.useChatContext(s => s.dispatch.toggleMessageReaction) const onReact = (emoji: string) => { toggleMessageReaction(ordinal, emoji) } - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const _onAddReaction = () => { navigateAppend(conversationIDKey => ({ name: 'chatChooseEmoji', @@ -108,13 +109,13 @@ export const useItems = (ordinal: T.Chat.Ordinal, onHidden: () => void) => { {icon: 'iconfont-link', onClick: onCopyLink, title: 'Copy a link to this message'}, ] as const - const {messageDelete, pinMessage, setMarkAsUnread} = Chat.useChatContext( + const {messageDelete, pinMessage, setMarkAsUnread} = ConvoState.useChatContext( C.useShallow(s => { const {messageDelete, pinMessage, setMarkAsUnread} = s.dispatch return {messageDelete, pinMessage, setMarkAsUnread} }) ) - const {setEditing, setReplyTo} = Chat.useChatUIContext( + const {setEditing, setReplyTo} = ConvoState.useChatUIContext( C.useShallow(s => ({setEditing: s.dispatch.setEditing, setReplyTo: s.dispatch.setReplyTo})) ) @@ -269,7 +270,7 @@ export const useItems = (ordinal: T.Chat.Ordinal, onHidden: () => void) => { } export const useHeader = (ordinal: T.Chat.Ordinal, onHidden: () => void) => { - const message = Chat.useChatContext(s => { + const message = ConvoState.useChatContext(s => { return s.messageMap.get(ordinal) ?? emptyText }) const you = useCurrentUserState(s => s.username) diff --git a/shared/chat/conversation/messages/message-popup/index.tsx b/shared/chat/conversation/messages/message-popup/index.tsx index dd46149379c6..98a08bc6b072 100644 --- a/shared/chat/conversation/messages/message-popup/index.tsx +++ b/shared/chat/conversation/messages/message-popup/index.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import type * as React from 'react' import AttachmentMessage from './attachment' @@ -19,7 +19,7 @@ type Props = { function MessagePopup(p: Props) { const {ordinal, attachTo, onHidden, position, style, visible, mode} = p - const type = Chat.useChatContext(s => s.messageMap.get(ordinal)?.type) + const type = ConvoState.useChatContext(s => s.messageMap.get(ordinal)?.type) switch (type) { case 'text': case 'setChannelname': @@ -118,12 +118,12 @@ export const useMessagePopup = (p: { shouldShow?: () => boolean style?: Kb.Styles.StylesCrossPlatform }) => { - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const {ordinal, shouldShow, style} = p const makePopup = (p: Kb.Popup2Parms) => { const {attachTo, hidePopup} = p return (shouldShow?.() ?? true) ? ( - + - + ) : null } return Kb.usePopup2(makePopup) diff --git a/shared/chat/conversation/messages/message-popup/journeycard.tsx b/shared/chat/conversation/messages/message-popup/journeycard.tsx index 3578f288a69f..b015e022262e 100644 --- a/shared/chat/conversation/messages/message-popup/journeycard.tsx +++ b/shared/chat/conversation/messages/message-popup/journeycard.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as T from '@/constants/types' import type * as React from 'react' @@ -16,11 +16,11 @@ type OwnProps = { const JourneyCard = (ownProps: OwnProps) => { const {ordinal, attachTo, mode, onHidden, style, visible, position} = ownProps - const cardType = Chat.useChatContext( + const cardType = ConvoState.useChatContext( s => s.messageMap.get(ordinal)?.cardType ?? T.RPCChat.JourneycardType.unused ) - const dismissJourneycard = Chat.useChatContext(s => s.dispatch.dismissJourneycard) + const dismissJourneycard = ConvoState.useChatContext(s => s.dispatch.dismissJourneycard) const onDismiss = () => { dismissJourneycard(cardType, ordinal) } diff --git a/shared/chat/conversation/messages/message-popup/text.tsx b/shared/chat/conversation/messages/message-popup/text.tsx index f822aacc8331..340bbc6dbbef 100644 --- a/shared/chat/conversation/messages/message-popup/text.tsx +++ b/shared/chat/conversation/messages/message-popup/text.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import {useConfigState} from '@/stores/config' import type * as React from 'react' import * as Kb from '@/common-adapters' @@ -23,7 +24,7 @@ const emptyMessage = Chat.makeMessageText({}) const PopText = (ownProps: OwnProps) => { const {ordinal, attachTo, mode, onHidden, position, style, visible} = ownProps - const message = Chat.useChatContext(s => { + const message = ConvoState.useChatContext(s => { const m = s.messageMap.get(ordinal) const message = m ?? emptyMessage return message @@ -64,7 +65,7 @@ const PopText = (ownProps: OwnProps) => { })() const yourMessage = author === you - const {isTeam, messageReplyPrivately, numPart, teamType} = Chat.useChatContext( + const {isTeam, messageReplyPrivately, numPart, teamType} = ConvoState.useChatContext( C.useShallow(s => { const {teamType, teamname} = s.meta const isTeam = !!teamname diff --git a/shared/chat/conversation/messages/pin/index.tsx b/shared/chat/conversation/messages/pin/index.tsx index 68bf1e8cccd4..ab00ff4bc351 100644 --- a/shared/chat/conversation/messages/pin/index.tsx +++ b/shared/chat/conversation/messages/pin/index.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import type * as T from '@/constants/types' @@ -6,7 +6,7 @@ type Props = {messageID: T.Chat.MessageID} const Pin = (props: Props) => { const {messageID} = props - const replyJump = Chat.useChatContext(s => s.dispatch.replyJump) + const replyJump = ConvoState.useChatContext(s => s.dispatch.replyJump) const onReplyClick = () => replyJump(messageID) return ( diff --git a/shared/chat/conversation/messages/react-button.tsx b/shared/chat/conversation/messages/react-button.tsx index 3fbcd7766bc3..c92b796cc40c 100644 --- a/shared/chat/conversation/messages/react-button.tsx +++ b/shared/chat/conversation/messages/react-button.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type {StylesCrossPlatform} from '@/styles' import {useOrdinal} from './ids-context' import * as Kb from '@/common-adapters' @@ -107,7 +107,7 @@ type NewReactionButtonProps = { export function NewReactionButton(p: NewReactionButtonProps) { const ordinal = useOrdinal() const isDarkMode = useColorScheme() === 'dark' - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onOpenEmojiPicker = () => { navigateAppend(conversationIDKey => ({ name: 'chatChooseEmoji', diff --git a/shared/chat/conversation/messages/reaction-tooltip.tsx b/shared/chat/conversation/messages/reaction-tooltip.tsx index 1b68cfa5fefc..af13035a2763 100644 --- a/shared/chat/conversation/messages/reaction-tooltip.tsx +++ b/shared/chat/conversation/messages/reaction-tooltip.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import type * as React from 'react' import ReactButton from './react-button' @@ -32,14 +33,14 @@ type Section = { const ReactionTooltip = (p: OwnProps) => { const {ordinal, onHidden, attachmentRef, onMouseLeave, onMouseOver, visible, emoji} = p - const reactions = Chat.useChatContext(s => { + const reactions = ConvoState.useChatContext(s => { const message = s.messageMap.get(ordinal) return message && Chat.isMessageWithReactions(message) ? message.reactions : undefined }) const usersInfo = useUsersState(s => (reactions ? s.infoMap : emptyUsersInfo)) - const toggleMessageReaction = Chat.useChatContext(s => s.dispatch.toggleMessageReaction) + const toggleMessageReaction = ConvoState.useChatContext(s => s.dispatch.toggleMessageReaction) - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onAddReaction = () => { onHidden() navigateAppend(conversationIDKey => ({ @@ -70,7 +71,7 @@ const ReactionTooltip = (p: OwnProps) => { reactionsToShow = reactionsToShow.filter(r => r.emoji === emoji) } const insets = Kb.useSafeAreaInsets() - const conversationIDKey = Chat.useChatContext(s => s.id) + const conversationIDKey = ConvoState.useChatContext(s => s.id) const messageContext = {isHighlighted: false, ordinal} if (!visible) { return null @@ -114,7 +115,7 @@ const ReactionTooltip = (p: OwnProps) => { style={styles.overlay} > {/* need context since this uses a portal... */} - + { )} - + ) } diff --git a/shared/chat/conversation/messages/reset-user.tsx b/shared/chat/conversation/messages/reset-user.tsx index 315d02340302..44126bda3d20 100644 --- a/shared/chat/conversation/messages/reset-user.tsx +++ b/shared/chat/conversation/messages/reset-user.tsx @@ -1,12 +1,12 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import {navToProfile} from '@/constants/router' const ResetUser = () => { - const meta = Chat.useChatContext(s => s.meta) - const participantInfo = Chat.useChatContext(s => s.participants) - const resetChatWithoutThem = Chat.useChatContext(s => s.dispatch.resetChatWithoutThem) - const resetLetThemIn = Chat.useChatContext(s => s.dispatch.resetLetThemIn) + const meta = ConvoState.useChatContext(s => s.meta) + const participantInfo = ConvoState.useChatContext(s => s.participants) + const resetChatWithoutThem = ConvoState.useChatContext(s => s.dispatch.resetChatWithoutThem) + const resetLetThemIn = ConvoState.useChatContext(s => s.dispatch.resetLetThemIn) const _participants = participantInfo.all const _resetParticipants = meta.resetParticipants const _viewProfile = navToProfile diff --git a/shared/chat/conversation/messages/retention-notice.tsx b/shared/chat/conversation/messages/retention-notice.tsx index 7767a95ddb03..077496fcc94f 100644 --- a/shared/chat/conversation/messages/retention-notice.tsx +++ b/shared/chat/conversation/messages/retention-notice.tsx @@ -1,5 +1,5 @@ import type * as T from '@/constants/types' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import * as Kb from '@/common-adapters' @@ -40,12 +40,12 @@ function makeRetentionNotice( } function RetentionNoticeContainer() { - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const {teamType, retentionPolicy: policy, teamRetentionPolicy: teamPolicy} = meta const canChange = Teams.useTeamsState(s => { return meta.teamType !== 'adhoc' ? Teams.getCanPerformByID(s, meta.teamID).setRetentionPolicy : true }) - const showInfoPanel = Chat.useChatContext(s => s.dispatch.showInfoPanel) + const showInfoPanel = ConvoState.useChatContext(s => s.dispatch.showInfoPanel) const onChange = () => showInfoPanel(true, 'settings') const explanation = makeRetentionNotice(policy, teamPolicy, teamType) ?? undefined diff --git a/shared/chat/conversation/messages/separator.tsx b/shared/chat/conversation/messages/separator.tsx index ba7704df6e40..cd68b589d016 100644 --- a/shared/chat/conversation/messages/separator.tsx +++ b/shared/chat/conversation/messages/separator.tsx @@ -1,5 +1,6 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as React from 'react' import * as T from '@/constants/types' @@ -13,7 +14,7 @@ const useSeparatorData = (trailingItem: T.Chat.Ordinal, leadingItem: T.Chat.Ordi const ordinal = Kb.Styles.isMobile ? leadingItem : trailingItem const orangeOrdinal = React.useContext(OrangeLineContext) - return Chat.useChatContext( + return ConvoState.useChatContext( C.useShallow(s => { const previous = s.separatorMap.get(ordinal) ?? T.Chat.numberToOrdinal(0) const m = s.messageMap.get(ordinal) ?? missingMessage diff --git a/shared/chat/conversation/messages/special-bottom-message.tsx b/shared/chat/conversation/messages/special-bottom-message.tsx index 7af99e8c7491..d422a2d40640 100644 --- a/shared/chat/conversation/messages/special-bottom-message.tsx +++ b/shared/chat/conversation/messages/special-bottom-message.tsx @@ -1,10 +1,11 @@ import * as C from '@/constants' import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import OldProfileReset from './system-old-profile-reset-notice/container' import ResetUser from './reset-user' function BottomMessageContainer() { - const {showSuperseded, showResetParticipants} = Chat.useChatContext( + const {showSuperseded, showResetParticipants} = ConvoState.useChatContext( C.useShallow(s => { const meta = s.meta const showResetParticipants = meta.resetParticipants.size !== 0 diff --git a/shared/chat/conversation/messages/special-top-message.tsx b/shared/chat/conversation/messages/special-top-message.tsx index ee208ca1c23b..265edc9c34ff 100644 --- a/shared/chat/conversation/messages/special-top-message.tsx +++ b/shared/chat/conversation/messages/special-top-message.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Kb from '@/common-adapters' import * as React from 'react' @@ -16,10 +16,9 @@ import {useCurrentUserState} from '@/stores/current-user' const ErrorMessage = () => { const createConversationError = useChatThreadRouteParams()?.createConversationError - const createConversation = Chat.useChatState(s => s.dispatch.createConversation) const _onCreateWithoutThem = (allowedUsers: ReadonlyArray) => { - createConversation(allowedUsers) + ConvoState.createConversation(allowedUsers) } const navigateToInbox = C.Router2.navigateToInbox @@ -110,7 +109,7 @@ const ErrorMessage = () => { function SpecialTopMessage() { const username = useCurrentUserState(s => s.username) - const data = Chat.useChatContext( + const data = ConvoState.useChatContext( C.useShallow(s => { const ordinals = s.messageOrdinals const hasLoadedEver = ordinals !== undefined @@ -119,9 +118,9 @@ function SpecialTopMessage() { const {teamType, supersedes, retentionPolicy, teamRetentionPolicy} = meta const loadMoreType = s.moreToLoadBack ? 'moreToLoad' : 'noMoreToLoad' const pendingState = - s.id === Chat.pendingWaitingConversationIDKey + s.id === T.Chat.pendingWaitingConversationIDKey ? 'waiting' - : s.id === Chat.pendingErrorConversationIDKey + : s.id === T.Chat.pendingErrorConversationIDKey ? 'error' : 'done' @@ -131,7 +130,7 @@ function SpecialTopMessage() { const isSelfConversation = teamType === 'adhoc' && partNum === 1 && partAll.includes(username) const showTeamOffer = hasLoadedEver && loadMoreType === 'noMoreToLoad' && teamType === 'adhoc' && partNum > 2 - const hasOlderResetConversation = supersedes !== Chat.noConversationIDKey + const hasOlderResetConversation = supersedes !== T.Chat.noConversationIDKey // don't show default header in the case of the retention notice being visible const showRetentionNotice = retentionPolicy.type !== 'retain' && diff --git a/shared/chat/conversation/messages/system-added-to-team/container.tsx b/shared/chat/conversation/messages/system-added-to-team/container.tsx index 5cf17a3d1ee9..6aa957a3ff77 100644 --- a/shared/chat/conversation/messages/system-added-to-team/container.tsx +++ b/shared/chat/conversation/messages/system-added-to-team/container.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import type * as T from '@/constants/types' import * as Kb from '@/common-adapters' @@ -13,7 +13,7 @@ type OwnProps = {message: T.Chat.MessageSystemAddedToTeam} function SystemAddedToTeamContainer(p: OwnProps) { const {message} = p const {addee, adder, author, bulkAdds, role: _role, timestamp} = message - const {teamID, teamname, teamType, showInfoPanel} = Chat.useChatContext( + const {teamID, teamname, teamType, showInfoPanel} = ConvoState.useChatContext( C.useShallow(s => ({ showInfoPanel: s.dispatch.showInfoPanel, teamID: s.meta.teamID, @@ -34,7 +34,7 @@ function SystemAddedToTeamContainer(p: OwnProps) { showInfoPanel(true, 'settings') } - const navigateAppend = Chat.useChatNavigateAppend() + const navigateAppend = ConvoState.useChatNavigateAppend() const onViewBot = () => { navigateAppend(conversationIDKey => ({ name: 'chatInstallBot', diff --git a/shared/chat/conversation/messages/system-change-retention/container.tsx b/shared/chat/conversation/messages/system-change-retention/container.tsx index ec98b2387414..ffae15f5f95f 100644 --- a/shared/chat/conversation/messages/system-change-retention/container.tsx +++ b/shared/chat/conversation/messages/system-change-retention/container.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import * as Kb from '@/common-adapters' import UserNotice from '../user-notice' @@ -13,7 +13,7 @@ function SystemChangeRetentionContainer(p: OwnProps) { const {message} = p const {isInherit, isTeam, membersType, policy, user} = message const you = useCurrentUserState(s => s.username) - const {teamType, teamname, showInfoPanel} = Chat.useChatContext( + const {teamType, teamname, showInfoPanel} = ConvoState.useChatContext( C.useShallow(s => ({ showInfoPanel: s.dispatch.showInfoPanel, teamType: s.meta.teamType, diff --git a/shared/chat/conversation/messages/system-create-team/container.tsx b/shared/chat/conversation/messages/system-create-team/container.tsx index 8fd7fb55d1f5..7307790beae1 100644 --- a/shared/chat/conversation/messages/system-create-team/container.tsx +++ b/shared/chat/conversation/messages/system-create-team/container.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import * as Kb from '@/common-adapters' import UserNotice from '../user-notice' @@ -10,7 +10,7 @@ type OwnProps = {message: T.Chat.MessageSystemCreateTeam} function SystemCreateTeamContainer(p: OwnProps) { const {creator} = p.message - const {showInfoPanel, teamID, teamname} = Chat.useChatContext( + const {showInfoPanel, teamID, teamname} = ConvoState.useChatContext( C.useShallow(s => { const {teamID, teamname} = s.meta const {showInfoPanel} = s.dispatch diff --git a/shared/chat/conversation/messages/system-invite-accepted/container.tsx b/shared/chat/conversation/messages/system-invite-accepted/container.tsx index 745f67cbbbb9..2e3de390cd50 100644 --- a/shared/chat/conversation/messages/system-invite-accepted/container.tsx +++ b/shared/chat/conversation/messages/system-invite-accepted/container.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Teams from '@/stores/teams' import type * as T from '@/constants/types' import * as Kb from '@/common-adapters' @@ -11,7 +11,7 @@ type OwnProps = {message: T.Chat.MessageSystemInviteAccepted} function SystemInviteAcceptedContainer(p: OwnProps) { const {message} = p const {role} = message - const teamID = Chat.useChatContext(s => s.meta.teamID) + const teamID = ConvoState.useChatContext(s => s.meta.teamID) const you = useCurrentUserState(s => s.username) const navigateAppend = C.Router2.navigateAppend const onViewTeam = () => { diff --git a/shared/chat/conversation/messages/system-joined/container.tsx b/shared/chat/conversation/messages/system-joined/container.tsx index 7df38429febe..dea7c8a4a4e6 100644 --- a/shared/chat/conversation/messages/system-joined/container.tsx +++ b/shared/chat/conversation/messages/system-joined/container.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' import * as Kb from '@/common-adapters' import UserNotice from '../user-notice' @@ -10,7 +10,7 @@ type OwnProps = {message: T.Chat.MessageSystemJoined} function JoinedContainer(p: OwnProps) { const {message} = p const {joiners, author, leavers, timestamp} = message - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const {channelname, teamType, teamname} = meta const joiners2 = !joiners?.length && !leavers?.length ? [author] : joiners const isBigTeam = teamType === 'big' @@ -45,13 +45,7 @@ const MultiUserJoinedNotice = (p: { return ( - + {getAddedUsernames(who)} diff --git a/shared/chat/conversation/messages/system-left/container.tsx b/shared/chat/conversation/messages/system-left/container.tsx index 16aeb257ba84..dc7572d399df 100644 --- a/shared/chat/conversation/messages/system-left/container.tsx +++ b/shared/chat/conversation/messages/system-left/container.tsx @@ -1,9 +1,9 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import UserNotice from '../user-notice' function LeftContainer() { - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const {channelname, teamType, teamname} = meta const isBigTeam = teamType === 'big' diff --git a/shared/chat/conversation/messages/system-new-channel/container.tsx b/shared/chat/conversation/messages/system-new-channel/container.tsx index 16fb0094286e..474b6f0cae31 100644 --- a/shared/chat/conversation/messages/system-new-channel/container.tsx +++ b/shared/chat/conversation/messages/system-new-channel/container.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import {useTeamsState} from '@/stores/teams' import type * as T from '@/constants/types' @@ -8,7 +8,7 @@ type OwnProps = {message: T.Chat.MessageSystemNewChannel} function SystemNewChannelContainer(p: OwnProps) { const {message} = p - const teamID = Chat.useChatContext(s => s.meta.teamID) + const teamID = ConvoState.useChatContext(s => s.meta.teamID) const manageChatChannels = useTeamsState(s => s.dispatch.manageChatChannels) const onManageChannels = () => { manageChatChannels(teamID) @@ -17,9 +17,7 @@ function SystemNewChannelContainer(p: OwnProps) { const descStyleOverride = { link: {fontSize: Kb.Styles.isMobile ? 15 : 13, fontWeight: '600'}, paragraph: { - color: Kb.Styles.isMobile - ? Kb.Styles.globalColors.black_50 - : Kb.Styles.globalColors.black_50OrWhite_40, + color: Kb.Styles.isMobile ? Kb.Styles.globalColors.black_50 : Kb.Styles.globalColors.black_50OrWhite_40, fontSize: Kb.Styles.isMobile ? 15 : 13, }, } as const diff --git a/shared/chat/conversation/messages/system-old-profile-reset-notice/container.tsx b/shared/chat/conversation/messages/system-old-profile-reset-notice/container.tsx index 6d730afe9028..c0efb62178e1 100644 --- a/shared/chat/conversation/messages/system-old-profile-reset-notice/container.tsx +++ b/shared/chat/conversation/messages/system-old-profile-reset-notice/container.tsx @@ -1,17 +1,17 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' import {previewConversation} from '@/constants/router' import {Text} from '@/common-adapters' import UserNotice from '../user-notice' const SystemOldProfileResetNotice = () => { - const participantInfo = Chat.useChatContext(s => s.participants) - const meta = Chat.useChatContext(s => s.meta) + const participantInfo = ConvoState.useChatContext(s => s.participants) + const meta = ConvoState.useChatContext(s => s.meta) const _participants = participantInfo.all const nextConversationIDKey = meta.supersededBy const username = meta.wasFinalizedBy || '' const onOpenConversation = (conversationIDKey: T.Chat.ConversationIDKey) => { - Chat.getConvoState(conversationIDKey).dispatch.navigateToThread('jumpFromReset') + ConvoState.getConvoState(conversationIDKey).dispatch.navigateToThread('jumpFromReset') } const startConversation = (participants: ReadonlyArray) => { previewConversation({participants, reason: 'fromAReset'}) diff --git a/shared/chat/conversation/messages/system-profile-reset-notice.tsx b/shared/chat/conversation/messages/system-profile-reset-notice.tsx index 9385c298cce8..31c849cc533e 100644 --- a/shared/chat/conversation/messages/system-profile-reset-notice.tsx +++ b/shared/chat/conversation/messages/system-profile-reset-notice.tsx @@ -1,14 +1,14 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as T from '@/constants/types' import * as Kb from '@/common-adapters' import UserNotice from './user-notice' const SystemProfileResetNotice = () => { - const meta = Chat.useChatContext(s => s.meta) + const meta = ConvoState.useChatContext(s => s.meta) const prevConversationIDKey = meta.supersedes const username = meta.wasFinalizedBy || '' const _onOpenOlderConversation = (conversationIDKey: T.Chat.ConversationIDKey) => { - Chat.getConvoState(conversationIDKey).dispatch.navigateToThread('jumpToReset') + ConvoState.getConvoState(conversationIDKey).dispatch.navigateToThread('jumpToReset') } const onOpenOlderConversation = () => { prevConversationIDKey && _onOpenOlderConversation(prevConversationIDKey) diff --git a/shared/chat/conversation/messages/system-simple-to-complex/container.tsx b/shared/chat/conversation/messages/system-simple-to-complex/container.tsx index 86c668a4b7ec..5acdf92ae8bd 100644 --- a/shared/chat/conversation/messages/system-simple-to-complex/container.tsx +++ b/shared/chat/conversation/messages/system-simple-to-complex/container.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import {useTeamsState} from '@/stores/teams' import type * as T from '@/constants/types' import * as Kb from '@/common-adapters' @@ -9,7 +9,7 @@ type OwnProps = {message: T.Chat.MessageSystemSimpleToComplex} function SystemSimpleToComplexContainer(p: OwnProps) { const {message} = p - const teamID = Chat.useChatContext(s => s.meta.teamID) + const teamID = ConvoState.useChatContext(s => s.meta.teamID) const you = useCurrentUserState(s => s.username) const manageChatChannels = useTeamsState(s => s.dispatch.manageChatChannels) const onManageChannels = () => { diff --git a/shared/chat/conversation/messages/system-users-added-to-conv/container.tsx b/shared/chat/conversation/messages/system-users-added-to-conv/container.tsx index aae824d05673..957401ac1a34 100644 --- a/shared/chat/conversation/messages/system-users-added-to-conv/container.tsx +++ b/shared/chat/conversation/messages/system-users-added-to-conv/container.tsx @@ -1,4 +1,4 @@ -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import type * as React from 'react' import type * as T from '@/constants/types' import * as Kb from '@/common-adapters' @@ -9,7 +9,7 @@ type OwnProps = {message: T.Chat.MessageSystemUsersAddedToConversation} function UsersAddedToConversationContainer(p: OwnProps) { const {usernames} = p.message - const channelname = Chat.useChatContext(s => s.meta.channelname) + const channelname = ConvoState.useChatContext(s => s.meta.channelname) const you = useCurrentUserState(s => s.username) let otherUsers: Array | undefined if (usernames.includes(you)) { diff --git a/shared/chat/conversation/messages/text/coinflip/index.tsx b/shared/chat/conversation/messages/text/coinflip/index.tsx index 29036345f59a..7d4b27abef8a 100644 --- a/shared/chat/conversation/messages/text/coinflip/index.tsx +++ b/shared/chat/conversation/messages/text/coinflip/index.tsx @@ -1,5 +1,5 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as Kb from '@/common-adapters' import * as T from '@/constants/types' import CoinFlipError from './errors' @@ -10,7 +10,7 @@ import {pluralize} from '@/util/string' function CoinFlipContainer() { const ordinal = useOrdinal() - const {isSendError, text, flipGameID, sendMessage} = Chat.useChatContext( + const {isSendError, text, flipGameID, sendMessage} = ConvoState.useChatContext( C.useShallow(s => { const message = s.messageMap.get(ordinal) const isSendError = message?.type === 'text' ? !!message.errorReason : false @@ -20,7 +20,7 @@ function CoinFlipContainer() { return {flipGameID, isSendError, message, sendMessage, text} }) ) - const status = Chat.useChatContext(s => s.flipStatusMap.get(flipGameID)) + const status = ConvoState.useChatContext(s => s.flipStatusMap.get(flipGameID)) const onFlipAgain = () => { text && sendMessage(text.stringValue()) } diff --git a/shared/chat/conversation/messages/text/reply.tsx b/shared/chat/conversation/messages/text/reply.tsx index eab74216309b..350a5f27b13d 100644 --- a/shared/chat/conversation/messages/text/reply.tsx +++ b/shared/chat/conversation/messages/text/reply.tsx @@ -1,6 +1,6 @@ import * as Kb from '@/common-adapters' import * as React from 'react' -import * as Chat from '@/stores/chat' +import {zoomImage} from '@/constants/chat/helpers' import {useIsHighlighted} from '../ids-context' import type * as T from '@/constants/types' @@ -38,7 +38,7 @@ const ReplyImage = () => { if (!imageURL) return null const imageHeight = replyTo.previewHeight const imageWidth = replyTo.previewWidth - const sizing = imageWidth && imageHeight ? Chat.zoomImage(imageWidth, imageHeight, 80) : undefined + const sizing = imageWidth && imageHeight ? zoomImage(imageWidth, imageHeight, 80) : undefined return ( diff --git a/shared/chat/conversation/messages/text/unfurl/prompt-list/container.tsx b/shared/chat/conversation/messages/text/unfurl/prompt-list/container.tsx index 8f52867ca53e..46af9599e79c 100644 --- a/shared/chat/conversation/messages/text/unfurl/prompt-list/container.tsx +++ b/shared/chat/conversation/messages/text/unfurl/prompt-list/container.tsx @@ -1,11 +1,11 @@ import * as C from '@/constants' -import * as Chat from '@/stores/chat' +import * as ConvoState from '@/stores/convostate' import * as T from '@/constants/types' import * as Kb from '@/common-adapters' import Prompt from './prompt' function UnfurlPromptListContainer({messageID}: {messageID: T.Chat.MessageID}) { - const {unfurlResolvePrompt, promptDomains} = Chat.useChatContext( + const {unfurlResolvePrompt, promptDomains} = ConvoState.useChatContext( C.useShallow(s => { const unfurlResolvePrompt = s.dispatch.unfurlResolvePrompt const promptDomains = s.unfurlPrompt.get(messageID) diff --git a/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/index.tsx b/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/index.tsx index fff9f4e7ccae..89a5573a6b2d 100644 --- a/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/index.tsx +++ b/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/index.tsx @@ -1,6 +1,6 @@ import type * as React from 'react' import * as Kb from '@/common-adapters/index' -import * as Chat from '@/stores/chat' +import {clampImageSize} from '@/constants/chat/helpers' import {maxWidth} from '@/chat/conversation/messages/attachment/shared' import {Video} from './video' import {openURL} from '@/util/misc' @@ -24,7 +24,7 @@ const UnfurlImage = (p: Props) => { linkURL && openURL(linkURL) } const maxSize = Math.min(maxWidth, 320) - (widthPadding || 0) - const {height, width} = Chat.clampImageSize(p.width, p.height, maxSize, 320) + const {height, width} = clampImageSize(p.width, p.height, maxSize, 320) return isVideo ? (