Skip to content

Commit

Permalink
Merge pull request #3065 from tloncorp/lb/remove-multidm-neg-check
Browse files Browse the repository at this point in the history
dms: fix new multidm negotiation blocking
  • Loading branch information
arthyn authored Dec 2, 2023
2 parents 9a221ab + 76d646c commit 3575af7
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 21 deletions.
3 changes: 3 additions & 0 deletions desk/app/chat.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,9 @@
|= [=mark =vase]
|^ ^+ cor
?+ mark ~|(bad-poke/mark !!)
%chat-negotiate
::TODO arguably should just be a /mar/negotiate
(emit (initiate:neg !<(@p vase) dap.bowl))
::
%chat-dm-rsvp
=+ !<(=rsvp:dm:c vase)
Expand Down
12 changes: 12 additions & 0 deletions desk/mar/chat/negotiate.hoon
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
|_ who=@p
++ grad %ship
++ grow
|%
++ noun who
--
++ grab
|%
++ noun @p
++ json (su:dejs:format ;~(pfix sig fed:ag))
--
--
20 changes: 14 additions & 6 deletions ui/src/dms/NewDm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef } from 'react';
import React, { useMemo, useRef } from 'react';
import cn from 'classnames';
import ChatInput from '@/chat/ChatInput/ChatInput';
import Layout from '@/components/Layout/Layout';
Expand All @@ -9,6 +9,7 @@ import { useIsScrolling } from '@/logic/scroll';
import { useIsMobile } from '@/logic/useMedia';
import { useChatInputFocus } from '@/logic/ChatInputFocusContext';
import { dmListPath } from '@/logic/utils';
import LoadingSpinner from '@/components/LoadingSpinner/LoadingSpinner';
import MessageSelector from './MessageSelector';

export default function NewDM() {
Expand All @@ -17,8 +18,9 @@ export default function NewDM() {
validShips,
whom,
isMultiDm,
confirmedMultiDmMismatch,
existingMultiDm,
multiDmVersionMismatch,
haveAllNegotiations,
} = useMessageSelector();
const dropZoneId = 'chat-new-dm-input-dropzone';
const { isDragging, isOver } = useDragAndDrop(dropZoneId);
Expand All @@ -28,7 +30,7 @@ export default function NewDM() {
const { isChatInputFocused } = useChatInputFocus();
const shouldApplyPaddingBottom = isMobile && !isChatInputFocused;
const shouldBlockInput =
isMultiDm && !existingMultiDm && confirmedMultiDmMismatch;
isMultiDm && !existingMultiDm && multiDmVersionMismatch;

return (
<Layout
Expand All @@ -41,9 +43,15 @@ export default function NewDM() {
}
footer={
shouldBlockInput ? (
<div className="rounded-lg border-2 border-transparent bg-gray-50 py-1 px-2 leading-5 text-gray-600">
Your version of the app does not match some of the members of this
chat.
<div className="flex items-center justify-center border-2 border-transparent bg-gray-50 py-1 px-2 leading-5 text-gray-600">
{haveAllNegotiations ? (
'Your version of the app does not match some of the members of this chat.'
) : (
<>
<LoadingSpinner />
<span className="ml-2">Checking version compatibility</span>
</>
)}
</div>
) : (
<div
Expand Down
27 changes: 18 additions & 9 deletions ui/src/logic/useMessageSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import {
useMultiDms,
useSendMessage,
} from '@/state/chat';
import { useNegotiateMulti } from '@/state/negotiation';
import {
useForceNegotiationUpdate,
useNegotiateMulti,
} from '@/state/negotiation';
import { createStorageKey, newUv } from './utils';

export default function useMessageSelector() {
Expand All @@ -28,13 +31,18 @@ export default function useMessageSelector() {
const { data: unreads } = useDmUnreads();
const { mutate: sendMessage } = useSendMessage();
const { mutateAsync: createMultiDm } = useCreateMultiDm();
const { match: negotiationMatch, isLoading: negotiationLoading } =
useNegotiateMulti(
ships.map((option) => option.value),
'chat',
'chat'
);
const confirmedMultiDmMismatch = !negotiationLoading && !negotiationMatch;

useForceNegotiationUpdate(shipValues, 'chat');
const {
match: negotiationMatch,
isLoading: negotiationLoading,
haveAllNegotiations,
} = useNegotiateMulti(
ships.map((option) => option.value),
'chat',
'chat'
);
const multiDmVersionMismatch = !negotiationLoading && !negotiationMatch;

const existingDm = useMemo(() => {
if (ships.length !== 1) {
Expand Down Expand Up @@ -169,7 +177,8 @@ export default function useMessageSelector() {

return {
isMultiDm,
confirmedMultiDmMismatch,
multiDmVersionMismatch,
haveAllNegotiations,
action,
existingDm,
existingMultiDm,
Expand Down
53 changes: 47 additions & 6 deletions ui/src/state/negotiation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { debounce } from 'lodash';
import api from '@/api';
Expand Down Expand Up @@ -99,13 +99,54 @@ export function useNegotiateMulti(ships: string[], app: string, agent: string) {
const { data, ...rest } = useNegotiation(app, agent);

if (rest.isLoading || rest.isError || data === undefined) {
return { ...rest, match: false };
return { ...rest, match: false, haveAllNegotiations: false };
}

const allShipsMatch = ships
const shipKeys = ships
.filter((ship) => ship !== window.our)
.map((ship) => `${ship}/${agent}`)
.every((ship) => ship in data && data[ship] === 'match');
.map((ship) => `${ship}/${agent}`);

return { ...rest, match: allShipsMatch };
const allShipsMatch = shipKeys.every(
(ship) => ship in data && data[ship] === 'match'
);

const haveAllNegotiations = shipKeys.every((ship) => ship in data);

return { ...rest, match: allShipsMatch, haveAllNegotiations };
}

export function useForceNegotiationUpdate(ships: string[], app: string) {
const { data } = useNegotiation(app, app);
const unknownShips = useMemo(
() =>
ships.filter(
(ship) =>
!data ||
!(`${ship}/${app}` in data) ||
data[`${ship}/${app}`] !== 'match'
),
[ships, app, data]
);
const negotiateUnknownShips = useCallback(
async (shipsToCheck: string[]) => {
const responses: Promise<number>[] = [];
shipsToCheck.forEach((ship) => {
responses.push(
api.poke({
app,
mark: 'chat-negotiate',
json: ship,
})
);
});
await Promise.all(responses);
},
[app]
);

useEffect(() => {
if (unknownShips.length > 0) {
negotiateUnknownShips(unknownShips);
}
}, [unknownShips, negotiateUnknownShips]);
}

0 comments on commit 3575af7

Please sign in to comment.