[Gekidou MM-39728] - Websocket Events - Channels (#6038)
* wip checkin * wip checkin because my system is messed up again * correct the add user and remove user from channel functions. THe user and channel ids sometimes come from the broudcast field, not the data object * remove old comments * remove old comments * remove old comments * add back in unarchive handler. handleChannelUpdateEvent will also update the deleteAt value for a channel, but does not get called when unarchive from the channel view, only through the system console. * nit remove empty line * wip * wip * remove handleChannelConvertedEvent * remove handleChannelDirectAddedEvent * wip * wip * wip * Fix websockets events * Address feedback * Ensure categories and some refactoring * Self review fixes * Fix category creation bug * Address feedback and minor improvements * Address feedback * Fix lint Co-authored-by: Daniel Espino García <larkox@gmail.com>
This commit is contained in:
parent
b13a4abc27
commit
137ba9d191
31 changed files with 558 additions and 299 deletions
|
|
@ -5,14 +5,17 @@ import {Model} from '@nozbe/watermelondb';
|
|||
import {DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import {General, Navigation as NavigationConstants, Preferences, Screens} from '@constants';
|
||||
import {CHANNELS_CATEGORY, DMS_CATEGORY} from '@constants/categories';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
|
||||
import {prepareDeleteChannel, prepareMyChannelsForTeam, queryAllMyChannel, getMyChannel, getChannelById, queryUsersOnChannel} from '@queries/servers/channel';
|
||||
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
|
||||
import {prepareCommonSystemValues, PrepareCommonSystemValuesArgs, getCommonSystemValues, getCurrentTeamId, setCurrentChannelId} from '@queries/servers/system';
|
||||
import {addChannelToTeamHistory, addTeamToTeamHistory, getTeamById, removeChannelFromTeamHistory} from '@queries/servers/team';
|
||||
import {prepareCommonSystemValues, PrepareCommonSystemValuesArgs, getCommonSystemValues, getCurrentTeamId, setCurrentChannelId, getCurrentUserId} from '@queries/servers/system';
|
||||
import {addChannelToTeamHistory, addTeamToTeamHistory, getTeamById, queryMyTeams, removeChannelFromTeamHistory} from '@queries/servers/team';
|
||||
import {getCurrentUser} from '@queries/servers/user';
|
||||
import {dismissAllModalsAndPopToRoot, dismissAllModalsAndPopToScreen} from '@screens/navigation';
|
||||
import {makeCategoryChannelId, makeCategoryId} from '@utils/categories';
|
||||
import {isDMorGM} from '@utils/channel';
|
||||
import {isTablet} from '@utils/helpers';
|
||||
import {displayGroupMessageName, displayUsername, getUserIdFromChannelName} from '@utils/user';
|
||||
|
||||
|
|
@ -253,20 +256,22 @@ export const storeMyChannelsForTeam = async (serverUrl: string, teamId: string,
|
|||
if (!operator) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
const prepare = await prepareMyChannelsForTeam(operator, teamId, channels, memberships);
|
||||
if (prepare) {
|
||||
modelPromises.push(...prepare);
|
||||
}
|
||||
const modelPromises: Array<Promise<Model[]>> = [
|
||||
...await prepareMyChannelsForTeam(operator, teamId, channels, memberships),
|
||||
];
|
||||
|
||||
const models = await Promise.all(modelPromises);
|
||||
if (!models.length) {
|
||||
return {models: []};
|
||||
}
|
||||
|
||||
const flattenedModels = models.flat() as Model[];
|
||||
|
||||
if (prepareRecordsOnly) {
|
||||
return {models: flattenedModels};
|
||||
}
|
||||
|
||||
if (flattenedModels?.length > 0) {
|
||||
if (flattenedModels.length) {
|
||||
try {
|
||||
await operator.batchRecords(flattenedModels);
|
||||
} catch (error) {
|
||||
|
|
@ -279,6 +284,42 @@ export const storeMyChannelsForTeam = async (serverUrl: string, teamId: string,
|
|||
return {models: flattenedModels};
|
||||
};
|
||||
|
||||
export const updateMyChannelFromWebsocket = async (serverUrl: string, channelMember: ChannelMembership, prepareRecordsOnly = false) => {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
const member = await getMyChannel(operator.database, channelMember.channel_id);
|
||||
if (member) {
|
||||
member.prepareUpdate((m) => {
|
||||
m.roles = channelMember.roles;
|
||||
});
|
||||
if (!prepareRecordsOnly) {
|
||||
operator.batchRecords([member]);
|
||||
}
|
||||
}
|
||||
return {model: member};
|
||||
};
|
||||
|
||||
export const updateChannelInfoFromChannel = async (serverUrl: string, channel: Channel, prepareRecordsOnly = false) => {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
const newInfo = (await operator.handleChannelInfo({channelInfos: [{
|
||||
header: channel.header,
|
||||
purpose: channel.purpose,
|
||||
id: channel.id,
|
||||
}],
|
||||
prepareRecordsOnly: true}))[0];
|
||||
if (!prepareRecordsOnly) {
|
||||
operator.batchRecords([newInfo]);
|
||||
}
|
||||
return {model: newInfo};
|
||||
};
|
||||
|
||||
export const updateLastPostAt = async (serverUrl: string, channelId: string, lastPostAt: number, prepareRecordsOnly = false) => {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
|
|
@ -355,3 +396,51 @@ export async function updateChannelsDisplayName(serverUrl: string, channels: Cha
|
|||
|
||||
return {models};
|
||||
}
|
||||
|
||||
export async function addChannelToDefaultCategory(serverUrl: string, channel: Channel | ChannelModel, prepareRecordsOnly = false) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
const {database} = operator;
|
||||
|
||||
const teamId = 'teamId' in channel ? channel.teamId : channel.team_id;
|
||||
const userId = await getCurrentUserId(database);
|
||||
if (!userId) {
|
||||
return {error: 'no current user id'};
|
||||
}
|
||||
|
||||
if (!isDMorGM(channel)) {
|
||||
const models = await operator.handleCategoryChannels({categoryChannels: [{
|
||||
category_id: makeCategoryId(CHANNELS_CATEGORY, userId, teamId),
|
||||
channel_id: channel.id,
|
||||
sort_order: 0,
|
||||
id: makeCategoryChannelId(teamId, channel.id),
|
||||
}],
|
||||
prepareRecordsOnly});
|
||||
|
||||
return {models};
|
||||
}
|
||||
|
||||
const allTeams = await queryMyTeams(database).fetch();
|
||||
const models = (
|
||||
await Promise.all(
|
||||
allTeams.map(
|
||||
(t) => operator.handleCategoryChannels({categoryChannels: [{
|
||||
category_id: makeCategoryId(DMS_CATEGORY, userId, t.id),
|
||||
channel_id: channel.id,
|
||||
sort_order: 0,
|
||||
id: makeCategoryChannelId(t.id, channel.id),
|
||||
}],
|
||||
prepareRecordsOnly: true}),
|
||||
),
|
||||
)
|
||||
).flat();
|
||||
|
||||
if (models.length && !prepareRecordsOnly) {
|
||||
operator.batchRecords(models);
|
||||
}
|
||||
|
||||
return {models};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {Model} from '@nozbe/watermelondb';
|
|||
import {IntlShape} from 'react-intl';
|
||||
|
||||
import {storeCategories} from '@actions/local/category';
|
||||
import {storeMyChannelsForTeam, switchToChannel} from '@actions/local/channel';
|
||||
import {addChannelToDefaultCategory, storeMyChannelsForTeam, switchToChannel} from '@actions/local/channel';
|
||||
import {General, Preferences} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {privateChannelJoinPrompt} from '@helpers/api/channel';
|
||||
|
|
@ -17,7 +17,7 @@ import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
|
|||
import {getCommonSystemValues, getCurrentTeamId, getCurrentUserId} from '@queries/servers/system';
|
||||
import {prepareMyTeams, getNthLastChannelFromTeam, getMyTeamById, getTeamById, getTeamByName} from '@queries/servers/team';
|
||||
import {getCurrentUser} from '@queries/servers/user';
|
||||
import {generateChannelNameFromDisplayName, getDirectChannelName} from '@utils/channel';
|
||||
import {generateChannelNameFromDisplayName, getDirectChannelName, isDMorGM} from '@utils/channel';
|
||||
import {PERMALINK_GENERIC_TEAM_NAME_REDIRECT} from '@utils/url';
|
||||
import {displayGroupMessageName, displayUsername} from '@utils/user';
|
||||
|
||||
|
|
@ -29,7 +29,6 @@ import {fetchProfilesPerChannels, fetchUsersByIds} from './user';
|
|||
|
||||
import type {Client} from '@client/rest';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
|
|
@ -140,22 +139,16 @@ export const createChannel = async (serverUrl: string, displayName: string, purp
|
|||
|
||||
const models: Model[] = [];
|
||||
const channelModels = await prepareMyChannelsForTeam(operator, channelData.team_id, [channelData], [member]);
|
||||
if (channelModels?.length) {
|
||||
if (channelModels.length) {
|
||||
const resolvedModels = await Promise.all(channelModels);
|
||||
models.push(...resolvedModels.flat());
|
||||
}
|
||||
const categoriesModels = await operator.handleCategoryChannels({categoryChannels: [{
|
||||
category_id: `channels_${currentUserId}_${currentTeamId}`,
|
||||
channel_id: channelData.id,
|
||||
sort_order: 0,
|
||||
id: `${currentTeamId}_${channelData.id}`,
|
||||
}],
|
||||
prepareRecordsOnly: true});
|
||||
if (categoriesModels?.length) {
|
||||
models.push(...categoriesModels);
|
||||
const categoriesModels = await addChannelToDefaultCategory(serverUrl, channelData, true);
|
||||
if (categoriesModels.models?.length) {
|
||||
models.push(...categoriesModels.models);
|
||||
}
|
||||
if (models.length) {
|
||||
await operator.batchRecords(models.flat());
|
||||
await operator.batchRecords(models);
|
||||
}
|
||||
fetchChannelStats(serverUrl, channelData.id, false);
|
||||
return {channel: channelData};
|
||||
|
|
@ -270,14 +263,11 @@ export const fetchChannelStats = async (serverUrl: string, channelId: string, fe
|
|||
if (!fetchOnly) {
|
||||
const channel = await getChannelById(operator.database, channelId);
|
||||
if (channel) {
|
||||
const channelInfo = await channel.info.fetch() as ChannelInfoModel;
|
||||
const channelInfos: ChannelInfo[] = [{
|
||||
const channelInfos: Array<Partial<ChannelInfo>> = [{
|
||||
guest_count: stats.guest_count,
|
||||
header: channelInfo.header,
|
||||
id: channelId,
|
||||
member_count: stats.member_count,
|
||||
pinned_post_count: stats.pinnedpost_count,
|
||||
purpose: channelInfo.purpose,
|
||||
}];
|
||||
await operator.handleChannelInfo({channelInfos, prepareRecordsOnly: false});
|
||||
}
|
||||
|
|
@ -313,7 +303,7 @@ export const fetchMyChannelsForTeam = async (serverUrl: string, teamId: string,
|
|||
let channels = allChannels;
|
||||
let memberships = channelMemberships;
|
||||
if (excludeDirect) {
|
||||
channels = channels.filter((c) => c.type !== General.GM_CHANNEL && c.type !== General.DM_CHANNEL);
|
||||
channels = channels.filter((c) => !isDMorGM(c));
|
||||
}
|
||||
|
||||
const channelIds = new Set<string>(channels.map((c) => c.id));
|
||||
|
|
@ -342,6 +332,11 @@ export const fetchMyChannelsForTeam = async (serverUrl: string, teamId: string,
|
|||
};
|
||||
|
||||
export const fetchMyChannel = async (serverUrl: string, teamId: string, channelId: string, fetchOnly = false): Promise<MyChannelsRequest> => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
let client: Client;
|
||||
try {
|
||||
client = NetworkManager.getClient(serverUrl);
|
||||
|
|
@ -356,7 +351,7 @@ export const fetchMyChannel = async (serverUrl: string, teamId: string, channelI
|
|||
]);
|
||||
|
||||
if (!fetchOnly) {
|
||||
storeMyChannelsForTeam(serverUrl, channel.team_id || teamId, [channel], [member]);
|
||||
await storeMyChannelsForTeam(serverUrl, channel.team_id || teamId, [channel], [member]);
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
@ -437,8 +432,7 @@ export const joinChannel = async (serverUrl: string, userId: string, teamId: str
|
|||
channel = await client.getChannel(channelId);
|
||||
} else if (channelName) {
|
||||
channel = await client.getChannelByName(teamId, channelName, true);
|
||||
const directTypes: string[] = [General.GM_CHANNEL, General.DM_CHANNEL];
|
||||
if (directTypes.includes(channel.type)) {
|
||||
if (isDMorGM(channel)) {
|
||||
member = await client.getChannelMember(channel.id, userId);
|
||||
} else {
|
||||
member = await client.addToChannel(userId, channel.id);
|
||||
|
|
@ -453,14 +447,14 @@ export const joinChannel = async (serverUrl: string, userId: string, teamId: str
|
|||
if (channel && member && !fetchOnly) {
|
||||
fetchRolesIfNeeded(serverUrl, member.roles.split(' '));
|
||||
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
const prepare = await prepareMyChannelsForTeam(operator, teamId, [channel], [member]);
|
||||
if (prepare) {
|
||||
modelPromises.push(...prepare);
|
||||
}
|
||||
const modelPromises: Array<Promise<Model[]>> = await prepareMyChannelsForTeam(operator, teamId, [channel], [member]);
|
||||
if (modelPromises.length) {
|
||||
const models = await Promise.all(modelPromises);
|
||||
const flattenedModels = models.flat() as Model[];
|
||||
const flattenedModels: Model[] = models.flat();
|
||||
const categoriesModels = await addChannelToDefaultCategory(serverUrl, channel, true);
|
||||
if (categoriesModels.models?.length) {
|
||||
flattenedModels.push(...categoriesModels.models);
|
||||
}
|
||||
if (flattenedModels?.length > 0) {
|
||||
try {
|
||||
await operator.batchRecords(flattenedModels);
|
||||
|
|
@ -593,10 +587,7 @@ export const switchToChannelByName = async (serverUrl: string, channelName: stri
|
|||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
const {operator} = DatabaseManager.serverDatabases[serverUrl];
|
||||
if (!(team instanceof Model)) {
|
||||
const prepT = prepareMyTeams(operator, [team], [(myTeam as TeamMembership)]);
|
||||
if (prepT) {
|
||||
modelPromises.push(...prepT);
|
||||
}
|
||||
modelPromises.push(...prepareMyTeams(operator, [team], [(myTeam as TeamMembership)]));
|
||||
} else if (!(myTeam instanceof Model)) {
|
||||
const mt: MyTeam[] = [{
|
||||
id: myTeam.team_id,
|
||||
|
|
@ -609,10 +600,7 @@ export const switchToChannelByName = async (serverUrl: string, channelName: stri
|
|||
}
|
||||
|
||||
if (!(myChannel instanceof Model)) {
|
||||
const prepCh = await prepareMyChannelsForTeam(operator, team.id, [channel], [myChannel]);
|
||||
if (prepCh) {
|
||||
modelPromises.push(...prepCh);
|
||||
}
|
||||
modelPromises.push(...await prepareMyChannelsForTeam(operator, team.id, [channel], [myChannel]));
|
||||
}
|
||||
|
||||
let teamId;
|
||||
|
|
@ -654,6 +642,7 @@ export const createDirectChannel = async (serverUrl: string, userId: string, dis
|
|||
if (!operator) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
const {database} = operator;
|
||||
|
||||
let client: Client;
|
||||
try {
|
||||
|
|
@ -663,7 +652,7 @@ export const createDirectChannel = async (serverUrl: string, userId: string, dis
|
|||
}
|
||||
|
||||
try {
|
||||
const currentUser = await getCurrentUser(operator.database);
|
||||
const currentUser = await getCurrentUser(database);
|
||||
if (!currentUser) {
|
||||
return {error: 'Cannot get the current user'};
|
||||
}
|
||||
|
|
@ -672,8 +661,8 @@ export const createDirectChannel = async (serverUrl: string, userId: string, dis
|
|||
if (displayName) {
|
||||
created.display_name = displayName;
|
||||
} else {
|
||||
const preferences = await queryPreferencesByCategoryAndName(operator.database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
|
||||
const system = await getCommonSystemValues(operator.database);
|
||||
const preferences = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
|
||||
const system = await getCommonSystemValues(database);
|
||||
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(preferences || [], system.config, system.license);
|
||||
const {directChannels} = await fetchMissingSidebarInfo(serverUrl, [created], currentUser.locale, teammateDisplayNameSetting, currentUser.id, true);
|
||||
created.display_name = directChannels?.[0].display_name || created.display_name;
|
||||
|
|
@ -694,12 +683,16 @@ export const createDirectChannel = async (serverUrl: string, userId: string, dis
|
|||
|
||||
const models = [];
|
||||
const channelPromises = await prepareMyChannelsForTeam(operator, '', [created], [member, {...member, user_id: userId}]);
|
||||
if (channelPromises) {
|
||||
if (channelPromises.length) {
|
||||
const channelModels = await Promise.all(channelPromises);
|
||||
const flattenedChannelModels = channelModels.flat();
|
||||
if (flattenedChannelModels.length) {
|
||||
models.push(...flattenedChannelModels);
|
||||
}
|
||||
const categoryModels = await addChannelToDefaultCategory(serverUrl, created, true);
|
||||
if (categoryModels.models?.length) {
|
||||
models.push(...categoryModels.models);
|
||||
}
|
||||
}
|
||||
|
||||
if (models.length) {
|
||||
|
|
@ -824,11 +817,15 @@ export const createGroupChannel = async (serverUrl: string, userIds: string[]) =
|
|||
|
||||
if (directChannels?.length) {
|
||||
const channelPromises = await prepareMyChannelsForTeam(operator, '', directChannels, members);
|
||||
if (channelPromises) {
|
||||
if (channelPromises.length) {
|
||||
const channelModels = await Promise.all(channelPromises);
|
||||
const flattenedChannelModels = channelModels.flat();
|
||||
if (flattenedChannelModels.length) {
|
||||
operator.batchRecords(flattenedChannelModels);
|
||||
const models: Model[] = channelModels.flat();
|
||||
const categoryModels = await addChannelToDefaultCategory(serverUrl, created, true);
|
||||
if (categoryModels.models?.length) {
|
||||
models.push(...categoryModels.models);
|
||||
}
|
||||
if (models.length) {
|
||||
operator.batchRecords(models);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -935,15 +932,20 @@ export async function getOrCreateDirectChannel(serverUrl: string, otherUserId: s
|
|||
|
||||
const member = await client.getMyChannelMember(newChannel.id);
|
||||
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
const prepare = await prepareMyChannelsForTeam(operator, '', [newChannel], [member]);
|
||||
if (prepare?.length) {
|
||||
modelPromises.push(...prepare);
|
||||
const models = await Promise.all(modelPromises);
|
||||
const flattenedModels = models.flat() as Model[];
|
||||
if (flattenedModels?.length > 0) {
|
||||
const modelPromises: Array<Promise<Model[]>> = [...await prepareMyChannelsForTeam(operator, '', [newChannel], [member])];
|
||||
if (modelPromises.length) {
|
||||
const channelModels = await Promise.all(modelPromises);
|
||||
const models: Model[] = channelModels.flat();
|
||||
const categoryModels = await addChannelToDefaultCategory(serverUrl, newChannel, true);
|
||||
if (categoryModels.models?.length) {
|
||||
models.push(...categoryModels.models);
|
||||
}
|
||||
if (models.length) {
|
||||
operator.batchRecords(models);
|
||||
}
|
||||
if (models.length > 0) {
|
||||
try {
|
||||
await operator.batchRecords(flattenedModels);
|
||||
await operator.batchRecords(models);
|
||||
} catch {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('FAILED TO BATCH CHANNELS');
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {MyPreferencesRequest, fetchMyPreferences} from '@actions/remote/preferen
|
|||
import {fetchConfigAndLicense} from '@actions/remote/systems';
|
||||
import {fetchAllTeams, fetchMyTeams, fetchTeamsChannelsAndUnreadPosts, MyTeamsRequest} from '@actions/remote/team';
|
||||
import {fetchMe, MyUserRequest, updateAllUsersSince} from '@actions/remote/user';
|
||||
import {General, Preferences} from '@constants';
|
||||
import {Preferences} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getPreferenceValue, getTeammateNameDisplaySetting} from '@helpers/api/preference';
|
||||
import {selectDefaultTeam} from '@helpers/api/team';
|
||||
|
|
@ -17,6 +17,7 @@ import {queryAllServers} from '@queries/app/servers';
|
|||
import {queryAllChannelsForTeam} from '@queries/servers/channel';
|
||||
import {getConfig} from '@queries/servers/system';
|
||||
import {deleteMyTeams, getAvailableTeamIds, queryMyTeams, queryMyTeamsByIds, queryTeamsById} from '@queries/servers/team';
|
||||
import {isDMorGM} from '@utils/channel';
|
||||
|
||||
import type ClientError from '@client/rest/error';
|
||||
|
||||
|
|
@ -192,7 +193,7 @@ export const deferredAppEntryActions = async (
|
|||
|
||||
// defer sidebar DM & GM profiles
|
||||
if (chData?.channels?.length && chData.memberships?.length) {
|
||||
const directChannels = chData.channels.filter((c) => c.type === General.DM_CHANNEL || c.type === General.GM_CHANNEL);
|
||||
const directChannels = chData.channels.filter(isDMorGM);
|
||||
const channelsToFetchProfiles = new Set<Channel>(directChannels);
|
||||
if (channelsToFetchProfiles.size) {
|
||||
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(preferences || [], config, license);
|
||||
|
|
|
|||
|
|
@ -685,8 +685,8 @@ export async function fetchMissingChannelsFromPosts(serverUrl: string, posts: Po
|
|||
const channelMemberships = await Promise.all(userPromises);
|
||||
|
||||
if (!fetchOnly && channels.length && channelMemberships.length) {
|
||||
const modelPromises = prepareMissingChannelsForAllTeams(operator, channels, channelMemberships) as Array<Promise<Model[]>>;
|
||||
if (modelPromises && modelPromises.length) {
|
||||
const modelPromises = prepareMissingChannelsForAllTeams(operator, channels, channelMemberships);
|
||||
if (modelPromises.length) {
|
||||
const channelModelsArray = await Promise.all(modelPromises);
|
||||
if (channelModelsArray.length) {
|
||||
const models = channelModelsArray.flatMap((mdls) => {
|
||||
|
|
@ -928,7 +928,7 @@ export async function fetchSavedPosts(serverUrl: string, teamId?: string, channe
|
|||
const promises: Array<Promise<Model[]>> = [];
|
||||
|
||||
const {authors} = await fetchPostAuthors(serverUrl, postsArray, true);
|
||||
const {channels, channelMemberships} = await fetchMissingChannelsFromPosts(serverUrl, postsArray, true) as {channels: Channel[]; channelMemberships: ChannelMembership[]};
|
||||
const {channels, channelMemberships} = await fetchMissingChannelsFromPosts(serverUrl, postsArray, true);
|
||||
|
||||
if (authors?.length) {
|
||||
promises.push(
|
||||
|
|
@ -940,8 +940,8 @@ export async function fetchSavedPosts(serverUrl: string, teamId?: string, channe
|
|||
}
|
||||
|
||||
if (channels?.length && channelMemberships?.length) {
|
||||
const channelPromises = prepareMissingChannelsForAllTeams(operator, channels, channelMemberships) as Array<Promise<Model[]>>;
|
||||
if (channelPromises && channelPromises.length) {
|
||||
const channelPromises = prepareMissingChannelsForAllTeams(operator, channels, channelMemberships);
|
||||
if (channelPromises.length) {
|
||||
promises.push(...channelPromises);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {General, Preferences} from '@constants';
|
||||
import {Preferences} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getPreferenceValue, getTeammateNameDisplaySetting} from '@helpers/api/preference';
|
||||
import {selectDefaultTeam} from '@helpers/api/team';
|
||||
import NetworkManager from '@init/network_manager';
|
||||
import {prepareCategories, prepareCategoryChannels} from '@queries/servers/categories';
|
||||
import {prepareMyChannelsForTeam} from '@queries/servers/channel';
|
||||
import {prepareMyPreferences, queryPreferencesByCategoryAndName} from '@queries/servers/preference';
|
||||
import {prepareCommonSystemValues, getCommonSystemValues} from '@queries/servers/system';
|
||||
import {prepareMyTeams} from '@queries/servers/team';
|
||||
import {getCurrentUser} from '@queries/servers/user';
|
||||
import {selectDefaultChannelForTeam} from '@utils/channel';
|
||||
import {isDMorGM, selectDefaultChannelForTeam} from '@utils/channel';
|
||||
|
||||
import {fetchMissingSidebarInfo, fetchMyChannelsForTeam, MyChannelsRequest} from './channel';
|
||||
import {fetchPostsForChannel} from './post';
|
||||
|
|
@ -23,11 +24,13 @@ import {fetchMyTeams, MyTeamsRequest} from './team';
|
|||
import type {Model} from '@nozbe/watermelondb';
|
||||
|
||||
export const retryInitialTeamAndChannel = async (serverUrl: string) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
const {database} = operator;
|
||||
|
||||
try {
|
||||
NetworkManager.getClient(serverUrl);
|
||||
} catch (error) {
|
||||
|
|
@ -95,42 +98,26 @@ export const retryInitialTeamAndChannel = async (serverUrl: string) => {
|
|||
return {error: true};
|
||||
}
|
||||
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
const {operator} = DatabaseManager.serverDatabases[serverUrl];
|
||||
const models: Model[] = (await Promise.all([
|
||||
prepareMyPreferences(operator, prefData.preferences!),
|
||||
...prepareMyTeams(operator, teamData.teams!, teamData.memberships!),
|
||||
...await prepareMyChannelsForTeam(operator, initialTeam.id, chData!.channels!, chData!.memberships!),
|
||||
prepareCategories(operator, chData!.categories!),
|
||||
prepareCategoryChannels(operator, chData!.categories!),
|
||||
prepareCommonSystemValues(
|
||||
operator,
|
||||
{
|
||||
config: clData.config!,
|
||||
license: clData.license!,
|
||||
currentTeamId: initialTeam?.id,
|
||||
currentChannelId: initialChannel?.id,
|
||||
},
|
||||
),
|
||||
])).flat();
|
||||
|
||||
const prefModel = prepareMyPreferences(operator, prefData.preferences!);
|
||||
if (prefModel) {
|
||||
modelPromises.push(prefModel);
|
||||
}
|
||||
await operator.batchRecords(models);
|
||||
|
||||
const teamModels = prepareMyTeams(operator, teamData.teams!, teamData.memberships!);
|
||||
if (teamModels) {
|
||||
modelPromises.push(...teamModels);
|
||||
}
|
||||
|
||||
const channelModels = await prepareMyChannelsForTeam(operator, initialTeam!.id, chData!.channels!, chData!.memberships!);
|
||||
if (channelModels) {
|
||||
modelPromises.push(...channelModels);
|
||||
}
|
||||
|
||||
const systemModels = prepareCommonSystemValues(
|
||||
operator,
|
||||
{
|
||||
config: clData.config!,
|
||||
license: clData.license!,
|
||||
currentTeamId: initialTeam?.id,
|
||||
currentChannelId: initialChannel?.id,
|
||||
},
|
||||
);
|
||||
|
||||
if (systemModels) {
|
||||
modelPromises.push(systemModels);
|
||||
}
|
||||
|
||||
const models = await Promise.all(modelPromises);
|
||||
await operator.batchRecords(models.flat());
|
||||
|
||||
const directChannels = chData!.channels!.filter((c) => c.type === General.DM_CHANNEL || c.type === General.GM_CHANNEL);
|
||||
const directChannels = chData!.channels!.filter(isDMorGM);
|
||||
const channelsToFetchProfiles = new Set<Channel>(directChannels);
|
||||
if (channelsToFetchProfiles.size) {
|
||||
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(prefData.preferences || [], clData.config, clData.license);
|
||||
|
|
@ -146,11 +133,13 @@ export const retryInitialTeamAndChannel = async (serverUrl: string) => {
|
|||
};
|
||||
|
||||
export const retryInitialChannel = async (serverUrl: string, teamId: string) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
const {database} = operator;
|
||||
|
||||
try {
|
||||
NetworkManager.getClient(serverUrl);
|
||||
} catch (error) {
|
||||
|
|
@ -198,29 +187,16 @@ export const retryInitialChannel = async (serverUrl: string, teamId: string) =>
|
|||
return {error: true};
|
||||
}
|
||||
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
const {operator} = DatabaseManager.serverDatabases[serverUrl];
|
||||
const models: Model[] = (await Promise.all([
|
||||
...await prepareMyChannelsForTeam(operator, teamId, chData!.channels!, chData!.memberships!),
|
||||
prepareCategories(operator, chData!.categories!),
|
||||
prepareCategoryChannels(operator, chData!.categories!),
|
||||
prepareCommonSystemValues(operator, {currentChannelId: initialChannel?.id}),
|
||||
])).flat();
|
||||
|
||||
const channelModels = await prepareMyChannelsForTeam(operator, teamId, chData!.channels!, chData!.memberships!);
|
||||
if (channelModels) {
|
||||
modelPromises.push(...channelModels);
|
||||
}
|
||||
await operator.batchRecords(models);
|
||||
|
||||
const systemModels = prepareCommonSystemValues(
|
||||
operator,
|
||||
{
|
||||
currentChannelId: initialChannel?.id,
|
||||
},
|
||||
);
|
||||
|
||||
if (systemModels) {
|
||||
modelPromises.push(systemModels);
|
||||
}
|
||||
|
||||
const models = await Promise.all(modelPromises);
|
||||
await operator.batchRecords(models.flat());
|
||||
|
||||
const directChannels = chData!.channels!.filter((c) => c.type === General.DM_CHANNEL || c.type === General.GM_CHANNEL);
|
||||
const directChannels = chData!.channels!.filter(isDMorGM);
|
||||
const channelsToFetchProfiles = new Set<Channel>(directChannels);
|
||||
if (channelsToFetchProfiles.size) {
|
||||
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(preferences || [], config, license);
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ export async function fetchRecentMentions(serverUrl: string): Promise<PostSearch
|
|||
|
||||
if (postsArray.length) {
|
||||
const {authors} = await fetchPostAuthors(serverUrl, postsArray, true);
|
||||
const {channels, channelMemberships} = await fetchMissingChannelsFromPosts(serverUrl, postsArray, true) as {channels: Channel[]; channelMemberships: ChannelMembership[]};
|
||||
const {channels, channelMemberships} = await fetchMissingChannelsFromPosts(serverUrl, postsArray, true);
|
||||
|
||||
if (authors?.length) {
|
||||
promises.push(
|
||||
|
|
@ -79,8 +79,8 @@ export async function fetchRecentMentions(serverUrl: string): Promise<PostSearch
|
|||
}
|
||||
|
||||
if (channels?.length && channelMemberships?.length) {
|
||||
const channelPromises = prepareMissingChannelsForAllTeams(operator, channels, channelMemberships) as Array<Promise<Model[]>>;
|
||||
if (channelPromises && channelPromises.length) {
|
||||
const channelPromises = prepareMissingChannelsForAllTeams(operator, channels, channelMemberships);
|
||||
if (channelPromises.length) {
|
||||
promises.push(...channelPromises);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {removeUserFromTeam as localRemoveUserFromTeam} from '@actions/local/team
|
|||
import {Events} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import NetworkManager from '@init/network_manager';
|
||||
import {prepareCategories, prepareCategoryChannels} from '@queries/servers/categories';
|
||||
import {prepareMyChannelsForTeam, getDefaultChannelForTeam} from '@queries/servers/channel';
|
||||
import {prepareCommonSystemValues, getCurrentTeamId, getWebSocketLastDisconnected} from '@queries/servers/system';
|
||||
import {addTeamToTeamHistory, prepareDeleteTeam, prepareMyTeams, getNthLastChannelFromTeam, queryTeamsById, syncTeamTable} from '@queries/servers/team';
|
||||
|
|
@ -39,7 +40,7 @@ export const addUserToTeam = async (serverUrl: string, teamId: string, userId: s
|
|||
|
||||
if (!fetchOnly) {
|
||||
fetchRolesIfNeeded(serverUrl, member.roles.split(' '));
|
||||
const {channels, memberships: channelMembers} = await fetchMyChannelsForTeam(serverUrl, teamId, false, 0, true);
|
||||
const {channels, memberships: channelMembers, categories} = await fetchMyChannelsForTeam(serverUrl, teamId, false, 0, true);
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (operator) {
|
||||
const myTeams: MyTeam[] = [{
|
||||
|
|
@ -47,17 +48,16 @@ export const addUserToTeam = async (serverUrl: string, teamId: string, userId: s
|
|||
roles: member.roles,
|
||||
}];
|
||||
|
||||
const models = await Promise.all([
|
||||
const models: Model[] = (await Promise.all([
|
||||
operator.handleMyTeam({myTeams, prepareRecordsOnly: true}),
|
||||
operator.handleTeamMemberships({teamMemberships: [member], prepareRecordsOnly: true}),
|
||||
prepareMyChannelsForTeam(operator, teamId, channels || [], channelMembers || []),
|
||||
]);
|
||||
...await prepareMyChannelsForTeam(operator, teamId, channels || [], channelMembers || []),
|
||||
prepareCategories(operator, categories || []),
|
||||
prepareCategoryChannels(operator, categories || []),
|
||||
])).flat();
|
||||
|
||||
if (models.length) {
|
||||
const flattenedModels = models.flat() as Model[];
|
||||
if (flattenedModels?.length > 0) {
|
||||
await operator.batchRecords(flattenedModels);
|
||||
}
|
||||
await operator.batchRecords(models);
|
||||
}
|
||||
|
||||
if (await isTablet()) {
|
||||
|
|
@ -92,15 +92,11 @@ export const fetchMyTeams = async (serverUrl: string, fetchOnly = false): Promis
|
|||
|
||||
if (!fetchOnly) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
|
||||
if (operator) {
|
||||
const removeTeamIds = memberships.filter((m) => m.delete_at > 0).map((m) => m.team_id);
|
||||
const remainingTeams = teams.filter((t) => !removeTeamIds.includes(t.id));
|
||||
const prepare = prepareMyTeams(operator, remainingTeams, memberships);
|
||||
if (prepare) {
|
||||
modelPromises.push(...prepare);
|
||||
}
|
||||
|
||||
const modelPromises = prepareMyTeams(operator, remainingTeams, memberships);
|
||||
if (removeTeamIds.length) {
|
||||
if (removeTeamIds?.length) {
|
||||
// Immediately delete myTeams so that the UI renders only teams the user is a member of.
|
||||
|
|
@ -113,8 +109,8 @@ export const fetchMyTeams = async (serverUrl: string, fetchOnly = false): Promis
|
|||
|
||||
if (modelPromises.length) {
|
||||
const models = await Promise.all(modelPromises);
|
||||
const flattenedModels = models.flat() as Model[];
|
||||
if (flattenedModels?.length > 0) {
|
||||
const flattenedModels = models.flat();
|
||||
if (flattenedModels.length > 0) {
|
||||
await operator.batchRecords(flattenedModels);
|
||||
}
|
||||
}
|
||||
|
|
@ -143,15 +139,11 @@ export const fetchMyTeam = async (serverUrl: string, teamId: string, fetchOnly =
|
|||
]);
|
||||
if (!fetchOnly) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
if (operator) {
|
||||
const prepare = prepareMyTeams(operator, [team], [membership]);
|
||||
if (prepare) {
|
||||
modelPromises.push(...prepare);
|
||||
}
|
||||
const modelPromises = prepareMyTeams(operator, [team], [membership]);
|
||||
if (modelPromises.length) {
|
||||
const models = await Promise.all(modelPromises);
|
||||
const flattenedModels = models.flat() as Model[];
|
||||
const flattenedModels = models.flat();
|
||||
if (flattenedModels?.length > 0) {
|
||||
await operator.batchRecords(flattenedModels);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,18 @@
|
|||
import {Model} from '@nozbe/watermelondb';
|
||||
import {DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import {removeCurrentUserFromChannel, setChannelDeleteAt, switchToChannel} from '@actions/local/channel';
|
||||
import {fetchMyChannel} from '@actions/remote/channel';
|
||||
import {
|
||||
addChannelToDefaultCategory,
|
||||
markChannelAsViewed,
|
||||
removeCurrentUserFromChannel,
|
||||
setChannelDeleteAt,
|
||||
storeMyChannelsForTeam,
|
||||
switchToChannel,
|
||||
updateChannelInfoFromChannel,
|
||||
updateMyChannelFromWebsocket} from '@actions/local/channel';
|
||||
import {fetchMissingSidebarInfo, fetchMyChannel, fetchChannelStats, fetchChannelById} from '@actions/remote/channel';
|
||||
import {fetchPostsForChannel} from '@actions/remote/post';
|
||||
import {fetchRolesIfNeeded} from '@actions/remote/role';
|
||||
import {fetchUsersByIds, updateUsersNoLongerVisible} from '@actions/remote/user';
|
||||
import Events from '@constants/events';
|
||||
import DatabaseManager from '@database/manager';
|
||||
|
|
@ -18,42 +27,201 @@ import {getCurrentUser, getUserById} from '@queries/servers/user';
|
|||
import {dismissAllModals, popToRoot} from '@screens/navigation';
|
||||
import {isTablet} from '@utils/helpers';
|
||||
|
||||
export async function handleUserAddedToChannelEvent(serverUrl: string, msg: any) {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl];
|
||||
if (!database) {
|
||||
// Received when current user created a channel in a different client
|
||||
export async function handleChannelCreatedEvent(serverUrl: string, msg: any) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
const currentUser = await getCurrentUser(database.database);
|
||||
const {team_id: teamId, user_id: userId} = msg.data;
|
||||
const {channel_id: channelId} = msg.broadcast;
|
||||
|
||||
const {team_id: teamId, channel_id: channelId} = msg.data;
|
||||
|
||||
try {
|
||||
const models: Model[] = [];
|
||||
const {channels, memberships} = await fetchMyChannel(serverUrl, teamId, channelId, true);
|
||||
if (channels && memberships) {
|
||||
const prepare = await prepareMyChannelsForTeam(operator, teamId, channels, memberships);
|
||||
if (prepare.length) {
|
||||
const prepareModels = await Promise.all(prepare);
|
||||
const flattenedModels = prepareModels.flat();
|
||||
if (flattenedModels?.length > 0) {
|
||||
models.push(...flattenedModels);
|
||||
}
|
||||
const categoryModels = await addChannelToDefaultCategory(serverUrl, channels[0], true);
|
||||
if (categoryModels.models?.length) {
|
||||
models.push(...categoryModels.models);
|
||||
}
|
||||
}
|
||||
}
|
||||
operator.batchRecords(models);
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleChannelUnarchiveEvent(serverUrl: string, msg: any) {
|
||||
try {
|
||||
await setChannelDeleteAt(serverUrl, msg.data.channel_id, 0);
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleChannelConvertedEvent(serverUrl: string, msg: any) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const channelId = msg.data.channel_id;
|
||||
const {channel} = await fetchChannelById(serverUrl, channelId);
|
||||
if (channel) {
|
||||
operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
||||
}
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleChannelUpdatedEvent(serverUrl: string, msg: any) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedChannel = JSON.parse(msg.data.channel);
|
||||
try {
|
||||
const models: Model[] = await operator.handleChannel({channels: [updatedChannel], prepareRecordsOnly: true});
|
||||
const infoModel = await updateChannelInfoFromChannel(serverUrl, updatedChannel, true);
|
||||
if (infoModel.model) {
|
||||
models.push(infoModel.model);
|
||||
}
|
||||
operator.batchRecords(models);
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleChannelViewedEvent(serverUrl: string, msg: any) {
|
||||
try {
|
||||
const {channel_id: channelId} = msg.data;
|
||||
|
||||
await markChannelAsViewed(serverUrl, channelId, false);
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// This event is triggered by changes in the notify props or in the roles.
|
||||
export async function handleChannelMemberUpdatedEvent(serverUrl: string, msg: any) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const models: Model[] = [];
|
||||
|
||||
const updatedChannelMember: ChannelMembership = JSON.parse(msg.data.channelMember);
|
||||
updatedChannelMember.id = updatedChannelMember.channel_id;
|
||||
|
||||
const myMemberModel = await updateMyChannelFromWebsocket(serverUrl, updatedChannelMember, true);
|
||||
if (myMemberModel.model) {
|
||||
models.push(myMemberModel.model);
|
||||
}
|
||||
models.push(...await operator.handleMyChannelSettings({
|
||||
settings: [updatedChannelMember],
|
||||
prepareRecordsOnly: true,
|
||||
}));
|
||||
const rolesRequest = await fetchRolesIfNeeded(serverUrl, updatedChannelMember.roles.split(','), true);
|
||||
if (rolesRequest.roles?.length) {
|
||||
models.push(...await operator.handleRole({roles: rolesRequest.roles, prepareRecordsOnly: true}));
|
||||
}
|
||||
operator.batchRecords(models);
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleDirectAddedEvent(serverUrl: string, msg: any) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {database} = operator;
|
||||
|
||||
try {
|
||||
const {channel_id: channelId} = msg.broadcast;
|
||||
const {channels, memberships} = await fetchMyChannel(serverUrl, '', channelId, true);
|
||||
if (!channels || !memberships) {
|
||||
return;
|
||||
}
|
||||
const user = await getCurrentUser(database);
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {directChannels} = await fetchMissingSidebarInfo(serverUrl, channels, user.locale, '', user.id, true);
|
||||
if (!directChannels?.[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const models: Model[] = [];
|
||||
const channelModels = await storeMyChannelsForTeam(serverUrl, '', directChannels, memberships);
|
||||
if (channelModels.models?.length) {
|
||||
models.push(...channelModels.models);
|
||||
}
|
||||
const categoryModels = await addChannelToDefaultCategory(serverUrl, channels[0], false);
|
||||
if (categoryModels.models?.length) {
|
||||
models.push(...categoryModels.models);
|
||||
}
|
||||
|
||||
if (models.length) {
|
||||
operator.batchRecords(models);
|
||||
}
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleUserAddedToChannelEvent(serverUrl: string, msg: any) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {database} = operator;
|
||||
|
||||
const currentUser = await getCurrentUser(database);
|
||||
const userId = msg.data.user_id || msg.broadcast.userId;
|
||||
const channelId = msg.data.channel_id || msg.broadcast.channel_id;
|
||||
const {team_id: teamId} = msg.data;
|
||||
const models: Model[] = [];
|
||||
|
||||
try {
|
||||
const addedUser = getUserById(database.database, userId);
|
||||
if (!addedUser) {
|
||||
// TODO Potential improvement https://mattermost.atlassian.net/browse/MM-40581
|
||||
const {users} = await fetchUsersByIds(serverUrl, [userId], true);
|
||||
if (users) {
|
||||
models.push(...await database.operator.handleUsers({users, prepareRecordsOnly: true}));
|
||||
}
|
||||
}
|
||||
|
||||
if (userId === currentUser?.id) {
|
||||
const {channels, memberships} = await fetchMyChannel(serverUrl, teamId, channelId, true);
|
||||
if (channels && memberships) {
|
||||
const prepare = await prepareMyChannelsForTeam(database.operator, teamId, channels, memberships);
|
||||
if (prepare) {
|
||||
const prepare = await prepareMyChannelsForTeam(operator, teamId, channels, memberships);
|
||||
if (prepare.length) {
|
||||
const prepareModels = await Promise.all(prepare);
|
||||
const flattenedModels = prepareModels.flat();
|
||||
if (flattenedModels?.length > 0) {
|
||||
models.push(...flattenedModels);
|
||||
await operator.batchRecords(flattenedModels);
|
||||
}
|
||||
}
|
||||
|
||||
const categoriesModels = await addChannelToDefaultCategory(serverUrl, channels[0], true);
|
||||
if (categoriesModels.models?.length) {
|
||||
models.push(...categoriesModels.models);
|
||||
}
|
||||
}
|
||||
|
||||
const {posts, order, authors, actionType, previousPostId} = await fetchPostsForChannel(serverUrl, channelId, true);
|
||||
if (posts?.length && order && actionType) {
|
||||
models.push(...await database.operator.handlePosts({
|
||||
models.push(...await operator.handlePosts({
|
||||
actionType,
|
||||
order,
|
||||
posts,
|
||||
|
|
@ -63,32 +231,43 @@ export async function handleUserAddedToChannelEvent(serverUrl: string, msg: any)
|
|||
}
|
||||
|
||||
if (authors?.length) {
|
||||
models.push(...await database.operator.handleUsers({users: authors, prepareRecordsOnly: true}));
|
||||
models.push(...await operator.handleUsers({users: authors, prepareRecordsOnly: true}));
|
||||
}
|
||||
} else {
|
||||
const channel = await getChannelById(database.database, channelId);
|
||||
const addedUser = getUserById(database, userId);
|
||||
if (!addedUser) {
|
||||
// TODO Potential improvement https://mattermost.atlassian.net/browse/MM-40581
|
||||
const {users} = await fetchUsersByIds(serverUrl, [userId], true);
|
||||
if (users) {
|
||||
models.push(...await operator.handleUsers({users, prepareRecordsOnly: true}));
|
||||
}
|
||||
}
|
||||
const channel = await getChannelById(database, channelId);
|
||||
if (channel) {
|
||||
models.push(...await database.operator.handleChannelMembership({
|
||||
models.push(...await operator.handleChannelMembership({
|
||||
channelMemberships: [{channel_id: channelId, user_id: userId}],
|
||||
prepareRecordsOnly: true,
|
||||
}));
|
||||
}
|
||||
}
|
||||
await operator.batchRecords(models);
|
||||
|
||||
await fetchChannelStats(serverUrl, channelId, false);
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
database.operator.batchRecords(models);
|
||||
}
|
||||
|
||||
export async function handleUserRemovedFromChannelEvent(serverUrl: string, msg: any) {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl];
|
||||
if (!database) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const channel = await getCurrentChannel(database.database);
|
||||
const user = await getCurrentUser(database.database);
|
||||
const {database} = operator;
|
||||
|
||||
const channel = await getCurrentChannel(database);
|
||||
const user = await getCurrentUser(database);
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -121,7 +300,7 @@ export async function handleUserRemovedFromChannelEvent(serverUrl: string, msg:
|
|||
await popToRoot();
|
||||
|
||||
if (await isTablet()) {
|
||||
const channelToJumpTo = await getNthLastChannelFromTeam(database.database, channel?.teamId);
|
||||
const channelToJumpTo = await getNthLastChannelFromTeam(database, channel?.teamId);
|
||||
if (channelToJumpTo) {
|
||||
const {models: switchChannelModels} = await switchToChannel(serverUrl, channelToJumpTo, '', true);
|
||||
if (switchChannelModels) {
|
||||
|
|
@ -129,7 +308,7 @@ export async function handleUserRemovedFromChannelEvent(serverUrl: string, msg:
|
|||
}
|
||||
} // TODO else jump to "join a channel" screen https://mattermost.atlassian.net/browse/MM-41051
|
||||
} else {
|
||||
const currentChannelModels = await prepareCommonSystemValues(database.operator, {currentChannelId: ''});
|
||||
const currentChannelModels = await prepareCommonSystemValues(operator, {currentChannelId: ''});
|
||||
if (currentChannelModels?.length) {
|
||||
models.push(...currentChannelModels);
|
||||
}
|
||||
|
|
@ -137,30 +316,33 @@ export async function handleUserRemovedFromChannelEvent(serverUrl: string, msg:
|
|||
}
|
||||
}
|
||||
} else {
|
||||
const {models: deleteMemberModels} = await deleteChannelMembership(database.operator, userId, channelId, true);
|
||||
const {models: deleteMemberModels} = await deleteChannelMembership(operator, userId, channelId, true);
|
||||
if (deleteMemberModels) {
|
||||
models.push(...deleteMemberModels);
|
||||
}
|
||||
}
|
||||
|
||||
database.operator.batchRecords(models);
|
||||
await fetchChannelStats(serverUrl, channelId, false);
|
||||
operator.batchRecords(models);
|
||||
}
|
||||
|
||||
export async function handleChannelDeletedEvent(serverUrl: string, msg: WebSocketMessage) {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl];
|
||||
if (!database) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentChannel = await getCurrentChannel(database.database);
|
||||
const user = await getCurrentUser(database.database);
|
||||
const {database} = operator;
|
||||
|
||||
const currentChannel = await getCurrentChannel(database);
|
||||
const user = await getCurrentUser(database);
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {channel_id: channelId, delete_at: deleteAt} = msg.data;
|
||||
|
||||
const config = await getConfig(database.database);
|
||||
const config = await getConfig(database);
|
||||
|
||||
await setChannelDeleteAt(serverUrl, channelId, deleteAt);
|
||||
|
||||
|
|
@ -180,12 +362,12 @@ export async function handleChannelDeletedEvent(serverUrl: string, msg: WebSocke
|
|||
await popToRoot();
|
||||
|
||||
if (await isTablet()) {
|
||||
const channelToJumpTo = await getNthLastChannelFromTeam(database.database, currentChannel?.teamId);
|
||||
const channelToJumpTo = await getNthLastChannelFromTeam(database, currentChannel?.teamId);
|
||||
if (channelToJumpTo) {
|
||||
switchToChannel(serverUrl, channelToJumpTo);
|
||||
} // TODO else jump to "join a channel" screen
|
||||
} else {
|
||||
setCurrentChannelId(database.operator, '');
|
||||
setCurrentChannelId(operator, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,17 +8,26 @@ import {fetchRoles} from '@actions/remote/role';
|
|||
import {fetchConfigAndLicense} from '@actions/remote/systems';
|
||||
import {fetchAllTeams, fetchTeamsChannelsAndUnreadPosts} from '@actions/remote/team';
|
||||
import {fetchStatusByIds, updateAllUsersSince} from '@actions/remote/user';
|
||||
import {General, WebsocketEvents} from '@constants';
|
||||
import {WebsocketEvents} from '@constants';
|
||||
import {SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
|
||||
import {queryChannelsById, getDefaultChannelForTeam} from '@queries/servers/channel';
|
||||
import {prepareModels} from '@queries/servers/entry';
|
||||
import {getCommonSystemValues, getConfig, getCurrentChannelId, getWebSocketLastDisconnected, resetWebSocketLastDisconnected, setCurrentTeamAndChannelId} from '@queries/servers/system';
|
||||
import {isDMorGM} from '@utils/channel';
|
||||
import {isTablet} from '@utils/helpers';
|
||||
|
||||
import {handleCategoryCreatedEvent, handleCategoryDeletedEvent, handleCategoryOrderUpdatedEvent, handleCategoryUpdatedEvent} from './category';
|
||||
import {handleChannelDeletedEvent, handleUserAddedToChannelEvent, handleUserRemovedFromChannelEvent} from './channel';
|
||||
import {handleChannelConvertedEvent, handleChannelCreatedEvent,
|
||||
handleChannelDeletedEvent,
|
||||
handleChannelMemberUpdatedEvent,
|
||||
handleChannelUnarchiveEvent,
|
||||
handleChannelUpdatedEvent,
|
||||
handleChannelViewedEvent,
|
||||
handleDirectAddedEvent,
|
||||
handleUserAddedToChannelEvent,
|
||||
handleUserRemovedFromChannelEvent} from './channel';
|
||||
import {handleNewPostEvent, handlePostDeleted, handlePostEdited, handlePostUnread} from './posts';
|
||||
import {handlePreferenceChangedEvent, handlePreferencesChangedEvent, handlePreferencesDeletedEvent} from './preferences';
|
||||
import {handleAddCustomEmoji, handleReactionRemovedFromPostEvent, handleReactionAddedToPostEvent} from './reactions';
|
||||
|
|
@ -106,7 +115,7 @@ async function doReconnect(serverUrl: string) {
|
|||
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(prefData.preferences || [], config, license);
|
||||
let directChannels: Channel[];
|
||||
[chData.channels, directChannels] = chData.channels.reduce(([others, direct], c: Channel) => {
|
||||
if (c.type === General.DM_CHANNEL || c.type === General.GM_CHANNEL) {
|
||||
if (isDMorGM(c)) {
|
||||
direct.push(c);
|
||||
} else {
|
||||
others.push(c);
|
||||
|
|
@ -248,40 +257,40 @@ export async function handleEvent(serverUrl: string, msg: WebSocketMessage) {
|
|||
break;
|
||||
|
||||
case WebsocketEvents.CHANNEL_CREATED:
|
||||
handleChannelCreatedEvent(serverUrl, msg);
|
||||
break;
|
||||
|
||||
// return dispatch(handleChannelCreatedEvent(msg));
|
||||
case WebsocketEvents.CHANNEL_DELETED:
|
||||
handleChannelDeletedEvent(serverUrl, msg);
|
||||
break;
|
||||
case WebsocketEvents.CHANNEL_UNARCHIVED:
|
||||
handleChannelUnarchiveEvent(serverUrl, msg);
|
||||
break;
|
||||
|
||||
// return dispatch(handleChannelUnarchiveEvent(msg));
|
||||
case WebsocketEvents.CHANNEL_UPDATED:
|
||||
handleChannelUpdatedEvent(serverUrl, msg);
|
||||
break;
|
||||
|
||||
// return dispatch(handleChannelUpdatedEvent(msg));
|
||||
case WebsocketEvents.CHANNEL_CONVERTED:
|
||||
handleChannelConvertedEvent(serverUrl, msg);
|
||||
break;
|
||||
|
||||
// return dispatch(handleChannelConvertedEvent(msg));
|
||||
case WebsocketEvents.CHANNEL_VIEWED:
|
||||
handleChannelViewedEvent(serverUrl, msg);
|
||||
break;
|
||||
|
||||
// return dispatch(handleChannelViewedEvent(msg));
|
||||
case WebsocketEvents.CHANNEL_MEMBER_UPDATED:
|
||||
handleChannelMemberUpdatedEvent(serverUrl, msg);
|
||||
break;
|
||||
|
||||
// return dispatch(handleChannelMemberUpdatedEvent(msg));
|
||||
case WebsocketEvents.CHANNEL_SCHEME_UPDATED:
|
||||
// Do nothing, handled by CHANNEL_UPDATED due to changes in the channel scheme.
|
||||
break;
|
||||
|
||||
// return dispatch(handleChannelSchemeUpdatedEvent(msg));
|
||||
case WebsocketEvents.DIRECT_ADDED:
|
||||
handleDirectAddedEvent(serverUrl, msg);
|
||||
break;
|
||||
|
||||
// return dispatch(handleDirectAddedEvent(msg));
|
||||
case WebsocketEvents.PREFERENCE_CHANGED:
|
||||
handlePreferenceChangedEvent(serverUrl, msg);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,11 @@ export async function handleTeamMemberRoleUpdatedEvent(serverUrl: string, msg: W
|
|||
}
|
||||
|
||||
try {
|
||||
const member = JSON.parse(msg.data.member);
|
||||
const member: TeamMembership = JSON.parse(msg.data.member);
|
||||
|
||||
if (member.delete_at > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentUserId = await getCurrentUserId(operator.database);
|
||||
if (currentUserId !== member.user_id) {
|
||||
|
|
|
|||
|
|
@ -112,10 +112,7 @@ export async function handleUserAddedToTeamEvent(serverUrl: string, msg: WebSock
|
|||
}
|
||||
|
||||
if (teams && teamMemberships) {
|
||||
const preparedTeamModels = prepareMyTeams(database.operator, teams, teamMemberships);
|
||||
if (preparedTeamModels) {
|
||||
modelPromises.push(...preparedTeamModels);
|
||||
}
|
||||
modelPromises.push(...prepareMyTeams(database.operator, teams, teamMemberships));
|
||||
}
|
||||
|
||||
if (modelPromises.length) {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|||
import ChannelIcon from '@components/channel_icon';
|
||||
import {BotTag, GuestTag} from '@components/tag';
|
||||
import TouchableWithFeedback from '@components/touchable_with_feedback';
|
||||
import {General} from '@constants';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {isDMorGM} from '@utils/channel';
|
||||
import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
|
|
@ -59,7 +59,7 @@ const ChannelMentionItem = ({
|
|||
const theme = useTheme();
|
||||
|
||||
const completeMention = () => {
|
||||
if (channel.type === General.DM_CHANNEL || channel.type === General.GM_CHANNEL) {
|
||||
if (isDMorGM(channel)) {
|
||||
onPress('@' + displayName?.replace(/ /g, ''));
|
||||
} else {
|
||||
onPress(channel.name);
|
||||
|
|
@ -78,7 +78,7 @@ const ChannelMentionItem = ({
|
|||
|
||||
const isArchived = ('delete_at' in channel ? channel.delete_at : channel.deleteAt) > 0;
|
||||
|
||||
if (channel.type === General.DM_CHANNEL || channel.type === General.GM_CHANNEL) {
|
||||
if (isDMorGM(channel)) {
|
||||
if (!displayName) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
import React, {useCallback, useMemo} from 'react';
|
||||
import {FlatList} from 'react-native';
|
||||
|
||||
import {DMS_CATEGORY} from '@constants/categories';
|
||||
import ChannelModel from '@typings/database/models/servers/channel';
|
||||
|
||||
import ChannelListItem from './channel';
|
||||
|
|
@ -29,7 +30,7 @@ const CategoryBody = ({currentChannelId, sortedChannels, category, hiddenChannel
|
|||
filteredChannels = sortedChannels.filter((item) => item && !hiddenChannelIds.includes(item.id));
|
||||
}
|
||||
|
||||
if (category.type === 'direct_messages' && limit > 0) {
|
||||
if (category.type === DMS_CATEGORY && limit > 0) {
|
||||
return filteredChannels.slice(0, limit - 1);
|
||||
}
|
||||
return filteredChannels;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {combineLatest, of as of$} from 'rxjs';
|
|||
import {map, switchMap, concatAll} from 'rxjs/operators';
|
||||
|
||||
import {General, Preferences} from '@constants';
|
||||
import {DMS_CATEGORY} from '@constants/categories';
|
||||
import {queryChannelsByNames, queryMyChannelSettingsByIds} from '@queries/servers/channel';
|
||||
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
|
||||
import {WithDatabaseArgs} from '@typings/database/database';
|
||||
|
|
@ -114,7 +115,7 @@ const enhance = withObservables(['category'], ({category, locale, database, curr
|
|||
observe().pipe(switchMap(mapPrefName));
|
||||
|
||||
let limit = of$(Preferences.CHANNEL_SIDEBAR_LIMIT_DMS_DEFAULT);
|
||||
if (category.type === 'direct_messages') {
|
||||
if (category.type === DMS_CATEGORY) {
|
||||
limit = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_LIMIT_DMS).observe().pipe(
|
||||
switchMap((val) => {
|
||||
return val[0] ? of$(parseInt(val[0].value, 10)) : of$(Preferences.CHANNEL_SIDEBAR_LIMIT_DMS_DEFAULT);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
lineHeight: 12,
|
||||
marginBottom: 8,
|
||||
marginTop: 2,
|
||||
height: 13,
|
||||
},
|
||||
titleContainer: {
|
||||
alignItems: Platform.select({android: 'flex-start', ios: 'center'}),
|
||||
|
|
|
|||
10
app/constants/categories.ts
Normal file
10
app/constants/categories.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export const CHANNELS_CATEGORY = 'channels';
|
||||
export const DMS_CATEGORY = 'direct_messages';
|
||||
|
||||
export default {
|
||||
CHANNELS_CATEGORY,
|
||||
DMS_CATEGORY,
|
||||
};
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import ActionType from './action_type';
|
||||
import Apps from './apps';
|
||||
import Categories from './categories';
|
||||
import Channel from './channel';
|
||||
import Config from './config';
|
||||
import {CustomStatusDuration} from './custom_status';
|
||||
|
|
@ -31,6 +32,7 @@ import WebsocketEvents from './websocket';
|
|||
export {
|
||||
ActionType,
|
||||
Apps,
|
||||
Categories,
|
||||
Config,
|
||||
CustomStatusDuration,
|
||||
Channel,
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
|||
}
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({
|
||||
raws: channelInfos,
|
||||
raws: channelInfos as ChannelInfo[],
|
||||
key: 'id',
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -109,17 +109,17 @@ export const transformMyChannelSettingsRecord = ({action, database, value}: Tran
|
|||
* @returns {Promise<ChannelInfoModel>}
|
||||
*/
|
||||
export const transformChannelInfoRecord = ({action, database, value}: TransformerArgs): Promise<ChannelInfoModel> => {
|
||||
const raw = value.raw as ChannelInfo;
|
||||
const raw = value.raw as Partial<ChannelInfo>;
|
||||
const record = value.record as ChannelInfoModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (channelInfo: ChannelInfoModel) => {
|
||||
channelInfo._raw.id = isCreateAction ? (raw.id || channelInfo.id) : record.id;
|
||||
channelInfo.guestCount = raw.guest_count;
|
||||
channelInfo.header = raw.header;
|
||||
channelInfo.memberCount = raw.member_count;
|
||||
channelInfo.pinnedPostCount = raw.pinned_post_count;
|
||||
channelInfo.purpose = raw.purpose;
|
||||
channelInfo.guestCount = raw.guest_count ?? channelInfo.guestCount ?? 0;
|
||||
channelInfo.header = raw.header ?? channelInfo.header ?? '';
|
||||
channelInfo.memberCount = raw.member_count ?? channelInfo.memberCount ?? 0;
|
||||
channelInfo.pinnedPostCount = raw.pinned_post_count ?? channelInfo.pinnedPostCount ?? 0;
|
||||
channelInfo.purpose = raw.purpose ?? channelInfo.purpose ?? '';
|
||||
};
|
||||
|
||||
return prepareBaseRecord({
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@
|
|||
import {Database, Model, Q, Query} from '@nozbe/watermelondb';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {makeCategoryChannelId} from '@utils/categories';
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
import type CategoryModel from '@typings/database/models/servers/category';
|
||||
import type CategoryChannelModel from '@typings/database/models/servers/category_channel';
|
||||
|
||||
const {SERVER: {CATEGORY}} = MM_TABLES;
|
||||
|
||||
|
|
@ -31,17 +33,17 @@ export const prepareCategories = (operator: ServerDataOperator, categories: Cate
|
|||
return operator.handleCategories({categories, prepareRecordsOnly: true});
|
||||
};
|
||||
|
||||
export const prepareCategoryChannels = (
|
||||
export async function prepareCategoryChannels(
|
||||
operator: ServerDataOperator,
|
||||
categories: CategoryWithChannels[],
|
||||
) => {
|
||||
): Promise<CategoryChannelModel[]> {
|
||||
try {
|
||||
const categoryChannels: CategoryChannel[] = [];
|
||||
|
||||
categories.forEach((category) => {
|
||||
category.channel_ids.forEach((channelId, index) => {
|
||||
categoryChannels.push({
|
||||
id: `${category.team_id}_${channelId}`,
|
||||
id: makeCategoryChannelId(category.team_id, channelId),
|
||||
category_id: category.id,
|
||||
channel_id: channelId,
|
||||
sort_order: index,
|
||||
|
|
@ -53,21 +55,21 @@ export const prepareCategoryChannels = (
|
|||
return operator.handleCategoryChannels({categoryChannels, prepareRecordsOnly: true});
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return [];
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const prepareDeleteCategory = async (category: CategoryModel): Promise<Model[]> => {
|
||||
const preparedModels: Model[] = [category.prepareDestroyPermanently()];
|
||||
|
||||
const associatedChildren: Array<Query<Model>|undefined> = [
|
||||
const associatedChildren: Array<Query<Model>> = [
|
||||
category.categoryChannels,
|
||||
];
|
||||
await Promise.all(associatedChildren.map(async (children) => {
|
||||
const models = await children?.fetch();
|
||||
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
const models = await children.fetch();
|
||||
models.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
}));
|
||||
|
||||
return preparedModels;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import type UserModel from '@typings/database/models/servers/user';
|
|||
|
||||
const {SERVER: {CHANNEL, MY_CHANNEL, CHANNEL_MEMBERSHIP, MY_CHANNEL_SETTINGS, CHANNEL_INFO, USER}} = MM_TABLES;
|
||||
|
||||
export function prepareMissingChannelsForAllTeams(operator: ServerDataOperator, channels: Channel[], channelMembers: ChannelMembership[]): Array<Promise<Model[]>> | undefined {
|
||||
export function prepareMissingChannelsForAllTeams(operator: ServerDataOperator, channels: Channel[], channelMembers: ChannelMembership[]): Array<Promise<Model[]>> {
|
||||
const channelInfos: ChannelInfo[] = [];
|
||||
const memberships = channelMembers.map((cm) => ({...cm, id: cm.channel_id}));
|
||||
|
||||
|
|
@ -38,19 +38,19 @@ export function prepareMissingChannelsForAllTeams(operator: ServerDataOperator,
|
|||
}
|
||||
|
||||
try {
|
||||
const channelRecords: Promise<Model[]> = operator.handleChannel({channels, prepareRecordsOnly: true});
|
||||
const channelInfoRecords: Promise<Model[]> = operator.handleChannelInfo({channelInfos, prepareRecordsOnly: true});
|
||||
const membershipRecords: Promise<Model[]> = operator.handleChannelMembership({channelMemberships: memberships, prepareRecordsOnly: true});
|
||||
const myChannelRecords: Promise<Model[]> = operator.handleMyChannel({channels, myChannels: memberships, prepareRecordsOnly: true});
|
||||
const myChannelSettingsRecords: Promise<Model[]> = operator.handleMyChannelSettings({settings: memberships, prepareRecordsOnly: true});
|
||||
const channelRecords = operator.handleChannel({channels, prepareRecordsOnly: true});
|
||||
const channelInfoRecords = operator.handleChannelInfo({channelInfos, prepareRecordsOnly: true});
|
||||
const membershipRecords = operator.handleChannelMembership({channelMemberships: memberships, prepareRecordsOnly: true});
|
||||
const myChannelRecords = operator.handleMyChannel({channels, myChannels: memberships, prepareRecordsOnly: true});
|
||||
const myChannelSettingsRecords = operator.handleMyChannelSettings({settings: memberships, prepareRecordsOnly: true});
|
||||
|
||||
return [channelRecords, channelInfoRecords, membershipRecords, myChannelRecords, myChannelSettingsRecords];
|
||||
} catch {
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export const prepareMyChannelsForTeam = async (operator: ServerDataOperator, teamId: string, channels: Channel[], channelMembers: ChannelMembership[]) => {
|
||||
export const prepareMyChannelsForTeam = async (operator: ServerDataOperator, teamId: string, channels: Channel[], channelMembers: ChannelMembership[]): Promise<Array<Promise<Model[]>>> => {
|
||||
const allChannelsForTeam = await queryAllChannelsForTeam(operator.database, teamId).fetch();
|
||||
const channelInfos: ChannelInfo[] = [];
|
||||
const memberships = channelMembers.map((cm) => ({...cm, id: cm.channel_id}));
|
||||
|
|
@ -92,7 +92,7 @@ export const prepareMyChannelsForTeam = async (operator: ServerDataOperator, tea
|
|||
|
||||
return [channelRecords, channelInfoRecords, membershipRecords, myChannelRecords, myChannelSettingsRecords];
|
||||
} catch {
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -292,7 +292,7 @@ export const queryUserChannelsByTypes = (database: Database, userId: string, cha
|
|||
};
|
||||
|
||||
export const queryTeamDefaultChannel = (database: Database, teamId: string) => {
|
||||
return database.get<ChannelModel>(MM_TABLES.SERVER.CHANNEL).query(
|
||||
return database.get<ChannelModel>(CHANNEL).query(
|
||||
Q.where('team_id', teamId),
|
||||
Q.where('name', General.DEFAULT_CHANNEL),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -43,44 +43,25 @@ export const prepareModels = async ({operator, initialTeamId, removeTeams, remov
|
|||
});
|
||||
}
|
||||
|
||||
if (teamData?.teams?.length) {
|
||||
const teamModels = prepareMyTeams(operator, teamData.teams, teamData.memberships || []);
|
||||
if (teamModels) {
|
||||
modelPromises.push(...teamModels);
|
||||
}
|
||||
if (teamData?.teams?.length && teamData.memberships?.length) {
|
||||
modelPromises.push(...prepareMyTeams(operator, teamData.teams, teamData.memberships));
|
||||
}
|
||||
|
||||
if (chData?.categories?.length) {
|
||||
const categoryModels = prepareCategories(operator, chData.categories);
|
||||
if (categoryModels) {
|
||||
modelPromises.push(categoryModels);
|
||||
}
|
||||
|
||||
const categoryChannelModels = prepareCategoryChannels(operator, chData.categories);
|
||||
if (categoryChannelModels) {
|
||||
modelPromises.push(categoryChannelModels);
|
||||
}
|
||||
modelPromises.push(prepareCategories(operator, chData.categories));
|
||||
modelPromises.push(prepareCategoryChannels(operator, chData.categories));
|
||||
}
|
||||
|
||||
if (initialTeamId && chData?.channels?.length) {
|
||||
const channelModels = await prepareMyChannelsForTeam(operator, initialTeamId, chData.channels, chData.memberships || []);
|
||||
if (channelModels) {
|
||||
modelPromises.push(...channelModels);
|
||||
}
|
||||
if (initialTeamId && chData?.channels?.length && chData.memberships?.length) {
|
||||
modelPromises.push(...await prepareMyChannelsForTeam(operator, initialTeamId, chData.channels, chData.memberships));
|
||||
}
|
||||
|
||||
if (prefData?.preferences?.length) {
|
||||
const prefModel = prepareMyPreferences(operator, prefData.preferences, true);
|
||||
if (prefModel) {
|
||||
modelPromises.push(prefModel);
|
||||
}
|
||||
modelPromises.push(prepareMyPreferences(operator, prefData.preferences, true));
|
||||
}
|
||||
|
||||
if (meData?.user) {
|
||||
const userModels = prepareUsers(operator, [meData.user]);
|
||||
if (userModels) {
|
||||
modelPromises.push(userModels);
|
||||
}
|
||||
modelPromises.push(prepareUsers(operator, [meData.user]));
|
||||
}
|
||||
|
||||
return modelPromises;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Database, Model, Q, Query, Relation} from '@nozbe/watermelondb';
|
||||
import {Database, Model, Q, Query} from '@nozbe/watermelondb';
|
||||
import {of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
|
||||
|
|
@ -15,16 +15,12 @@ const {SERVER: {POST, POSTS_IN_CHANNEL, POSTS_IN_THREAD}} = MM_TABLES;
|
|||
|
||||
export const prepareDeletePost = async (post: PostModel): Promise<Model[]> => {
|
||||
const preparedModels: Model[] = [post.prepareDestroyPermanently()];
|
||||
const relations: Array<Relation<Model> | Query<Model>> = [post.drafts, post.postsInThread];
|
||||
const relations: Array<Query<Model>> = [post.drafts, post.postsInThread];
|
||||
for await (const relation of relations) {
|
||||
try {
|
||||
const model = await relation?.fetch();
|
||||
const model = await relation.fetch();
|
||||
if (model) {
|
||||
if (Array.isArray(model)) {
|
||||
model.forEach((m) => preparedModels.push(m.prepareDestroyPermanently()));
|
||||
} else {
|
||||
preparedModels.push(model.prepareDestroyPermanently());
|
||||
}
|
||||
model.forEach((m) => preparedModels.push(m.prepareDestroyPermanently()));
|
||||
}
|
||||
} catch {
|
||||
// Record not found, do nothing
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import type PreferenceModel from '@typings/database/models/servers/preference';
|
|||
|
||||
const {SERVER: {PREFERENCE}} = MM_TABLES;
|
||||
|
||||
export const prepareMyPreferences = (operator: ServerDataOperator, preferences: PreferenceType[], sync = false) => {
|
||||
export async function prepareMyPreferences(operator: ServerDataOperator, preferences: PreferenceType[], sync = false): Promise<PreferenceModel[]> {
|
||||
try {
|
||||
return operator.handlePreferences({
|
||||
prepareRecordsOnly: true,
|
||||
|
|
@ -22,9 +22,9 @@ export const prepareMyPreferences = (operator: ServerDataOperator, preferences:
|
|||
sync,
|
||||
});
|
||||
} catch {
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const queryPreferencesByCategoryAndName = (database: Database, category: string, name?: string, value?: string) => {
|
||||
const clauses = [Q.where('category', category)];
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {of as of$, combineLatest} from 'rxjs';
|
|||
import {switchMap} from 'rxjs/operators';
|
||||
|
||||
import {Database as DatabaseConstants, General, Permissions} from '@constants';
|
||||
import {isDMorGM} from '@utils/channel';
|
||||
import {hasPermission} from '@utils/role';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
|
|
@ -71,8 +72,7 @@ export function observePermissionForPost(post: PostModel, user: UserModel, permi
|
|||
|
||||
export function observeCanManageChannelMembers(post: PostModel, user: UserModel) {
|
||||
return post.channel.observe().pipe((switchMap((c) => {
|
||||
const directTypes: ChannelType[] = [General.DM_CHANNEL, General.GM_CHANNEL];
|
||||
if (!c || c.deleteAt !== 0 || directTypes.includes(c.type) || c.name === General.DEFAULT_CHANNEL) {
|
||||
if (!c || c.deleteAt !== 0 || isDMorGM(c) || c.name === General.DEFAULT_CHANNEL) {
|
||||
return of$(false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -262,8 +262,8 @@ export const patchTeamHistory = (operator: ServerDataOperator, value: string[],
|
|||
prepareRecordsOnly});
|
||||
};
|
||||
|
||||
export const prepareCommonSystemValues = (
|
||||
operator: ServerDataOperator, values: PrepareCommonSystemValuesArgs) => {
|
||||
export async function prepareCommonSystemValues(
|
||||
operator: ServerDataOperator, values: PrepareCommonSystemValuesArgs): Promise<SystemModel[]> {
|
||||
try {
|
||||
const {config, currentChannelId, currentTeamId, currentUserId, license} = values;
|
||||
const systems: IdValue[] = [];
|
||||
|
|
@ -307,9 +307,9 @@ export const prepareCommonSystemValues = (
|
|||
prepareRecordsOnly: true,
|
||||
});
|
||||
} catch {
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const setCurrentChannelId = async (operator: ServerDataOperator, channelId: string) => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ import {patchTeamHistory, getConfig, getTeamHistory, observeCurrentTeamId} from
|
|||
import {getCurrentUser} from './user';
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
import type CategoryModel from '@typings/database/models/servers/category';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
|
||||
|
|
@ -183,7 +181,7 @@ export const getDefaultTeamId = async (database: Database) => {
|
|||
return defaultTeam?.id;
|
||||
};
|
||||
|
||||
export const prepareMyTeams = (operator: ServerDataOperator, teams: Team[], memberships: TeamMembership[]) => {
|
||||
export function prepareMyTeams(operator: ServerDataOperator, teams: Team[], memberships: TeamMembership[]): Array<Promise<Model[]>> {
|
||||
try {
|
||||
const teamRecords = operator.handleTeam({prepareRecordsOnly: true, teams});
|
||||
const teamMemberships = memberships.filter((m) => teams.find((t) => t.id === m.team_id) && m.delete_at === 0);
|
||||
|
|
@ -198,9 +196,9 @@ export const prepareMyTeams = (operator: ServerDataOperator, teams: Team[], memb
|
|||
|
||||
return [teamRecords, teamMembershipRecords, myTeamRecords];
|
||||
} catch {
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const deleteMyTeams = async (operator: ServerDataOperator, myTeams: MyTeamModel[]) => {
|
||||
try {
|
||||
|
|
@ -247,8 +245,8 @@ export const prepareDeleteTeam = async (team: TeamModel): Promise<Model[]> => {
|
|||
}
|
||||
}));
|
||||
|
||||
const categories = await team.categories?.fetch() as CategoryModel[] | undefined;
|
||||
if (categories?.length) {
|
||||
const categories = await team.categories?.fetch();
|
||||
if (categories.length) {
|
||||
for await (const category of categories) {
|
||||
try {
|
||||
const preparedCategory = await prepareDeleteCategory(category);
|
||||
|
|
@ -259,8 +257,8 @@ export const prepareDeleteTeam = async (team: TeamModel): Promise<Model[]> => {
|
|||
}
|
||||
}
|
||||
|
||||
const channels = await team.channels?.fetch() as ChannelModel[] | undefined;
|
||||
if (channels?.length) {
|
||||
const channels = await team.channels?.fetch();
|
||||
if (channels.length) {
|
||||
for await (const channel of channels) {
|
||||
try {
|
||||
const preparedChannel = await prepareDeleteChannel(channel);
|
||||
|
|
|
|||
|
|
@ -58,17 +58,17 @@ export const queryUsersByUsername = (database: Database, usernames: string[]) =>
|
|||
return database.get<UserModel>(USER).query(Q.where('username', Q.oneOf(usernames)));
|
||||
};
|
||||
|
||||
export const prepareUsers = (operator: ServerDataOperator, users: UserProfile[]) => {
|
||||
export async function prepareUsers(operator: ServerDataOperator, users: UserProfile[]): Promise<UserModel[]> {
|
||||
try {
|
||||
if (users.length) {
|
||||
return operator.handleUsers({users, prepareRecordsOnly: true});
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return [];
|
||||
} catch {
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const observeTeammateNameDisplay = (database: Database) => {
|
||||
const config = observeConfig(database);
|
||||
|
|
|
|||
10
app/utils/categories.ts
Normal file
10
app/utils/categories.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export function makeCategoryId(name: string, userId: string, teamId: string) {
|
||||
return `${name}_${userId}_${teamId}`;
|
||||
}
|
||||
|
||||
export function makeCategoryChannelId(teamId: string, channelId: string) {
|
||||
return `${teamId}_${channelId}`;
|
||||
}
|
||||
|
|
@ -23,6 +23,11 @@ export function getDirectChannelName(id: string, otherId: string): string {
|
|||
return handle;
|
||||
}
|
||||
|
||||
export function isDMorGM(channel: Channel | ChannelModel): boolean {
|
||||
const directTypes: string[] = [General.GM_CHANNEL, General.DM_CHANNEL];
|
||||
return directTypes.includes(channel.type);
|
||||
}
|
||||
|
||||
export function selectDefaultChannelForTeam<T extends Channel|ChannelModel>(channels: T[], memberships: ChannelMembership[], teamId: string, roles?: Role[], locale = DEFAULT_LOCALE) {
|
||||
let channel: T|undefined;
|
||||
let canIJoinPublicChannelsInTeam = false;
|
||||
|
|
|
|||
2
types/database/database.d.ts
vendored
2
types/database/database.d.ts
vendored
|
|
@ -204,7 +204,7 @@ export type HandleMyChannelArgs = PrepareOnly & {
|
|||
};
|
||||
|
||||
export type HandleChannelInfoArgs = PrepareOnly &{
|
||||
channelInfos: ChannelInfo[];
|
||||
channelInfos: Array<Partial<ChannelInfo>>;
|
||||
};
|
||||
|
||||
export type HandleMyChannelSettingsArgs = PrepareOnly & {
|
||||
|
|
|
|||
Loading…
Reference in a new issue