Skip to content

Commit 6dcce51

Browse files
author
SeRoNet Concourse
committed
Merge remote-tracking branch 'rocket.chat/develop' into HEAD
2 parents 4487a9f + 9503f82 commit 6dcce51

20 files changed

Lines changed: 3504 additions & 3311 deletions

File tree

app/otr/client/rocketchat.otr.room.js

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import toastr from 'toastr';
1010

1111
import { OTR } from './rocketchat.otr';
1212
import { Notifications } from '../../notifications';
13-
import { modal } from '../../ui-utils';
1413
import { getUidDirectMessage } from '../../ui-utils/client/lib/getUidDirectMessage';
1514
import { Presence } from '../../../client/lib/presence';
1615
import { goToRoomById } from '../../../client/lib/goToRoomById';
16+
import { imperativeModal } from '../../../client/lib/imperativeModal';
17+
import GenericModal from '../../../client/components/GenericModal';
1718

1819
OTR.Room = class {
1920
constructor(userId, roomId) {
@@ -208,31 +209,32 @@ OTR.Room = class {
208209
this.reset();
209210
}
210211

211-
modal.open({
212-
title: TAPi18n.__('OTR'),
213-
text: TAPi18n.__('Username_wants_to_start_otr_Do_you_want_to_accept', { username }),
214-
html: true,
215-
showCancelButton: true,
216-
allowOutsideClick: false,
217-
confirmButtonText: TAPi18n.__('Yes'),
218-
cancelButtonText: TAPi18n.__('No'),
219-
}, (isConfirm) => {
220-
if (isConfirm) {
221-
establishConnection();
222-
} else {
223-
Meteor.clearTimeout(timeout);
224-
this.deny();
225-
}
212+
imperativeModal.open({ component: GenericModal,
213+
props: {
214+
variant: 'warning',
215+
title: TAPi18n.__('OTR'),
216+
children: TAPi18n.__('Username_wants_to_start_otr_Do_you_want_to_accept', { username }),
217+
confirmText: TAPi18n.__('Yes'),
218+
cancelText: TAPi18n.__('No'),
219+
onClose: () => imperativeModal.close,
220+
onCancel: () => {
221+
Meteor.clearTimeout(timeout);
222+
this.deny();
223+
imperativeModal.close();
224+
},
225+
onConfirm: () => {
226+
establishConnection();
227+
imperativeModal.close();
228+
},
229+
},
226230
});
227231
}
228232

229233
timeout = Meteor.setTimeout(() => {
230234
this.establishing.set(false);
231-
modal.close();
235+
imperativeModal.close();
232236
}, 10000);
233237
})();
234-
235-
236238
break;
237239

238240
case 'acknowledge':
@@ -242,28 +244,41 @@ OTR.Room = class {
242244
break;
243245

244246
case 'deny':
245-
if (this.establishing.get()) {
246-
this.reset();
247-
const user = Meteor.users.findOne(this.peerId);
248-
modal.open({
249-
title: TAPi18n.__('OTR'),
250-
text: TAPi18n.__('Username_denied_the_OTR_session', { username: user.username }),
251-
html: true,
252-
});
253-
}
247+
(async () => {
248+
const { username } = await Presence.get(this.peerId);
249+
if (this.establishing.get()) {
250+
this.reset();
251+
imperativeModal.open({ component: GenericModal,
252+
props: {
253+
variant: 'warning',
254+
title: TAPi18n.__('OTR'),
255+
children: TAPi18n.__('Username_denied_the_OTR_session', { username }),
256+
onClose: imperativeModal.close,
257+
onConfirm: imperativeModal.close,
258+
},
259+
});
260+
}
261+
})();
254262
break;
255263

256264
case 'end':
257-
if (this.established.get()) {
258-
this.reset();
259-
const user = Meteor.users.findOne(this.peerId);
260-
modal.open({
261-
title: TAPi18n.__('OTR'),
262-
text: TAPi18n.__('Username_ended_the_OTR_session', { username: user.username }),
263-
html: true,
264-
confirmButtonText: TAPi18n.__('Ok'),
265-
});
266-
}
265+
(async () => {
266+
const { username } = await Presence.get(this.peerId);
267+
268+
if (this.established.get()) {
269+
this.reset();
270+
imperativeModal.open({ component: GenericModal,
271+
props: {
272+
variant: 'warning',
273+
title: TAPi18n.__('OTR'),
274+
children: TAPi18n.__('Username_ended_the_OTR_session', { username }),
275+
confirmText: TAPi18n.__('Ok'),
276+
onClose: imperativeModal.close,
277+
onConfirm: imperativeModal.close,
278+
},
279+
});
280+
}
281+
})();
267282
break;
268283
}
269284
}

app/ui-utils/client/lib/readMessages.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export const readMessage = new class extends Emitter {
3131
return;
3232
}
3333

34-
3534
const subscription = ChatSubscription.findOne({ rid });
3635
if (subscription == null) {
3736
this.log('readMessage -> readNow canceled, no subscription found for rid:', rid);
@@ -71,6 +70,13 @@ export const readMessage = new class extends Emitter {
7170
this.log('readMessage -> readNow canceled, no rid informed');
7271
return;
7372
}
73+
74+
const subscription = ChatSubscription.findOne({ rid });
75+
if (subscription == null) {
76+
this.log('readMessage -> readNow canceled, no subscription found for rid:', rid);
77+
return;
78+
}
79+
7480
return Meteor.call('readMessages', rid, () => {
7581
RoomHistoryManager.getRoom(rid).unreadNotLoaded.set(0);
7682
return this.emit(rid);

client/components/CreateDiscussion/DefaultParentRoomField.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { Skeleton, Select, Callout } from '@rocket.chat/fuselage';
1+
import { Skeleton, TextInput, Callout } from '@rocket.chat/fuselage';
22
import React, { useMemo, ReactElement } from 'react';
33

4+
import { roomTypes } from '../../../app/utils/client/lib/roomTypes';
45
import { useTranslation } from '../../contexts/TranslationContext';
56
import { AsyncStatePhase } from '../../hooks/useAsyncState';
67
import { useEndpointData } from '../../hooks/useEndpointData';
@@ -29,12 +30,9 @@ const DefaultParentRoomField = ({
2930
return <Callout type={'error'}>{t('Error')}</Callout>;
3031
}
3132

32-
const { _id, fname, name } = value?.room;
33-
3433
return (
35-
<Select
36-
options={[[_id, (fname || name) as string]]}
37-
value={_id}
34+
<TextInput
35+
value={roomTypes.getRoomName(value.room.t, value.room)}
3836
disabled
3937
onChange={(): string => ''}
4038
/>

client/contexts/UserContext.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
12
import { FilterQuery } from 'mongodb';
23
import { createContext, useContext, useMemo } from 'react';
34
import { useSubscription, Subscription, Unsubscribe } from 'use-subscription';
45

56
import { IRoom } from '../../definition/IRoom';
67
import { ISubscription } from '../../definition/ISubscription';
8+
import { useRoute } from './RouterContext';
79

810
type SubscriptionQuery =
911
| {
@@ -34,6 +36,7 @@ type UserContextValue = {
3436
userId: string | null;
3537
user: Meteor.User | null;
3638
loginWithPassword: (user: string | object, password: string) => Promise<void>;
39+
logout: () => Promise<void>;
3740
queryPreference: <T>(
3841
key: string | Mongo.ObjectID,
3942
defaultValue?: T,
@@ -58,6 +61,7 @@ export const UserContext = createContext<UserContextValue>({
5861
userId: null,
5962
user: null,
6063
loginWithPassword: async () => undefined,
64+
logout: () => Promise.resolve(),
6165
queryPreference: () => ({
6266
getCurrentValue: (): undefined => undefined,
6367
subscribe: (): Unsubscribe => (): void => undefined,
@@ -85,6 +89,18 @@ export const useLoginWithPassword = (): ((
8589
password: string,
8690
) => Promise<void>) => useContext(UserContext).loginWithPassword;
8791

92+
export const useLogout = (): (() => void) => {
93+
const router = useRoute('home');
94+
const { logout } = useContext(UserContext);
95+
96+
const handleLogout = useMutableCallback(() => {
97+
logout();
98+
router.push({});
99+
});
100+
101+
return handleLogout;
102+
};
103+
88104
export const useUserPreference = <T>(key: string, defaultValue?: T): T | undefined => {
89105
const { queryPreference } = useContext(UserContext);
90106
const subscription = useMemo(

client/providers/UserProvider.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Meteor } from 'meteor/meteor';
22
import React, { useMemo, FC } from 'react';
33

4+
import { callbacks } from '../../app/callbacks/client';
45
import { Subscriptions, Rooms } from '../../app/models/client';
56
import { getUserPreference } from '../../app/utils/client';
67
import { IRoom } from '../../definition/IRoom';
@@ -29,6 +30,20 @@ const loginWithPassword = (user: string | object, password: string): Promise<voi
2930
);
3031
});
3132

33+
const logout = (): Promise<void> =>
34+
new Promise((resolve) => {
35+
const user = Meteor.user();
36+
37+
if (!user) {
38+
return resolve();
39+
}
40+
41+
Meteor.logout(() => {
42+
callbacks.run('afterLogoutCleanUp', user);
43+
Meteor.call('logoutCleanUp', user, resolve);
44+
});
45+
});
46+
3247
const UserProvider: FC = ({ children }) => {
3348
const userId = useReactiveValue(getUserId);
3449
const user = useReactiveValue(getUser);
@@ -37,6 +52,7 @@ const UserProvider: FC = ({ children }) => {
3752
userId,
3853
user,
3954
loginWithPassword,
55+
logout,
4056
queryPreference: createReactiveSubscriptionFactory((key, defaultValue) =>
4157
getUserPreference(userId, key, defaultValue),
4258
),

client/sidebar/header/UserDropdown.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Box, Margins, Divider, Option } from '@rocket.chat/fuselage';
22
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
33
import { FlowRouter } from 'meteor/kadira:flow-router';
4-
import { Meteor } from 'meteor/meteor';
54
import React from 'react';
65

76
import { callbacks } from '../../../app/callbacks/client';
@@ -14,6 +13,7 @@ import { useAtLeastOnePermission } from '../../contexts/AuthorizationContext';
1413
import { useRoute } from '../../contexts/RouterContext';
1514
import { useSetting } from '../../contexts/SettingsContext';
1615
import { useTranslation } from '../../contexts/TranslationContext';
16+
import { useLogout } from '../../contexts/UserContext';
1717
import { useReactiveValue } from '../../hooks/useReactiveValue';
1818

1919
const ADMIN_PERMISSIONS = [
@@ -47,10 +47,11 @@ const getItems = () => AccountBox.getItems();
4747

4848
const UserDropdown = ({ user, onClose }) => {
4949
const t = useTranslation();
50-
const homeRoute = useRoute('home');
5150
const accountRoute = useRoute('account');
5251
const adminRoute = useRoute('admin');
5352

53+
const logout = useLogout();
54+
5455
const { name, username, avatarETag, status, statusText } = user;
5556

5657
const useRealName = useSetting('UI_Use_Real_Name');
@@ -78,15 +79,6 @@ const UserDropdown = ({ user, onClose }) => {
7879
onClose();
7980
});
8081

81-
const handleLogout = useMutableCallback(() => {
82-
Meteor.logout(() => {
83-
callbacks.run('afterLogoutCleanUp', user);
84-
Meteor.call('logoutCleanUp', user);
85-
homeRoute.push({});
86-
popover.close();
87-
});
88-
});
89-
9082
const handleMyAccount = useMutableCallback(() => {
9183
accountRoute.push({});
9284
popover.close();
@@ -97,6 +89,11 @@ const UserDropdown = ({ user, onClose }) => {
9789
popover.close();
9890
});
9991

92+
const handleLogout = useMutableCallback(() => {
93+
logout();
94+
popover.close();
95+
});
96+
10097
const accountBoxItems = useReactiveValue(getItems);
10198

10299
return (

client/views/account/AccountProfilePage.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { useMethod } from '../../contexts/ServerContext';
1010
import { useSetting } from '../../contexts/SettingsContext';
1111
import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext';
1212
import { useTranslation } from '../../contexts/TranslationContext';
13-
import { useUser } from '../../contexts/UserContext';
13+
import { useUser, useLogout } from '../../contexts/UserContext';
1414
import { useForm } from '../../hooks/useForm';
1515
import { useUpdateAvatar } from '../../hooks/useUpdateAvatar';
1616
import AccountProfileForm from './AccountProfileForm';
@@ -37,9 +37,10 @@ const AccountProfilePage = () => {
3737

3838
const user = useUser();
3939

40-
const { values, handlers, hasUnsavedChanges, commit } = useForm(getInitialValues(user));
40+
const { values, handlers, hasUnsavedChanges, commit } = useForm(getInitialValues(user ?? {}));
4141
const [canSave, setCanSave] = useState(true);
4242
const setModal = useSetModal();
43+
const logout = useLogout();
4344
const [loggingOut, setLoggingOut] = useState(false);
4445

4546
const logoutOtherClients = useMethod('logoutOtherClients');
@@ -114,7 +115,7 @@ const AccountProfilePage = () => {
114115

115116
const { handleAvatar, handlePassword, handleConfirmationPassword } = handlers;
116117

117-
const updateAvatar = useUpdateAvatar(avatar, user._id);
118+
const updateAvatar = useUpdateAvatar(avatar, user?._id);
118119

119120
const onSave = useCallback(async () => {
120121
const save = async (typedPassword) => {
@@ -192,6 +193,7 @@ const AccountProfilePage = () => {
192193
try {
193194
await deleteOwnAccount(SHA256(passwordOrUsername));
194195
dispatchToastMessage({ type: 'success', message: t('User_has_been_deleted') });
196+
logout();
195197
} catch (error) {
196198
if (error.error === 'user-last-owner') {
197199
const { shouldChangeOwner, shouldBeRemoved } = error.details;
@@ -233,7 +235,16 @@ const AccountProfilePage = () => {
233235
text={t('If_you_are_sure_type_in_your_username')}
234236
/>
235237
));
236-
}, [closeModal, deleteOwnAccount, dispatchToastMessage, erasureType, localPassword, t, setModal]);
238+
}, [
239+
closeModal,
240+
deleteOwnAccount,
241+
dispatchToastMessage,
242+
erasureType,
243+
localPassword,
244+
t,
245+
logout,
246+
setModal,
247+
]);
237248

238249
return (
239250
<Page>
@@ -249,7 +260,7 @@ const AccountProfilePage = () => {
249260
<AccountProfileForm
250261
values={values}
251262
handlers={handlers}
252-
user={user}
263+
user={user ?? { emails: [] }}
253264
settings={settings}
254265
onSaveStateChange={setCanSave}
255266
/>

0 commit comments

Comments
 (0)