Fix call link delete to require inactive call
This commit is contained in:
parent
902c1f4634
commit
3f8b8bdb2d
5 changed files with 98 additions and 37 deletions
|
@ -24,6 +24,7 @@ export default {
|
|||
callHistoryGroup: getFakeCallLinkHistoryGroup(),
|
||||
callLink: FAKE_CALL_LINK_WITH_ADMIN_KEY,
|
||||
isAnybodyInCall: false,
|
||||
isCallActiveOnServer: false,
|
||||
isInCall: false,
|
||||
isInAnotherCall: false,
|
||||
onDeleteCallLink: action('onDeleteCallLink'),
|
||||
|
@ -39,11 +40,19 @@ export function Admin(args: CallLinkDetailsProps): JSX.Element {
|
|||
}
|
||||
|
||||
export function AdminAndCallActive(args: CallLinkDetailsProps): JSX.Element {
|
||||
return <CallLinkDetails {...args} isAnybodyInCall />;
|
||||
return <CallLinkDetails {...args} isAnybodyInCall isCallActiveOnServer />;
|
||||
}
|
||||
|
||||
export function AdminAndInCall(args: CallLinkDetailsProps): JSX.Element {
|
||||
return <CallLinkDetails {...args} isAnybodyInCall isInCall />;
|
||||
return (
|
||||
<CallLinkDetails {...args} isAnybodyInCall isCallActiveOnServer isInCall />
|
||||
);
|
||||
}
|
||||
|
||||
export function AdminRecentlyEndedCall(
|
||||
args: CallLinkDetailsProps
|
||||
): JSX.Element {
|
||||
return <CallLinkDetails {...args} isCallActiveOnServer />;
|
||||
}
|
||||
|
||||
export function NonAdmin(args: CallLinkDetailsProps): JSX.Element {
|
||||
|
@ -52,13 +61,23 @@ export function NonAdmin(args: CallLinkDetailsProps): JSX.Element {
|
|||
|
||||
export function NonAdminAndCallActive(args: CallLinkDetailsProps): JSX.Element {
|
||||
return (
|
||||
<CallLinkDetails {...args} callLink={FAKE_CALL_LINK} isAnybodyInCall />
|
||||
<CallLinkDetails
|
||||
{...args}
|
||||
callLink={FAKE_CALL_LINK}
|
||||
isAnybodyInCall
|
||||
isCallActiveOnServer
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function InAnotherCall(args: CallLinkDetailsProps): JSX.Element {
|
||||
return (
|
||||
<CallLinkDetails {...args} callLink={FAKE_CALL_LINK} isInAnotherCall />
|
||||
<CallLinkDetails
|
||||
{...args}
|
||||
callLink={FAKE_CALL_LINK}
|
||||
isInAnotherCall
|
||||
isCallActiveOnServer
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -70,6 +89,7 @@ export function InAnotherCallAndCallActive(
|
|||
{...args}
|
||||
callLink={FAKE_CALL_LINK}
|
||||
isAnybodyInCall
|
||||
isCallActiveOnServer
|
||||
isInAnotherCall
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -33,6 +33,7 @@ export type CallLinkDetailsProps = Readonly<{
|
|||
callHistoryGroup: CallHistoryGroup;
|
||||
callLink: CallLinkType | undefined;
|
||||
isAnybodyInCall: boolean;
|
||||
isCallActiveOnServer: boolean;
|
||||
isInCall: boolean;
|
||||
isInAnotherCall: boolean;
|
||||
i18n: LocalizerType;
|
||||
|
@ -48,6 +49,7 @@ export function CallLinkDetails({
|
|||
callLink,
|
||||
i18n,
|
||||
isAnybodyInCall,
|
||||
isCallActiveOnServer,
|
||||
isInCall,
|
||||
isInAnotherCall,
|
||||
onDeleteCallLink,
|
||||
|
@ -88,7 +90,7 @@ export function CallLinkDetails({
|
|||
);
|
||||
const callLinkRestrictionsSelect = (
|
||||
<CallLinkRestrictionsSelect
|
||||
disabled={isAnybodyInCall}
|
||||
disabled={isCallActiveOnServer}
|
||||
i18n={i18n}
|
||||
value={callLink.restrictions}
|
||||
onChange={onUpdateCallLinkRestrictions}
|
||||
|
@ -159,7 +161,7 @@ export function CallLinkDetails({
|
|||
}
|
||||
label={i18n('icu:CallLinkDetails__ApproveAllMembersLabel')}
|
||||
right={
|
||||
isAnybodyInCall ? (
|
||||
isCallActiveOnServer ? (
|
||||
<Tooltip
|
||||
className="CallLinkDetails__ApproveAllMembersDisabledTooltip"
|
||||
content={i18n(
|
||||
|
@ -207,9 +209,9 @@ export function CallLinkDetails({
|
|||
className={classNames({
|
||||
CallLinkDetails__DeleteLink: true,
|
||||
'CallLinkDetails__DeleteLink--disabled-for-active-call':
|
||||
isAnybodyInCall,
|
||||
isCallActiveOnServer,
|
||||
})}
|
||||
disabled={isAnybodyInCall}
|
||||
disabled={isCallActiveOnServer}
|
||||
icon={
|
||||
<ConversationDetailsIcon
|
||||
ariaLabel={i18n('icu:CallLinkDetails__DeleteLink')}
|
||||
|
@ -217,7 +219,7 @@ export function CallLinkDetails({
|
|||
/>
|
||||
}
|
||||
label={
|
||||
isAnybodyInCall ? (
|
||||
isCallActiveOnServer ? (
|
||||
<Tooltip
|
||||
className="CallLinkDetails__DeleteLinkTooltip"
|
||||
content={i18n(
|
||||
|
|
|
@ -311,32 +311,49 @@ export function CallsList({
|
|||
|
||||
const { mode, peerId } = callHistoryGroup;
|
||||
const call = getCallByPeerId({ mode, peerId });
|
||||
if (!call) {
|
||||
if (!call || !isGroupOrAdhocCallState(call)) {
|
||||
// We can't tell from CallHistory alone whether a 1:1 call is active
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isGroupOrAdhocCallState(call)) {
|
||||
if (!isAnybodyInGroupCall(call.peekInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode === CallMode.Group) {
|
||||
const eraId = call.peekInfo?.eraId;
|
||||
if (!eraId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const callId = getCallIdFromEra(eraId);
|
||||
return callHistoryGroup.children.some(
|
||||
groupItem => groupItem.callId === callId
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
// eraId indicates a group/call link call is active.
|
||||
const eraId = call.peekInfo?.eraId;
|
||||
if (!eraId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We can't tell from CallHistory alone whether a 1:1 call is active
|
||||
return false;
|
||||
// Group calls have multiple entries sharing a peerId. To distinguish them we need
|
||||
// to compare the active callId (derived from eraId) with this item's callId set.
|
||||
if (mode === CallMode.Group) {
|
||||
const callId = getCallIdFromEra(eraId);
|
||||
return callHistoryGroup.children.some(
|
||||
groupItem => groupItem.callId === callId
|
||||
);
|
||||
}
|
||||
|
||||
// Call links only show once in the calls list, so we can just return active.
|
||||
return true;
|
||||
},
|
||||
[getCallByPeerId]
|
||||
);
|
||||
|
||||
const getIsAnybodyInCall = useCallback(
|
||||
({
|
||||
callHistoryGroup,
|
||||
}: {
|
||||
callHistoryGroup: CallHistoryGroup | null;
|
||||
}): boolean => {
|
||||
if (!callHistoryGroup) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { mode, peerId } = callHistoryGroup;
|
||||
const call = getCallByPeerId({ mode, peerId });
|
||||
if (!call || !isGroupOrAdhocCallState(call)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isAnybodyInGroupCall(call.peekInfo);
|
||||
},
|
||||
[getCallByPeerId]
|
||||
);
|
||||
|
@ -370,7 +387,7 @@ export function CallsList({
|
|||
);
|
||||
}
|
||||
|
||||
// For group and adhoc calls, a call has to have members in it (see getIsCallActive)
|
||||
// For group and adhoc calls
|
||||
return Boolean(
|
||||
isActive &&
|
||||
conversation &&
|
||||
|
@ -433,8 +450,9 @@ export function CallsList({
|
|||
for (const item of callItems) {
|
||||
const { mode } = item;
|
||||
if (isGroupOrAdhocCallMode(mode)) {
|
||||
const isActive = getIsCallActive({ callHistoryGroup: item });
|
||||
|
||||
const isActive = getIsCallActive({
|
||||
callHistoryGroup: item,
|
||||
});
|
||||
if (isActive) {
|
||||
// Don't peek if you're already in the call.
|
||||
const activeCallConversationId = activeCall?.conversationId;
|
||||
|
@ -711,6 +729,13 @@ export function CallsList({
|
|||
const isActive = getIsCallActive({
|
||||
callHistoryGroup: item,
|
||||
});
|
||||
// After everyone leaves a call, it remains active on the server for a little bit.
|
||||
// We don't need to show the active call join button in this case.
|
||||
const isAnybodyInCall =
|
||||
isActive &&
|
||||
getIsAnybodyInCall({
|
||||
callHistoryGroup: item,
|
||||
});
|
||||
const isInCall = getIsInCall({
|
||||
activeCallConversationId,
|
||||
callHistoryGroup: item,
|
||||
|
@ -722,7 +747,9 @@ export function CallsList({
|
|||
const isCallButtonVisible = Boolean(
|
||||
!isAdhoc || (isAdhoc && getCallLink(item.peerId))
|
||||
);
|
||||
const isActiveVisible = Boolean(isCallButtonVisible && item && isActive);
|
||||
const isActiveVisible = Boolean(
|
||||
isCallButtonVisible && item && isAnybodyInCall
|
||||
);
|
||||
|
||||
if (searchPending || item == null || conversation == null) {
|
||||
return (
|
||||
|
@ -887,6 +914,7 @@ export function CallsList({
|
|||
searchPending,
|
||||
getCallLink,
|
||||
getConversationForItem,
|
||||
getIsAnybodyInCall,
|
||||
getIsCallActive,
|
||||
getIsInCall,
|
||||
selectedCallHistoryGroup,
|
||||
|
|
|
@ -54,3 +54,9 @@ export const isAnybodyInGroupCall = (
|
|||
}
|
||||
return peekInfo.acis.length > 0;
|
||||
};
|
||||
|
||||
export const isGroupCallActiveOnServer = (
|
||||
peekInfo: undefined | Readonly<Pick<GroupCallPeekInfoType, 'eraId'>>
|
||||
): boolean => {
|
||||
return Boolean(peekInfo?.eraId);
|
||||
};
|
||||
|
|
|
@ -14,7 +14,10 @@ import { useGlobalModalActions } from '../ducks/globalModals';
|
|||
import { useCallingActions } from '../ducks/calling';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
import type { CallLinkRestrictions } from '../../types/CallLink';
|
||||
import { isAnybodyInGroupCall } from '../ducks/callingHelpers';
|
||||
import {
|
||||
isAnybodyInGroupCall,
|
||||
isGroupCallActiveOnServer,
|
||||
} from '../ducks/callingHelpers';
|
||||
|
||||
export type SmartCallLinkDetailsProps = Readonly<{
|
||||
roomId: string;
|
||||
|
@ -66,7 +69,8 @@ export const SmartCallLinkDetails = memo(function SmartCallLinkDetails({
|
|||
|
||||
const adhocCallSelector = useSelector(getAdhocCallSelector);
|
||||
const adhocCall = adhocCallSelector(roomId);
|
||||
const hasActiveCall = isAnybodyInGroupCall(adhocCall?.peekInfo);
|
||||
const isAnybodyInCall = isAnybodyInGroupCall(adhocCall?.peekInfo);
|
||||
const isCallActiveOnServer = isGroupCallActiveOnServer(adhocCall?.peekInfo);
|
||||
|
||||
const activeCall = useSelector(getActiveCallState);
|
||||
const isInAnotherCall = Boolean(
|
||||
|
@ -80,7 +84,8 @@ export const SmartCallLinkDetails = memo(function SmartCallLinkDetails({
|
|||
<CallLinkDetails
|
||||
callHistoryGroup={callHistoryGroup}
|
||||
callLink={callLink}
|
||||
isAnybodyInCall={hasActiveCall}
|
||||
isAnybodyInCall={isAnybodyInCall}
|
||||
isCallActiveOnServer={isCallActiveOnServer}
|
||||
isInCall={isInCall}
|
||||
isInAnotherCall={isInAnotherCall}
|
||||
i18n={i18n}
|
||||
|
|
Loading…
Reference in a new issue