[Gekidou] Extract common observers to queries (#5984)

* Extract common observers to queries

* Separate also queries and more agressive refactoring

* Use query to avoid throws from findAndObserve

* Fix minor error

* Address feedback

* Address feedback

* Address feedback

* Fix model types

* Address feedback
This commit is contained in:
Daniel Espino García
2022-03-23 13:19:29 +01:00
committed by GitHub
parent 3e94958ab0
commit 7c642b1e80
179 changed files with 1615 additions and 2011 deletions

View File

@@ -4,7 +4,7 @@
import {Model} from '@nozbe/watermelondb';
import DatabaseManager from '@database/manager';
import {prepareCategories, prepareCategoryChannels, queryCategoriesByTeamIds, queryCategoryById} from '@queries/servers/categories';
import {prepareCategories, prepareCategoryChannels, queryCategoriesByTeamIds, getCategoryById} from '@queries/servers/categories';
import {pluckUnique} from '@utils/helpers';
export const deleteCategory = async (serverUrl: string, categoryId: string) => {
@@ -14,7 +14,7 @@ export const deleteCategory = async (serverUrl: string, categoryId: string) => {
}
try {
const category = await queryCategoryById(database, categoryId);
const category = await getCategoryById(database, categoryId);
if (category) {
await database.write(async () => {
@@ -56,7 +56,7 @@ export const storeCategories = async (serverUrl: string, categories: CategoryWit
// If the passed categories have more than one team, we want to update across teams
const teamIds = pluckUnique('team_id')(categories) as string[];
const localCategories = await queryCategoriesByTeamIds(database, teamIds);
const localCategories = await queryCategoriesByTeamIds(database, teamIds).fetch();
localCategories.
filter((category) => category.type === 'custom').
@@ -92,7 +92,7 @@ export const toggleCollapseCategory = async (serverUrl: string, categoryId: stri
}
try {
const category = await queryCategoryById(database, categoryId);
const category = await getCategoryById(database, categoryId);
if (category) {
await database.write(async () => {

View File

@@ -8,9 +8,9 @@ import {Navigation} from '@constants';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import ServerDataOperator from '@database/operator/server_data_operator';
import {queryMyChannel} from '@queries/servers/channel';
import {queryCommonSystemValues, queryTeamHistory} from '@queries/servers/system';
import {queryChannelHistory} from '@queries/servers/team';
import {getMyChannel} from '@queries/servers/channel';
import {getCommonSystemValues, getTeamHistory} from '@queries/servers/system';
import {getTeamChannelHistory} from '@queries/servers/team';
import {dismissAllModalsAndPopToRoot, dismissAllModalsAndPopToScreen} from '@screens/navigation';
import {switchToChannel} from './channel';
@@ -37,10 +37,10 @@ jest.mock('@utils/helpers', () => {
});
const queryDatabaseValues = async (database: Database, teamId: string, channelId: string) => ({
systemValues: await queryCommonSystemValues(database),
teamHistory: await queryTeamHistory(database),
channelHistory: await queryChannelHistory(database, teamId),
member: await queryMyChannel(database, channelId),
systemValues: await getCommonSystemValues(database),
teamHistory: await getTeamHistory(database),
channelHistory: await getTeamChannelHistory(database, teamId),
member: await getMyChannel(database, channelId),
});
describe('switchToChannel', () => {

View File

@@ -1,18 +1,17 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Model, Q} from '@nozbe/watermelondb';
import {Model} from '@nozbe/watermelondb';
import {DeviceEventEmitter} from 'react-native';
import {General, Navigation as NavigationConstants, Preferences, Screens} from '@constants';
import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
import {prepareDeleteChannel, prepareMyChannelsForTeam, queryAllMyChannelIds, queryChannelsById, queryMyChannel} from '@queries/servers/channel';
import {prepareDeleteChannel, prepareMyChannelsForTeam, queryAllMyChannel, getMyChannel, getChannelById, queryUsersOnChannel} from '@queries/servers/channel';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {prepareCommonSystemValues, PrepareCommonSystemValuesArgs, queryCommonSystemValues, queryCurrentTeamId, setCurrentChannelId} from '@queries/servers/system';
import {addChannelToTeamHistory, addTeamToTeamHistory, queryTeamById, removeChannelFromTeamHistory} from '@queries/servers/team';
import {queryCurrentUser} from '@queries/servers/user';
import {prepareCommonSystemValues, PrepareCommonSystemValuesArgs, getCommonSystemValues, getCurrentTeamId, setCurrentChannelId} from '@queries/servers/system';
import {addChannelToTeamHistory, addTeamToTeamHistory, getTeamById, removeChannelFromTeamHistory} from '@queries/servers/team';
import {getCurrentUser} from '@queries/servers/user';
import {dismissAllModalsAndPopToRoot, dismissAllModalsAndPopToScreen} from '@screens/navigation';
import {isTablet} from '@utils/helpers';
import {displayGroupMessageName, displayUsername, getUserIdFromChannelName} from '@utils/user';
@@ -20,8 +19,6 @@ import {displayGroupMessageName, displayUsername, getUserIdFromChannelName} from
import type ChannelModel from '@typings/database/models/servers/channel';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {CHANNEL_MEMBERSHIP, USER}} = MM_TABLES;
export const switchToChannel = async (serverUrl: string, channelId: string, teamId?: string, prepareRecordsOnly = false) => {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
if (!operator) {
@@ -33,63 +30,65 @@ export const switchToChannel = async (serverUrl: string, channelId: string, team
try {
const dt = Date.now();
const isTabletDevice = await isTablet();
const system = await queryCommonSystemValues(database);
const member = await queryMyChannel(database, channelId);
const system = await getCommonSystemValues(database);
const member = await getMyChannel(database, channelId);
if (member) {
const channel: ChannelModel = await member.channel.fetch();
if (!channel.teamId && teamId) {
const team = await queryTeamById(database, teamId);
if (!team) {
return {error: `team with id ${teamId} not found`};
const channel = await member.channel.fetch();
if (channel) {
if (!channel.teamId && teamId) {
const team = await getTeamById(database, teamId);
if (!team) {
return {error: `team with id ${teamId} not found`};
}
}
}
const toTeamId = channel.teamId || teamId || system.currentTeamId;
const toTeamId = channel.teamId || teamId || system.currentTeamId;
if (isTabletDevice && system.currentChannelId !== channelId) {
// On tablet, the channel is being rendered, by setting the channel to empty first we speed up
// the switch by ~3x
await setCurrentChannelId(operator, '');
}
if (system.currentTeamId !== toTeamId) {
const history = await addTeamToTeamHistory(operator, toTeamId, true);
models.push(...history);
}
if ((system.currentTeamId !== toTeamId) || (system.currentChannelId !== channelId)) {
const commonValues: PrepareCommonSystemValuesArgs = {
currentChannelId: system.currentChannelId === channelId ? undefined : channelId,
currentTeamId: system.currentTeamId === toTeamId ? undefined : toTeamId,
};
const common = await prepareCommonSystemValues(operator, commonValues);
if (common) {
models.push(...common);
if (isTabletDevice && system.currentChannelId !== channelId) {
// On tablet, the channel is being rendered, by setting the channel to empty first we speed up
// the switch by ~3x
await setCurrentChannelId(operator, '');
}
}
if (system.currentChannelId !== channelId || system.currentTeamId !== toTeamId) {
const history = await addChannelToTeamHistory(operator, toTeamId, channelId, true);
models.push(...history);
}
if (system.currentTeamId !== toTeamId) {
const history = await addTeamToTeamHistory(operator, toTeamId, true);
models.push(...history);
}
const {member: viewedAt} = await markChannelAsViewed(serverUrl, channelId, true);
if (viewedAt) {
models.push(viewedAt);
}
if ((system.currentTeamId !== toTeamId) || (system.currentChannelId !== channelId)) {
const commonValues: PrepareCommonSystemValuesArgs = {
currentChannelId: system.currentChannelId === channelId ? undefined : channelId,
currentTeamId: system.currentTeamId === toTeamId ? undefined : toTeamId,
};
const common = await prepareCommonSystemValues(operator, commonValues);
if (common) {
models.push(...common);
}
}
if (models.length && !prepareRecordsOnly) {
await operator.batchRecords(models);
}
if (system.currentChannelId !== channelId || system.currentTeamId !== toTeamId) {
const history = await addChannelToTeamHistory(operator, toTeamId, channelId, true);
models.push(...history);
}
if (isTabletDevice) {
dismissAllModalsAndPopToRoot();
DeviceEventEmitter.emit(NavigationConstants.NAVIGATION_HOME);
} else {
dismissAllModalsAndPopToScreen(Screens.CHANNEL, '', undefined, {topBar: {visible: false}});
}
const {member: viewedAt} = await markChannelAsViewed(serverUrl, channelId, true);
if (viewedAt) {
models.push(viewedAt);
}
console.log('channel switch to', channel?.displayName, channelId, (Date.now() - dt), 'ms'); //eslint-disable-line
if (models.length && !prepareRecordsOnly) {
await operator.batchRecords(models);
}
if (isTabletDevice) {
dismissAllModalsAndPopToRoot();
DeviceEventEmitter.emit(NavigationConstants.NAVIGATION_HOME);
} else {
dismissAllModalsAndPopToScreen(Screens.CHANNEL, '', undefined, {topBar: {visible: false}});
}
console.log('channel switch to', channel?.displayName, channelId, (Date.now() - dt), 'ms'); //eslint-disable-line
}
}
} catch (error) {
return {error};
@@ -107,13 +106,13 @@ export const removeCurrentUserFromChannel = async (serverUrl: string, channelId:
const {operator, database} = serverDatabase;
const models: Model[] = [];
const myChannel = await queryMyChannel(database, channelId);
const myChannel = await getMyChannel(database, channelId);
if (myChannel) {
const channel = await myChannel.channel.fetch() as ChannelModel;
models.push(...await prepareDeleteChannel(channel));
let teamId = channel.teamId;
if (teamId) {
teamId = await queryCurrentTeamId(database);
teamId = await getCurrentTeamId(database);
}
const system = await removeChannelFromTeamHistory(operator, teamId, channel.id, true);
if (system) {
@@ -139,12 +138,11 @@ export const setChannelDeleteAt = async (serverUrl: string, channelId: string, d
const {operator, database} = serverDatabase;
const channels = await queryChannelsById(database, [channelId]);
if (!channels?.length) {
const channel = await getChannelById(database, channelId);
if (!channel) {
return;
}
const channel = channels[0];
const model = channel.prepareUpdate((c) => {
c.deleteAt = deleteAt;
});
@@ -163,7 +161,7 @@ export const selectAllMyChannelIds = async (serverUrl: string) => {
return [];
}
return queryAllMyChannelIds(database);
return queryAllMyChannel(database).fetchIds();
};
export const markChannelAsViewed = async (serverUrl: string, channelId: string, prepareRecordsOnly = false) => {
@@ -172,7 +170,7 @@ export const markChannelAsViewed = async (serverUrl: string, channelId: string,
return {error: `${serverUrl} database not found`};
}
const member = await queryMyChannel(operator.database, channelId);
const member = await getMyChannel(operator.database, channelId);
if (!member) {
return {error: 'not a member'};
}
@@ -202,7 +200,7 @@ export const markChannelAsUnread = async (serverUrl: string, channelId: string,
return {error: `${serverUrl} database not found`};
}
const member = await queryMyChannel(operator.database, channelId);
const member = await getMyChannel(operator.database, channelId);
if (!member) {
return {error: 'not a member'};
}
@@ -233,7 +231,7 @@ export const resetMessageCount = async (serverUrl: string, channelId: string) =>
return {error: `${serverUrl} database not found`};
}
const member = await queryMyChannel(operator.database, channelId);
const member = await getMyChannel(operator.database, channelId);
if (!member) {
return {error: 'not a member'};
}
@@ -287,7 +285,7 @@ export const updateLastPostAt = async (serverUrl: string, channelId: string, las
return {error: `${serverUrl} database not found`};
}
const member = await queryMyChannel(operator.database, channelId);
const member = await getMyChannel(operator.database, channelId);
if (!member) {
return {error: 'not a member'};
}
@@ -316,13 +314,13 @@ export async function updateChannelsDisplayName(serverUrl: string, channels: Cha
}
const {database} = operator;
const currentUser = await queryCurrentUser(database);
const currentUser = await getCurrentUser(database);
if (!currentUser) {
return {};
}
const {config, license} = await queryCommonSystemValues(database);
const preferences = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT);
const {config, license} = await getCommonSystemValues(database);
const preferences = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
const displaySettings = getTeammateNameDisplaySetting(preferences, config, license);
const models: Model[] = [];
for await (const channel of channels) {
@@ -332,7 +330,7 @@ export async function updateChannelsDisplayName(serverUrl: string, channels: Cha
const user = users.find((u) => u.id === otherUserId);
newDisplayName = displayUsername(user, currentUser.locale, displaySettings);
} else {
const dbProfiles = await database.get<UserModel>(USER).query(Q.on(CHANNEL_MEMBERSHIP, Q.where('channel_id', channel.id))).fetch();
const dbProfiles = await queryUsersOnChannel(database, channel.id).fetch();
const profileIds = dbProfiles.map((p) => p.id);
const gmUsers = users.filter((u) => profileIds.includes(u.id));
if (gmUsers.length) {

View File

@@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import DatabaseManager from '@database/manager';
import {queryDraft} from '@queries/servers/drafts';
import {getDraft} from '@queries/servers/drafts';
export const updateDraftFile = async (serverUrl: string, channelId: string, rootId: string, file: FileInfo, prepareRecordsOnly = false) => {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
@@ -10,7 +10,7 @@ export const updateDraftFile = async (serverUrl: string, channelId: string, root
return {error: `${serverUrl} database not found`};
}
const draft = await queryDraft(operator.database, channelId, rootId);
const draft = await getDraft(operator.database, channelId, rootId);
if (!draft) {
return {error: 'no draft'};
}
@@ -44,7 +44,7 @@ export const removeDraftFile = async (serverUrl: string, channelId: string, root
return {error: `${serverUrl} database not found`};
}
const draft = await queryDraft(operator.database, channelId, rootId);
const draft = await getDraft(operator.database, channelId, rootId);
if (!draft) {
return {error: 'no draft'};
}
@@ -79,7 +79,7 @@ export const updateDraftMessage = async (serverUrl: string, channelId: string, r
return {error: `${serverUrl} database not found`};
}
const draft = await queryDraft(operator.database, channelId, rootId);
const draft = await getDraft(operator.database, channelId, rootId);
if (!draft) {
if (!message) {
return {};
@@ -123,7 +123,7 @@ export const addFilesToDraft = async (serverUrl: string, channelId: string, root
return {error: `${serverUrl} database not found`};
}
const draft = await queryDraft(operator.database, channelId, rootId);
const draft = await getDraft(operator.database, channelId, rootId);
if (!draft) {
const newDraft: Draft = {
channel_id: channelId,
@@ -156,7 +156,7 @@ export const removeDraft = async (serverUrl: string, channelId: string, rootId =
return {error: `${serverUrl} database not found`};
}
const draft = await queryDraft(database, channelId, rootId);
const draft = await getDraft(database, channelId, rootId);
if (draft) {
await database.write(async () => {
await draft.destroyPermanently();

View File

@@ -1,11 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
import {queryPostsInChannel} from '@queries/servers/post';
import type PostModel from '@typings/database/models/servers/post';
import {getPostById, queryPostsInChannel} from '@queries/servers/post';
export const updatePostSinceCache = async (serverUrl: string, notification: NotificationWithData) => {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
@@ -16,15 +13,17 @@ export const updatePostSinceCache = async (serverUrl: string, notification: Noti
try {
if (notification.payload?.channel_id) {
const {database} = operator;
const chunks = await queryPostsInChannel(database, notification.payload.channel_id);
const chunks = await queryPostsInChannel(database, notification.payload.channel_id).fetch();
if (chunks.length) {
const recent = chunks[0];
const lastPost = await database.get<PostModel>(MM_TABLES.SERVER.POST).find(notification.payload.post_id);
await operator.database.write(async () => {
await recent.update(() => {
recent.latest = lastPost.createAt;
const lastPost = await getPostById(database, notification.payload.post_id);
if (lastPost) {
await operator.database.write(async () => {
await recent.update(() => {
recent.latest = lastPost.createAt;
});
});
});
}
}
}
return {};

View File

@@ -4,8 +4,8 @@
import {postActionWithCookie} from '@actions/remote/post';
import {ActionType, Post} from '@constants';
import DatabaseManager from '@database/manager';
import {prepareDeletePost, queryPostById} from '@queries/servers/post';
import {queryCurrentUserId} from '@queries/servers/system';
import {getPostById, prepareDeletePost} from '@queries/servers/post';
import {getCurrentUserId} from '@queries/servers/system';
import {generateId} from '@utils/general';
import {getPostIdsForCombinedUserActivityPost} from '@utils/post_list';
@@ -66,7 +66,7 @@ export const sendEphemeralPost = async (serverUrl: string, message: string, chan
let authorId = userId;
if (!authorId) {
authorId = await queryCurrentUserId(operator.database);
authorId = await getCurrentUserId(operator.database);
}
const timestamp = Date.now();
@@ -110,7 +110,7 @@ export const removePost = async (serverUrl: string, post: PostModel | Post) => {
const systemPostIds = getPostIdsForCombinedUserActivityPost(post.id);
const removeModels = [];
for await (const id of systemPostIds) {
const postModel = await queryPostById(operator.database, id);
const postModel = await getPostById(operator.database, id);
if (postModel) {
const preparedPost = await prepareDeletePost(postModel);
removeModels.push(...preparedPost);
@@ -121,7 +121,7 @@ export const removePost = async (serverUrl: string, post: PostModel | Post) => {
await operator.batchRecords(removeModels);
}
} else {
const postModel = await queryPostById(operator.database, post.id);
const postModel = await getPostById(operator.database, post.id);
if (postModel) {
const preparedPost = await prepareDeletePost(postModel);
if (preparedPost.length) {
@@ -143,7 +143,7 @@ export const markPostAsDeleted = async (serverUrl: string, post: Post) => {
return {error: `${serverUrl} database not found`};
}
const dbPost = await queryPostById(operator.database, post.id);
const dbPost = await getPostById(operator.database, post.id);
if (!dbPost) {
return {};
}

View File

@@ -1,11 +1,9 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import {safeParseJSON} from '@utils/helpers';
import type SystemModel from '@typings/database/models/servers/system';
import {getRecentReactions} from '@queries/servers/system';
const MAXIMUM_RECENT_EMOJI = 27;
@@ -14,18 +12,13 @@ export const addRecentReaction = async (serverUrl: string, emojiNames: string[],
if (!operator) {
return {error: `${serverUrl} database not found`};
}
const {database} = operator;
if (!emojiNames.length) {
return [];
}
let recent: string[] = [];
try {
const emojis = await operator.database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).find(SYSTEM_IDENTIFIERS.RECENT_REACTIONS);
recent.push(...(safeParseJSON(emojis.value) as string[] || []));
} catch {
// no previous values.. continue
}
let recent = await getRecentReactions(database);
try {
const recentEmojis = new Set(recent);

View File

@@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import DatabaseManager from '@database/manager';
import {prepareDeleteTeam, queryMyTeamById, removeTeamFromTeamHistory} from '@queries/servers/team';
import {prepareDeleteTeam, getMyTeamById, removeTeamFromTeamHistory} from '@queries/servers/team';
import type TeamModel from '@typings/database/models/servers/team';
@@ -14,7 +14,7 @@ export const removeUserFromTeam = async (serverUrl: string, teamId: string) => {
const {operator, database} = serverDatabase;
const myTeam = await queryMyTeamById(database, teamId);
const myTeam = await getMyTeamById(database, teamId);
if (myTeam) {
const team = await myTeam.team.fetch() as TeamModel;
const models = await prepareDeleteTeam(team);

View File

@@ -4,9 +4,9 @@
import {General, Screens} from '@constants';
import DatabaseManager from '@database/manager';
import {getTranslations, t} from '@i18n';
import {queryChannelById} from '@queries/servers/channel';
import {queryPostById} from '@queries/servers/post';
import {queryCurrentUser} from '@queries/servers/user';
import {getChannelById} from '@queries/servers/channel';
import {getPostById} from '@queries/servers/post';
import {getCurrentUser} from '@queries/servers/user';
import {goToScreen} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {changeOpacity} from '@utils/theme';
@@ -18,16 +18,16 @@ export const switchToThread = async (serverUrl: string, rootId: string) => {
}
try {
const user = await queryCurrentUser(database);
const user = await getCurrentUser(database);
if (!user) {
return {error: 'User not found'};
}
const post = await queryPostById(database, rootId);
const post = await getPostById(database, rootId);
if (!post) {
return {error: 'Post not found'};
}
const channel = await queryChannelById(database, post.channelId);
const channel = await getChannelById(database, post.channelId);
if (!channel) {
return {error: 'Channel not found'};
}

View File

@@ -5,7 +5,7 @@ import {getTimeZone} from 'react-native-localize';
import {updateMe} from '@actions/remote/user';
import DatabaseManager from '@database/manager';
import {queryUserById} from '@queries/servers/user';
import {getUserById} from '@queries/servers/user';
import type UserModel from '@typings/database/models/servers/user';
@@ -23,7 +23,7 @@ export const autoUpdateTimezone = async (serverUrl: string, {deviceTimezone, use
return {error: `No database present for ${serverUrl}`};
}
const currentUser = await queryUserById(database, userId) ?? null;
const currentUser = await getUserById(database, userId);
if (!currentUser) {
return null;

View File

@@ -4,8 +4,8 @@
import {SYSTEM_IDENTIFIERS} from '@constants/database';
import General from '@constants/general';
import DatabaseManager from '@database/manager';
import {queryRecentCustomStatuses} from '@queries/servers/system';
import {queryCurrentUser} from '@queries/servers/user';
import {getRecentCustomStatuses} from '@queries/servers/system';
import {getCurrentUser} from '@queries/servers/user';
import {addRecentReaction} from './reactions';
@@ -20,7 +20,7 @@ export const setCurrentUserStatusOffline = async (serverUrl: string) => {
const {database, operator} = serverDatabase;
const user = await queryCurrentUser(database);
const user = await getCurrentUser(database);
if (!user) {
return {error: `No current user for ${serverUrl}`};
}
@@ -80,8 +80,7 @@ export const updateRecentCustomStatuses = async (serverUrl: string, customStatus
return {error: `${serverUrl} database not found`};
}
const recent = await queryRecentCustomStatuses(operator.database);
const recentStatuses = (recent ? recent.value : []) as UserCustomStatus[];
const recentStatuses = await getRecentCustomStatuses(operator.database);
const index = recentStatuses.findIndex((cs) => (
cs.emoji === customStatus.emoji &&
cs.text === customStatus.text &&
@@ -115,7 +114,7 @@ export const updateLocalUser = async (
}
try {
const user = await queryCurrentUser(database);
const user = await getCurrentUser(database);
if (user) {
await database.write(async () => {
await user.update((userRecord: UserModel) => {

View File

@@ -12,11 +12,11 @@ import DatabaseManager from '@database/manager';
import {privateChannelJoinPrompt} from '@helpers/api/channel';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
import NetworkManager from '@init/network_manager';
import {prepareMyChannelsForTeam, queryChannelById, queryChannelByName, queryMyChannel} from '@queries/servers/channel';
import {prepareMyChannelsForTeam, getChannelById, getChannelByName, getMyChannel} from '@queries/servers/channel';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {queryCommonSystemValues, queryCurrentTeamId, queryCurrentUserId} from '@queries/servers/system';
import {prepareMyTeams, queryNthLastChannelFromTeam, queryMyTeamById, queryTeamById, queryTeamByName} from '@queries/servers/team';
import {queryCurrentUser} from '@queries/servers/user';
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 {getDirectChannelName} from '@utils/channel';
import {PERMALINK_GENERIC_TEAM_NAME_REDIRECT} from '@utils/url';
import {displayGroupMessageName, displayUsername} from '@utils/user';
@@ -121,8 +121,8 @@ export const fetchChannelCreator = async (serverUrl: string, channelId: string,
}
try {
const currentUserId = await queryCurrentUserId(operator.database);
const channel = await queryChannelById(operator.database, channelId);
const currentUserId = await getCurrentUserId(operator.database);
const channel = await getChannelById(operator.database, channelId);
if (channel && channel.creatorId) {
const user = await client.getUser(channel.creatorId);
@@ -170,7 +170,7 @@ export const fetchChannelStats = async (serverUrl: string, channelId: string, fe
try {
const stats = await client.getChannelStats(channelId);
if (!fetchOnly) {
const channel = await queryChannelById(operator.database, channelId);
const channel = await getChannelById(operator.database, channelId);
if (channel) {
const channelInfo = await channel.info.fetch() as ChannelInfoModel;
const channelInfos: ChannelInfo[] = [{
@@ -303,7 +303,7 @@ export const fetchMissingSidebarInfo = async (serverUrl: string, directChannels:
const ownDirectChannel = directChannels.find((dm) => dm.name === getDirectChannelName(currentUserId, currentUserId));
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
if (ownDirectChannel && database) {
const currentUser = await queryCurrentUser(database);
const currentUser = await getCurrentUser(database);
ownDirectChannel.display_name = displayUsername(currentUser, locale, teammateDisplayNameSetting);
}
}
@@ -339,7 +339,8 @@ 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);
if ([General.GM_CHANNEL, General.DM_CHANNEL].includes(channel.type)) {
const directTypes: string[] = [General.GM_CHANNEL, General.DM_CHANNEL];
if (directTypes.includes(channel.type)) {
member = await client.getChannelMember(channel.id, userId);
} else {
member = await client.addToChannel(userId, channel.id);
@@ -402,13 +403,13 @@ export const switchToChannelByName = async (serverUrl: string, channelName: stri
let myTeam: MyTeamModel | TeamMembership | undefined;
let name = teamName;
const roles: string [] = [];
const system = await queryCommonSystemValues(database);
const currentTeam = await queryTeamById(database, system.currentTeamId);
const system = await getCommonSystemValues(database);
const currentTeam = await getTeamById(database, system.currentTeamId);
if (name === PERMALINK_GENERIC_TEAM_NAME_REDIRECT) {
name = currentTeam!.name;
} else {
team = await queryTeamByName(database, teamName);
team = await getTeamByName(database, teamName);
}
if (!team) {
@@ -422,7 +423,7 @@ export const switchToChannelByName = async (serverUrl: string, channelName: stri
}
let joinedNewTeam = false;
myTeam = await queryMyTeamById(database, team.id);
myTeam = await getMyTeamById(database, team.id);
if (!myTeam) {
const added = await addUserToTeam(serverUrl, team.id, system.currentUserId, true);
if (added.error) {
@@ -457,7 +458,7 @@ export const switchToChannelByName = async (serverUrl: string, channelName: stri
return {error: 'Channel is archived'};
}
myChannel = await queryMyChannel(database, channel.id);
myChannel = await getMyChannel(database, channel.id);
if (!myChannel) {
if (channel.type === General.PRIVATE_CHANNEL) {
@@ -564,7 +565,7 @@ export const createDirectChannel = async (serverUrl: string, userId: string, dis
}
try {
const currentUser = await queryCurrentUser(operator.database);
const currentUser = await getCurrentUser(operator.database);
if (!currentUser) {
return {error: 'Cannot get the current user'};
}
@@ -573,8 +574,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);
const system = await queryCommonSystemValues(operator.database);
const preferences = await queryPreferencesByCategoryAndName(operator.database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
const system = await getCommonSystemValues(operator.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;
@@ -638,9 +639,9 @@ export const makeDirectChannel = async (serverUrl: string, userId: string, displ
}
try {
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const channelName = getDirectChannelName(userId, currentUserId);
let channel: Channel|ChannelModel|undefined = await queryChannelByName(operator.database, channelName);
let channel: Channel|ChannelModel|undefined = await getChannelByName(operator.database, channelName);
let result: {data?: Channel|ChannelModel; error?: any};
if (channel) {
result = {data: channel};
@@ -689,7 +690,7 @@ export const createGroupChannel = async (serverUrl: string, userIds: string[]) =
return {error};
}
try {
const currentUser = await queryCurrentUser(operator.database);
const currentUser = await getCurrentUser(operator.database);
if (!currentUser) {
return {error: 'Cannot get the current user'};
}
@@ -701,8 +702,8 @@ export const createGroupChannel = async (serverUrl: string, userIds: string[]) =
return {data: created};
}
const preferences = await queryPreferencesByCategoryAndName(operator.database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT);
const system = await queryCommonSystemValues(operator.database);
const preferences = await queryPreferencesByCategoryAndName(operator.database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
const system = await getCommonSystemValues(operator.database);
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(preferences || [], system.config, system.license);
const {directChannels} = await fetchMissingSidebarInfo(serverUrl, [created], currentUser.locale, teammateDisplayNameSetting, currentUser.id, true);
@@ -764,7 +765,7 @@ export const makeGroupChannel = async (serverUrl: string, userIds: string[], sho
}
try {
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const result = await createGroupChannel(serverUrl, [currentUserId, ...userIds]);
const channel = result.data;
@@ -822,10 +823,10 @@ export async function getOrCreateDirectChannel(serverUrl: string, otherUserId: s
return {error};
}
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const channelName = getDirectChannelName(currentUserId, otherUserId);
const channel = await queryChannelByName(operator.database, channelName);
const channel = await getChannelByName(operator.database, channelName);
let result;
if (channel) {
result = {channel};
@@ -884,8 +885,8 @@ export const switchToPenultimateChannel = async (serverUrl: string) => {
}
try {
const currentTeam = await queryCurrentTeamId(database);
const channelId = await queryNthLastChannelFromTeam(database, currentTeam, 1);
const currentTeam = await getCurrentTeamId(database);
const channelId = await getNthLastChannelFromTeam(database, currentTeam, 1);
return switchToChannelById(serverUrl, channelId);
} catch (error) {
return {error};
@@ -906,7 +907,7 @@ export const searchChannels = async (serverUrl: string, term: string) => {
}
try {
const currentTeamId = await queryCurrentTeamId(database);
const currentTeamId = await getCurrentTeamId(database);
const channels = await client.autocompleteChannels(currentTeamId, term);
return {channels};
} catch (error) {

View File

@@ -10,8 +10,8 @@ import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DeepLinkTypes from '@constants/deep_linking';
import DatabaseManager from '@database/manager';
import NetworkManager from '@init/network_manager';
import {queryChannelsById} from '@queries/servers/channel';
import {queryConfig, queryCurrentTeamId} from '@queries/servers/system';
import {getChannelById} from '@queries/servers/channel';
import {getConfig, getCurrentTeamId} from '@queries/servers/system';
import {queryUsersByUsername} from '@queries/servers/user';
import {showModal} from '@screens/navigation';
import * as DraftUtils from '@utils/draft';
@@ -43,8 +43,8 @@ export const executeCommand = async (serverUrl: string, intl: IntlShape, message
// }
// }
const channel = (await queryChannelsById(operator.database, [channelId]))?.[0];
const teamId = channel?.teamId || (await queryCurrentTeamId(operator.database));
const channel = await getChannelById(operator.database, channelId);
const teamId = channel?.teamId || (await getCurrentTeamId(operator.database));
const args: CommandArgs = {
channel_id: channelId,
@@ -129,8 +129,8 @@ export const handleGotoLocation = async (serverUrl: string, intl: IntlShape, loc
return {error: `${serverUrl} database not found`};
}
const config = await queryConfig(operator.database);
const match = matchDeepLink(location, serverUrl, config.SiteURL);
const config = await getConfig(operator.database);
const match = matchDeepLink(location, serverUrl, config?.SiteURL);
if (match) {
switch (match.type) {
@@ -158,7 +158,7 @@ export const handleGotoLocation = async (serverUrl: string, intl: IntlShape, loc
return {error: `${serverUrl} database not found`};
}
}
const user = (await queryUsersByUsername(serverDatabase, [data.userName]))?.[0];
const user = (await queryUsersByUsername(serverDatabase, [data.userName]).fetch())[0];
if (!user) {
DraftUtils.errorUnkownUser(intl);
return {data: false};

View File

@@ -54,7 +54,7 @@ export const searchCustomEmojis = async (serverUrl: string, term: string) => {
const data = await client.searchCustomEmoji(term);
if (data.length) {
const names = data.map((c) => c.name);
const exist = await queryCustomEmojisByName(operator.database, names);
const exist = await queryCustomEmojisByName(operator.database, names).fetch();
const emojis = data.filter((d) => exist.findIndex((c) => c.name === d.name));
if (emojis.length) {
await operator.handleCustomEmojis({

View File

@@ -5,10 +5,10 @@ import {switchToChannelById} from '@actions/remote/channel';
import {fetchRoles} from '@actions/remote/role';
import {fetchConfigAndLicense} from '@actions/remote/systems';
import DatabaseManager from '@database/manager';
import {queryChannelsById, queryDefaultChannelForTeam} from '@queries/servers/channel';
import {queryChannelsById, getDefaultChannelForTeam} from '@queries/servers/channel';
import {prepareModels} from '@queries/servers/entry';
import {prepareCommonSystemValues, queryCommonSystemValues, queryCurrentChannelId, queryCurrentTeamId, queryWebSocketLastDisconnected, setCurrentTeamAndChannelId} from '@queries/servers/system';
import {queryCurrentUser} from '@queries/servers/user';
import {prepareCommonSystemValues, getCommonSystemValues, getCurrentChannelId, getCurrentTeamId, getWebSocketLastDisconnected, setCurrentTeamAndChannelId} from '@queries/servers/system';
import {getCurrentUser} from '@queries/servers/user';
import {deleteV1Data} from '@utils/file';
import {isTablet} from '@utils/helpers';
@@ -22,8 +22,8 @@ export const appEntry = async (serverUrl: string, since = 0) => {
const {database} = operator;
const tabletDevice = await isTablet();
const currentTeamId = await queryCurrentTeamId(database);
const lastDisconnectedAt = (await queryWebSocketLastDisconnected(database)) || since;
const currentTeamId = await getCurrentTeamId(database);
const lastDisconnectedAt = (await getWebSocketLastDisconnected(database)) || since;
const fetchedData = await fetchAppEntryData(serverUrl, lastDisconnectedAt, currentTeamId);
const fetchedError = (fetchedData as AppEntryError).error;
@@ -35,10 +35,10 @@ export const appEntry = async (serverUrl: string, since = 0) => {
const rolesData = await fetchRoles(serverUrl, teamData?.memberships, chData?.memberships, meData?.user, true);
if (initialTeamId === currentTeamId) {
let cId = await queryCurrentChannelId(database);
let cId = await getCurrentChannelId(database);
if (tabletDevice) {
if (!cId) {
const channel = await queryDefaultChannelForTeam(database, initialTeamId);
const channel = await getDefaultChannelForTeam(database, initialTeamId);
if (channel) {
cId = channel.id;
}
@@ -51,7 +51,7 @@ export const appEntry = async (serverUrl: string, since = 0) => {
// renders the correct team.
let channelId = '';
if (tabletDevice) {
const channel = await queryDefaultChannelForTeam(database, initialTeamId);
const channel = await getDefaultChannelForTeam(database, initialTeamId);
channelId = channel?.id || '';
}
if (channelId) {
@@ -65,7 +65,7 @@ export const appEntry = async (serverUrl: string, since = 0) => {
let removeChannels;
if (removeChannelIds?.length) {
removeChannels = await queryChannelsById(database, removeChannelIds);
removeChannels = await queryChannelsById(database, removeChannelIds).fetch();
}
const modelPromises = await prepareModels({operator, initialTeamId, removeTeams, removeChannels, teamData, chData, prefData, meData});
@@ -77,8 +77,8 @@ export const appEntry = async (serverUrl: string, since = 0) => {
await operator.batchRecords(models.flat());
}
const {id: currentUserId, locale: currentUserLocale} = meData.user || (await queryCurrentUser(database))!;
const {config, license} = await queryCommonSystemValues(database);
const {id: currentUserId, locale: currentUserLocale} = meData.user || (await getCurrentUser(database))!;
const {config, license} = await getCommonSystemValues(database);
deferredAppEntryActions(serverUrl, lastDisconnectedAt, currentUserId, currentUserLocale, prefData.preferences, config, license, teamData, chData, initialTeamId);
if (!since) {

View File

@@ -15,8 +15,8 @@ import {DEFAULT_LOCALE} from '@i18n';
import NetworkManager from '@init/network_manager';
import {queryAllServers} from '@queries/app/servers';
import {queryAllChannelsForTeam} from '@queries/servers/channel';
import {queryConfig} from '@queries/servers/system';
import {deleteMyTeams, queryAvailableTeamIds, queryMyTeams, queryMyTeamsById, queryTeamsById} from '@queries/servers/team';
import {getConfig} from '@queries/servers/system';
import {deleteMyTeams, getAvailableTeamIds, queryMyTeams, queryMyTeamsByIds, queryTeamsById} from '@queries/servers/team';
import type ClientError from '@client/rest/error';
@@ -43,11 +43,11 @@ export const teamsToRemove = async (serverUrl: string, removeTeamIds?: string[])
const {database} = operator;
if (removeTeamIds?.length) {
// Immediately delete myTeams so that the UI renders only teams the user is a member of.
const removeMyTeams = await queryMyTeamsById(database, removeTeamIds);
const removeMyTeams = await queryMyTeamsByIds(database, removeTeamIds).fetch();
if (removeMyTeams?.length) {
await deleteMyTeams(operator, removeMyTeams);
const ids = removeMyTeams.map((m) => m.id);
const removeTeams = await queryTeamsById(database, ids);
const removeTeams = await queryTeamsById(database, ids).fetch();
return removeTeams;
}
}
@@ -81,11 +81,11 @@ export const fetchAppEntryData = async (serverUrl: string, since: number, initia
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 queryConfig(database);
const config = await getConfig(database);
const teamOrderPreference = getPreferenceValue(prefData.preferences || [], Preferences.TEAMS_ORDER, '', '') as string;
const teamMembers = teamData.memberships.filter((m) => m.delete_at === 0).map((m) => m.team_id);
const myTeams = teamData.teams!.filter((t) => teamMembers?.includes(t.id));
const defaultTeam = selectDefaultTeam(myTeams, meData.user?.locale || DEFAULT_LOCALE, teamOrderPreference, config.ExperimentalPrimaryTeam);
const defaultTeam = selectDefaultTeam(myTeams, meData.user?.locale || DEFAULT_LOCALE, teamOrderPreference, config?.ExperimentalPrimaryTeam);
if (defaultTeam?.id) {
chData = await fetchMyChannelsForTeam(serverUrl, defaultTeam.id, includeDeletedChannels, since, fetchOnly);
}
@@ -107,8 +107,8 @@ export const fetchAppEntryData = async (serverUrl: string, since: number, initia
if (teamData.teams?.length === 0 && !teamData.error) {
// User is no longer a member of any team
const myTeams = await queryMyTeams(database);
removeTeamIds.push(...(myTeams?.map((myTeam) => myTeam.id) || []));
const myTeams = await queryMyTeams(database).fetch();
removeTeamIds.push(...(myTeams.map((myTeam) => myTeam.id) || []));
return {
...data,
@@ -125,7 +125,7 @@ export const fetchAppEntryData = async (serverUrl: string, since: number, initia
removeTeamIds.push(initialTeamId);
}
const availableTeamIds = await queryAvailableTeamIds(database, initialTeamId, teamData.teams, prefData.preferences, meData.user?.locale);
const availableTeamIds = await getAvailableTeamIds(database, initialTeamId, teamData.teams, prefData.preferences, meData.user?.locale);
const alternateTeamData = await fetchAlternateTeamData(serverUrl, availableTeamIds, removeTeamIds, includeDeletedChannels, since, fetchOnly);
data = {
@@ -138,7 +138,7 @@ export const fetchAppEntryData = async (serverUrl: string, since: number, initia
const removeChannelIds: string[] = [];
const fetchedChannelIds = data.chData.channels.map((channel) => channel.id);
const channels = await queryAllChannelsForTeam(database, initialTeamId);
const channels = await queryAllChannelsForTeam(database, initialTeamId).fetch();
for (const channel of channels) {
if (!fetchedChannelIds.includes(channel.id)) {
removeChannelIds.push(channel.id);

View File

@@ -8,11 +8,11 @@ import {markChannelAsRead} from '@actions/remote/channel';
import {fetchRoles} from '@actions/remote/role';
import {Screens} from '@constants';
import DatabaseManager from '@database/manager';
import {queryChannelsById, queryDefaultChannelForTeam, queryMyChannel} from '@queries/servers/channel';
import {queryChannelsById, getDefaultChannelForTeam, getMyChannel} from '@queries/servers/channel';
import {prepareModels} from '@queries/servers/entry';
import {queryCommonSystemValues, queryCurrentTeamId, queryWebSocketLastDisconnected, setCurrentTeamAndChannelId} from '@queries/servers/system';
import {queryMyTeamById} from '@queries/servers/team';
import {queryCurrentUser} from '@queries/servers/user';
import {getCommonSystemValues, getCurrentTeamId, getWebSocketLastDisconnected, setCurrentTeamAndChannelId} from '@queries/servers/system';
import {getMyTeamById} from '@queries/servers/team';
import {getCurrentUser} from '@queries/servers/user';
import EphemeralStore from '@store/ephemeral_store';
import {isTablet} from '@utils/helpers';
import {emitNotificationError} from '@utils/notification';
@@ -29,8 +29,8 @@ export const pushNotificationEntry = async (serverUrl: string, notification: Not
const channelId = notification.payload!.channel_id!;
const isTabletDevice = await isTablet();
const {database} = operator;
const currentTeamId = await queryCurrentTeamId(database);
const lastDisconnectedAt = await queryWebSocketLastDisconnected(database);
const currentTeamId = await getCurrentTeamId(database);
const lastDisconnectedAt = await getWebSocketLastDisconnected(database);
const currentServerUrl = await DatabaseManager.getActiveServerUrl();
let isDirectChannel = false;
@@ -46,8 +46,8 @@ export const pushNotificationEntry = async (serverUrl: string, notification: Not
}
// To make the switch faster we determine if we already have the team & channel
const myChannel = await queryMyChannel(database, channelId);
const myTeam = await queryMyTeamById(database, teamId);
const myChannel = await getMyChannel(database, channelId);
const myTeam = await getMyTeamById(database, teamId);
let switchedToTeamAndChanel = false;
if (myChannel && myTeam) {
switchedToTeamAndChanel = true;
@@ -79,7 +79,7 @@ export const pushNotificationEntry = async (serverUrl: string, notification: Not
selectedTeamId = initialTeamId;
if (!isDirectChannel) {
if (isTabletDevice) {
const channel = await queryDefaultChannelForTeam(operator.database, selectedTeamId);
const channel = await getDefaultChannelForTeam(operator.database, selectedTeamId);
selectedChannelId = channel?.id || '';
} else {
selectedChannelId = '';
@@ -93,7 +93,7 @@ export const pushNotificationEntry = async (serverUrl: string, notification: Not
// renders the correct channel.
if (isTabletDevice) {
const channel = await queryDefaultChannelForTeam(operator.database, selectedTeamId);
const channel = await getDefaultChannelForTeam(operator.database, selectedTeamId);
selectedChannelId = channel?.id || '';
} else {
selectedChannelId = '';
@@ -121,7 +121,7 @@ export const pushNotificationEntry = async (serverUrl: string, notification: Not
let removeChannels;
if (removeChannelIds?.length) {
removeChannels = await queryChannelsById(operator.database, removeChannelIds);
removeChannels = await queryChannelsById(operator.database, removeChannelIds).fetch();
}
const modelPromises = await prepareModels({operator, initialTeamId, removeTeams, removeChannels, teamData, chData, prefData, meData});
@@ -134,8 +134,8 @@ export const pushNotificationEntry = async (serverUrl: string, notification: Not
await operator.batchRecords(models.flat() as Model[]);
}
const {id: currentUserId, locale: currentUserLocale} = meData.user || (await queryCurrentUser(operator.database))!;
const {config, license} = await queryCommonSystemValues(operator.database);
const {id: currentUserId, locale: currentUserLocale} = meData.user || (await getCurrentUser(operator.database))!;
const {config, license} = await getCommonSystemValues(operator.database);
deferredAppEntryActions(serverUrl, lastDisconnectedAt, currentUserId, currentUserLocale, prefData.preferences, config, license, teamData, chData, selectedTeamId, selectedChannelId);
syncOtherServers(serverUrl);

View File

@@ -5,7 +5,7 @@ import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import {t} from '@i18n';
import NetworkManager from '@init/network_manager';
import {queryExpandedLinks} from '@queries/servers/system';
import {getExpandedLinks} from '@queries/servers/system';
import {forceLogoutIfNecessary} from './session';
@@ -69,7 +69,7 @@ export const getRedirectLocation = async (serverUrl: string, link: string) => {
try {
const expandedLink = await client.getRedirectLocation(link);
if (expandedLink?.location) {
const storedLinks = await queryExpandedLinks(operator.database);
const storedLinks = await getExpandedLinks(operator.database);
storedLinks[link] = expandedLink.location;
const expanded: IdValue = {
id: SYSTEM_IDENTIFIERS.EXPANDED_LINKS,

View File

@@ -10,11 +10,11 @@ import {fetchMyTeam} from '@actions/remote/team';
import {Preferences} from '@constants';
import DatabaseManager from '@database/manager';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
import {queryChannelsById, queryMyChannel} from '@queries/servers/channel';
import {getMyChannel, getChannelById} from '@queries/servers/channel';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {queryCommonSystemValues, queryWebSocketLastDisconnected} from '@queries/servers/system';
import {queryMyTeamById} from '@queries/servers/team';
import {queryCurrentUser} from '@queries/servers/user';
import {getCommonSystemValues, getWebSocketLastDisconnected} from '@queries/servers/system';
import {getMyTeamById} from '@queries/servers/team';
import {getCurrentUser} from '@queries/servers/user';
import {emitNotificationError} from '@utils/notification';
const fetchNotificationData = async (serverUrl: string, notification: NotificationWithData, skipEvents = false) => {
@@ -31,7 +31,7 @@ const fetchNotificationData = async (serverUrl: string, notification: Notificati
}
const {database} = operator;
const system = await queryCommonSystemValues(database);
const system = await getCommonSystemValues(database);
let teamId = notification.payload?.team_id;
let isDirectChannel = false;
@@ -42,8 +42,8 @@ const fetchNotificationData = async (serverUrl: string, notification: Notificati
}
// To make the switch faster we determine if we already have the team & channel
const myChannel = await queryMyChannel(database, channelId);
const myTeam = await queryMyTeamById(database, teamId);
const myChannel = await getMyChannel(database, channelId);
const myTeam = await getMyTeamById(database, teamId);
if (!myTeam) {
const teamsReq = await fetchMyTeam(serverUrl, teamId, false);
@@ -68,12 +68,12 @@ const fetchNotificationData = async (serverUrl: string, notification: Notificati
}
if (isDirectChannel) {
const preferences = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT);
const currentUser = await queryCurrentUser(database);
const preferences = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
const currentUser = await getCurrentUser(database);
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(preferences || [], system.config, system.license);
const channel = await queryChannelsById(database, [channelId]);
if (channel?.length) {
fetchMissingSidebarInfo(serverUrl, [channel[0].toApi()], currentUser?.locale, teammateDisplayNameSetting, currentUser?.id);
const channel = await getChannelById(database, channelId);
if (channel) {
fetchMissingSidebarInfo(serverUrl, [channel.toApi()], currentUser?.locale, teammateDisplayNameSetting, currentUser?.id);
}
}
}
@@ -91,7 +91,7 @@ export const backgroundNotification = async (serverUrl: string, notification: No
return;
}
const lastDisconnectedAt = await queryWebSocketLastDisconnected(database);
const lastDisconnectedAt = await getWebSocketLastDisconnected(database);
if (lastDisconnectedAt) {
if (Platform.OS === 'ios') {
@@ -113,7 +113,7 @@ export const openNotification = async (serverUrl: string, notification: Notifica
await markChannelAsRead(serverUrl, channelId);
const {database} = operator;
const system = await queryCommonSystemValues(database);
const system = await getCommonSystemValues(database);
const currentServerUrl = await DatabaseManager.getActiveServerUrl();
let teamId = notification.payload?.team_id;
@@ -127,8 +127,8 @@ export const openNotification = async (serverUrl: string, notification: Notifica
}
// To make the switch faster we determine if we already have the team & channel
const myChannel = await queryMyChannel(database, channelId);
const myTeam = await queryMyTeamById(database, teamId);
const myChannel = await getMyChannel(database, channelId);
const myTeam = await getMyTeamById(database, teamId);
if (myChannel && myTeam) {
switchToChannelById(serverUrl, channelId, teamId);

View File

@@ -3,8 +3,8 @@
import {fetchMyChannelsForTeam} from '@actions/remote/channel';
import DatabaseManager from '@database/manager';
import {queryCommonSystemValues} from '@queries/servers/system';
import {queryTeamById, queryTeamByName} from '@queries/servers/team';
import {getCommonSystemValues} from '@queries/servers/system';
import {getTeamById, getTeamByName} from '@queries/servers/team';
import {permalinkBadTeam} from '@utils/draft';
import {displayPermalink} from '@utils/permalink';
import {PERMALINK_GENERIC_TEAM_NAME_REDIRECT} from '@utils/url';
@@ -21,16 +21,16 @@ export const showPermalink = async (serverUrl: string, teamName: string, postId:
try {
let name = teamName;
let team: TeamModel | undefined;
const system = await queryCommonSystemValues(database);
const system = await getCommonSystemValues(database);
if (!name || name === PERMALINK_GENERIC_TEAM_NAME_REDIRECT) {
team = await queryTeamById(database, system.currentTeamId);
team = await getTeamById(database, system.currentTeamId);
if (team) {
name = team.name;
}
}
if (!team) {
team = await queryTeamByName(database, name);
team = await getTeamByName(database, name);
if (!team) {
permalinkBadTeam(intl);
return {error: 'Bad Permalink team'};

View File

@@ -16,10 +16,10 @@ import {filterPostsInOrderedArray} from '@helpers/api/post';
import {getNeededAtMentionedUsernames} from '@helpers/api/user';
import {extractRecordsForTable} from '@helpers/database';
import NetworkManager from '@init/network_manager';
import {prepareMissingChannelsForAllTeams, queryAllMyChannelIds} from '@queries/servers/channel';
import {prepareMissingChannelsForAllTeams, queryAllMyChannel} from '@queries/servers/channel';
import {queryAllCustomEmojis} from '@queries/servers/custom_emoji';
import {queryPostById, queryRecentPostsInChannel} from '@queries/servers/post';
import {queryCurrentUserId, queryCurrentChannelId} from '@queries/servers/system';
import {getPostById, getRecentPostsInChannel} from '@queries/servers/post';
import {getCurrentUserId, getCurrentChannelId} from '@queries/servers/system';
import {queryAllUsers} from '@queries/servers/user';
import {getValidEmojis, matchEmoticons} from '@utils/emoji/helpers';
import {getPostIdsForCombinedUserActivityPost} from '@utils/post_list';
@@ -62,11 +62,11 @@ export const createPost = async (serverUrl: string, post: Partial<Post>, files:
return {error};
}
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const timestamp = Date.now();
const pendingPostId = post.pending_post_id || `${currentUserId}:${timestamp}`;
const existing = await queryPostById(operator.database, pendingPostId);
const existing = await getPostById(operator.database, pendingPostId);
if (existing && !existing.props.failed) {
return {data: false};
}
@@ -111,7 +111,7 @@ export const createPost = async (serverUrl: string, post: Partial<Post>, files:
initialPostModels.push(...postModels);
}
const customEmojis = await queryAllCustomEmojis(operator.database);
const customEmojis = await queryAllCustomEmojis(operator.database).fetch();
const emojisInMessage = matchEmoticons(newPost.message);
const reactionModels = await addRecentReaction(serverUrl, getValidEmojis(emojisInMessage, customEmojis), true);
if (!('error' in reactionModels) && reactionModels.length) {
@@ -164,7 +164,7 @@ export const fetchPostsForCurrentChannel = async (serverUrl: string) => {
return {error: `${serverUrl} database not found`};
}
const currentChannelId = await queryCurrentChannelId(database);
const currentChannelId = await getCurrentChannelId(database);
return fetchPostsForChannel(serverUrl, currentChannelId);
};
@@ -176,7 +176,7 @@ export const fetchPostsForChannel = async (serverUrl: string, channelId: string,
let postAction: Promise<PostsRequest>|undefined;
let actionType: string|undefined;
const postsInChannel = await queryRecentPostsInChannel(operator.database, channelId);
const postsInChannel = await getRecentPostsInChannel(operator.database, channelId);
if (!postsInChannel || postsInChannel.length < General.POST_CHUNK_SIZE) {
postAction = fetchPosts(serverUrl, channelId, 0, General.POST_CHUNK_SIZE, true);
actionType = ActionType.POSTS.RECEIVED_IN_CHANNEL;
@@ -364,8 +364,8 @@ export const fetchPostAuthors = async (serverUrl: string, posts: Post[], fetchOn
return {error};
}
const currentUserId = await queryCurrentUserId(operator.database);
const users = await queryAllUsers(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const users = await queryAllUsers(operator.database).fetch();
const existingUserIds = new Set<string>();
const existingUserNames = new Set<string>();
let excludeUsername;
@@ -552,7 +552,7 @@ export async function fetchMissingChannelsFromPosts(serverUrl: string, posts: Po
}
try {
const channelIds = await queryAllMyChannelIds(operator.database);
const channelIds = await queryAllMyChannel(operator.database).fetchIds();
const channelPromises: Array<Promise<Channel>> = [];
const userPromises: Array<Promise<ChannelMembership>> = [];
@@ -654,7 +654,7 @@ export const togglePinPost = async (serverUrl: string, postId: string) => {
}
try {
const post = await queryPostById(database, postId);
const post = await getPostById(database, postId);
if (post) {
const isPinned = post.isPinned;
const request = isPinned ? client.unpinPost : client.pinPost;
@@ -716,7 +716,7 @@ export const markPostAsUnread = async (serverUrl: string, postId: string) => {
}
try {
const [userId, post] = await Promise.all([queryCurrentUserId(database), queryPostById(database, postId)]);
const [userId, post] = await Promise.all([getCurrentUserId(database), getPostById(database, postId)]);
if (post && userId) {
await client.markPostAsUnread(userId, postId);
const {channelId} = post;
@@ -756,7 +756,7 @@ export const editPost = async (serverUrl: string, postId: string, postMessage: s
}
try {
const post = await queryPostById(database, postId);
const post = await getPostById(database, postId);
if (post) {
const {update_at, edit_at, message: updatedMessage} = await client.patchPost({message: postMessage, id: postId});
await database.write(async () => {
@@ -789,7 +789,7 @@ export async function fetchSavedPosts(serverUrl: string, teamId?: string, channe
}
try {
const userId = await queryCurrentUserId(operator.database);
const userId = await getCurrentUserId(operator.database);
const data = await client.getSavedPosts(userId, channelId, teamId, page, perPage);
const posts = data.posts || {};
const order = data.order || [];

View File

@@ -5,7 +5,7 @@ import {Preferences} from '@constants';
import DatabaseManager from '@database/manager';
import NetworkManager from '@init/network_manager';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {queryCurrentUserId} from '@queries/servers/system';
import {getCurrentUserId} from '@queries/servers/system';
import {forceLogoutIfNecessary} from './session';
@@ -53,7 +53,7 @@ export const saveFavoriteChannel = async (serverUrl: string, channelId: string,
try {
// Todo: @shaz I think you'll need to add the category handler here so that the channel is added/removed from the favorites category
const userId = await queryCurrentUserId(operator.database);
const userId = await getCurrentUserId(operator.database);
const favPref: PreferenceType = {
category: CATEGORY_FAVORITE_CHANNEL,
name: channelId,
@@ -73,7 +73,7 @@ export const savePostPreference = async (serverUrl: string, postId: string) => {
}
try {
const userId = await queryCurrentUserId(operator.database);
const userId = await getCurrentUserId(operator.database);
const pref: PreferenceType = {
user_id: userId,
category: CATEGORY_SAVED_POST,
@@ -100,7 +100,7 @@ export const savePreference = async (serverUrl: string, preferences: PreferenceT
}
try {
const userId = await queryCurrentUserId(operator.database);
const userId = await getCurrentUserId(operator.database);
client.savePreferences(userId, preferences);
await operator.handlePreferences({
preferences,
@@ -126,8 +126,8 @@ export const deleteSavedPost = async (serverUrl: string, postId: string) => {
return {error};
}
try {
const userId = await queryCurrentUserId(operator.database);
const records = await queryPreferencesByCategoryAndName(operator.database, CATEGORY_SAVED_POST, postId);
const userId = await getCurrentUserId(operator.database);
const records = await queryPreferencesByCategoryAndName(operator.database, CATEGORY_SAVED_POST, postId).fetch();
const postPreferenceRecord = records.find((r) => postId === r.name);
const pref = {
user_id: userId,

View File

@@ -1,14 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Model, Q} from '@nozbe/watermelondb';
import {Model} from '@nozbe/watermelondb';
import {addRecentReaction} from '@actions/local/reactions';
import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
import NetworkManager from '@init/network_manager';
import {queryRecentPostsInChannel, queryRecentPostsInThread} from '@queries/servers/post';
import {queryCurrentChannelId, queryCurrentUserId} from '@queries/servers/system';
import {getRecentPostsInChannel, getRecentPostsInThread} from '@queries/servers/post';
import {queryReaction} from '@queries/servers/reactions';
import {getCurrentChannelId, getCurrentUserId} from '@queries/servers/system';
import {forceLogoutIfNecessary} from './session';
@@ -29,7 +29,7 @@ export const addReaction = async (serverUrl: string, postId: string, emojiName:
}
try {
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const reaction = await client.addReaction(currentUserId, postId, emojiName);
const models: Model[] = [];
@@ -73,15 +73,11 @@ export const removeReaction = async (serverUrl: string, postId: string, emojiNam
}
try {
const currentUserId = await queryCurrentUserId(database);
const currentUserId = await getCurrentUserId(database);
await client.removeReaction(currentUserId, postId, emojiName);
// should return one or no reaction
const reaction = await database.get(MM_TABLES.SERVER.REACTION).query(
Q.where('emoji_name', emojiName),
Q.where('post_id', postId),
Q.where('user_id', currentUserId),
).fetch();
const reaction = await queryReaction(database, emojiName, postId, currentUserId).fetch();
if (reaction.length) {
await database.write(async () => {
@@ -105,10 +101,10 @@ export const handleReactionToLatestPost = async (serverUrl: string, emojiName: s
try {
let posts: PostModel[];
if (rootId) {
posts = await queryRecentPostsInThread(operator.database, rootId);
posts = await getRecentPostsInThread(operator.database, rootId);
} else {
const channelId = await queryCurrentChannelId(operator.database);
posts = await queryRecentPostsInChannel(operator.database, channelId);
const channelId = await getCurrentChannelId(operator.database);
posts = await getRecentPostsInChannel(operator.database, channelId);
}
if (add) {

View File

@@ -8,9 +8,9 @@ import {selectDefaultTeam} from '@helpers/api/team';
import NetworkManager from '@init/network_manager';
import {prepareMyChannelsForTeam} from '@queries/servers/channel';
import {prepareMyPreferences, queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {prepareCommonSystemValues, queryCommonSystemValues} from '@queries/servers/system';
import {prepareCommonSystemValues, getCommonSystemValues} from '@queries/servers/system';
import {prepareMyTeams} from '@queries/servers/team';
import {queryCurrentUser} from '@queries/servers/user';
import {getCurrentUser} from '@queries/servers/user';
import {selectDefaultChannelForTeam} from '@utils/channel';
import {fetchMissingSidebarInfo, fetchMyChannelsForTeam, MyChannelsRequest} from './channel';
@@ -38,7 +38,7 @@ export const retryInitialTeamAndChannel = async (serverUrl: string) => {
let initialTeam: Team|undefined;
let initialChannel: Channel|undefined;
const user = await queryCurrentUser(database);
const user = await getCurrentUser(database);
if (!user) {
return {error: true};
}
@@ -161,19 +161,19 @@ export const retryInitialChannel = async (serverUrl: string, teamId: string) =>
let initialChannel: Channel|undefined;
const rolesToFetch = new Set<string>();
const user = await queryCurrentUser(database);
const user = await getCurrentUser(database);
if (!user) {
return {error: true};
}
const prefs = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT);
const prefs = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
const preferences: PreferenceType[] = prefs.map((p) => ({
category: p.category,
name: p.name,
user_id: p.userId,
value: p.value,
}));
const {config, license} = await queryCommonSystemValues(database);
const {config, license} = await getCommonSystemValues(database);
// fetch channels / channel membership for initial team
const chData = await fetchMyChannelsForTeam(serverUrl, teamId, false, 0, true);

View File

@@ -26,7 +26,7 @@ export const fetchRolesIfNeeded = async (serverUrl: string, updatedRoles: string
const database = DatabaseManager.serverDatabases[serverUrl].database;
const operator = DatabaseManager.serverDatabases[serverUrl].operator;
const existingRoles = await queryRoles(database);
const existingRoles = await queryRoles(database).fetch();
const roleNames = existingRoles.map((role) => {
return role.name;

View File

@@ -6,7 +6,7 @@ import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import NetworkManager from '@init/network_manager';
import {prepareMissingChannelsForAllTeams} from '@queries/servers/channel';
import {queryCurrentUser} from '@queries/servers/user';
import {getCurrentUser} from '@queries/servers/user';
import {fetchPostAuthors, fetchMissingChannelsFromPosts} from './post';
import {forceLogoutIfNecessary} from './session';
@@ -39,7 +39,7 @@ export async function fetchRecentMentions(serverUrl: string): Promise<PostSearch
let order: string[] = [];
try {
const currentUser = await queryCurrentUser(operator.database);
const currentUser = await getCurrentUser(operator.database);
if (!currentUser) {
return {
posts: [],

View File

@@ -11,7 +11,7 @@ import {getServerCredentials} from '@init/credentials';
import NetworkManager from '@init/network_manager';
import WebsocketManager from '@init/websocket_manager';
import {queryDeviceToken} from '@queries/app/global';
import {queryCurrentUserId, queryCommonSystemValues} from '@queries/servers/system';
import {getCurrentUserId, getCommonSystemValues} from '@queries/servers/system';
import {getCSRFFromCookie} from '@utils/security';
import {loginEntry} from './entry';
@@ -30,7 +30,7 @@ export const completeLogin = async (serverUrl: string, user: UserProfile) => {
}
const {database} = operator;
const {config, license}: { config: Partial<ClientConfig>; license: Partial<ClientLicense> } = await queryCommonSystemValues(database);
const {config, license}: { config: Partial<ClientConfig>; license: Partial<ClientLicense> } = await getCommonSystemValues(database);
if (!Object.keys(config)?.length || !Object.keys(license)?.length) {
return null;
@@ -68,7 +68,7 @@ export const forceLogoutIfNecessary = async (serverUrl: string, err: ClientError
return {error: `${serverUrl} database not found`};
}
const currentUserId = await queryCurrentUserId(database);
const currentUserId = await getCurrentUserId(database);
if ('status_code' in err && err.status_code === HTTP_UNAUTHORIZED && err?.url?.indexOf('/login') === -1 && currentUserId) {
await logout(serverUrl);

View File

@@ -9,7 +9,7 @@ import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import {getServerCredentials} from '@init/credentials';
import NetworkManager from '@init/network_manager';
import {queryCommonSystemValues} from '@queries/servers/system';
import {getCommonSystemValues} from '@queries/servers/system';
import type ClientError from '@client/rest/error';
@@ -73,7 +73,7 @@ export const fetchConfigAndLicense = async (serverUrl: string, fetchOnly = false
const credentials = await getServerCredentials(serverUrl);
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
if (credentials && operator) {
const current = await queryCommonSystemValues(operator.database);
const current = await getCommonSystemValues(operator.database);
const systems: IdValue[] = [];
if (!deepEqual(config, current.config)) {
systems.push({

View File

@@ -8,9 +8,9 @@ import {removeUserFromTeam as localRemoveUserFromTeam} from '@actions/local/team
import {Events} from '@constants';
import DatabaseManager from '@database/manager';
import NetworkManager from '@init/network_manager';
import {prepareMyChannelsForTeam, queryDefaultChannelForTeam} from '@queries/servers/channel';
import {prepareCommonSystemValues, queryCurrentTeamId, queryWebSocketLastDisconnected} from '@queries/servers/system';
import {addTeamToTeamHistory, prepareDeleteTeam, prepareMyTeams, queryNthLastChannelFromTeam, queryTeamsById, syncTeamTable} from '@queries/servers/team';
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';
import {isTablet} from '@utils/helpers';
import {fetchMyChannelsForTeam, switchToChannelById} from './channel';
@@ -61,7 +61,7 @@ export const addUserToTeam = async (serverUrl: string, teamId: string, userId: s
}
if (await isTablet()) {
const channel = await queryDefaultChannelForTeam(operator.database, teamId);
const channel = await getDefaultChannelForTeam(operator.database, teamId);
if (channel) {
fetchPostsForChannel(serverUrl, channel.id);
}
@@ -104,8 +104,8 @@ export const fetchMyTeams = async (serverUrl: string, fetchOnly = false): Promis
if (removeTeamIds.length) {
if (removeTeamIds?.length) {
// Immediately delete myTeams so that the UI renders only teams the user is a member of.
const removeTeams = await queryTeamsById(operator.database, removeTeamIds);
removeTeams?.forEach((team) => {
const removeTeams = await queryTeamsById(operator.database, removeTeamIds).fetch();
removeTeams.forEach((team) => {
modelPromises.push(prepareDeleteTeam(team));
});
}
@@ -268,7 +268,7 @@ export const handleTeamChange = async (serverUrl: string, teamId: string) => {
}
const {database} = operator;
const currentTeamId = await queryCurrentTeamId(database);
const currentTeamId = await getCurrentTeamId(database);
if (currentTeamId === teamId) {
return;
@@ -276,7 +276,7 @@ export const handleTeamChange = async (serverUrl: string, teamId: string) => {
let channelId = '';
if (await isTablet()) {
channelId = await queryNthLastChannelFromTeam(database, teamId);
channelId = await getNthLastChannelFromTeam(database, teamId);
if (channelId) {
await switchToChannelById(serverUrl, channelId, teamId);
return;
@@ -298,7 +298,7 @@ export const handleTeamChange = async (serverUrl: string, teamId: string) => {
}
// If WebSocket is not disconnected we fetch everything since this moment
const lastDisconnectedAt = (await queryWebSocketLastDisconnected(database)) || Date.now();
const lastDisconnectedAt = (await getWebSocketLastDisconnected(database)) || Date.now();
const {channels, memberships, error} = await fetchMyChannelsForTeam(serverUrl, teamId, true, lastDisconnectedAt, false, true);
if (error) {

View File

@@ -1,26 +1,25 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Model, Q} from '@nozbe/watermelondb';
import {Model} from '@nozbe/watermelondb';
import {chunk} from 'lodash';
import {updateChannelsDisplayName} from '@actions/local/channel';
import {updateRecentCustomStatuses, updateLocalUser} from '@actions/local/user';
import {fetchRolesIfNeeded} from '@actions/remote/role';
import {removeUserFromList} from '@app/utils/user';
import {Database, General} from '@constants';
import {MM_TABLES} from '@constants/database';
import {General} from '@constants';
import DatabaseManager from '@database/manager';
import {debounce} from '@helpers/api/general';
import NetworkManager from '@init/network_manager';
import {queryCurrentTeamId, queryCurrentUserId} from '@queries/servers/system';
import {prepareUsers, queryAllUsers, queryCurrentUser, queryUsersById, queryUsersByUsername} from '@queries/servers/user';
import {queryChannelsByTypes} from '@queries/servers/channel';
import {getCurrentTeamId, getCurrentUserId} from '@queries/servers/system';
import {getCurrentUser, prepareUsers, queryAllUsers, queryUsersById, queryUsersByUsername} from '@queries/servers/user';
import {removeUserFromList} from '@utils/user';
import {forceLogoutIfNecessary} from './session';
import type {Client} from '@client/rest';
import type ClientError from '@client/rest/error';
import type ChannelModel from '@typings/database/models/servers/channel';
import type UserModel from '@typings/database/models/servers/user';
export type MyUserRequest = {
@@ -39,8 +38,6 @@ export type ProfilesInChannelRequest = {
error?: unknown;
}
const {SERVER: {CHANNEL}} = MM_TABLES;
export const fetchMe = async (serverUrl: string, fetchOnly = false): Promise<MyUserRequest> => {
let client;
try {
@@ -224,7 +221,7 @@ export const fetchStatusByIds = async (serverUrl: string, userIds: string[], fet
if (!fetchOnly && DatabaseManager.serverDatabases[serverUrl]) {
const {database, operator} = DatabaseManager.serverDatabases[serverUrl];
if (operator) {
const users = await database.get(Database.MM_TABLES.SERVER.USER).query(Q.where('id', Q.oneOf(userIds))).fetch() as UserModel[];
const users = await queryUsersById(database, userIds).fetch();
for (const user of users) {
const status = statuses.find((s) => s.user_id === user.id);
user.prepareStatus(status?.status || General.OFFLINE);
@@ -258,8 +255,8 @@ export const fetchUsersByIds = async (serverUrl: string, userIds: string[], fetc
}
try {
const currentUser = await queryCurrentUser(operator.database);
const existingUsers = await queryUsersById(operator.database, userIds);
const currentUser = await getCurrentUser(operator.database);
const existingUsers = await queryUsersById(operator.database, userIds).fetch();
if (userIds.includes(currentUser!.id)) {
existingUsers.push(currentUser!);
}
@@ -299,8 +296,8 @@ export const fetchUsersByUsernames = async (serverUrl: string, usernames: string
}
try {
const currentUser = await queryCurrentUser(operator.database);
const exisingUsers = await queryUsersByUsername(operator.database, usernames);
const currentUser = await getCurrentUser(operator.database);
const exisingUsers = await queryUsersByUsername(operator.database, usernames).fetch();
const usersToLoad = usernames.filter((username) => (username !== currentUser?.username && !exisingUsers.find((u) => u.username === username)));
const users = await client.getProfilesByUsernames([...new Set(usersToLoad)]);
@@ -335,7 +332,7 @@ export const fetchProfiles = async (serverUrl: string, page = 0, perPage: number
const users = await client.getProfiles(page, perPage, options);
if (!fetchOnly) {
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const toStore = removeUserFromList(currentUserId, users);
await operator.handleUsers({
users: toStore,
@@ -367,7 +364,7 @@ export const fetchProfilesInTeam = async (serverUrl: string, teamId: string, pag
const users = await client.getProfilesInTeam(teamId, page, perPage, sort, options);
if (!fetchOnly) {
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const toStore = removeUserFromList(currentUserId, users);
await operator.handleUsers({
@@ -397,7 +394,7 @@ export const searchProfiles = async (serverUrl: string, term: string, options: a
}
try {
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const users = await client.searchUsers(term, options);
if (!fetchOnly) {
@@ -462,6 +459,7 @@ export const updateAllUsersSince = async (serverUrl: string, since: number, fetc
if (!operator) {
return {error: `${serverUrl} database not found`};
}
const database = operator.database;
let client: Client;
try {
@@ -470,9 +468,8 @@ export const updateAllUsersSince = async (serverUrl: string, since: number, fetc
return {error};
}
const currentUserId = await queryCurrentUserId(operator.database);
const users = await queryAllUsers(operator.database);
const userIds = users.map((u) => u.id).filter((id) => id !== currentUserId);
const currentUserId = await getCurrentUserId(database);
const userIds = (await queryAllUsers(database).fetchIds()).filter((id) => id !== currentUserId);
let userUpdates: UserProfile[] = [];
try {
userUpdates = await client.getProfilesByIds(userIds, {since});
@@ -480,9 +477,7 @@ export const updateAllUsersSince = async (serverUrl: string, since: number, fetc
const modelsToBatch: Model[] = [];
const userModels = await operator.handleUsers({users: userUpdates, prepareRecordsOnly: true});
modelsToBatch.push(...userModels);
const directChannels = await operator.database.get<ChannelModel>(CHANNEL).
query(Q.where('type', Q.oneOf([General.DM_CHANNEL, General.GM_CHANNEL]))).
fetch();
const directChannels = await queryChannelsByTypes(database, [General.DM_CHANNEL, General.GM_CHANNEL]).fetch();
const {models} = await updateChannelsDisplayName(serverUrl, directChannels, userUpdates, true);
if (models?.length) {
modelsToBatch.push(...models);
@@ -515,10 +510,10 @@ export const updateUsersNoLongerVisible = async (serverUrl: string, prepareRecor
const models: Model[] = [];
try {
const knownUsers = new Set(await client.getKnownUsers());
const currentUserId = await queryCurrentUserId(serverDatabase.database);
const currentUserId = await getCurrentUserId(serverDatabase.database);
knownUsers.add(currentUserId);
const allUsers = await queryAllUsers(serverDatabase.database);
const allUsers = await queryAllUsers(serverDatabase.database).fetch();
for (const user of allUsers) {
if (!knownUsers.has(user.id)) {
user.prepareDestroyPermanently();
@@ -648,7 +643,7 @@ export const uploadUserProfileImage = async (serverUrl: string, localPath: strin
}
try {
const currentUser = await queryCurrentUser(database);
const currentUser = await getCurrentUser(database);
if (currentUser) {
const endpoint = `${client.getUserRoute(currentUser.id)}/image`;
@@ -680,7 +675,7 @@ export const searchUsers = async (serverUrl: string, term: string, channelId?: s
}
try {
const currentTeamId = await queryCurrentTeamId(database);
const currentTeamId = await getCurrentTeamId(database);
const users = await client.autocompleteUsers(term, currentTeamId, channelId);
return {users};
} catch (error) {

View File

@@ -92,7 +92,7 @@ export async function handleCategoryOrderUpdatedEvent(serverUrl: string, msg: We
// Update category order
if (msg.data.order?.length) {
const order = msg.data.order;
const categories = await queryCategoriesById(database, order);
const categories = await queryCategoriesById(database, order).fetch();
categories.forEach((c) => {
const findOrder = (id: string) => id === c.id;
c.prepareUpdate(() => {

View File

@@ -11,10 +11,10 @@ import {fetchUsersByIds, updateUsersNoLongerVisible} from '@actions/remote/user'
import Events from '@constants/events';
import DatabaseManager from '@database/manager';
import {queryActiveServer} from '@queries/app/servers';
import {deleteChannelMembership, prepareMyChannelsForTeam, queryChannelsById, queryCurrentChannel} from '@queries/servers/channel';
import {prepareCommonSystemValues, queryConfig, setCurrentChannelId} from '@queries/servers/system';
import {queryNthLastChannelFromTeam} from '@queries/servers/team';
import {queryCurrentUser, queryUserById} from '@queries/servers/user';
import {deleteChannelMembership, getChannelById, prepareMyChannelsForTeam, getCurrentChannel} from '@queries/servers/channel';
import {prepareCommonSystemValues, getConfig, setCurrentChannelId} from '@queries/servers/system';
import {getNthLastChannelFromTeam} from '@queries/servers/team';
import {getCurrentUser, getUserById} from '@queries/servers/user';
import {dismissAllModals, popToRoot} from '@screens/navigation';
import {isTablet} from '@utils/helpers';
@@ -23,13 +23,13 @@ export async function handleUserAddedToChannelEvent(serverUrl: string, msg: any)
if (!database) {
return;
}
const currentUser = await queryCurrentUser(database.database);
const currentUser = await getCurrentUser(database.database);
const {team_id: teamId, user_id: userId} = msg.data;
const {channel_id: channelId} = msg.broadcast;
const models: Model[] = [];
try {
const addedUser = queryUserById(database.database, userId);
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);
@@ -66,8 +66,8 @@ export async function handleUserAddedToChannelEvent(serverUrl: string, msg: any)
models.push(...await database.operator.handleUsers({users: authors, prepareRecordsOnly: true}));
}
} else {
const channels = await queryChannelsById(database.database, [channelId]);
if (channels?.[0]) {
const channel = await getChannelById(database.database, channelId);
if (channel) {
models.push(...await database.operator.handleChannelMembership({
channelMemberships: [{channel_id: channelId, user_id: userId}],
prepareRecordsOnly: true,
@@ -87,8 +87,8 @@ export async function handleUserRemovedFromChannelEvent(serverUrl: string, msg:
return;
}
const channel = await queryCurrentChannel(database.database);
const user = await queryCurrentUser(database.database);
const channel = await getCurrentChannel(database.database);
const user = await getCurrentUser(database.database);
if (!user) {
return;
}
@@ -121,7 +121,7 @@ export async function handleUserRemovedFromChannelEvent(serverUrl: string, msg:
await popToRoot();
if (await isTablet()) {
const channelToJumpTo = await queryNthLastChannelFromTeam(database.database, channel?.teamId);
const channelToJumpTo = await getNthLastChannelFromTeam(database.database, channel?.teamId);
if (channelToJumpTo) {
const {models: switchChannelModels} = await switchToChannel(serverUrl, channelToJumpTo, '', true);
if (switchChannelModels) {
@@ -152,15 +152,15 @@ export async function handleChannelDeletedEvent(serverUrl: string, msg: WebSocke
return;
}
const currentChannel = await queryCurrentChannel(database.database);
const user = await queryCurrentUser(database.database);
const currentChannel = await getCurrentChannel(database.database);
const user = await getCurrentUser(database.database);
if (!user) {
return;
}
const {channel_id: channelId, delete_at: deleteAt} = msg.data;
const config = await queryConfig(database.database);
const config = await getConfig(database.database);
await setChannelDeleteAt(serverUrl, channelId, deleteAt);
@@ -180,7 +180,7 @@ export async function handleChannelDeletedEvent(serverUrl: string, msg: WebSocke
await popToRoot();
if (await isTablet()) {
const channelToJumpTo = await queryNthLastChannelFromTeam(database.database, currentChannel?.teamId);
const channelToJumpTo = await getNthLastChannelFromTeam(database.database, currentChannel?.teamId);
if (channelToJumpTo) {
switchToChannel(serverUrl, channelToJumpTo);
} // TODO else jump to "join a channel" screen

View File

@@ -12,9 +12,9 @@ import {General, WebsocketEvents} from '@constants';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
import {queryChannelsById, queryDefaultChannelForTeam} from '@queries/servers/channel';
import {queryChannelsById, getDefaultChannelForTeam} from '@queries/servers/channel';
import {prepareModels} from '@queries/servers/entry';
import {queryCommonSystemValues, queryConfig, queryCurrentChannelId, queryWebSocketLastDisconnected, resetWebSocketLastDisconnected, setCurrentTeamAndChannelId} from '@queries/servers/system';
import {getCommonSystemValues, getConfig, getCurrentChannelId, getWebSocketLastDisconnected, resetWebSocketLastDisconnected, setCurrentTeamAndChannelId} from '@queries/servers/system';
import {isTablet} from '@utils/helpers';
import {handleCategoryCreatedEvent, handleCategoryDeletedEvent, handleCategoryOrderUpdatedEvent, handleCategoryUpdatedEvent} from './category';
@@ -36,11 +36,11 @@ export async function handleFirstConnect(serverUrl: string) {
return;
}
const {database} = operator;
const config = await queryConfig(database);
const lastDisconnect = await queryWebSocketLastDisconnected(database);
const config = await getConfig(database);
const lastDisconnect = await getWebSocketLastDisconnected(database);
// ESR: 5.37
if (lastDisconnect && config.EnableReliableWebSockets !== 'true' && alreadyConnected.has(serverUrl)) {
if (lastDisconnect && config?.EnableReliableWebSockets !== 'true' && alreadyConnected.has(serverUrl)) {
handleReconnect(serverUrl);
return;
}
@@ -78,8 +78,8 @@ async function doReconnect(serverUrl: string) {
const {database} = operator;
const tabletDevice = await isTablet();
const system = await queryCommonSystemValues(database);
const lastDisconnectedAt = await queryWebSocketLastDisconnected(database);
const system = await getCommonSystemValues(database);
const lastDisconnectedAt = await getWebSocketLastDisconnected(database);
resetWebSocketLastDisconnected(operator);
let {config, license} = await fetchConfigAndLicense(serverUrl);
@@ -125,7 +125,7 @@ async function doReconnect(serverUrl: string) {
let cId = '';
if (tabletDevice) {
if (!cId) {
const channel = await queryDefaultChannelForTeam(database, initialTeamId);
const channel = await getDefaultChannelForTeam(database, initialTeamId);
if (channel) {
cId = channel.id;
}
@@ -140,7 +140,7 @@ async function doReconnect(serverUrl: string) {
let removeChannels;
if (removeChannelIds?.length) {
removeChannels = await queryChannelsById(database, removeChannelIds);
removeChannels = await queryChannelsById(database, removeChannelIds).fetch();
}
const modelPromises = await prepareModels({operator, initialTeamId, removeTeams, removeChannels, teamData, chData, prefData, meData});
@@ -161,7 +161,7 @@ async function doReconnect(serverUrl: string) {
}
}
const currentChannelId = await queryCurrentChannelId(database);
const currentChannelId = await getCurrentChannelId(database);
if (currentChannelId) {
// https://mattermost.atlassian.net/browse/MM-40098
fetchPostsSince(serverUrl, currentChannelId, lastDisconnectedAt);

View File

@@ -10,9 +10,9 @@ import {fetchMyChannel, markChannelAsRead} from '@actions/remote/channel';
import {fetchPostAuthors, fetchPostById} from '@actions/remote/post';
import {ActionType, Events} from '@constants';
import DatabaseManager from '@database/manager';
import {queryMyChannel} from '@queries/servers/channel';
import {queryPostById} from '@queries/servers/post';
import {queryCurrentChannelId, queryCurrentUserId} from '@queries/servers/system';
import {getMyChannel} from '@queries/servers/channel';
import {getPostById} from '@queries/servers/post';
import {getCurrentChannelId, getCurrentUserId} from '@queries/servers/system';
import {isFromWebhook, isSystemMessage, shouldIgnorePost} from '@utils/post';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
@@ -37,9 +37,9 @@ export async function handleNewPostEvent(serverUrl: string, msg: WebSocketMessag
} catch {
return;
}
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
const existing = await queryPostById(operator.database, post.pending_post_id);
const existing = await getPostById(operator.database, post.pending_post_id);
if (existing) {
return;
@@ -59,7 +59,7 @@ export async function handleNewPostEvent(serverUrl: string, msg: WebSocketMessag
}
// Ensure the channel membership
let myChannel = await queryMyChannel(operator.database, post.channel_id);
let myChannel = await getMyChannel(operator.database, post.channel_id);
if (myChannel) {
const {member} = await updateLastPostAt(serverUrl, post.channel_id, post.create_at, false);
if (member) {
@@ -77,7 +77,7 @@ export async function handleNewPostEvent(serverUrl: string, msg: WebSocketMessag
return;
}
myChannel = await queryMyChannel(operator.database, post.channel_id);
myChannel = await getMyChannel(operator.database, post.channel_id);
if (!myChannel) {
return;
}
@@ -85,14 +85,14 @@ export async function handleNewPostEvent(serverUrl: string, msg: WebSocketMessag
// If we don't have the root post for this post, fetch it from the server
if (post.root_id) {
const rootPost = await queryPostById(operator.database, post.root_id);
const rootPost = await getPostById(operator.database, post.root_id);
if (!rootPost) {
fetchPostById(serverUrl, post.root_id);
}
}
const currentChannelId = await queryCurrentChannelId(operator.database);
const currentChannelId = await getCurrentChannelId(operator.database);
if (post.channel_id === currentChannelId) {
const data = {

View File

@@ -4,7 +4,7 @@
import {fetchPostById} from '@actions/remote/post';
import {Preferences} from '@constants';
import DatabaseManager from '@database/manager';
import {queryPostById} from '@queries/servers/post';
import {getPostById} from '@queries/servers/post';
import {deletePreferences} from '@queries/servers/preference';
export async function handlePreferenceChangedEvent(serverUrl: string, msg: WebSocketMessage): Promise<void> {
@@ -70,7 +70,7 @@ async function handleSavePostAdded(serverUrl: string, preferences: PreferenceTyp
const savedPosts = preferences.filter((p) => p.category === Preferences.CATEGORY_SAVED_POST);
for await (const saved of savedPosts) {
const post = await queryPostById(database, saved.name);
const post = await getPostById(database, saved.name);
if (!post) {
await fetchPostById(serverUrl, saved.name, false);
}

View File

@@ -1,10 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
import {queryReaction} from '@queries/servers/reactions';
export async function handleAddCustomEmoji(serverUrl: string, msg: WebSocketMessage): Promise<void> {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
@@ -52,11 +50,7 @@ export async function handleReactionRemovedFromPostEvent(serverUrl: string, msg:
try {
const msgReaction = JSON.parse(msg.data.reaction) as Reaction;
const reaction = await database.get(MM_TABLES.SERVER.REACTION).query(
Q.where('emoji_name', msgReaction.emoji_name),
Q.where('post_id', msgReaction.post_id),
Q.where('user_id', msgReaction.user_id),
).fetch();
const reaction = await queryReaction(database, msgReaction.emoji_name, msgReaction.post_id, msgReaction.user_id).fetch();
if (reaction.length) {
await database.write(async () => {

View File

@@ -3,9 +3,9 @@
import {fetchRolesIfNeeded} from '@actions/remote/role';
import DatabaseManager from '@database/manager';
import {queryRoleById} from '@queries/servers/role';
import {queryCurrentUserId} from '@queries/servers/system';
import {queryCurrentUser} from '@queries/servers/user';
import {getRoleById} from '@queries/servers/role';
import {getCurrentUserId} from '@queries/servers/system';
import {getCurrentUser} from '@queries/servers/user';
import type {Model} from '@nozbe/watermelondb';
@@ -18,7 +18,7 @@ export async function handleRoleUpdatedEvent(serverUrl: string, msg: WebSocketMe
// only update Role records that exist in the Role Table
try {
const role = JSON.parse(msg.data.role) as Role;
const dbRole = await queryRoleById(operator.database, role.id);
const dbRole = await getRoleById(operator.database, role.id);
if (!dbRole) {
return;
}
@@ -38,7 +38,7 @@ export async function handleUserRoleUpdatedEvent(serverUrl: string, msg: WebSock
return;
}
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
if (currentUserId !== msg.data.user_id) {
return;
}
@@ -60,7 +60,7 @@ export async function handleUserRoleUpdatedEvent(serverUrl: string, msg: WebSock
}
// update User Table record
const user = await queryCurrentUser(operator.database);
const user = await getCurrentUser(operator.database);
if (user) {
user!.prepareUpdate((u) => {
u.roles = msg.data.roles;
@@ -82,7 +82,7 @@ export async function handleTeamMemberRoleUpdatedEvent(serverUrl: string, msg: W
try {
const member = JSON.parse(msg.data.member);
const currentUserId = await queryCurrentUserId(operator.database);
const currentUserId = await getCurrentUserId(operator.database);
if (currentUserId !== member.user_id) {
return;
}

View File

@@ -11,9 +11,9 @@ import {updateUsersNoLongerVisible} from '@actions/remote/user';
import Events from '@constants/events';
import DatabaseManager from '@database/manager';
import {queryActiveServer} from '@queries/app/servers';
import {queryCurrentTeamId} from '@queries/servers/system';
import {queryLastTeam, prepareMyTeams} from '@queries/servers/team';
import {queryCurrentUser} from '@queries/servers/user';
import {getCurrentTeamId} from '@queries/servers/system';
import {getLastTeam, prepareMyTeams} from '@queries/servers/team';
import {getCurrentUser} from '@queries/servers/user';
import {dismissAllModals, popToRoot} from '@screens/navigation';
export async function handleLeaveTeamEvent(serverUrl: string, msg: WebSocketMessage) {
@@ -22,8 +22,8 @@ export async function handleLeaveTeamEvent(serverUrl: string, msg: WebSocketMess
return;
}
const currentTeamId = await queryCurrentTeamId(database.database);
const user = await queryCurrentUser(database.database);
const currentTeamId = await getCurrentTeamId(database.database);
const user = await getCurrentUser(database.database);
if (!user) {
return;
}
@@ -46,7 +46,7 @@ export async function handleLeaveTeamEvent(serverUrl: string, msg: WebSocketMess
await popToRoot();
}
const teamToJumpTo = await queryLastTeam(database.database);
const teamToJumpTo = await getLastTeam(database.database);
if (teamToJumpTo) {
handleTeamChange(serverUrl, teamToJumpTo);
} // TODO else jump to "join a team" screen

View File

@@ -1,25 +1,21 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Model, Q} from '@nozbe/watermelondb';
import {Model} from '@nozbe/watermelondb';
import {DeviceEventEmitter} from 'react-native';
import {updateChannelsDisplayName} from '@actions/local/channel';
import {fetchMe, fetchUsersByIds} from '@actions/remote/user';
import {General, Events, Preferences} from '@constants';
import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
import WebsocketManager from '@init/websocket_manager';
import {queryChannelsByTypes, queryUserChannelsByTypes} from '@queries/servers/channel';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {queryCommonSystemValues} from '@queries/servers/system';
import {queryCurrentUser} from '@queries/servers/user';
import {getCommonSystemValues} from '@queries/servers/system';
import {getCurrentUser} from '@queries/servers/user';
import {displayUsername} from '@utils/user';
import type ChannelModel from '@typings/database/models/servers/channel';
const {SERVER: {CHANNEL, CHANNEL_MEMBERSHIP}} = MM_TABLES;
export async function handleUserUpdatedEvent(serverUrl: string, msg: WebSocketMessage) {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
if (!operator) {
@@ -27,7 +23,7 @@ export async function handleUserUpdatedEvent(serverUrl: string, msg: WebSocketMe
}
const {database} = operator;
const currentUser = await queryCurrentUser(database);
const currentUser = await getCurrentUser(database);
if (!currentUser) {
return;
}
@@ -51,8 +47,7 @@ export async function handleUserUpdatedEvent(serverUrl: string, msg: WebSocketMe
// Update GMs display name if locale has changed
if (user.locale !== currentUser.locale) {
const channels = await database.get<ChannelModel>(CHANNEL).query(
Q.where('type', Q.eq(General.GM_CHANNEL))).fetch();
const channels = await queryChannelsByTypes(database, [General.GM_CHANNEL]).fetch();
if (channels.length) {
const {models} = await updateChannelsDisplayName(serverUrl, channels, [user], true);
if (models?.length) {
@@ -62,9 +57,7 @@ export async function handleUserUpdatedEvent(serverUrl: string, msg: WebSocketMe
}
}
} else {
const channels = await database.get<ChannelModel>(CHANNEL).query(
Q.where('type', Q.oneOf([General.DM_CHANNEL, General.GM_CHANNEL])),
Q.on(CHANNEL_MEMBERSHIP, Q.where('user_id', user.id))).fetch();
const channels = await queryUserChannelsByTypes(database, user.id, [General.DM_CHANNEL, General.GM_CHANNEL]).fetch();
if (channels.length) {
const {models} = await updateChannelsDisplayName(serverUrl, channels, [user], true);
if (models?.length) {
@@ -91,14 +84,14 @@ export async function handleUserTypingEvent(serverUrl: string, msg: WebSocketMes
return;
}
const {config, license} = await queryCommonSystemValues(database);
const {config, license} = await getCommonSystemValues(database);
const {users, existingUsers} = await fetchUsersByIds(serverUrl, [msg.data.user_id]);
const user = users?.[0] || existingUsers?.[0];
const namePreference = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT);
const namePreference = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(namePreference, config, license);
const currentUser = await queryCurrentUser(database);
const currentUser = await getCurrentUser(database);
const username = displayUsername(user, currentUser?.locale, teammateDisplayNameSetting);
const data = {
channelId: msg.broadcast.channel_id,

View File

@@ -6,7 +6,7 @@ import {Platform} from 'react-native';
import {WebsocketEvents} from '@constants';
import DatabaseManager from '@database/manager';
import {queryCommonSystemValues} from '@queries/servers/system';
import {getCommonSystemValues} from '@queries/servers/system';
const MAX_WEBSOCKET_FAILS = 7;
const MIN_WEBSOCKET_RETRY_TIME = 3000; // 3 sec
@@ -74,7 +74,7 @@ export default class WebSocketClient {
return;
}
const system = await queryCommonSystemValues(database);
const system = await getCommonSystemValues(database);
const connectionUrl = (system.config.WebsocketURL || this.serverUrl) + '/api/v4/websocket';
if (this.connectingCallback) {

View File

@@ -7,37 +7,30 @@ import {of as of$, from as from$, combineLatest, Observable} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {Permissions} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeChannel} from '@queries/servers/channel';
import {observeLicense} from '@queries/servers/system';
import {observeCurrentUser} from '@queries/servers/user';
import {hasPermissionForChannel} from '@utils/role';
import AtMention from './at_mention';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {SYSTEM, USER, CHANNEL}} = MM_TABLES;
type OwnProps = {channelId?: string}
const enhanced = withObservables([], ({database, channelId}: WithDatabaseArgs & OwnProps) => {
const currentUser = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => of$(value)),
).pipe(
switchMap((id) => database.get<UserModel>(USER).findAndObserve(id)),
);
const currentUser = observeCurrentUser(database);
const hasLicense = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.LICENSE).pipe(
switchMap(({value}) => of$(value?.IsLicensed === 'true')),
const hasLicense = observeLicense(database).pipe(
switchMap((lcs) => of$(lcs?.IsLicensed === 'true')),
);
let useChannelMentions: Observable<boolean>;
let useGroupMentions: Observable<boolean>;
if (channelId) {
const currentChannel = database.get<ChannelModel>(CHANNEL).findAndObserve(channelId);
useChannelMentions = combineLatest([currentUser, currentChannel]).pipe(switchMap(([u, c]) => from$(hasPermissionForChannel(c, u, Permissions.USE_CHANNEL_MENTIONS, false))));
const currentChannel = observeChannel(database, channelId);
useChannelMentions = combineLatest([currentUser, currentChannel]).pipe(switchMap(([u, c]) => (u && c ? from$(hasPermissionForChannel(c, u, Permissions.USE_CHANNEL_MENTIONS, false)) : of$(false))));
useGroupMentions = combineLatest([currentUser, currentChannel, hasLicense]).pipe(
switchMap(([u, c, lcs]) => (lcs ? from$(hasPermissionForChannel(c, u, Permissions.USE_GROUP_MENTIONS, false)) : of$(false))),
switchMap(([u, c, lcs]) => (lcs && u && c ? from$(hasPermissionForChannel(c, u, Permissions.USE_GROUP_MENTIONS, false)) : of$(false))),
);
} else {
useChannelMentions = of$(false);

View File

@@ -6,27 +6,21 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfig, observeCurrentUserId} from '@queries/servers/system';
import AtMentionItem from './at_mention_item';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {SYSTEM}} = MM_TABLES;
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const config = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap(({value}) => of$(value as ClientConfig)),
);
const config = observeConfig(database);
const isCustomStatusEnabled = config.pipe(
switchMap((cfg) => of$(cfg.EnableCustomUserStatuses === 'true')),
switchMap((cfg) => of$(cfg?.EnableCustomUserStatuses === 'true')),
);
const showFullName = config.pipe(
switchMap((cfg) => of$(cfg.ShowFullName === 'true')),
);
const currentUserId = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => of$(value)),
switchMap((cfg) => of$(cfg?.ShowFullName === 'true')),
);
const currentUserId = observeCurrentUserId(database);
return {
isCustomStatusEnabled,
showFullName,

View File

@@ -4,17 +4,15 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {MM_TABLES} from '@constants/database';
import {queryAllMyChannel} from '@queries/servers/channel';
import ChannelMention from './channel_mention';
import type {WithDatabaseArgs} from '@typings/database/database';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
const {SERVER: {MY_CHANNEL}} = MM_TABLES;
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
return {
myMembers: database.get<MyChannelModel>(MY_CHANNEL).query().observe(),
myMembers: queryAllMyChannel(database).observe(),
};
});

View File

@@ -5,7 +5,7 @@ import React, {useMemo} from 'react';
import {Text, View} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import ChannelIcon from '@app/components/channel_icon';
import ChannelIcon from '@components/channel_icon';
import {BotTag, GuestTag} from '@components/tag';
import TouchableWithFeedback from '@components/touchable_with_feedback';
import {General} from '@constants';

View File

@@ -7,7 +7,7 @@ import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {General} from '@constants';
import {MM_TABLES} from '@constants/database';
import {observeUser} from '@queries/servers/user';
import ChannelMentionItem from './channel_mention_item';
@@ -18,11 +18,10 @@ type OwnProps = {
channel: Channel;
}
const {SERVER: {USER}} = MM_TABLES;
const enhanced = withObservables([], ({database, channel}: WithDatabaseArgs & OwnProps) => {
let user = of$<UserModel | undefined>(undefined);
if (channel.type === General.DM_CHANNEL) {
user = database.get<UserModel>(USER).findAndObserve(channel.teammate_id!);
user = observeUser(database, channel.teammate_id!);
}
const isBot = user.pipe(switchMap((u) => of$(u ? u.isBot : false)));

View File

@@ -1,40 +1,32 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {Preferences} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {queryAllCustomEmojis} from '@queries/servers/custom_emoji';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeConfigBooleanValue} from '@queries/servers/system';
import EmojiSuggestion from './emoji_suggestion';
import type {WithDatabaseArgs} from '@typings/database/database';
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {SYSTEM, CUSTOM_EMOJI, PREFERENCE}} = MM_TABLES;
const emptyEmojiList: CustomEmojiModel[] = [];
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const isCustomEmojisEnabled = database.get<SystemModel>(SYSTEM).
findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap((config) => of$(config.value.EnableCustomEmoji === 'true')),
);
const isCustomEmojisEnabled = observeConfigBooleanValue(database, 'EnableCustomEmoji');
return {
customEmojis: isCustomEmojisEnabled.pipe(
switchMap((enabled) => (enabled ?
database.get<CustomEmojiModel>(CUSTOM_EMOJI).query().observe() :
queryAllCustomEmojis(database).observe() :
of$(emptyEmojiList)),
),
),
skinTone: database.get<PreferenceModel>(PREFERENCE).query(
Q.where('category', Preferences.CATEGORY_EMOJI),
Q.where('name', Preferences.EMOJI_SKINTONE),
).observe().pipe(
skinTone: queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_EMOJI, Preferences.EMOJI_SKINTONE).observe().pipe(
switchMap((prefs) => of$(prefs?.[0]?.value ?? 'default')),
),
};

View File

@@ -3,20 +3,15 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfigBooleanValue} from '@queries/servers/system';
import Autocomplete from './autocomplete';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => ({
isAppsEnabled: database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap((cfg) => of$(cfg.value.FeatureFlagAppsEnabled === 'true')),
),
isAppsEnabled: observeConfigBooleanValue(database, 'FeatureFlagAppsEnabled'),
}));
export default withDatabase(enhanced(Autocomplete));

View File

@@ -1,30 +1,24 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import React, {ReactNode, useCallback, useState} from 'react';
import {useIntl} from 'react-intl';
import {Text, View} from 'react-native';
import {combineLatest} from 'rxjs';
import {map} from 'rxjs/operators';
import CompasIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
import TouchableWithFeedback from '@components/touchable_with_feedback';
import {Preferences, Screens, View as ViewConstants} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {Screens, View as ViewConstants} from '@constants';
import {useTheme} from '@context/theme';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
import {observeTeammateNameDisplay} from '@queries/servers/user';
import {goToScreen} from '@screens/navigation';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {displayUsername} from '@utils/user';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type SystemModel from '@typings/database/models/servers/system';
type AutoCompleteSelectorProps = {
dataSource?: string;
@@ -43,8 +37,6 @@ type AutoCompleteSelectorProps = {
teammateNameDisplay: string;
}
const {SERVER: {PREFERENCE, SYSTEM}} = MM_TABLES;
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
const input = {
borderWidth: 1,
@@ -240,16 +232,8 @@ const AutoCompleteSelector = ({
};
const withTeammateNameDisplay = withObservables([], ({database}: WithDatabaseArgs) => {
const config = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG);
const license = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.LICENSE);
const preferences = database.get<PreferenceModel>(PREFERENCE).query(Q.where('category', Preferences.CATEGORY_DISPLAY_SETTINGS)).observe();
const teammateNameDisplay = combineLatest([config, license, preferences]).pipe(
map(
([{value: cfg}, {value: lcs}, prefs]) => getTeammateNameDisplaySetting(prefs, cfg, lcs),
),
);
return {
teammateNameDisplay,
teammateNameDisplay: observeTeammateNameDisplay(database),
};
});

View File

@@ -1,28 +1,21 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeCurrentUserId} from '@queries/servers/system';
import {observeUser} from '@queries/servers/user';
import {getUserIdFromChannelName} from '@utils/user';
import DmAvatar from './dm_avatar';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {USER, SYSTEM}} = MM_TABLES;
const {CURRENT_USER_ID} = SYSTEM_IDENTIFIERS;
const enhance = withObservables(['channelName'], ({channelName, database}: {channelName: string} & WithDatabaseArgs) => {
const currentUserId = database.get<SystemModel>(SYSTEM).findAndObserve(CURRENT_USER_ID).pipe(
switchMap(({value}) => of$(value)),
);
const currentUserId = observeCurrentUserId(database);
const authorId = currentUserId.pipe(
switchMap((userId) => of$(getUserIdFromChannelName(userId, channelName))),
@@ -30,10 +23,7 @@ const enhance = withObservables(['channelName'], ({channelName, database}: {chan
const author = authorId.pipe(
switchMap((id) => {
return database.get<UserModel>(USER).query(Q.where('id', id)).observe().pipe(
// eslint-disable-next-line max-nested-callbacks
switchMap((users) => (users[0] ? of$(users[0]) : of$(undefined))),
);
return observeUser(database, id);
}),
);

View File

@@ -7,28 +7,22 @@ import {combineLatest, of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {General} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeMyChannel} from '@queries/servers/channel';
import {observeCurrentUserId} from '@queries/servers/system';
import {getUserIdFromChannelName} from '@utils/user';
import ChannelListItem from './channel_list_item';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {MY_CHANNEL, SYSTEM}} = MM_TABLES;
const {CURRENT_USER_ID} = SYSTEM_IDENTIFIERS;
const enhance = withObservables(['channelId'], ({channelId, database}: {channelId: string} & WithDatabaseArgs) => {
const myChannel = database.get<MyChannelModel>(MY_CHANNEL).findAndObserve(channelId);
const currentUserId = database.get<SystemModel>(SYSTEM).findAndObserve(CURRENT_USER_ID).pipe(
switchMap(({value}) => of$(value)),
);
const myChannel = observeMyChannel(database, channelId);
const currentUserId = observeCurrentUserId(database);
const channel = myChannel.pipe(switchMap((my) => my.channel.observe()));
const settings = channel.pipe(switchMap((c) => c.settings.observe()));
const channel = myChannel.pipe(switchMap((my) => (my ? my.channel.observe() : of$(undefined))));
const settings = channel.pipe(switchMap((c) => (c ? c.settings.observe() : of$(undefined))));
const isOwnDirectMessage = combineLatest([currentUserId, channel]).pipe(
switchMap(([userId, ch]) => {

View File

@@ -1,14 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Database, Q} from '@nozbe/watermelondb';
import {Database} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES} from '@app/constants/database';
import {General, Preferences} from '@constants';
import {queryMyChannelSettingsByIds} from '@queries/servers/channel';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {WithDatabaseArgs} from '@typings/database/database';
import CategoryBody from './category_body';
@@ -16,14 +17,11 @@ import CategoryBody from './category_body';
import type CategoryModel from '@typings/database/models/servers/category';
import type ChannelModel from '@typings/database/models/servers/channel';
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
import type PreferenceModel from '@typings/database/models/servers/preference';
type ChannelData = Pick<ChannelModel, 'id' | 'displayName'> & {
isMuted: boolean;
};
const {SERVER: {MY_CHANNEL_SETTINGS, PREFERENCE}} = MM_TABLES;
const sortAlpha = (locale: string, a: ChannelData, b: ChannelData) => {
if (a.isMuted && !b.isMuted) {
return 1;
@@ -49,12 +47,9 @@ const buildAlphaData = (channels: ChannelModel[], settings: MyChannelSettingsMod
return of$(combined.map((c) => c.id));
};
const querySettings = (database: Database, channels: ChannelModel[]) => {
const observeSettings = (database: Database, channels: ChannelModel[]) => {
const ids = channels.map((c) => c.id);
return database.get<MyChannelSettingsModel>(MY_CHANNEL_SETTINGS).
query(
Q.where('id', Q.oneOf(ids)),
).observeWithColumns(['notify_props']);
return queryMyChannelSettingsByIds(database, ids).observeWithColumns(['notify_props']);
};
const getSortedIds = (database: Database, category: CategoryModel, locale: string) => {
@@ -62,7 +57,7 @@ const getSortedIds = (database: Database, category: CategoryModel, locale: strin
case 'alpha': {
const channels = category.channels.observeWithColumns(['display_name']);
const settings = channels.pipe(
switchMap((cs) => querySettings(database, cs)),
switchMap((cs) => observeSettings(database, cs)),
);
return combineLatest([channels, settings]).pipe(
switchMap(([cs, st]) => buildAlphaData(cs, st, locale)),
@@ -90,21 +85,11 @@ const enhance = withObservables(['category'], ({category, locale, database}: {ca
let limit = of$(0);
if (category.type === 'direct_messages') {
limit = database.get<PreferenceModel>(PREFERENCE).
query(
Q.where('category', Preferences.CATEGORY_SIDEBAR_SETTINGS),
Q.where('name', 'limit_visible_dms_gms'),
).observe().pipe(
switchMap(
(val) => {
if (val[0]) {
return of$(parseInt(val[0].value, 10));
}
return of$(0);
},
),
);
limit = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_SIDEBAR_SETTINGS, 'limit_visible_dms_gms').observe().pipe(
switchMap((val) => {
return val[0] ? of$(parseInt(val[0].value, 10)) : of$(0);
}),
);
}
return {

View File

@@ -6,8 +6,8 @@ import {Text, TouchableOpacity, View} from 'react-native';
import Animated, {Easing, useAnimatedStyle, useDerivedValue, useSharedValue, withTiming} from 'react-native-reanimated';
import {toggleCollapseCategory} from '@actions/local/category';
import CompassIcon from '@app/components/compass_icon';
import {useServerUrl} from '@app/context/server';
import CompassIcon from '@components/compass_icon';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';

View File

@@ -1,34 +1,23 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {queryCategoriesByTeamIds} from '@queries/servers/categories';
import {observeCurrentChannelId} from '@queries/servers/system';
import Categories from './categories';
import type {WithDatabaseArgs} from '@typings/database/database';
import type CategoryModel from '@typings/database/models/servers/category';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {CATEGORY, SYSTEM}} = MM_TABLES;
const {CURRENT_CHANNEL_ID} = SYSTEM_IDENTIFIERS;
type WithDatabaseProps = {currentTeamId: string } & WithDatabaseArgs
const enhanced = withObservables(
['currentTeamId'],
({currentTeamId, database}: WithDatabaseProps) => {
const currentChannelId = database.get<SystemModel>(SYSTEM).findAndObserve(CURRENT_CHANNEL_ID).pipe(
switchMap(({value}) => of$(value)),
);
const categories = database.get<CategoryModel>(CATEGORY).query(
Q.where('team_id', currentTeamId),
).observeWithColumns(['sort_order']);
const currentChannelId = observeCurrentChannelId(database);
const categories = queryCategoriesByTeamIds(database, [currentTeamId]).observeWithColumns(['sort_order']);
return {
currentChannelId,

View File

@@ -3,43 +3,33 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {catchError, combineLatest, of as of$, from as from$} from 'rxjs';
import {combineLatest, of as of$, from as from$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {Permissions} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeCurrentTeam} from '@queries/servers/team';
import {observeCurrentUser} from '@queries/servers/user';
import {hasPermissionForTeam} from '@utils/role';
import ChannelListHeader from './header';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
import type TeamModel from '@typings/database/models/servers/team';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {SYSTEM, TEAM, USER}} = MM_TABLES;
const {CURRENT_TEAM_ID, CURRENT_USER_ID} = SYSTEM_IDENTIFIERS;
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const team = database.get<SystemModel>(SYSTEM).findAndObserve(CURRENT_TEAM_ID).pipe(
switchMap((id) => database.get<TeamModel>(TEAM).findAndObserve(id.value)),
catchError(() => of$({displayName: ''})),
);
const team = observeCurrentTeam(database);
const currentUser = database.get<SystemModel>(SYSTEM).findAndObserve(CURRENT_USER_ID).pipe(
switchMap(({value}) => database.get<UserModel>(USER).findAndObserve(value)),
);
const currentUser = observeCurrentUser(database);
const canJoinChannels = combineLatest([currentUser, team]).pipe(
switchMap(([u, t]) => (('id' in t) ? from$(hasPermissionForTeam(t, u, Permissions.JOIN_PUBLIC_CHANNELS, true)) : of$(false))),
switchMap(([u, t]) => (t && u ? from$(hasPermissionForTeam(t, u, Permissions.JOIN_PUBLIC_CHANNELS, true)) : of$(false))),
);
const canCreatePublicChannels = combineLatest([currentUser, team]).pipe(
switchMap(([u, t]) => (('id' in t) ? from$(hasPermissionForTeam(t, u, Permissions.CREATE_PUBLIC_CHANNEL, true)) : of$(false))),
switchMap(([u, t]) => (t && u ? from$(hasPermissionForTeam(t, u, Permissions.CREATE_PUBLIC_CHANNEL, true)) : of$(false))),
);
const canCreatePrivateChannels = combineLatest([currentUser, team]).pipe(
switchMap(([u, t]) => (('id' in t) ? from$(hasPermissionForTeam(t, u, Permissions.CREATE_PRIVATE_CHANNEL, false)) : of$(false))),
switchMap(([u, t]) => (t && u ? from$(hasPermissionForTeam(t, u, Permissions.CREATE_PRIVATE_CHANNEL, false)) : of$(false))),
);
const canCreateChannels = combineLatest([canCreatePublicChannels, canCreatePrivateChannels]).pipe(
@@ -50,7 +40,7 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
canCreateChannels,
canJoinChannels,
displayName: team.pipe(
switchMap((t) => of$(t.displayName)),
switchMap((t) => of$(t?.displayName)),
),
};
});

View File

@@ -5,8 +5,7 @@ import Database from '@nozbe/watermelondb/Database';
import React from 'react';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {MM_TABLES} from '@constants/database';
import {TeamModel} from '@database/models/server';
import {getTeamById} from '@queries/servers/team';
import {renderWithEverything} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
@@ -18,7 +17,7 @@ describe('components/channel_list', () => {
const server = await TestHelper.setupServerDatabase();
database = server.database;
const team = await database.get<TeamModel>(MM_TABLES.SERVER.TEAM).find(TestHelper.basicTeam!.id);
const team = await getTeamById(database, TestHelper.basicTeam!.id);
await database.write(async () => {
await team?.update(() => {
team.displayName = 'Test Team!';

View File

@@ -6,20 +6,18 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES} from '@constants/database';
import {observeTeam} from '@queries/servers/team';
const {SERVER: {TEAM}} = MM_TABLES;
import LoadChannelsError from './load_channel_error';
import type {WithDatabaseArgs} from '@typings/database/database';
import type TeamModel from '@typings/database/models/servers/team';
const enhanced = withObservables(['teamId'], ({database, teamId}: {teamId: string} & WithDatabaseArgs) => {
const team = database.get<TeamModel>(TEAM).findAndObserve(teamId);
const team = observeTeam(database, teamId);
return {
teamDisplayName: team.pipe(
switchMap((t) => of$(t.displayName)),
switchMap((t) => of$(t?.displayName)),
),
};
});

View File

@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import moment, {Moment} from 'moment-timezone';
@@ -15,13 +14,12 @@ import FormattedDate from '@components/formatted_date';
import FormattedText from '@components/formatted_text';
import FormattedTime from '@components/formatted_time';
import {Preferences} from '@constants';
import {MM_TABLES} from '@constants/database';
import {getPreferenceAsBool} from '@helpers/api/preference';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {getCurrentMomentForTimezone} from '@utils/helpers';
import {makeStyleSheetFromTheme} from '@utils/theme';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type UserModel from '@typings/database/models/servers/user';
type Props = {
@@ -128,14 +126,11 @@ const CustomStatusExpiry = ({currentUser, isMilitaryTime, showPrefix, showTimeCo
};
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => ({
isMilitaryTime: database.get<PreferenceModel>(MM_TABLES.SERVER.PREFERENCE).
query(
Q.where('category', Preferences.CATEGORY_DISPLAY_SETTINGS),
).observe().pipe(
switchMap(
(preferences) => of$(getPreferenceAsBool(preferences, Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', false)),
),
isMilitaryTime: queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS).observe().pipe(
switchMap(
(preferences) => of$(getPreferenceAsBool(preferences, Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', false)),
),
),
}));
export default withDatabase(enhanced(CustomStatusExpiry));

View File

@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import React from 'react';
@@ -16,14 +15,14 @@ import FastImage, {ImageStyle} from 'react-native-fast-image';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {useServerUrl} from '@context/server';
import NetworkManager from '@init/network_manager';
import {queryCustomEmojisByName} from '@queries/servers/custom_emoji';
import {observeConfigBooleanValue} from '@queries/servers/system';
import {EmojiIndicesByAlias, Emojis} from '@utils/emoji';
import type {WithDatabaseArgs} from '@typings/database/database';
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
import type SystemModel from '@typings/database/models/servers/system';
const assetImages = new Map([['mattermost.png', require('@assets/images/emojis/mattermost.png')]]);
@@ -149,13 +148,13 @@ const Emoji = (props: Props) => {
const withCustomEmojis = withObservables(['emojiName'], ({database, emojiName}: WithDatabaseArgs & {emojiName: string}) => {
const hasEmojiBuiltIn = EmojiIndicesByAlias.has(emojiName);
const displayTextOnly = hasEmojiBuiltIn ? of$(false) : database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap((config) => of$(config.value.EnableCustomEmoji !== 'true')),
const displayTextOnly = hasEmojiBuiltIn ? of$(false) : observeConfigBooleanValue(database, 'EnableCustomEmoji').pipe(
switchMap((value) => of$(!value)),
);
return {
displayTextOnly,
customEmojis: hasEmojiBuiltIn ? of$([]) : database.get<CustomEmojiModel>(MM_TABLES.SERVER.CUSTOM_EMOJI).query(Q.where('name', emojiName)).observe(),
customEmojis: hasEmojiBuiltIn ? of$([]) : queryCustomEmojisByName(database, [emojiName]).observe(),
};
});

View File

@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import React, {useCallback, useState} from 'react';
@@ -9,16 +8,17 @@ import {useIntl} from 'react-intl';
import {LayoutChangeEvent, Platform, View} from 'react-native';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import {of as of$} from 'rxjs';
import {catchError, switchMap} from 'rxjs/operators';
import {switchMap} from 'rxjs/operators';
import {searchCustomEmojis} from '@actions/remote/custom_emoji';
import SearchBar from '@components/search_bar';
import {Preferences} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {debounce} from '@helpers/api/general';
import {safeParseJSON} from '@utils/helpers';
import {queryAllCustomEmojis} from '@queries/servers/custom_emoji';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeConfigBooleanValue, observeRecentReactions} from '@queries/servers/system';
import {changeOpacity, getKeyboardAppearanceFromTheme, makeStyleSheetFromTheme} from '@utils/theme';
import EmojiFiltered from './filtered';
@@ -26,8 +26,6 @@ import EmojiSections from './sections';
import type {WithDatabaseArgs} from '@typings/database/database';
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type SystemModel from '@typings/database/models/servers/system';
export const SCROLLVIEW_NATIVE_ID = 'emojiSelector';
const edges: Edge[] = ['bottom', 'left', 'right'];
@@ -150,21 +148,10 @@ const EmojiPicker = ({customEmojis, customEmojisEnabled, onEmojiPress, recentEmo
};
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => ({
customEmojisEnabled: database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).
findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap((config) => of$(config.value.EnableCustomEmoji === 'true')),
),
customEmojis: database.get<CustomEmojiModel>(MM_TABLES.SERVER.CUSTOM_EMOJI).query().observe(),
recentEmojis: database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).
findAndObserve(SYSTEM_IDENTIFIERS.RECENT_REACTIONS).
pipe(
switchMap((recent) => of$(safeParseJSON(recent.value) as string[])),
catchError(() => of$([])),
),
skinTone: database.get<PreferenceModel>(MM_TABLES.SERVER.PREFERENCE).query(
Q.where('category', Preferences.CATEGORY_EMOJI),
Q.where('name', Preferences.EMOJI_SKINTONE),
).observe().pipe(
customEmojisEnabled: observeConfigBooleanValue(database, 'EnableCustomEmoji'),
customEmojis: queryAllCustomEmojis(database).observe(),
recentEmojis: observeRecentReactions(database),
skinTone: queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_EMOJI, Preferences.EMOJI_SKINTONE).observe().pipe(
switchMap((prefs) => of$(prefs?.[0]?.value ?? 'default')),
),
}));

View File

@@ -1,37 +1,19 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
import {Preferences} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
import {observeCurrentUserId} from '@queries/servers/system';
import {observeTeammateNameDisplay, queryUsersLike} from '@queries/servers/user';
import AtMention from './at_mention';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {PREFERENCE, SYSTEM, USER}} = MM_TABLES;
const {CONFIG, CURRENT_USER_ID, LICENSE} = SYSTEM_IDENTIFIERS;
const enhance = withObservables(['mentionName'], ({database, mentionName}: {mentionName: string} & WithDatabaseArgs) => {
const config = database.get<SystemModel>(SYSTEM).findAndObserve(CONFIG);
const license = database.get<SystemModel>(SYSTEM).findAndObserve(LICENSE);
const preferences = database.get<PreferenceModel>(PREFERENCE).query(Q.where('category', Preferences.CATEGORY_DISPLAY_SETTINGS)).observe();
const currentUserId = database.get<SystemModel>(SYSTEM).findAndObserve(CURRENT_USER_ID).pipe(
switchMap(({value}) => of$(value)),
);
const teammateNameDisplay = combineLatest([config, license, preferences]).pipe(
map(
([{value: cfg}, {value: lcs}, prefs]) => getTeammateNameDisplaySetting(prefs, cfg, lcs),
),
);
const currentUserId = observeCurrentUserId(database);
const teammateNameDisplay = observeTeammateNameDisplay(database);
let mn = mentionName.toLowerCase();
if ((/[._-]$/).test(mn)) {
@@ -41,11 +23,7 @@ const enhance = withObservables(['mentionName'], ({database, mentionName}: {ment
return {
currentUserId,
teammateNameDisplay,
users: database.get(USER).query(
Q.where('username', Q.like(
`%${Q.sanitizeLikeString(mn)}%`,
)),
).observeWithColumns(['username']),
users: queryUsersLike(database, mn).observeWithColumns(['username']),
};
});

View File

@@ -1,38 +1,34 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {map, switchMap} from 'rxjs/operators';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {queryAllChannelsForTeam} from '@queries/servers/channel';
import {observeCurrentTeamId, observeCurrentUserId} from '@queries/servers/system';
import {observeTeam} from '@queries/servers/team';
import ChannelMention from './channel_mention';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type SystemModel from '@typings/database/models/servers/system';
import type TeamModel from '@typings/database/models/servers/team';
export type ChannelMentions = Record<string, {id?: string; display_name: string; name?: string; team_name: string}>;
const {SERVER: {CHANNEL, SYSTEM, TEAM}} = MM_TABLES;
const enhance = withObservables([], ({database}: WithDatabaseArgs) => {
const currentTeamId = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID);
const currentUserId = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID);
const currentTeamId = observeCurrentTeamId(database);
const currentUserId = observeCurrentUserId(database);
const channels = currentTeamId.pipe(
switchMap(({value}) => database.get<ChannelModel>(CHANNEL).query(Q.where('team_id', value)).observeWithColumns(['display_name'])),
switchMap((id) => queryAllChannelsForTeam(database, id).observeWithColumns(['display_name'])),
);
const team = currentTeamId.pipe(
switchMap(({value}) => database.get<TeamModel>(TEAM).findAndObserve(value)),
switchMap((id) => observeTeam(database, id)),
);
return {
channels,
currentTeamId: currentTeamId.pipe(map((ct) => ct.value)),
currentUserId: currentUserId.pipe(map((cu) => cu.value)),
currentTeamId,
currentUserId,
team,
};
});

View File

@@ -6,24 +6,19 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfig} from '@queries/servers/system';
import MarkdownLink from './markdown_link';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
type ConfigValue = {
value: ClientConfig;
}
const enhance = withObservables([], ({database}: WithDatabaseArgs) => {
const config = database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG);
const config = observeConfig(database);
const experimentalNormalizeMarkdownLinks = config.pipe(
switchMap(({value}: ConfigValue) => of$(value.ExperimentalNormalizeMarkdownLinks)),
switchMap((cfg) => of$(cfg?.ExperimentalNormalizeMarkdownLinks)),
);
const siteURL = config.pipe(
switchMap(({value}: ConfigValue) => of$(value.SiteURL)),
switchMap((cfg) => of$(cfg?.SiteURL)),
);
return {

View File

@@ -6,40 +6,33 @@ import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {DEFAULT_SERVER_MAX_FILE_SIZE} from '@constants/post_draft';
import {observeConfig, observeLicense} from '@queries/servers/system';
import {isMinimumServerVersion} from '@utils/helpers';
import DraftHandler from './draft_handler';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {SYSTEM}} = MM_TABLES;
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const config = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap(({value}) => of$(value as ClientConfig)),
);
const config = observeConfig(database);
const license = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.LICENSE).pipe(
switchMap(({value}) => of$(value as ClientLicense)),
);
const license = observeLicense(database);
const canUploadFiles = combineLatest([config, license]).pipe(
switchMap(([c, l]) => of$(
c.EnableFileAttachments !== 'false' &&
(l.IsLicensed === 'false' || l.Compliance === 'false' || c.EnableMobileFileUpload !== 'false'),
c?.EnableFileAttachments === 'true' ||
(l?.IsLicensed !== 'true' && l?.Compliance !== 'true' && c?.EnableMobileFileUpload === 'true'),
),
),
);
const maxFileSize = config.pipe(
switchMap((cfg) => of$(parseInt(cfg.MaxFileSize || '0', 10) || DEFAULT_SERVER_MAX_FILE_SIZE)),
switchMap((cfg) => of$(parseInt(cfg?.MaxFileSize || '0', 10) || DEFAULT_SERVER_MAX_FILE_SIZE)),
);
const maxFileCount = config.pipe(
switchMap((cfg) => of$(isMinimumServerVersion(cfg.Version, 6, 0) ? 10 : 5)),
switchMap((cfg) => of$(isMinimumServerVersion(cfg?.Version || '', 6, 0) ? 10 : 5)),
);
return {

View File

@@ -1,26 +1,23 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$, from as from$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {General, Permissions} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeChannel} from '@queries/servers/channel';
import {queryDraft} from '@queries/servers/drafts';
import {observeConfigBooleanValue, observeCurrentChannelId} from '@queries/servers/system';
import {observeCurrentUser, observeUser} from '@queries/servers/user';
import {hasPermissionForChannel} from '@utils/role';
import {isSystemAdmin, getUserIdFromChannelName} from '@utils/user';
import PostDraft from './post_draft';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type DraftModel from '@typings/database/models/servers/draft';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {DRAFT, SYSTEM, USER, CHANNEL}} = MM_TABLES;
type OwnProps = {
channelId: string;
@@ -28,50 +25,50 @@ type OwnProps = {
rootId?: string;
}
const observeFirst = (v: DraftModel[]) => v[0]?.observe() || of$(undefined);
const enhanced = withObservables([], (ownProps: WithDatabaseArgs & OwnProps) => {
const {database, rootId = ''} = ownProps;
const draft = database.get<DraftModel>(DRAFT).query(
Q.where('channel_id', ownProps.channelId),
Q.where('root_id', rootId),
).observeWithColumns(['message', 'files']).pipe(switchMap((v) => of$(v[0])));
let channelId = of$(ownProps.channelId);
if (!ownProps.channelId) {
channelId = observeCurrentChannelId(database);
}
const draft = channelId.pipe(
switchMap((cId) => queryDraft(database, cId, rootId).observeWithColumns(['message', 'files']).pipe(
switchMap(observeFirst),
)),
);
const files = draft.pipe(switchMap((d) => of$(d?.files)));
const message = draft.pipe(switchMap((d) => of$(d?.message)));
const currentUser = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => database.get<UserModel>(USER).findAndObserve(value)),
);
let channelId = of$(ownProps.channelId);
if (!ownProps.channelId) {
channelId = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID).pipe(
switchMap((t) => of$(t.value)),
);
}
const currentUser = observeCurrentUser(database);
const channel = channelId.pipe(
switchMap((id) => database.get<ChannelModel>(CHANNEL).findAndObserve(id!)),
switchMap((id) => observeChannel(database, id!)),
);
const canPost = combineLatest([channel, currentUser]).pipe(switchMap(([c, u]) => from$(hasPermissionForChannel(c, u, Permissions.CREATE_POST, false))));
const channelIsArchived = channel.pipe(switchMap((c) => (ownProps.channelIsArchived ? of$(true) : of$(c.deleteAt !== 0))));
const canPost = combineLatest([channel, currentUser]).pipe(switchMap(([c, u]) => (c && u ? from$(hasPermissionForChannel(c, u, Permissions.CREATE_POST, false)) : of$(false))));
const channelIsArchived = channel.pipe(switchMap((c) => (ownProps.channelIsArchived ? of$(true) : of$(c?.deleteAt !== 0))));
const experimentalTownSquareIsReadOnly = database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap(({value}: {value: ClientConfig}) => of$(value.ExperimentalTownSquareIsReadOnly === 'true')),
);
const experimentalTownSquareIsReadOnly = observeConfigBooleanValue(database, 'ExperimentalTownSquareIsReadOnly');
const channelIsReadOnly = combineLatest([currentUser, channel, experimentalTownSquareIsReadOnly]).pipe(
switchMap(([u, c, readOnly]) => of$(c?.name === General.DEFAULT_CHANNEL && !isSystemAdmin(u.roles) && readOnly)),
switchMap(([u, c, readOnly]) => of$(c?.name === General.DEFAULT_CHANNEL && !isSystemAdmin(u?.roles || '') && readOnly)),
);
const deactivatedChannel = combineLatest([currentUser, channel]).pipe(
switchMap(([u, c]) => {
if (!u || !c) {
return of$(false);
}
if (c.type !== General.DM_CHANNEL) {
return of$(false);
}
const teammateId = getUserIdFromChannelName(u.id, c.name);
if (teammateId) {
return database.get<UserModel>(USER).findAndObserve(teammateId).pipe(
switchMap((u2) => of$(Boolean(u2.deleteAt))), // eslint-disable-line max-nested-callbacks
return observeUser(database, teammateId).pipe(
switchMap((u2) => (u2 ? of$(Boolean(u2.deleteAt)) : of$(false))), // eslint-disable-line max-nested-callbacks
);
}
return of$(true);

View File

@@ -6,16 +6,13 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeChannel, observeCurrentChannel} from '@queries/servers/channel';
import {observeConfig} from '@queries/servers/system';
import PostInput from './post_input';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {SYSTEM, CHANNEL}} = MM_TABLES;
type OwnProps = {
channelId: string;
@@ -23,35 +20,33 @@ type OwnProps = {
}
const enhanced = withObservables([], ({database, channelId, rootId}: WithDatabaseArgs & OwnProps) => {
const config = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG);
const config = observeConfig(database);
const timeBetweenUserTypingUpdatesMilliseconds = config.pipe(
switchMap(({value}: {value: ClientConfig}) => of$(parseInt(value.TimeBetweenUserTypingUpdatesMilliseconds, 10))),
switchMap((cfg) => of$(parseInt(cfg?.TimeBetweenUserTypingUpdatesMilliseconds || '0', 10))),
);
const enableUserTypingMessage = config.pipe(
switchMap(({value}: {value: ClientConfig}) => of$(value.EnableUserTypingMessages === 'true')),
switchMap((cfg) => of$(cfg?.EnableUserTypingMessages === 'true')),
);
const maxNotificationsPerChannel = config.pipe(
switchMap(({value}: {value: ClientConfig}) => of$(parseInt(value.MaxNotificationsPerChannel, 10))),
switchMap((cfg) => of$(parseInt(cfg?.MaxNotificationsPerChannel || '0', 10))),
);
let channel;
if (rootId) {
channel = database.get<ChannelModel>(CHANNEL).findAndObserve(channelId);
channel = observeChannel(database, channelId);
} else {
channel = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID).pipe(
switchMap((t) => database.get<ChannelModel>(CHANNEL).findAndObserve(t.value)),
);
channel = observeCurrentChannel(database);
}
const channelDisplayName = channel.pipe(
switchMap((c) => of$(c.displayName)),
switchMap((c) => of$(c?.displayName)),
);
const channelInfo = channel.pipe(switchMap((c) => c.info.observe()));
const membersInChannel = channelInfo.pipe(
const membersInChannel = channel.pipe(
switchMap((c) => (c ? c.info.observe() : of$({memberCount: 0}))),
).pipe(
switchMap((i: ChannelInfoModel) => of$(i.memberCount)),
);

View File

@@ -6,34 +6,27 @@ import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfig, observeLicense} from '@queries/servers/system';
import {isMinimumServerVersion} from '@utils/helpers';
import QuickActions from './quick_actions';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {SYSTEM}} = MM_TABLES;
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const config = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap(({value}) => of$(value as ClientConfig)),
);
const license = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.LICENSE).pipe(
switchMap(({value}) => of$(value as ClientLicense)),
);
const config = observeConfig(database);
const license = observeLicense(database);
const canUploadFiles = combineLatest([config, license]).pipe(
switchMap(([c, l]) => of$(
c.EnableFileAttachments !== 'false' &&
(l.IsLicensed === 'false' || l.Compliance === 'false' || c.EnableMobileFileUpload !== 'false'),
c?.EnableFileAttachments === 'true' ||
(l?.IsLicensed !== 'true' && l?.Compliance !== 'true' && c?.EnableMobileFileUpload === 'true'),
),
),
);
const maxFileCount = config.pipe(
switchMap((cfg) => of$(isMinimumServerVersion(cfg.Version, 6, 0) ? 10 : 5)),
switchMap((cfg) => of$(isMinimumServerVersion(cfg?.Version || '', 6, 0) ? 10 : 5)),
);
return {

View File

@@ -7,20 +7,16 @@ import {combineLatest, of as of$, from as from$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {General, Permissions} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {MAX_MESSAGE_LENGTH_FALLBACK} from '@constants/post_draft';
import {observeChannel, observeCurrentChannel} from '@queries/servers/channel';
import {queryAllCustomEmojis} from '@queries/servers/custom_emoji';
import {observeConfig, observeCurrentUserId} from '@queries/servers/system';
import {observeUser} from '@queries/servers/user';
import {hasPermissionForChannel} from '@utils/role';
import SendHandler from './send_handler';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {SYSTEM, USER, CHANNEL, CUSTOM_EMOJI}} = MM_TABLES;
type OwnProps = {
rootId: string;
@@ -33,34 +29,28 @@ const enhanced = withObservables([], (ownProps: WithDatabaseArgs & OwnProps) =>
const {rootId, channelId} = ownProps;
let channel;
if (rootId) {
channel = database.get<ChannelModel>(CHANNEL).findAndObserve(channelId);
channel = observeChannel(database, channelId);
} else {
channel = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID).pipe(
switchMap((t) => database.get<ChannelModel>(CHANNEL).findAndObserve(t.value)),
);
channel = observeCurrentChannel(database);
}
const currentUserId = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => of$(value)),
);
const currentUserId = observeCurrentUserId(database);
const currentUser = currentUserId.pipe(
switchMap((id) => database.get<UserModel>(USER).findAndObserve(id)),
);
switchMap((id) => observeUser(database, id),
));
const userIsOutOfOffice = currentUser.pipe(
switchMap((u) => of$(u.status === General.OUT_OF_OFFICE)),
switchMap((u) => of$(u?.status === General.OUT_OF_OFFICE)),
);
const config = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap(({value}) => of$(value as ClientConfig)),
);
const config = observeConfig(database);
const enableConfirmNotificationsToChannel = config.pipe(
switchMap((cfg) => of$(Boolean(cfg.EnableConfirmNotificationsToChannel === 'true'))),
switchMap((cfg) => of$(Boolean(cfg?.EnableConfirmNotificationsToChannel === 'true'))),
);
const isTimezoneEnabled = config.pipe(
switchMap((cfg) => of$(Boolean(cfg.ExperimentalTimezone === 'true'))),
switchMap((cfg) => of$(Boolean(cfg?.ExperimentalTimezone === 'true'))),
);
const maxMessageLength = config.pipe(
switchMap((cfg) => of$(parseInt(cfg.MaxPostSize || '0', 10) || MAX_MESSAGE_LENGTH_FALLBACK)),
switchMap((cfg) => of$(parseInt(cfg?.MaxPostSize || '0', 10) || MAX_MESSAGE_LENGTH_FALLBACK)),
);
const useChannelMentions = combineLatest([channel, currentUser]).pipe(
@@ -69,16 +59,16 @@ const enhanced = withObservables([], (ownProps: WithDatabaseArgs & OwnProps) =>
return of$(true);
}
return from$(hasPermissionForChannel(c, u, Permissions.USE_CHANNEL_MENTIONS, false));
return u ? from$(hasPermissionForChannel(c, u, Permissions.USE_CHANNEL_MENTIONS, false)) : of$(false);
}),
);
const channelInfo = channel.pipe(switchMap((c) => c.info.observe()));
const channelInfo = channel.pipe(switchMap((c) => (c ? c.info.observe() : of$(undefined))));
const membersCount = channelInfo.pipe(
switchMap((i: ChannelInfoModel) => of$(i.memberCount)),
switchMap((i) => (i ? of$(i.memberCount) : of$(0))),
);
const customEmojis = database.get<CustomEmojiModel>(CUSTOM_EMOJI).query().observe();
const customEmojis = queryAllCustomEmojis(database).observe();
return {
currentUserId,

View File

@@ -1,50 +1,38 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {combineLatest, from as from$, of as of$} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
import {Permissions} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {queryPostsById} from '@queries/servers/post';
import {observeCurrentUserId} from '@queries/servers/system';
import {observeUser, queryUsersByIdsOrUsernames} from '@queries/servers/user';
import {generateCombinedPost, getPostIdsForCombinedUserActivityPost} from '@utils/post_list';
import {hasPermissionForPost} from '@utils/role';
import CombinedUserActivity from './combined_user_activity';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PostModel from '@typings/database/models/servers/post';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {POST, SYSTEM, USER}} = MM_TABLES;
const withCombinedPosts = withObservables(['postId'], ({database, postId}: WithDatabaseArgs & {postId: string}) => {
const currentUserId = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
map(({value}: {value: string}) => value),
);
const currentUserId = observeCurrentUserId(database);
const currentUser = currentUserId.pipe(
switchMap((value) => database.get<UserModel>(USER).findAndObserve(value)),
switchMap((value) => observeUser(database, value)),
);
const postIds = getPostIdsForCombinedUserActivityPost(postId);
const posts = database.get<PostModel>(POST).query(
Q.where('id', Q.oneOf(postIds)),
).observe();
const posts = queryPostsById(database, postIds).observe();
const post = posts.pipe(map((ps) => generateCombinedPost(postId, ps)));
const canDelete = combineLatest([posts, currentUser]).pipe(
switchMap(([ps, u]) => from$(hasPermissionForPost(ps[0], u, Permissions.DELETE_OTHERS_POSTS, false))),
switchMap(([ps, u]) => (u ? from$(hasPermissionForPost(ps[0], u, Permissions.DELETE_OTHERS_POSTS, false)) : of$(false))),
);
const usernamesById = post.pipe(
switchMap(
(p) => database.get<UserModel>(USER).query(
Q.or(
Q.where('id', Q.oneOf(p.props.user_activity.allUserIds)),
Q.where('username', Q.oneOf(p.props.user_activity.allUsernames)),
)).observe().
(p) => queryUsersByIdsOrUsernames(database, p.props.user_activity.allUserIds, p.props.user_activity.allUsernames).observe().
pipe(
// eslint-disable-next-line max-nested-callbacks
switchMap((users) => {

View File

@@ -6,20 +6,16 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {Database} from '@constants';
import {observeMyChannel} from '@queries/servers/channel';
import MoreMessages from './more_messages';
import type {WithDatabaseArgs} from '@typings/database/database';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
const {MM_TABLES} = Database;
const {SERVER: {MY_CHANNEL}} = MM_TABLES;
const enhanced = withObservables(['channelId'], ({channelId, database}: {channelId: string} & WithDatabaseArgs) => {
const myChannel = database.get<MyChannelModel>(MY_CHANNEL).findAndObserve(channelId);
const isManualUnread = myChannel.pipe(switchMap((ch) => of$(ch.manuallyUnread)));
const unreadCount = myChannel.pipe(switchMap((ch) => of$(ch.messageCount)));
const myChannel = observeMyChannel(database, channelId);
const isManualUnread = myChannel.pipe(switchMap((ch) => of$(ch?.manuallyUnread)));
const unreadCount = myChannel.pipe(switchMap((ch) => of$(ch?.messageCount)));
return {
isManualUnread,

View File

@@ -3,21 +3,16 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import enhance from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfigBooleanValue} from '@queries/servers/system';
import Avatar from './avatar';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PostModel from '@typings/database/models/servers/post';
import type SystemModel from '@typings/database/models/servers/system';
const withPost = enhance(['post'], ({database, post}: {post: PostModel} & WithDatabaseArgs) => {
const enablePostIconOverride = database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap((cfg) => of$(cfg.value.EnablePostIconOverride === 'true')),
);
const enablePostIconOverride = observeConfigBooleanValue(database, 'EnablePostIconOverride');
return {
author: post.author.observe(),

View File

@@ -6,21 +6,16 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeCurrentUser} from '@queries/servers/user';
import AddMembers from './add_members';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostModel from '@typings/database/models/servers/post';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {SYSTEM, USER}} = MM_TABLES;
const enhance = withObservables(['post'], ({database, post}: WithDatabaseArgs & {post: PostModel}) => ({
currentUser: database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => database.get(USER).findAndObserve(value)),
),
currentUser: observeCurrentUser(database),
channelType: post.channel.observe().pipe(
switchMap(
(channel: ChannelModel) => (channel ? of$(channel.type) : of$(null)),

View File

@@ -9,8 +9,8 @@ import {map} from 'rxjs/operators';
import {doAppCall, postEphemeralCallResponseForPost} from '@actions/remote/apps';
import {AppExpandLevels, AppBindingLocations, AppCallTypes, AppCallResponseTypes} from '@constants/apps';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {useServerUrl} from '@context/server';
import {observeCurrentTeamId} from '@queries/servers/system';
import {createCallContext, createCallRequest} from '@utils/apps';
import {getStatusColors} from '@utils/message_attachment_colors';
import {preventDoubleTap} from '@utils/tap';
@@ -20,7 +20,6 @@ import ButtonBindingText from './button_binding_text';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostModel from '@typings/database/models/servers/post';
import type SystemModel from '@typings/database/models/servers/system';
type Props = {
currentTeamId: string;
@@ -30,8 +29,6 @@ type Props = {
theme: Theme;
}
const {SERVER: {SYSTEM}} = MM_TABLES;
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
const STATUS_COLORS = getStatusColors(theme);
return {
@@ -136,9 +133,7 @@ const ButtonBinding = ({currentTeamId, binding, post, teamID, theme}: Props) =>
const withTeamId = withObservables(['post'], ({post}: {post: PostModel}) => ({
teamID: post.channel.observe().pipe(map((channel: ChannelModel) => channel.teamId)),
currentTeamId: post.collections.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID).pipe(
map(({value}) => value),
),
currentTeamId: observeCurrentTeamId(post.database),
}));
export default withTeamId(ButtonBinding);

View File

@@ -9,13 +9,12 @@ import {map} from 'rxjs/operators';
import {doAppCall, postEphemeralCallResponseForPost} from '@actions/remote/apps';
import AutocompleteSelector from '@components/autocomplete_selector';
import {AppExpandLevels, AppBindingLocations, AppCallTypes, AppCallResponseTypes} from '@constants/apps';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {useServerUrl} from '@context/server';
import {observeCurrentTeamId} from '@queries/servers/system';
import {createCallContext, createCallRequest} from '@utils/apps';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostModel from '@typings/database/models/servers/post';
import type SystemModel from '@typings/database/models/servers/system';
type Props = {
binding: AppBinding;
@@ -25,8 +24,6 @@ type Props = {
theme: Theme;
}
const {SERVER: {SYSTEM}} = MM_TABLES;
const MenuBinding = ({binding, currentTeamId, post, teamID, theme}: Props) => {
const [selected, setSelected] = useState<PostActionOption>();
const intl = useIntl();
@@ -109,9 +106,7 @@ const MenuBinding = ({binding, currentTeamId, post, teamID, theme}: Props) => {
const withTeamId = withObservables(['post'], ({post}: {post: PostModel}) => ({
teamID: post.channel.observe().pipe(map((channel: ChannelModel) => channel.teamId)),
currentTeamId: post.collections.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID).pipe(
map(({value}) => value),
),
currentTeamId: observeCurrentTeamId(post.database),
}));
export default withTeamId(MenuBinding);

View File

@@ -1,28 +1,24 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeExpandedLinks} from '@queries/servers/system';
import ImagePreview from './image_preview';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
const enhance = withObservables(['metadata'], ({database, metadata}: WithDatabaseArgs & {metadata: PostMetadata}) => {
const link = metadata.embeds?.[0].url;
return {
expandedLink: database.get(MM_TABLES.SERVER.SYSTEM).query(
Q.where('id', SYSTEM_IDENTIFIERS.EXPANDED_LINKS),
).observe().pipe(
switchMap((values: SystemModel[]) => (
(link && values.length) ? of$((values[0].value as Record<string, string>)[link]) : of$(undefined)),
expandedLink: observeExpandedLinks(database).pipe(
switchMap((expandedLinks) => (
link ? of$(expandedLinks[link]) : of$(undefined)),
),
),
link: of$(link),

View File

@@ -1,21 +1,18 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {of as of$, combineLatest} from 'rxjs';
import {Preferences} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {getPreferenceAsBool} from '@helpers/api/preference';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeConfig} from '@queries/servers/system';
import Opengraph from './opengraph';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type SystemModel from '@typings/database/models/servers/system';
const enhance = withObservables(
['removeLinkPreview'],
@@ -24,21 +21,12 @@ const enhance = withObservables(
return {showLinkPreviews: of$(false)};
}
const showLinkPreviews = database.get(MM_TABLES.SERVER.PREFERENCE).query(
Q.where('category', Preferences.CATEGORY_DISPLAY_SETTINGS),
Q.where('name', Preferences.LINK_PREVIEW_DISPLAY),
).observe().pipe(
switchMap(
(preferences: PreferenceModel[]) => database.get(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
// eslint-disable-next-line max-nested-callbacks
switchMap((config: SystemModel) => {
const cfg: ClientConfig = config.value;
const previewsEnabled = getPreferenceAsBool(preferences, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.LINK_PREVIEW_DISPLAY, true);
return of$(previewsEnabled && cfg.EnableLinkPreviews === 'true');
}),
),
),
);
const config = observeConfig(database);
const linkPreviewPreference = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.LINK_PREVIEW_DISPLAY).observe();
const showLinkPreviews = combineLatest([config, linkPreviewPreference], (cfg, pref) => {
const previewsEnabled = getPreferenceAsBool(pref, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.LINK_PREVIEW_DISPLAY, true);
return of$(previewsEnabled && cfg?.EnableLinkPreviews === 'true');
});
return {showLinkPreviews};
},

View File

@@ -3,22 +3,15 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfigValue} from '@queries/servers/system';
import YouTube from './youtube';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
const enhance = withObservables([], ({database}: WithDatabaseArgs) => ({
googleDeveloperKey: database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap(({value}: {value: ClientConfig}) => {
return of$(value.GoogleDeveloperKey);
}),
),
googleDeveloperKey: observeConfigValue(database, 'GoogleDeveloperKey'),
}));
export default withDatabase(enhance(YouTube));

View File

@@ -6,7 +6,7 @@ import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$, from as from$} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfig, observeLicense} from '@queries/servers/system';
import {fileExists} from '@utils/file';
import Files from './files';
@@ -14,7 +14,6 @@ import Files from './files';
import type {WithDatabaseArgs} from '@typings/database/database';
import type FileModel from '@typings/database/models/servers/file';
import type PostModel from '@typings/database/models/servers/post';
import type SystemModel from '@typings/database/models/servers/system';
type EnhanceProps = WithDatabaseArgs & {
post: PostModel;
@@ -37,17 +36,17 @@ const filesLocalPathValidation = async (files: FileModel[], authorId: string) =>
};
const enhance = withObservables(['post'], ({database, post}: EnhanceProps) => {
const config = database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG);
const config = observeConfig(database);
const enableMobileFileDownload = config.pipe(
switchMap(({value}: {value: ClientConfig}) => of$(value.EnableMobileFileDownload !== 'false')),
switchMap((cfg) => of$(cfg?.EnableMobileFileDownload !== 'false')),
);
const publicLinkEnabled = config.pipe(
switchMap(({value}: {value: ClientConfig}) => of$(value.EnablePublicLink !== 'false')),
switchMap((cfg) => of$(cfg?.EnablePublicLink !== 'false')),
);
const complianceDisabled = database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.LICENSE).pipe(
switchMap(({value}: {value: ClientLicense}) => of$(value.IsLicensed === 'false' || value.Compliance === 'false')),
const complianceDisabled = observeLicense(database).pipe(
switchMap((lcs) => of$(lcs?.IsLicensed === 'false' || lcs?.Compliance === 'false')),
);
const canDownloadFiles = combineLatest([enableMobileFileDownload, complianceDisabled]).pipe(

View File

@@ -3,22 +3,15 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeCurrentUser} from '@queries/servers/user';
import Message from './message';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {SYSTEM, USER}} = MM_TABLES;
const withMessageInput = withObservables([], ({database}: WithDatabaseArgs) => {
const currentUser = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => database.get<UserModel>(USER).findAndObserve(value)),
);
const currentUser = observeCurrentUser(database);
return {
currentUser,
};

View File

@@ -7,7 +7,8 @@ import {combineLatest, from as from$, of as of$} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
import {General, Permissions} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfigBooleanValue, observeCurrentUserId} from '@queries/servers/system';
import {observeUser} from '@queries/servers/user';
import {hasPermissionForPost} from '@utils/role';
import {isSystemAdmin} from '@utils/user';
@@ -17,30 +18,24 @@ import type {Relation} from '@nozbe/watermelondb';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostModel from '@typings/database/models/servers/post';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
type WithReactionsInput = WithDatabaseArgs & {
post: PostModel;
}
const withReactions = withObservables(['post'], ({database, post}: WithReactionsInput) => {
const currentUserId = database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
map(({value}: {value: string}) => value),
);
const currentUserId = observeCurrentUserId(database);
const currentUser = currentUserId.pipe(
switchMap((id) => database.get<UserModel>(MM_TABLES.SERVER.USER).findAndObserve(id)),
switchMap((id) => observeUser(database, id)),
);
const channel = (post.channel as Relation<ChannelModel>).observe();
const experimentalTownSquareIsReadOnly = database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
map(({value}: {value: ClientConfig}) => value.ExperimentalTownSquareIsReadOnly === 'true'),
);
const experimentalTownSquareIsReadOnly = observeConfigBooleanValue(database, 'ExperimentalTownSquareIsReadOnly');
const disabled = combineLatest([currentUser, channel, experimentalTownSquareIsReadOnly]).pipe(
map(([u, c, readOnly]) => ((c && c.deleteAt > 0) || (c?.name === General.DEFAULT_CHANNEL && !isSystemAdmin(u.roles) && readOnly))),
map(([u, c, readOnly]) => ((c && c.deleteAt > 0) || (c?.name === General.DEFAULT_CHANNEL && !isSystemAdmin(u?.roles || '') && readOnly))),
);
const canAddReaction = currentUser.pipe(switchMap((u) => from$(hasPermissionForPost(post, u, Permissions.ADD_REACTION, true))));
const canRemoveReaction = currentUser.pipe(switchMap((u) => from$(hasPermissionForPost(post, u, Permissions.REMOVE_REACTION, true))));
const canAddReaction = currentUser.pipe(switchMap((u) => (u ? from$(hasPermissionForPost(post, u, Permissions.ADD_REACTION, true)) : of$(true))));
const canRemoveReaction = currentUser.pipe(switchMap((u) => (u ? from$(hasPermissionForPost(post, u, Permissions.REMOVE_REACTION, true)) : of$(true))));
return {
canAddReaction,

View File

@@ -1,51 +1,43 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
import {Preferences} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {getPreferenceAsBool, getTeammateNameDisplaySetting} from '@helpers/api/preference';
import {queryPostsInThread} from '@queries/servers/post';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeConfig, observeLicense} from '@queries/servers/system';
import {isMinimumServerVersion} from '@utils/helpers';
import Header from './header';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PostModel from '@typings/database/models/servers/post';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type SystemModel from '@typings/database/models/servers/system';
type HeaderInputProps = {
differentThreadSequence: boolean;
post: PostModel;
};
const {SERVER: {POST, PREFERENCE, SYSTEM}} = MM_TABLES;
const withHeaderProps = withObservables(
['post', 'differentThreadSequence'],
({post, database, differentThreadSequence}: WithDatabaseArgs & HeaderInputProps) => {
const config = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(switchMap(({value}) => of$(value as ClientConfig)));
const license = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.LICENSE).pipe(switchMap(({value}) => of$(value as ClientLicense)));
const preferences = database.get<PreferenceModel>(PREFERENCE).query(Q.where('category', Preferences.CATEGORY_DISPLAY_SETTINGS)).observe();
const config = observeConfig(database);
const license = observeLicense(database);
const preferences = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS).observe();
const author = post.author.observe();
const enablePostUsernameOverride = config.pipe(map((cfg) => cfg.EnablePostUsernameOverride === 'true'));
const isTimezoneEnabled = config.pipe(map((cfg) => cfg.ExperimentalTimezone === 'true'));
const enablePostUsernameOverride = config.pipe(map((cfg) => cfg?.EnablePostUsernameOverride === 'true'));
const isTimezoneEnabled = config.pipe(map((cfg) => cfg?.ExperimentalTimezone === 'true'));
const isMilitaryTime = preferences.pipe(map((prefs) => getPreferenceAsBool(prefs, Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', false)));
const isCustomStatusEnabled = config.pipe(map((cfg) => cfg.EnableCustomUserStatuses === 'true' && isMinimumServerVersion(cfg.Version, 5, 36)));
const isCustomStatusEnabled = config.pipe(map((cfg) => cfg?.EnableCustomUserStatuses === 'true' && isMinimumServerVersion(cfg.Version, 5, 36)));
const teammateNameDisplay = combineLatest([preferences, config, license]).pipe(
map(([prefs, cfg, lcs]) => getTeammateNameDisplaySetting(prefs, cfg, lcs)),
);
const commentCount = database.get(POST).query(
Q.and(
Q.where('root_id', (post.rootId || post.id)),
Q.where('delete_at', Q.eq(0)),
),
).observeCount();
const commentCount = queryPostsInThread(database, post.rootId || post.id).observeCount();
const rootPostAuthor = differentThreadSequence ? post.root.observe().pipe(switchMap((root) => {
if (root.length) {
return root[0].author.observe();

View File

@@ -1,15 +1,17 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {from as from$, of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {Permissions, Preferences} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {appsEnabled} from '@utils/apps';
import {queryAllCustomEmojis} from '@queries/servers/custom_emoji';
import {queryPostsBetween} from '@queries/servers/post';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeConfigBooleanValue} from '@queries/servers/system';
import {observeCurrentUser} from '@queries/servers/user';
import {hasJumboEmojiOnly} from '@utils/emoji/helpers';
import {areConsecutivePosts, isPostEphemeral} from '@utils/post';
import {canManageChannelMembers, hasPermissionForPost} from '@utils/role';
@@ -20,14 +22,10 @@ import type {WithDatabaseArgs} from '@typings/database/database';
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
import type PostModel from '@typings/database/models/servers/post';
import type PostsInThreadModel from '@typings/database/models/servers/posts_in_thread';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {CUSTOM_EMOJI, POST, PREFERENCE, SYSTEM, USER}} = MM_TABLES;
type PropsInput = WithDatabaseArgs & {
featureFlagAppsEnabled?: string;
appsEnabled: boolean;
currentUser: UserModel;
nextPost: PostModel | undefined;
post: PostModel;
@@ -38,13 +36,7 @@ async function shouldHighlightReplyBar(currentUser: UserModel, post: PostModel,
let commentsNotifyLevel = Preferences.COMMENTS_NEVER;
let threadCreatedByCurrentUser = false;
let rootPost: PostModel | undefined;
const myPosts = await postsInThread.collections.get(POST).query(
Q.and(
Q.where('root_id', post.rootId || post.id),
Q.where('create_at', Q.between(postsInThread.earliest, postsInThread.latest)),
Q.where('user_id', currentUser.id),
),
).fetch();
const myPosts = await queryPostsBetween(postsInThread.database, postsInThread.earliest, postsInThread.latest, null, currentUser.id, '', post.rootId || post.id).fetch();
const threadRepliedToByCurrentUser = myPosts.length > 0;
const root = await post.root.fetch();
@@ -82,17 +74,13 @@ function isFirstReply(post: PostModel, previousPost?: PostModel) {
}
const withSystem = withObservables([], ({database}: WithDatabaseArgs) => ({
featureFlagAppsEnabled: database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap((cfg) => of$(cfg.value.FeatureFlagAppsEnabled)),
),
currentUser: database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap((currentUserId) => database.get<UserModel>(USER).findAndObserve(currentUserId.value)),
),
appsEnabled: observeConfigBooleanValue(database, 'FeatureFlagAppsEnabled'),
currentUser: observeCurrentUser(database),
}));
const withPost = withObservables(
['currentUser', 'post', 'previousPost', 'nextPost'],
({featureFlagAppsEnabled, currentUser, database, post, previousPost, nextPost}: PropsInput) => {
({appsEnabled, currentUser, database, post, previousPost, nextPost}: PropsInput) => {
let isJumboEmoji = of$(false);
let isLastReply = of$(true);
let isPostAddChannelMember = of$(false);
@@ -100,10 +88,9 @@ const withPost = withObservables(
const author = post.author.observe();
const canDelete = from$(hasPermissionForPost(post, currentUser, isOwner ? Permissions.DELETE_POST : Permissions.DELETE_OTHERS_POSTS, false));
const isEphemeral = of$(isPostEphemeral(post));
const isSaved = database.get<PreferenceModel>(PREFERENCE).query(
Q.where('category', Preferences.CATEGORY_SAVED_POST),
Q.where('name', post.id),
).observe().pipe(switchMap((pref) => of$(Boolean(pref.length))));
const isSaved = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_SAVED_POST, post.id).observe().pipe(
switchMap((pref) => of$(Boolean(pref.length))),
);
if (post.props?.add_channel_member && isPostEphemeral(post)) {
isPostAddChannelMember = from$(canManageChannelMembers(post, currentUser));
@@ -124,7 +111,7 @@ const withPost = withObservables(
}
if (post.message.length && !(/^\s{4}/).test(post.message)) {
isJumboEmoji = post.collections.get(CUSTOM_EMOJI).query().observe().pipe(
isJumboEmoji = queryAllCustomEmojis(post.database).observe().pipe(
// eslint-disable-next-line max-nested-callbacks
switchMap((customEmojis: CustomEmojiModel[]) => of$(hasJumboEmojiOnly(post.message, customEmojis.map((c) => c.name))),
),
@@ -132,15 +119,11 @@ const withPost = withObservables(
}
const hasReplies = from$(post.hasReplies());
const isConsecutivePost = author.pipe(
switchMap((user) => of$(Boolean(post && previousPost && !user.isBot && areConsecutivePosts(post, previousPost)))),
switchMap((user) => of$(Boolean(post && previousPost && !user?.isBot && areConsecutivePosts(post, previousPost)))),
);
const partialConfig: Partial<ClientConfig> = {
FeatureFlagAppsEnabled: featureFlagAppsEnabled,
};
return {
appsEnabled: of$(appsEnabled(partialConfig)),
appsEnabled: of$(appsEnabled),
canDelete,
differentThreadSequence: of$(differentThreadSequence),
filesCount: post.files.observeCount(),

View File

@@ -1,45 +1,30 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {Preferences} from '@constants';
import {MM_TABLES} from '@constants/database';
import {observePost, queryPostsInThread} from '@queries/servers/post';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import ThreadOverview from './thread_overview';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PostModel from '@typings/database/models/servers/post';
import type PreferenceModel from '@typings/database/models/servers/preference';
const {SERVER: {POST, PREFERENCE}} = MM_TABLES;
const enhanced = withObservables(
['rootId'],
({database, rootId}: WithDatabaseArgs & {rootId: string}) => {
return {
rootPost: database.get<PostModel>(POST).query(
Q.where('id', rootId),
).observe().pipe(
// Root post might not have loaded while the thread screen is opening
switchMap((posts) => posts[0]?.observe() || of$(undefined)),
),
isSaved: database.
get<PreferenceModel>(PREFERENCE).
query(Q.where('category', Preferences.CATEGORY_SAVED_POST), Q.where('name', rootId)).
rootPost: observePost(database, rootId),
isSaved: queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_SAVED_POST, rootId).
observe().
pipe(
switchMap((pref) => of$(Boolean(pref[0]?.value === 'true'))),
),
repliesCount: database.get(POST).query(
Q.where('root_id', rootId),
Q.where('delete_at', Q.eq(0)),
).observeCount(),
repliesCount: queryPostsInThread(database, rootId).observeCount(),
};
});

View File

@@ -7,14 +7,14 @@ import {Keyboard, Platform, View} from 'react-native';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {deleteSavedPost, savePostPreference} from '@actions/remote/preference';
import FormattedText from '@app/components/formatted_text';
import {Screens} from '@app/constants';
import {preventDoubleTap} from '@app/utils/tap';
import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import {bottomSheetModalOptions, showModal, showModalOverCurrentContext} from '@screens/navigation';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';

View File

@@ -7,18 +7,17 @@ import {switchMap, of as of$} from 'rxjs';
import ChannelInfo from './channel_info';
import type PostModel from '@typings/database/models/servers/post';
import type TeamModel from '@typings/database/models/servers/team';
const enhance = withObservables(['post'], ({post}: {post: PostModel}) => {
const channel = post.channel.observe();
return {
channelName: channel.pipe(
switchMap((chan) => of$(chan.displayName)),
switchMap((chan) => (chan ? of$(chan.displayName) : '')),
),
teamName: channel.pipe(
switchMap((chan) => chan.team || of$(null)),
switchMap((team: TeamModel|null) => of$(team?.displayName || null)),
switchMap((chan) => (chan ? chan.team.observe() : of$(null))),
switchMap((team) => of$(team?.displayName || null)),
),
};
});

View File

@@ -5,26 +5,22 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {useEffect} from 'react';
import {useIntl} from 'react-intl';
import {of as of$} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
import {map} from 'rxjs/operators';
import {SupportedServer} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeConfigValue} from '@queries/servers/system';
import {observeCurrentUser} from '@queries/servers/user';
import {isMinimumServerVersion} from '@utils/helpers';
import {unsupportedServer} from '@utils/server';
import {isSystemAdmin} from '@utils/user';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
type ServerVersionProps = WithDatabaseArgs & {
version?: string;
roles: string;
};
const {SERVER: {SYSTEM, USER}} = MM_TABLES;
const ServerVersion = ({version, roles}: ServerVersionProps) => {
const intl = useIntl();
@@ -46,16 +42,9 @@ const ServerVersion = ({version, roles}: ServerVersionProps) => {
};
const enahanced = withObservables([], ({database}: WithDatabaseArgs) => ({
varsion: database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG).pipe(
switchMap(({value}: {value: ClientConfig}) => of$(value.Version)),
),
roles: database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(
({value}) => database.get<UserModel>(USER).findAndObserve(value).pipe(
// eslint-disable-next-line max-nested-callbacks
map((user) => user.roles),
),
),
version: observeConfigValue(database, 'Version'),
roles: observeCurrentUser(database).pipe(
map((user) => user?.roles),
),
}));

View File

@@ -1,25 +1,24 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import React from 'react';
import {View} from 'react-native';
import {map, switchMap} from 'rxjs/operators';
import {map} from 'rxjs/operators';
import FormattedText from '@components/formatted_text';
import FormattedTime from '@components/formatted_time';
import {Preferences} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {getPreferenceAsBool} from '@helpers/api/preference';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeConfig} from '@queries/servers/system';
import {observeCurrentUser} from '@queries/servers/user';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import {getUserTimezone} from '@utils/user';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type SystemModel from '@typings/database/models/servers/system';
import type UserModel from '@typings/database/models/servers/user';
type Props = {
@@ -30,8 +29,6 @@ type Props = {
user: UserModel;
}
const {SERVER: {PREFERENCE, SYSTEM, USER}} = MM_TABLES;
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
return {
displayName: {
@@ -83,17 +80,13 @@ const SystemHeader = ({isMilitaryTime, isTimezoneEnabled, createAt, theme, user}
};
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const config = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG);
const preferences = database.get<PreferenceModel>(PREFERENCE).query(
Q.where('category', Preferences.CATEGORY_DISPLAY_SETTINGS), Q.where('name', 'use_military_time'),
).observe();
const isTimezoneEnabled = config.pipe(map(({value}: {value: ClientConfig}) => value.ExperimentalTimezone === 'true'));
const config = observeConfig(database);
const preferences = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time').observe();
const isTimezoneEnabled = config.pipe(map((cfg) => cfg?.ExperimentalTimezone === 'true'));
const isMilitaryTime = preferences.pipe(
map((prefs) => getPreferenceAsBool(prefs, Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', false)),
);
const user = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => database.get(USER).findAndObserve(value)),
);
const user = observeCurrentUser(database);
return {
isMilitaryTime,

View File

@@ -3,21 +3,15 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {observeCurrentUserId} from '@queries/servers/system';
import TeamListItem from './team_list_item';
import type {WithDatabaseArgs} from '@typings/database/database';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {SYSTEM}} = MM_TABLES;
const withSystem = withObservables([], ({database}: WithDatabaseArgs) => ({
currentUserId: database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap((currentUserId) => of$(currentUserId.value))),
currentUserId: observeCurrentUserId(database),
}));
export default withDatabase(withSystem(TeamListItem));

View File

@@ -1,45 +1,33 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {Permissions} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {queryRolesByNames} from '@queries/servers/role';
import {queryMyTeams, queryOtherTeams} from '@queries/servers/team';
import {observeCurrentUser} from '@queries/servers/user';
import {hasPermission} from '@utils/role';
import TeamSidebar from './team_sidebar';
import type {WithDatabaseArgs} from '@typings/database/database';
import type MyTeam from '@typings/database/models/servers/my_team';
import type RoleModel from '@typings/database/models/servers/role';
import type SystemModel from '@typings/database/models/servers/system';
import type TeamModel from '@typings/database/models/servers/team';
import type UserModel from '@typings/database/models/servers/user';
const {SERVER: {SYSTEM, MY_TEAM, TEAM, USER, ROLE}} = MM_TABLES;
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const currentUser = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => database.get<UserModel>(USER).findAndObserve(value)),
);
const rolesArray = currentUser.pipe(
switchMap((u) => of$(u.roles.split(' '))),
);
const roles = rolesArray.pipe(
switchMap((values) => database.get<RoleModel>(ROLE).query(Q.where('name', Q.oneOf(values))).observe()),
const canCreateTeams = observeCurrentUser(database).pipe(
switchMap((u) => (u ? of$(u.roles.split(' ')) : of$([]))),
switchMap((values) => queryRolesByNames(database, values).observe()),
switchMap((r) => of$(hasPermission(r, Permissions.CREATE_TEAM, false))),
);
const canCreateTeams = roles.pipe(switchMap((r) => of$(hasPermission(r, Permissions.CREATE_TEAM, false))));
const otherTeams = database.get<MyTeam>(MY_TEAM).query().observe().pipe(
const otherTeams = queryMyTeams(database).observe().pipe(
switchMap((mm) => {
// eslint-disable-next-line max-nested-callbacks
const ids = mm.map((m) => m.id);
return database.get<TeamModel>(TEAM).query(Q.where('id', Q.notIn(ids))).observe();
return queryOtherTeams(database, ids).observe();
}),
);

View File

@@ -3,34 +3,25 @@
/* eslint-disable max-nested-callbacks */
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$, combineLatest} from 'rxjs';
import {switchMap, map} from 'rxjs/operators';
import {Preferences} from '@constants';
import {MM_TABLES} from '@constants/database';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {queryJoinedTeams, queryMyTeams} from '@queries/servers/team';
import TeamList from './team_list';
import type {WithDatabaseArgs} from '@typings/database/database';
import type MyTeamModel from '@typings/database/models/servers/my_team';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type TeamModel from '@typings/database/models/servers/team';
const {SERVER: {MY_TEAM, PREFERENCE, TEAM}} = MM_TABLES;
const withTeams = withObservables([], ({database}: WithDatabaseArgs) => {
const myTeams = database.get<MyTeamModel>(MY_TEAM).query().observe();
const teamIds = database.get<TeamModel>(TEAM).query(
Q.on(MY_TEAM, Q.where('id', Q.notEq(''))),
).observe().pipe(
const myTeams = queryMyTeams(database).observe();
const teamIds = queryJoinedTeams(database).observe().pipe(
map((ts) => ts.map((t) => ({id: t.id, displayName: t.displayName}))),
);
const order = database.get<PreferenceModel>(PREFERENCE).query(
Q.where('category', Preferences.TEAMS_ORDER),
).observe().pipe(
const order = queryPreferencesByCategoryAndName(database, Preferences.TEAMS_ORDER).observe().pipe(
switchMap((p) => (p.length ? of$(p[0].value.split(',')) : of$([]))),
);
const myOrderedTeams = combineLatest([myTeams, order, teamIds]).pipe(

View File

@@ -1,29 +1,25 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {MyChannelModel} from '@database/models/server';
import {queryMyChannelsByTeam} from '@queries/servers/channel';
import {observeCurrentTeamId} from '@queries/servers/system';
import TeamItem from './team_item';
import type {WithDatabaseArgs} from '@typings/database/database';
import type MyTeamModel from '@typings/database/models/servers/my_team';
import type SystemModel from '@typings/database/models/servers/system';
const {SERVER: {SYSTEM, MY_CHANNEL, CHANNEL}} = MM_TABLES;
type WithTeamsArgs = WithDatabaseArgs & {
myTeam: MyTeamModel;
}
const enhance = withObservables(['myTeam'], ({myTeam, database}: WithTeamsArgs) => {
const myChannels = database.get<MyChannelModel>(MY_CHANNEL).query(Q.on(CHANNEL, Q.and(Q.where('delete_at', Q.eq(0)), Q.where('team_id', Q.eq(myTeam.id))))).observeWithColumns(['mentions_count', 'is_unread']);
const myChannels = queryMyChannelsByTeam(database, myTeam.id).observeWithColumns(['mentions_count', 'is_unread']);
const mentionCount = myChannels.pipe(
// eslint-disable-next-line max-nested-callbacks
switchMap((val) => of$(val.reduce((acc, v) => acc + v.mentionsCount, 0))),
@@ -32,12 +28,9 @@ const enhance = withObservables(['myTeam'], ({myTeam, database}: WithTeamsArgs)
// eslint-disable-next-line max-nested-callbacks
switchMap((val) => of$(val.reduce((acc, v) => acc || v.isUnread, false))),
);
const currentTeamId = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID).pipe(
switchMap((t) => of$(t.value)),
);
return {
currentTeamId,
currentTeamId: observeCurrentTeamId(database),
team: myTeam.team.observe(),
mentionCount,
hasUnreads,

View File

@@ -5,9 +5,9 @@ import React, {useMemo} from 'react';
import {StyleProp, Text, useWindowDimensions, View, ViewStyle} from 'react-native';
import Animated, {AnimatedStyleProp} from 'react-native-reanimated';
import {changeOpacity, makeStyleSheetFromTheme} from '@app/utils/theme';
import CompassIcon from '@components/compass_icon';
import {useTheme} from '@context/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
type ToastProps = {

View File

@@ -16,10 +16,10 @@ export default {
DND: 'dnd',
STATUS_COMMANDS: ['offline', 'away', 'online', 'dnd'],
DEFAULT_CHANNEL: 'town-square',
DM_CHANNEL: 'D',
OPEN_CHANNEL: 'O',
PRIVATE_CHANNEL: 'P',
GM_CHANNEL: 'G',
DM_CHANNEL: 'D' as const,
OPEN_CHANNEL: 'O' as const,
PRIVATE_CHANNEL: 'P' as const,
GM_CHANNEL: 'G' as const,
TEAMMATE_NAME_DISPLAY: {
SHOW_USERNAME: 'username',
SHOW_NICKNAME_FULLNAME: 'nickname_full_name',

View File

@@ -1,19 +1,17 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import withObservables from '@nozbe/with-observables';
import React, {ComponentType, createContext, useEffect} from 'react';
import {Appearance, EventSubscription} from 'react-native';
import {of as of$} from 'rxjs';
import {catchError, switchMap} from 'rxjs/operators';
import {Preferences} from '@constants';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeCurrentTeamId} from '@queries/servers/system';
import EphemeralStore from '@store/ephemeral_store';
import {setNavigationStackStyles, setThemeDefaults} from '@utils/theme';
import type {PreferenceModel, SystemModel} from '@database/models/server';
import type {PreferenceModel} from '@database/models/server';
import type Database from '@nozbe/watermelondb/Database';
type Props = {
@@ -26,8 +24,6 @@ type WithThemeProps = {
theme: Theme;
}
const {SERVER: {PREFERENCE, SYSTEM}} = MM_TABLES;
export function getDefaultThemeByAppearance(): Theme {
if (Appearance.getColorScheme() === 'dark') {
return Preferences.THEMES.onyx;
@@ -98,11 +94,8 @@ export function useTheme(): Theme {
}
const enhancedThemeProvider = withObservables([], ({database}: {database: Database}) => ({
currentTeamId: database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID).pipe(
switchMap((row) => of$(row.value)),
catchError(() => of$(undefined)),
),
themes: database.get(PREFERENCE).query(Q.where('category', Preferences.CATEGORY_THEME)).observeWithColumns(['value']),
currentTeamId: observeCurrentTeamId(database),
themes: queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_THEME).observeWithColumns(['value']),
}));
export default enhancedThemeProvider(ThemeProvider);

View File

@@ -5,14 +5,12 @@ import withObservables from '@nozbe/with-observables';
import React, {ComponentType, createContext} from 'react';
import {IntlProvider} from 'react-intl';
import {of as of$} from 'rxjs';
import {catchError, switchMap} from 'rxjs/operators';
import {switchMap} from 'rxjs/operators';
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import {DEFAULT_LOCALE, getTranslations} from '@i18n';
import {observeCurrentUser} from '@queries/servers/user';
import type {SystemModel} from '@database/models/server';
import type Database from '@nozbe/watermelondb/Database';
import type UserModel from '@typings/database/models/servers/user';
type Props = {
locale: string;
@@ -23,8 +21,6 @@ type WithUserLocaleProps = {
locale: string;
}
const {SERVER: {USER, SYSTEM}} = MM_TABLES;
export const UserLocaleContext = createContext(DEFAULT_LOCALE);
const {Consumer, Provider} = UserLocaleContext;
@@ -64,12 +60,8 @@ export function useUserLocale(): string {
}
const enhancedThemeProvider = withObservables([], ({database}: {database: Database}) => ({
locale: database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
switchMap(({value}) => database.get<UserModel>(USER).findAndObserve(value).pipe(
// eslint-disable-next-line max-nested-callbacks
switchMap((user) => of$(user.locale)),
)),
catchError(() => of$(DEFAULT_LOCALE)),
locale: observeCurrentUser(database).pipe(
switchMap((user) => of$(user?.locale || DEFAULT_LOCALE)),
),
}));

View File

@@ -8,7 +8,7 @@ import {addFilesToDraft} from '@actions/local/draft';
import {PROGRESS_TIME_TO_STORE} from '@constants/files';
import DatabaseManager from '@database/manager';
import ServerDataOperator from '@database/operator/server_data_operator';
import {queryDraft} from '@queries/servers/drafts';
import {getDraft} from '@queries/servers/drafts';
import TestHelper from '@test/test_helper';
import {exportedForTesting} from '.';
@@ -94,7 +94,7 @@ describe('draft upload manager', () => {
// Wait for other promises (on complete write) to finish
await new Promise(process.nextTick);
const draft = await queryDraft(operator.database, channelId, rootId);
const draft = await getDraft(operator.database, channelId, rootId);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].id).toBe(fileServerId);
@@ -121,7 +121,7 @@ describe('draft upload manager', () => {
await new Promise(process.nextTick);
// There has been progress, but we are not storing in to the database since the app is still active.
let draft = await queryDraft(operator.database, channelId, rootId);
let draft = await getDraft(operator.database, channelId, rootId);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].bytesRead).toBeUndefined();
@@ -131,7 +131,7 @@ describe('draft upload manager', () => {
await new Promise(process.nextTick);
// After a failure, we store the progress on the database, so we can resume from the point before failure.
draft = await queryDraft(operator.database, channelId, rootId);
draft = await getDraft(operator.database, channelId, rootId);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].bytesRead).toBe(bytesRead);
expect(draft?.files[0].failed).toBe(true);
@@ -196,7 +196,7 @@ describe('draft upload manager', () => {
for (let i = 0; i < 3; i++) {
// eslint-disable-next-line no-await-in-loop
const draft = await queryDraft(operator.database, channelIds[i], rootIds[i]);
const draft = await getDraft(operator.database, channelIds[i], rootIds[i]);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].bytesRead).toBe(bytesReads[i]);
}
@@ -213,7 +213,7 @@ describe('draft upload manager', () => {
for (let i = 0; i < 3; i++) {
// eslint-disable-next-line no-await-in-loop
const draft = await queryDraft(operator.database, channelIds[i], rootIds[i]);
const draft = await getDraft(operator.database, channelIds[i], rootIds[i]);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].bytesRead).toBe(bytesReads[i]);
}
@@ -231,7 +231,7 @@ describe('draft upload manager', () => {
for (let i = 0; i < 3; i++) {
// eslint-disable-next-line no-await-in-loop
const draft = await queryDraft(operator.database, channelIds[i], rootIds[i]);
const draft = await getDraft(operator.database, channelIds[i], rootIds[i]);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].bytesRead).toBe(bytesReadsStore[i]);
}
@@ -245,7 +245,7 @@ describe('draft upload manager', () => {
for (let i = 0; i < 3; i++) {
// eslint-disable-next-line no-await-in-loop
const draft = await queryDraft(operator.database, channelIds[i], rootIds[i]);
const draft = await getDraft(operator.database, channelIds[i], rootIds[i]);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].bytesRead).toBe(bytesReadsStore[i]);
}
@@ -270,7 +270,7 @@ describe('draft upload manager', () => {
// Wait for other promises (on complete write) to finish
await new Promise(process.nextTick);
const draft = await queryDraft(operator.database, channelId, rootId);
const draft = await getDraft(operator.database, channelId, rootId);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].id).toBeUndefined();
expect(draft?.files[0].failed).toBe(true);
@@ -294,7 +294,7 @@ describe('draft upload manager', () => {
// Wait for other promises (on complete write) to finish
await new Promise(process.nextTick);
const draft = await queryDraft(operator.database, channelId, rootId);
const draft = await getDraft(operator.database, channelId, rootId);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].id).toBeUndefined();
expect(draft?.files[0].failed).toBe(true);
@@ -318,7 +318,7 @@ describe('draft upload manager', () => {
// Wait for other promises (on complete write) to finish
await new Promise(process.nextTick);
const draft = await queryDraft(operator.database, channelId, rootId);
const draft = await getDraft(operator.database, channelId, rootId);
expect(draft?.files.length).toBe(1);
expect(draft?.files[0].id).toBeUndefined();
expect(draft?.files[0].failed).toBe(true);

View File

@@ -16,7 +16,7 @@ import {getLaunchPropsFromDeepLink, relaunchApp} from '@init/launch';
import NetworkManager from '@init/network_manager';
import PushNotifications from '@init/push_notifications';
import WebsocketManager from '@init/websocket_manager';
import {queryCurrentUser} from '@queries/servers/user';
import {getCurrentUser} from '@queries/servers/user';
import EphemeralStore from '@store/ephemeral_store';
import {LaunchType} from '@typings/launch';
import {deleteFileCache} from '@utils/file';
@@ -158,7 +158,7 @@ class GlobalEventHandler {
resetLocale = async () => {
if (Object.keys(DatabaseManager.serverDatabases).length) {
const serverDatabase = await DatabaseManager.getActiveServerDatabase();
const user = await queryCurrentUser(serverDatabase!);
const user = await getCurrentUser(serverDatabase!);
resetMomentLocale(user?.locale);
} else {
resetMomentLocale();

View File

@@ -9,8 +9,8 @@ import {appEntry, pushNotificationEntry, upgradeEntry} from '@actions/remote/ent
import {Screens} from '@constants';
import DatabaseManager from '@database/manager';
import {getActiveServerUrl, getServerCredentials, removeServerCredentials} from '@init/credentials';
import {queryThemeForCurrentTeam} from '@queries/servers/preference';
import {queryCurrentUserId} from '@queries/servers/system';
import {getThemeForCurrentTeam} from '@queries/servers/preference';
import {getCurrentUserId} from '@queries/servers/system';
import {goToScreen, resetToHome, resetToSelectServer} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {DeepLinkChannel, DeepLinkDM, DeepLinkGM, DeepLinkPermalink, DeepLinkType, DeepLinkWithData, LaunchProps, LaunchType} from '@typings/launch';
@@ -81,8 +81,8 @@ const launchApp = async (props: LaunchProps, resetNavigation = true) => {
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
let hasCurrentUser = false;
if (database) {
EphemeralStore.theme = await queryThemeForCurrentTeam(database);
const currentUserId = await queryCurrentUserId(database);
EphemeralStore.theme = await getThemeForCurrentTeam(database);
const currentUserId = await getCurrentUserId(database);
hasCurrentUser = Boolean(currentUserId);
}

View File

@@ -22,7 +22,7 @@ import DatabaseManager from '@database/manager';
import {DEFAULT_LOCALE, getLocalizedMessage, t} from '@i18n';
import NativeNotifications from '@notifications';
import {queryServerName} from '@queries/app/servers';
import {queryCurrentChannelId} from '@queries/servers/system';
import {getCurrentChannelId} from '@queries/servers/system';
import {showOverlay} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {isTablet} from '@utils/helpers';
@@ -134,7 +134,7 @@ class PushNotifications {
const isTabletDevice = await isTablet();
const activeServerUrl = await getActiveServerUrl();
const displayName = await queryServerName(DatabaseManager.appDatabase!.database, serverUrl);
const channelId = await queryCurrentChannelId(database);
const channelId = await getCurrentChannelId(database);
let serverName;
if (serverUrl !== activeServerUrl && Object.keys(DatabaseManager.serverDatabases).length > 1) {
serverName = displayName;

View File

@@ -12,7 +12,7 @@ import {handleClose, handleEvent, handleFirstConnect, handleReconnect} from '@ac
import WebSocketClient from '@client/websocket';
import {General} from '@constants';
import DatabaseManager from '@database/manager';
import {queryCurrentUserId} from '@queries/servers/system';
import {getCurrentUserId} from '@queries/servers/system';
import {queryAllUsers} from '@queries/servers/user';
import type {ServerCredential} from '@typings/credentials';
@@ -157,13 +157,8 @@ class WebsocketManager {
return;
}
const currentUserId = await queryCurrentUserId(database.database);
const users = await queryAllUsers(database.database);
const userIds = users.map((u) => u.id).filter((id) => id !== currentUserId);
if (!userIds.length) {
return;
}
const currentUserId = await getCurrentUserId(database.database);
const userIds = (await queryAllUsers(database.database).fetchIds()).filter((id) => id !== currentUserId);
fetchStatusByIds(serverUrl, userIds);
};

View File

@@ -10,7 +10,7 @@ import type CategoryModel from '@typings/database/models/servers/category';
const {SERVER: {CATEGORY}} = MM_TABLES;
export const queryCategoryById = async (database: Database, categoryId: string) => {
export const getCategoryById = async (database: Database, categoryId: string) => {
try {
const record = (await database.collections.get<CategoryModel>(CATEGORY).find(categoryId));
return record;
@@ -19,61 +19,12 @@ export const queryCategoryById = async (database: Database, categoryId: string)
}
};
export const queryCategoriesById = async (database: Database, categoryIds: string[]): Promise<CategoryModel[]> => {
try {
const records = (await database.get<CategoryModel>(CATEGORY).query(Q.where('id', Q.oneOf(categoryIds))).fetch());
return records;
} catch {
return Promise.resolve([] as CategoryModel[]);
}
export const queryCategoriesById = (database: Database, categoryIds: string[]) => {
return database.get<CategoryModel>(CATEGORY).query(Q.where('id', Q.oneOf(categoryIds)));
};
export const queryCategoriesByType = async (database: Database, type: CategoryType): Promise<CategoryModel[]> => {
try {
const records = (await database.get<CategoryModel>(CATEGORY).query(Q.where('type', type)).fetch());
return records;
} catch {
return Promise.resolve([] as CategoryModel[]);
}
};
export const queryCategoriesByTeamId = async (database: Database, teamId: string): Promise<CategoryModel[]> => {
try {
const records = (await database.get<CategoryModel>(CATEGORY).query(Q.where('team_id', teamId)).fetch());
return records;
} catch {
return Promise.resolve([] as CategoryModel[]);
}
};
export const queryCategoriesByTeamIds = async (database: Database, teamIds: string[]): Promise<CategoryModel[]> => {
try {
const records = (await database.get<CategoryModel>(CATEGORY).query(Q.where('team_id', Q.oneOf(teamIds))).fetch());
return records;
} catch {
return Promise.resolve([] as CategoryModel[]);
}
};
export const queryCategoriesByTypeTeamId = async (database: Database, type: CategoryType, teamId: string): Promise<CategoryModel[]> => {
try {
const records = await database.get<CategoryModel>(CATEGORY).query(
Q.where('team_id', teamId),
Q.where('type', type),
).fetch();
return records;
} catch {
return Promise.resolve([] as CategoryModel[]);
}
};
export const queryAllCategories = async (database: Database): Promise<CategoryModel[]> => {
try {
const records = await database.get<CategoryModel>(CATEGORY).query().fetch();
return records;
} catch {
return Promise.resolve([] as CategoryModel[]);
}
export const queryCategoriesByTeamIds = (database: Database, teamIds: string[]) => {
return database.get<CategoryModel>(CATEGORY).query(Q.where('team_id', Q.oneOf(teamIds)));
};
export const prepareCategories = (operator: ServerDataOperator, categories: CategoryWithChannels[]) => {

Some files were not shown because too many files have changed in this diff Show More