Handled websocket notification race condition
This commit is contained in:
parent
aff310471a
commit
082b3c7f1e
8 changed files with 42 additions and 15 deletions
|
|
@ -9,7 +9,7 @@ import {queryMyTeams} from '@queries/servers/team';
|
|||
import {isDMorGM} from '@utils/channel';
|
||||
import {logDebug, logError} from '@utils/log';
|
||||
|
||||
import type {Database} from '@nozbe/watermelondb';
|
||||
import type {Database, Model} from '@nozbe/watermelondb';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
|
||||
export const deleteCategory = async (serverUrl: string, categoryId: string) => {
|
||||
|
|
@ -116,8 +116,10 @@ async function prepareAddNonGMDMChannelToDefaultCategory(database: Database, tea
|
|||
const channelCategory = categories.find((category) => category.type === CHANNELS_CATEGORY);
|
||||
if (channelCategory) {
|
||||
const cwc = await channelCategory.toCategoryWithChannels();
|
||||
cwc.channel_ids.unshift(channelId);
|
||||
return cwc;
|
||||
if (!cwc.channel_ids.indexOf(channelId)) {
|
||||
cwc.channel_ids.unshift(channelId);
|
||||
return cwc;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
|
@ -127,9 +129,15 @@ export async function putGMInCorrectCategory(serverUrl: string, channelId: strin
|
|||
try {
|
||||
const {database, operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
|
||||
const categoryChannels = await queryCategoryChannelsByChannelId(database, channelId).fetch();
|
||||
categoryChannels.forEach((categoryChannel) => categoryChannel.prepareDestroyPermanently());
|
||||
|
||||
const models: any[] = categoryChannels;
|
||||
const categories = await queryCategoriesByTeamIds(database, [targetTeamID]).fetch();
|
||||
const channelCategory = categories.find((category) => category.type === CHANNELS_CATEGORY);
|
||||
|
||||
categoryChannels.
|
||||
filter((categoryChannel) => categoryChannel.categoryId !== channelCategory?.id).
|
||||
forEach((categoryChannel) => categoryChannel.prepareDestroyPermanently());
|
||||
|
||||
const models: Model[] = categoryChannels;
|
||||
|
||||
const cwc = await prepareAddNonGMDMChannelToDefaultCategory(database, targetTeamID, channelId);
|
||||
if (cwc) {
|
||||
|
|
|
|||
|
|
@ -1277,7 +1277,7 @@ export const getGroupMessageMembersCommonTeams = async (serverUrl: string, chann
|
|||
}
|
||||
};
|
||||
|
||||
export const convertGroupMessageToPrivateChannel = async (serverUrl: string, channelId: string, teamId: string, displayName: string) => {
|
||||
export const convertGroupMessageToPrivateChannel = async (serverUrl: string, channelId: string, targetTeamId: string, displayName: string) => {
|
||||
try {
|
||||
const name = generateChannelNameFromDisplayName(displayName);
|
||||
const {database, operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
|
||||
|
|
@ -1288,18 +1288,19 @@ export const convertGroupMessageToPrivateChannel = async (serverUrl: string, cha
|
|||
}
|
||||
|
||||
const client = NetworkManager.getClient(serverUrl);
|
||||
const updatedChannel = await client.convertGroupMessageToPrivateChannel(channelId, teamId, displayName, name);
|
||||
const updatedChannel = await client.convertGroupMessageToPrivateChannel(channelId, targetTeamId, displayName, name);
|
||||
|
||||
if (existingChannel) {
|
||||
existingChannel.prepareUpdate((channel) => {
|
||||
channel.type = General.PRIVATE_CHANNEL;
|
||||
channel.displayName = displayName;
|
||||
channel.name = name;
|
||||
channel.teamId = targetTeamId;
|
||||
});
|
||||
|
||||
const models: any[] = [existingChannel];
|
||||
|
||||
const {models: categoryUpdateModels} = await putGMInCorrectCategory(serverUrl, channelId, teamId, true);
|
||||
const {models: categoryUpdateModels} = await putGMInCorrectCategory(serverUrl, channelId, targetTeamId, true);
|
||||
if (categoryUpdateModels) {
|
||||
models.push(...categoryUpdateModels);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
storeMyChannelsForTeam, updateChannelInfoFromChannel, updateMyChannelFromWebsocket,
|
||||
} from '@actions/local/channel';
|
||||
import {storePostsForChannel} from '@actions/local/post';
|
||||
import {fetchMissingDirectChannelsInfo, fetchMyChannel, fetchChannelStats, fetchChannelById, handleKickFromChannel} from '@actions/remote/channel';
|
||||
import {fetchMissingDirectChannelsInfo, fetchMyChannel, fetchChannelStats, fetchChannelById, handleKickFromChannel, goToNPSChannel, switchToChannelById} from '@actions/remote/channel';
|
||||
import {fetchPostsForChannel} from '@actions/remote/post';
|
||||
import {fetchRolesIfNeeded} from '@actions/remote/role';
|
||||
import {fetchUsersByIds, updateUsersNoLongerVisible} from '@actions/remote/user';
|
||||
|
|
@ -15,7 +15,7 @@ import {loadCallForChannel} from '@calls/actions/calls';
|
|||
import {Events, General} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {deleteChannelMembership, getChannelById, prepareMyChannelsForTeam, getCurrentChannel} from '@queries/servers/channel';
|
||||
import {getConfig, getCurrentChannelId} from '@queries/servers/system';
|
||||
import {getConfig, getCurrentChannelId, getCurrentTeamId} from '@queries/servers/system';
|
||||
import {getCurrentUser, getTeammateNameDisplay, getUserById} from '@queries/servers/user';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
|
|
@ -95,9 +95,10 @@ export async function handleChannelUpdatedEvent(serverUrl: string, msg: any) {
|
|||
const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
|
||||
const updatedChannel = JSON.parse(msg.data.channel) as Channel;
|
||||
|
||||
// if (EphemeralStore.isConvertingChannel(updatedChannel.id)) {
|
||||
// return;
|
||||
// }
|
||||
if (EphemeralStore.isConvertingChannel(updatedChannel.id)) {
|
||||
logDebug('Already processing.....');
|
||||
return;
|
||||
}
|
||||
|
||||
logDebug(`updatedChannel.id: ${updatedChannel.id}`);
|
||||
|
||||
|
|
@ -112,9 +113,18 @@ export async function handleChannelUpdatedEvent(serverUrl: string, msg: any) {
|
|||
}
|
||||
operator.batchRecords(models, 'handleChannelUpdatedEvent');
|
||||
|
||||
// This indicates a GM was converted to a private channel
|
||||
if (existingChannelType === General.GM_CHANNEL && updatedChannel.type === General.PRIVATE_CHANNEL) {
|
||||
logDebug('Yo yoyo!');
|
||||
await putGMInCorrectCategory(serverUrl, updatedChannel.id, updatedChannel.team_id);
|
||||
|
||||
const currentChannelId = await getCurrentChannelId(database);
|
||||
const currentTeamId = await getCurrentTeamId(database);
|
||||
|
||||
// Making sure user is not only in the correct channel, but also
|
||||
// in the correct team.
|
||||
if (currentChannelId === updatedChannel.id && currentTeamId !== updatedChannel.team_id) {
|
||||
await switchToChannelById(serverUrl, updatedChannel.id, updatedChannel.team_id);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Do nothing
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ async function doReconnect(serverUrl: string) {
|
|||
}
|
||||
|
||||
export async function handleEvent(serverUrl: string, msg: WebSocketMessage) {
|
||||
logDebug(msg);
|
||||
|
||||
switch (msg.event) {
|
||||
case WebsocketEvents.POSTED:
|
||||
case WebsocketEvents.EPHEMERAL_MESSAGE:
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ const launchAppFromNotification = async (notification: NotificationWithData, col
|
|||
|
||||
* @returns a redirection to a screen, either onboarding, add_server, login or home depending on the scenario
|
||||
*/
|
||||
|
||||
// LOL
|
||||
const launchApp = async (props: LaunchProps) => {
|
||||
let serverUrl: string | undefined;
|
||||
switch (props?.launchType) {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ export const ConvertGMToChannelForm = ({
|
|||
return;
|
||||
}
|
||||
|
||||
switchToChannelById(serverUrl, updatedChannel.id, selectedTeam.id);
|
||||
await switchToChannelById(serverUrl, updatedChannel.id, selectedTeam.id);
|
||||
}, [selectedTeam]);
|
||||
|
||||
const handleOnChannelNameChange = useCallback((newName: string) => {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {FlatList} from 'react-native';
|
|||
import Animated, {Easing, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
|
||||
|
||||
import {fetchDirectChannelsInfo} from '@actions/remote/channel';
|
||||
import {logDebug} from '@app/utils/log';
|
||||
import ChannelItem from '@components/channel_item';
|
||||
import {ROW_HEIGHT as CHANNEL_ROW_HEIGHT} from '@components/channel_item/channel_item';
|
||||
import {useServerUrl} from '@context/server';
|
||||
|
|
@ -25,6 +26,8 @@ type Props = {
|
|||
const extractKey = (item: ChannelModel) => item.id;
|
||||
|
||||
const CategoryBody = ({sortedChannels, unreadIds, unreadsOnTop, category, onChannelSwitch}: Props) => {
|
||||
sortedChannels.forEach((c) => logDebug(c.displayName));
|
||||
|
||||
const serverUrl = useServerUrl();
|
||||
const ids = useMemo(() => {
|
||||
const filteredChannels = unreadsOnTop ? sortedChannels.filter((c) => !unreadIds.has(c.id)) : sortedChannels;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {useIntl} from 'react-intl';
|
|||
import {FlatList, StyleSheet, View} from 'react-native';
|
||||
|
||||
import {switchToChannelById} from '@actions/remote/channel';
|
||||
import {logDebug} from '@app/utils/log';
|
||||
import Loading from '@components/loading';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
|
|
|
|||
Loading…
Reference in a new issue