forked from Ivasoft/mattermost-mobile
fix reconnect state; correct new channel state (#6574)
This commit is contained in:
committed by
GitHub
parent
da4b7184df
commit
6e3b2c2bd9
@@ -15,6 +15,7 @@ import {fetchMissingDirectChannelsInfo, fetchMyChannel, fetchChannelStats, fetch
|
||||
import {fetchPostsForChannel} from '@actions/remote/post';
|
||||
import {fetchRolesIfNeeded} from '@actions/remote/role';
|
||||
import {fetchUsersByIds, updateUsersNoLongerVisible} from '@actions/remote/user';
|
||||
import {loadCallForChannel} from '@calls/actions/calls';
|
||||
import {Events, Screens} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {queryActiveServer} from '@queries/app/servers';
|
||||
@@ -293,6 +294,8 @@ export async function handleUserAddedToChannelEvent(serverUrl: string, msg: any)
|
||||
models.push(...prepared);
|
||||
}
|
||||
}
|
||||
|
||||
loadCallForChannel(serverUrl, channelId);
|
||||
} else {
|
||||
const addedUser = getUserById(database, userId);
|
||||
if (!addedUser) {
|
||||
|
||||
@@ -11,7 +11,8 @@ import {fetchStatusByIds} from '@actions/remote/user';
|
||||
import {loadConfigAndCalls} from '@calls/actions/calls';
|
||||
import {
|
||||
handleCallChannelDisabled,
|
||||
handleCallChannelEnabled, handleCallEnded,
|
||||
handleCallChannelEnabled,
|
||||
handleCallEnded,
|
||||
handleCallScreenOff,
|
||||
handleCallScreenOn,
|
||||
handleCallStarted,
|
||||
@@ -175,10 +176,6 @@ async function doReconnectRest(serverUrl: string, operator: ServerDataOperator,
|
||||
const {locale: currentUserLocale} = (await getCurrentUser(database))!;
|
||||
await deferredAppEntryActions(serverUrl, lastDisconnectedAt, currentUserId, currentUserLocale, prefData.preferences, config, license, teamData, chData, initialTeamId, switchedToChannel ? initialChannelId : undefined);
|
||||
|
||||
if (isSupportedServerCalls(config?.Version)) {
|
||||
loadConfigAndCalls(serverUrl, currentUserId);
|
||||
}
|
||||
|
||||
// https://mattermost.atlassian.net/browse/MM-41520
|
||||
}
|
||||
|
||||
@@ -207,6 +204,11 @@ async function doReconnect(serverUrl: string) {
|
||||
} else {
|
||||
await doReconnectRest(serverUrl, operator, system.currentTeamId, system.currentUserId, config, license, lastDisconnectedAt);
|
||||
}
|
||||
|
||||
// Calls is not set up for GraphQL yet
|
||||
if (isSupportedServerCalls(config?.Version)) {
|
||||
loadConfigAndCalls(serverUrl, system.currentUserId);
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleEvent(serverUrl: string, msg: WebSocketMessage) {
|
||||
|
||||
@@ -6,7 +6,8 @@ import InCallManager from 'react-native-incall-manager';
|
||||
import {forceLogoutIfNecessary} from '@actions/remote/session';
|
||||
import {fetchUsersByIds} from '@actions/remote/user';
|
||||
import {
|
||||
getCallsConfig, getCallsState,
|
||||
getCallsConfig,
|
||||
getCallsState,
|
||||
myselfLeftCall,
|
||||
setCalls,
|
||||
setChannelEnabled,
|
||||
@@ -14,6 +15,7 @@ import {
|
||||
setPluginEnabled,
|
||||
setScreenShareURL,
|
||||
setSpeakerPhone,
|
||||
setCallForChannel,
|
||||
} from '@calls/state';
|
||||
import {General, Preferences} from '@constants';
|
||||
import Calls from '@constants/calls';
|
||||
@@ -33,6 +35,7 @@ import type {
|
||||
Call,
|
||||
CallParticipant,
|
||||
CallsConnection,
|
||||
ServerCallState,
|
||||
ServerChannelState,
|
||||
} from '@calls/types/calls';
|
||||
import type {Client} from '@client/rest';
|
||||
@@ -94,24 +97,7 @@ export const loadCalls = async (serverUrl: string, userId: string) => {
|
||||
|
||||
for (const channel of resp) {
|
||||
if (channel.call) {
|
||||
const call = channel.call;
|
||||
callsResults[channel.channel_id] = {
|
||||
participants: channel.call.users.reduce((accum, cur, curIdx) => {
|
||||
// Add the id to the set of UserModels we want to ensure are loaded.
|
||||
ids.add(cur);
|
||||
|
||||
// Create the CallParticipant
|
||||
const muted = call.states && call.states[curIdx] ? !call.states[curIdx].unmuted : true;
|
||||
const raisedHand = call.states && call.states[curIdx] ? call.states[curIdx].raised_hand : 0;
|
||||
accum[cur] = {id: cur, muted, raisedHand};
|
||||
return accum;
|
||||
}, {} as Dictionary<CallParticipant>),
|
||||
channelId: channel.channel_id,
|
||||
startTime: call.start_at,
|
||||
screenOn: call.screen_sharing_id,
|
||||
threadId: call.thread_id,
|
||||
ownerId: call.owner_id,
|
||||
};
|
||||
callsResults[channel.channel_id] = createCallAndAddToIds(channel.channel_id, channel.call, ids);
|
||||
}
|
||||
enabledChannels[channel.channel_id] = channel.enabled;
|
||||
}
|
||||
@@ -126,6 +112,58 @@ export const loadCalls = async (serverUrl: string, userId: string) => {
|
||||
return {data: {calls: callsResults, enabled: enabledChannels}};
|
||||
};
|
||||
|
||||
export const loadCallForChannel = async (serverUrl: string, channelId: string) => {
|
||||
let client: Client;
|
||||
try {
|
||||
client = NetworkManager.getClient(serverUrl);
|
||||
} catch (error) {
|
||||
return {error};
|
||||
}
|
||||
|
||||
let resp: ServerChannelState;
|
||||
try {
|
||||
resp = await client.getCallForChannel(channelId);
|
||||
} catch (error) {
|
||||
await forceLogoutIfNecessary(serverUrl, error as ClientError);
|
||||
return {error};
|
||||
}
|
||||
|
||||
let call: Call | undefined;
|
||||
const ids = new Set<string>();
|
||||
if (resp.call) {
|
||||
call = createCallAndAddToIds(channelId, resp.call, ids);
|
||||
}
|
||||
|
||||
// Batch load user models async because we'll need them later
|
||||
if (ids.size > 0) {
|
||||
fetchUsersByIds(serverUrl, Array.from(ids));
|
||||
}
|
||||
|
||||
setCallForChannel(serverUrl, channelId, resp.enabled, call);
|
||||
|
||||
return {data: {call, enabled: resp.enabled}};
|
||||
};
|
||||
|
||||
const createCallAndAddToIds = (channelId: string, call: ServerCallState, ids: Set<string>) => {
|
||||
return {
|
||||
participants: call.users.reduce((accum, cur, curIdx) => {
|
||||
// Add the id to the set of UserModels we want to ensure are loaded.
|
||||
ids.add(cur);
|
||||
|
||||
// Create the CallParticipant
|
||||
const muted = call.states && call.states[curIdx] ? !call.states[curIdx].unmuted : true;
|
||||
const raisedHand = call.states && call.states[curIdx] ? call.states[curIdx].raised_hand : 0;
|
||||
accum[cur] = {id: cur, muted, raisedHand};
|
||||
return accum;
|
||||
}, {} as Dictionary<CallParticipant>),
|
||||
channelId,
|
||||
startTime: call.start_at,
|
||||
screenOn: call.screen_sharing_id,
|
||||
threadId: call.thread_id,
|
||||
ownerId: call.owner_id,
|
||||
} as Call;
|
||||
};
|
||||
|
||||
export const loadConfigAndCalls = async (serverUrl: string, userId: string) => {
|
||||
const res = await checkIsCallsPluginEnabled(serverUrl);
|
||||
if (res.data) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {ServerChannelState, ServerCallsConfig, ApiResp, ICEServersConfigs}
|
||||
export interface ClientCallsMix {
|
||||
getEnabled: () => Promise<Boolean>;
|
||||
getCalls: () => Promise<ServerChannelState[]>;
|
||||
getCallForChannel: (channelId: string) => Promise<ServerChannelState>;
|
||||
getCallsConfig: () => Promise<ServerCallsConfig>;
|
||||
enableChannelCalls: (channelId: string, enable: boolean) => Promise<ServerChannelState>;
|
||||
endCall: (channelId: string) => Promise<ApiResp>;
|
||||
@@ -32,6 +33,13 @@ const ClientCalls = (superclass: any) => class extends superclass {
|
||||
);
|
||||
};
|
||||
|
||||
getCallForChannel = async (channelId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getCallsRoute()}/${channelId}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getCallsConfig = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getCallsRoute()}/config`,
|
||||
|
||||
@@ -24,6 +24,40 @@ export const setCalls = (serverUrl: string, myUserId: string, calls: Dictionary<
|
||||
setCallsState(serverUrl, {serverUrl, myUserId, calls, enabled});
|
||||
};
|
||||
|
||||
export const setCallForChannel = (serverUrl: string, channelId: string, enabled: boolean, call?: Call) => {
|
||||
const callsState = getCallsState(serverUrl);
|
||||
const nextEnabled = {...callsState.enabled, [channelId]: enabled};
|
||||
|
||||
const nextCalls = {...callsState.calls};
|
||||
if (call) {
|
||||
nextCalls[channelId] = call;
|
||||
|
||||
// In case we got a complete update on the currentCall
|
||||
const currentCall = getCurrentCall();
|
||||
if (currentCall?.channelId === channelId) {
|
||||
setCurrentCall({
|
||||
...currentCall,
|
||||
...call,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
delete nextCalls[channelId];
|
||||
}
|
||||
|
||||
setCallsState(serverUrl, {...callsState, calls: nextCalls, enabled: nextEnabled});
|
||||
|
||||
const channelsWithCalls = getChannelsWithCalls(serverUrl);
|
||||
if (call && !channelsWithCalls[channelId]) {
|
||||
const nextChannelsWithCalls = {...channelsWithCalls};
|
||||
nextChannelsWithCalls[channelId] = true;
|
||||
setChannelsWithCalls(serverUrl, nextChannelsWithCalls);
|
||||
} else if (!call && channelsWithCalls[channelId]) {
|
||||
const nextChannelsWithCalls = {...channelsWithCalls};
|
||||
delete nextChannelsWithCalls[channelId];
|
||||
setChannelsWithCalls(serverUrl, nextChannelsWithCalls);
|
||||
}
|
||||
};
|
||||
|
||||
export const userJoinedCall = (serverUrl: string, channelId: string, userId: string) => {
|
||||
const callsState = getCallsState(serverUrl);
|
||||
if (!callsState.calls[channelId]) {
|
||||
@@ -46,11 +80,11 @@ export const userJoinedCall = (serverUrl: string, channelId: string, userId: str
|
||||
// Did the user join the current call? If so, update that too.
|
||||
const currentCall = getCurrentCall();
|
||||
if (currentCall && currentCall.channelId === channelId) {
|
||||
const nextCall2 = {
|
||||
const nextCurrentCall = {
|
||||
...currentCall,
|
||||
participants: {...currentCall.participants, [userId]: nextCall.participants[userId]},
|
||||
};
|
||||
setCurrentCall(nextCall2);
|
||||
setCurrentCall(nextCurrentCall);
|
||||
}
|
||||
|
||||
// Was it me that joined the call?
|
||||
@@ -97,12 +131,12 @@ export const userLeftCall = (serverUrl: string, channelId: string, userId: strin
|
||||
return;
|
||||
}
|
||||
|
||||
const nextCall2 = {
|
||||
const nextCurrentCall = {
|
||||
...currentCall,
|
||||
participants: {...currentCall.participants},
|
||||
};
|
||||
delete nextCall2.participants[userId];
|
||||
setCurrentCall(nextCall2);
|
||||
delete nextCurrentCall.participants[userId];
|
||||
setCurrentCall(nextCurrentCall);
|
||||
};
|
||||
|
||||
export const myselfLeftCall = () => {
|
||||
|
||||
Reference in New Issue
Block a user