Fix: remove user-settings subscription

This commit is contained in:
Tainan Felipe 2024-04-24 11:18:58 -03:00
parent cfbeb92cd7
commit 97393f6aa0
15 changed files with 30 additions and 272 deletions

View File

@ -4,7 +4,6 @@ import AbstractCollection from '/imports/ui/services/LocalCollectionSynchronizer
import PresentationUploadToken from '/imports/api/presentation-upload-token';
import Screenshare from '/imports/api/screenshare';
import UserInfos from '/imports/api/users-infos';
import UserSettings from '/imports/api/users-settings';
import VideoStreams from '/imports/api/video-streams';
import VoiceUsers from '/imports/api/voice-users';
import WhiteboardMultiUser from '/imports/api/whiteboard-multi-user';
@ -23,7 +22,6 @@ export const localCollectionRegistry = {
),
localScreenshareSync: new AbstractCollection(Screenshare, Screenshare),
localUserInfosSync: new AbstractCollection(UserInfos, UserInfos),
localUserSettingsSync: new AbstractCollection(UserSettings, UserSettings),
localVideoStreamsSync: new AbstractCollection(VideoStreams, VideoStreams),
localVoiceUsersSync: new AbstractCollection(VoiceUsers, VoiceUsers),
localWhiteboardMultiUserSync: new AbstractCollection(WhiteboardMultiUser, WhiteboardMultiUser),

View File

@ -4,7 +4,6 @@ import Logger from '/imports/startup/server/logger';
import { removeExternalVideoStreamer } from '/imports/api/external-videos/server/streamer';
import clearUsers from '/imports/api/users/server/modifiers/clearUsers';
import clearUsersSettings from '/imports/api/users-settings/server/modifiers/clearUsersSettings';
import clearBreakouts from '/imports/api/breakouts/server/modifiers/clearBreakouts';
import clearPads from '/imports/api/pads/server/modifiers/clearPads';
import clearVoiceUsers from '/imports/api/voice-users/server/modifiers/clearVoiceUsers';
@ -30,7 +29,6 @@ export default async function meetingHasEnded(meetingId) {
clearPads(meetingId),
clearBreakouts(meetingId),
clearUsers(meetingId),
clearUsersSettings(meetingId),
clearVoiceUsers(meetingId),
clearUserInfo(meetingId),
clearTimer(meetingId),

View File

@ -1,15 +0,0 @@
import { Meteor } from 'meteor/meteor';
const collectionOptions = Meteor.isClient ? {
connection: null,
} : {};
const UserSettings = new Mongo.Collection('users-settings', collectionOptions);
if (Meteor.isServer) {
UserSettings.createIndexAsync({
meetingId: 1, userId: 1,
});
}
export default UserSettings;

View File

@ -1,2 +0,0 @@
import './methods';
import './publishers';

View File

@ -1,6 +0,0 @@
import { Meteor } from 'meteor/meteor';
import addUserSettings from './methods/addUserSettings';
Meteor.methods({
addUserSettings,
});

View File

@ -1,134 +0,0 @@
import { check } from 'meteor/check';
import addUserSetting from '/imports/api/users-settings/server/modifiers/addUserSetting';
import logger from '/imports/startup/server/logger';
import { extractCredentials } from '/imports/api/common/server/helpers';
const oldParameters = {
askForFeedbackOnLogout: 'bbb_ask_for_feedback_on_logout',
autoJoin: 'bbb_auto_join_audio',
autoShareWebcam: 'bbb_auto_share_webcam',
clientTitle: 'bbb_client_title',
customStyle: 'bbb_custom_style',
customStyleUrl: 'bbb_custom_style_url',
displayBrandingArea: 'bbb_display_branding_area',
enableVideo: 'bbb_enable_video',
forceListenOnly: 'bbb_force_listen_only',
hidePresentationOnJoin: 'bbb_hide_presentation',
listenOnlyMode: 'bbb_listen_only_mode',
multiUserPenOnly: 'bbb_multi_user_pen_only',
multiUserTools: 'bbb_multi_user_tools',
presenterTools: 'bbb_presenter_tools',
shortcuts: 'bbb_shortcuts',
skipCheck: 'bbb_skip_check_audio',
};
const oldParametersKeys = Object.keys(oldParameters);
const currentParameters = [
// APP
'bbb_ask_for_feedback_on_logout',
'bbb_override_default_locale',
'bbb_auto_join_audio',
'bbb_client_title',
'bbb_force_listen_only',
'bbb_listen_only_mode',
'bbb_skip_check_audio',
'bbb_skip_check_audio_on_first_join',
'bbb_fullaudio_bridge',
'bbb_transparent_listen_only',
'bbb_show_animations_default',
// BRANDING
'bbb_display_branding_area',
// SHORTCUTS
'bbb_shortcuts',
// KURENTO
'bbb_auto_share_webcam',
'bbb_preferred_camera_profile',
'bbb_enable_video',
'bbb_record_video',
'bbb_skip_video_preview',
'bbb_skip_video_preview_on_first_join',
'bbb_mirror_own_webcam',
// PRESENTATION
'bbb_force_restore_presentation_on_new_events',
// WHITEBOARD
'bbb_multi_user_pen_only',
'bbb_presenter_tools',
'bbb_multi_user_tools',
// SKINNING/THEMMING
'bbb_custom_style',
'bbb_custom_style_url',
// LAYOUT
'bbb_hide_presentation_on_join',
'bbb_show_participants_on_login',
'bbb_show_public_chat_on_login',
'bbb_hide_actions_bar',
'bbb_hide_nav_bar',
'bbb_change_layout',
'bbb_direct_leave_button',
'bbb_default_layout',
];
function valueParser(val) {
try {
const parsedValue = JSON.parse(val.toLowerCase().trim());
return parsedValue;
} catch (error) {
logger.warn(`addUserSettings:Parameter ${val} could not be parsed (was not json)`);
return val;
}
}
export default function addUserSettings(settings) {
try {
check(settings, [Object]);
const { meetingId, requesterUserId: userId } = extractCredentials(this.userId);
check(meetingId, String);
check(userId, String);
let parameters = {};
settings.forEach((el) => {
const settingKey = Object.keys(el).shift();
const normalizedKey = settingKey.trim();
if (currentParameters.includes(normalizedKey)) {
if (!Object.keys(parameters).includes(normalizedKey)) {
parameters = {
[normalizedKey]: valueParser(el[settingKey]),
...parameters,
};
} else {
parameters[normalizedKey] = el[settingKey];
}
return;
}
if (oldParametersKeys.includes(normalizedKey)) {
const matchingNewKey = oldParameters[normalizedKey];
if (!Object.keys(parameters).includes(matchingNewKey)) {
parameters = {
[matchingNewKey]: valueParser(el[settingKey]),
...parameters,
};
}
return;
}
logger.warn(`Parameter ${normalizedKey} not handled`);
});
const settingsAdded = [];
Object.entries(parameters).forEach((el) => {
const setting = el[0];
const value = el[1];
settingsAdded.push(addUserSetting(meetingId, userId, setting, value));
});
return settingsAdded;
} catch (err) {
logger.error(`Exception while invoking method addUserSettings ${err.stack}`);
}
}

View File

@ -1,34 +0,0 @@
import { check } from 'meteor/check';
import UserSettings from '/imports/api/users-settings';
import Logger from '/imports/startup/server/logger';
export default async function addUserSetting(meetingId, userId, setting, value) {
check(meetingId, String);
check(userId, String);
check(setting, String);
check(value, Match.Any);
const selector = {
meetingId,
userId,
setting,
};
const modifier = {
$set: {
meetingId,
userId,
setting,
value,
},
};
try {
const { numberAffected } = await UserSettings.upsertAsync(selector, modifier);
if (numberAffected) {
Logger.verbose('Upserted user setting', { meetingId, userId, setting });
}
} catch (err) {
Logger.error(`Adding user setting to collection: ${err}`);
}
}

View File

@ -1,14 +0,0 @@
import UserSettings from '/imports/api/users-settings';
import Logger from '/imports/startup/server/logger';
export default async function clearUsersSettings(meetingId) {
try {
const numberAffected = await UserSettings.removeAsync({ meetingId });
if (numberAffected) {
Logger.info(`Cleared User Settings (${meetingId})`);
}
} catch (err) {
Logger.error(`Error on clearing User Settings (${meetingId}). ${err}`);
}
}

View File

@ -1,27 +0,0 @@
import { Meteor } from 'meteor/meteor';
import UserSettings from '/imports/api/users-settings';
import Logger from '/imports/startup/server/logger';
import AuthTokenValidation, { ValidationStates } from '/imports/api/auth-token-validation';
async function userSettings() {
const tokenValidation = await AuthTokenValidation
.findOneAsync({ connectionId: this.connection.id });
if (!tokenValidation || tokenValidation.validationStatus !== ValidationStates.VALIDATED) {
Logger.warn(`Publishing UserSettings was requested by unauth connection ${this.connection.id}`);
return UserSettings.find({ meetingId: '' });
}
const { meetingId, userId } = tokenValidation;
Logger.debug('Publishing UserSettings', { meetingId, userId });
return UserSettings.find({ meetingId, userId });
}
function publish(...args) {
const boundUserSettings = userSettings.bind(this);
return boundUserSettings(...args);
}
Meteor.publish('users-settings', publish);

View File

@ -1,7 +1,8 @@
import { useQuery } from '@apollo/client';
import React, { useCallback, useEffect } from 'react';
import { Meteor } from 'meteor/meteor';
import React, { useEffect } from 'react';
import { UserCustomParameterResponse, getCustomParameter } from './queries';
import { setUserSettings } from '/imports/ui/core/local-states/useUserSettings';
import { containsBooleanValue } from './sevice';
interface CustomUsersSettingsProps {
children: React.ReactNode;
@ -16,32 +17,14 @@ const CustomUsersSettings: React.FC<CustomUsersSettingsProps> = ({
error: customParameterError,
} = useQuery<UserCustomParameterResponse>(getCustomParameter);
const [allowToRender, setAllowToRender] = React.useState(false);
const sendToServer = useCallback((data: Array<{[x: string]: string}>, count = 0) => {
Meteor.callAsync('addUserSettings', data).then(() => {
setAllowToRender(true);
})
.catch(() => {
if (count < 3) {
setTimeout(() => {
sendToServer(data, count + 1);
}, 500);
} else {
throw new Error('Error on sending user settings to server');
}
});
}, []);
useEffect(() => {
if (customParameterData && !customParameterLoading) {
const filteredData = customParameterData.user_customParameter.map((uc) => {
const { parameter, value } = uc;
return { [parameter]: value };
return { [parameter]: containsBooleanValue(value) ? JSON.parse(value.toLowerCase()) : value };
});
const clientSettings = JSON.parse(sessionStorage.getItem('clientStartupSettings') || '{}');
if (clientSettings.skipMeteorConnection) {
setAllowToRender(true);
return;
}
sendToServer(filteredData);
setUserSettings(filteredData.reduce((acc, item) => ({ ...acc, ...item }), {}));
setAllowToRender(true);
}
}, [
customParameterData,

View File

@ -0,0 +1,9 @@
export const containsBooleanValue = (value: string): boolean => {
const comparisonValues = ['true', 'false'];
const stringValue = value.toLowerCase();
return comparisonValues.includes(stringValue);
};
export default {
containsBooleanValue,
};

View File

@ -17,7 +17,7 @@ const SUBSCRIPTIONS = [
// 'captions',
// 'voiceUsers',
'screenshare',
'users-settings',
// 'users-settings',
'users-infos',
'meeting-time-remaining',
// 'record-meetings',

View File

@ -0,0 +1,11 @@
import createUseLocalState from './createUseLocalState';
type genericObject = {[key:string]: boolean | string};
const initialUserSettings: genericObject = {};
const [useUserSettings, setUserSettings, localUserSettings] = createUseLocalState<genericObject>(initialUserSettings);
export default useUserSettings;
export {
setUserSettings,
localUserSettings,
};

View File

@ -1,17 +1,9 @@
import Auth from '/imports/ui/services/auth';
import UserSettings from '/imports/api/users-settings';
import { localUserSettings } from '../../core/local-states/useUserSettings';
export default function getFromUserSettings(setting, defaultValue) {
const selector = {
meetingId: Auth.meetingID,
userId: Auth.userID,
setting,
};
const userSetting = UserSettings.findOne(selector);
const userSetting = localUserSettings()[setting];
if (userSetting !== undefined) {
return userSetting.value;
return userSetting;
}
return defaultValue;

View File

@ -6,7 +6,6 @@ import '/imports/api/users/server';
import '/imports/api/presentation-upload-token/server';
import '/imports/api/breakouts/server';
import '/imports/api/screenshare/server';
import '/imports/api/users-settings/server';
import '/imports/api/voice-users/server';
import '/imports/api/whiteboard-multi-user/server';
import '/imports/api/video-streams/server';