Added onReconnect handling for converted GM

This commit is contained in:
harshil Sharma 2023-11-23 10:40:49 +05:30
parent 55004c9773
commit 58fc869d70
3 changed files with 59 additions and 14 deletions

View file

@ -19,7 +19,7 @@ import {selectDefaultTeam} from '@helpers/api/team';
import {DEFAULT_LOCALE} from '@i18n';
import NetworkManager from '@managers/network_manager';
import {getDeviceToken} from '@queries/app/global';
import {queryAllChannelsForTeam, queryChannelsById} from '@queries/servers/channel';
import {getChannelById, queryAllChannelsForTeam, queryChannelsById} from '@queries/servers/channel';
import {prepareModels, truncateCrtRelatedTables} from '@queries/servers/entry';
import {getHasCRTChanged} from '@queries/servers/preference';
import {getConfig, getCurrentChannelId, getCurrentTeamId, getIsDataRetentionEnabled, getPushVerificationStatus, getWebSocketLastDisconnected, setCurrentTeamAndChannelId} from '@queries/servers/system';
@ -42,6 +42,8 @@ export type AppEntryData = {
removeTeamIds?: string[];
removeChannelIds?: string[];
isCRTEnabled: boolean;
initialChannelId?: string;
gmConverted?: boolean;
}
export type AppEntryError = {
@ -56,6 +58,7 @@ export type EntryResponse = {
teamData: MyTeamsRequest;
chData?: MyChannelsRequest;
meData?: MyUserRequest;
gmConverted?: boolean;
} | {
error: unknown;
}
@ -123,12 +126,12 @@ const entryRest = async (serverUrl: string, teamId?: string, channelId?: string,
const lastDisconnectedAt = since || await getWebSocketLastDisconnected(database);
const fetchedData = await fetchAppEntryData(serverUrl, lastDisconnectedAt, teamId);
const fetchedData = await fetchAppEntryData(serverUrl, lastDisconnectedAt, teamId, channelId);
if ('error' in fetchedData) {
return {error: fetchedData.error};
}
const {initialTeamId, teamData, chData, prefData, meData, removeTeamIds, removeChannelIds, isCRTEnabled} = fetchedData;
const {initialTeamId, initialChannelId: fetchedChannelId, teamData, chData, prefData, meData, removeTeamIds, removeChannelIds, isCRTEnabled, gmConverted} = fetchedData;
const chError = chData?.error;
if (isErrorWithStatusCode(chError) && chError.status_code === 403) {
// if the user does not have appropriate permissions, which means the user those not belong to the team,
@ -142,7 +145,7 @@ const entryRest = async (serverUrl: string, teamId?: string, channelId?: string,
const rolesData = await fetchRoles(serverUrl, teamData.memberships, chData?.memberships, meData.user, true);
const initialChannelId = await entryInitialChannelId(database, channelId, teamId, initialTeamId, meData?.user?.locale || '', chData?.channels, chData?.memberships);
const initialChannelId = await entryInitialChannelId(database, fetchedChannelId, teamId, initialTeamId, meData?.user?.locale || '', chData?.channels, chData?.memberships);
const removeTeams = await teamsToRemove(serverUrl, removeTeamIds);
@ -158,10 +161,10 @@ const entryRest = async (serverUrl: string, teamId?: string, channelId?: string,
const models = await Promise.all(modelPromises);
return {models: models.flat(), initialChannelId, initialTeamId, prefData, teamData, chData, meData};
return {models: models.flat(), initialChannelId, initialTeamId, prefData, teamData, chData, meData, gmConverted};
};
const fetchAppEntryData = async (serverUrl: string, sinceArg: number, initialTeamId = ''): Promise<AppEntryData | AppEntryError> => {
const fetchAppEntryData = async (serverUrl: string, sinceArg: number, onLoadTeamId = '', channelId?: string): Promise<AppEntryData | AppEntryError> => {
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
if (!database) {
return {error: `${serverUrl} database not found`};
@ -191,7 +194,7 @@ const fetchAppEntryData = async (serverUrl: string, sinceArg: number, initialTea
// Fetch in parallel teams / team membership / channels for current team / user preferences / user
const promises: [Promise<MyTeamsRequest>, Promise<MyChannelsRequest | undefined>, Promise<MyUserRequest>] = [
fetchMyTeams(serverUrl, fetchOnly),
initialTeamId ? fetchMyChannelsForTeam(serverUrl, initialTeamId, includeDeletedChannels, since, fetchOnly, false, isCRTEnabled) : Promise.resolve(undefined),
onLoadTeamId ? fetchMyChannelsForTeam(serverUrl, onLoadTeamId, includeDeletedChannels, since, fetchOnly, false, isCRTEnabled) : Promise.resolve(undefined),
fetchMe(serverUrl, fetchOnly),
];
@ -199,6 +202,41 @@ const fetchAppEntryData = async (serverUrl: string, sinceArg: number, initialTea
const [teamData, , meData] = resolution;
let [, chData] = resolution;
let initialTeamId = onLoadTeamId;
let initialChannelId = channelId;
let gmConverted = false;
if (channelId && chData?.channels) {
// check if channelId is in list of team's channels returned by server
const channelInServerData = chData.channels.find((channel) => channel.id === channelId);
// if channel is not found in server data, we need to check if it
// was a GM that is converted to a private or public channel in a different team than
// the team the mobile app was last closed in.
// Although yon can convert GM only to a pirvate channel, a private channel can furthur be converted to a public channel.
// So between the mobile app being on the GM and reconnecting,
// it may have become either a public or a private channel. So we need to check for both.
if (!channelInServerData) {
const existingChannel = await getChannelById(database, channelId);
if (existingChannel && existingChannel.type === General.GM_CHANNEL) {
// Okay, so now we know the channel existsin in mobile app's database as a GM.
// We now need to also check if channel on server is actually a private channel,
// and if so, which team does it belong to now. That team will become the
// active team on mobile app after this point.
const client = NetworkManager.getClient(serverUrl);
const serverChannel = await client.getChannel(channelId);
if (serverChannel.type === General.PRIVATE_CHANNEL || serverChannel.type === General.OPEN_CHANNEL) {
initialTeamId = serverChannel.team_id;
initialChannelId = channelId;
gmConverted = true;
chData = await fetchMyChannelsForTeam(serverUrl, serverChannel.team_id, includeDeletedChannels, since, fetchOnly, false, isCRTEnabled);
}
}
}
}
if (!initialTeamId && teamData.teams?.length && teamData.memberships?.length) {
// If no initial team was set in the database but got teams in the response
const config = await getConfig(database);
@ -221,6 +259,8 @@ const fetchAppEntryData = async (serverUrl: string, sinceArg: number, initialTea
meData,
removeTeamIds,
isCRTEnabled,
initialChannelId,
gmConverted,
};
if (teamData.teams?.length === 0 && !teamData.error) {
@ -438,6 +478,7 @@ export async function handleEntryAfterLoadNavigation(
currentChannelId: string,
initialTeamId: string,
initialChannelId: string,
gmConverted: boolean,
) {
try {
const {operator, database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
@ -462,7 +503,11 @@ export async function handleEntryAfterLoadNavigation(
await handleKickFromTeam(serverUrl, currentTeamIdAfterLoad);
}
} else if (currentTeamIdAfterLoad !== initialTeamId) {
await handleKickFromTeam(serverUrl, currentTeamIdAfterLoad);
if (gmConverted) {
await setCurrentTeamAndChannelId(operator, initialTeamId, currentChannelId);
} else {
await handleKickFromTeam(serverUrl, currentTeamIdAfterLoad);
}
} else if (currentChannelIdAfterLoad !== currentChannelId) {
// Switched channels while loading
if (!channelMembers.find((m) => m.channel_id === currentChannelIdAfterLoad)) {

View file

@ -159,9 +159,9 @@ async function doReconnect(serverUrl: string) {
setTeamLoading(serverUrl, false);
return entryData.error;
}
const {models, initialTeamId, initialChannelId, prefData, teamData, chData} = entryData;
const {models, initialTeamId, initialChannelId, prefData, teamData, chData, gmConverted} = entryData;
await handleEntryAfterLoadNavigation(serverUrl, teamData.memberships || [], chData?.memberships || [], currentTeamId || '', currentChannelId || '', initialTeamId, initialChannelId);
await handleEntryAfterLoadNavigation(serverUrl, teamData.memberships || [], chData?.memberships || [], currentTeamId || '', currentChannelId || '', initialTeamId, initialChannelId, Boolean(gmConverted));
const dt = Date.now();
if (models?.length) {

View file

@ -570,9 +570,9 @@ PODS:
- React-Core
- RNVectorIcons (10.0.0):
- React-Core
- SDWebImage (5.18.2):
- SDWebImage/Core (= 5.18.2)
- SDWebImage/Core (5.18.2)
- SDWebImage (5.18.3):
- SDWebImage/Core (= 5.18.3)
- SDWebImage/Core (5.18.3)
- SDWebImageWebPCoder (0.13.0):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.17)
@ -986,7 +986,7 @@ SPEC CHECKSUMS:
RNShare: da6d90b6dc332f51f86498041d6e34211f96b630
RNSVG: 03e4d258ca355d7836a0a5dd4d4dc63c1eb49cbb
RNVectorIcons: 8b5bb0fa61d54cd2020af4f24a51841ce365c7e9
SDWebImage: c0de394d7cf7f9838aed1fd6bb6037654a4572e4
SDWebImage: 96e0c18ef14010b7485210e92fac888587ebb958
SDWebImageWebPCoder: af09429398d99d524cae2fe00f6f0f6e491ed102
Sentry: 56c76eed917f7dffd46db50906afbf5c9aa2673a
SentryPrivate: f3be34b5deb9fe676fdfb1f1ad5cdb1b740c5688