@selfcommunity/react-ui 0.7.9-alpha.15 → 0.7.9-alpha.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.js +8 -5
- package/lib/cjs/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
- package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +3 -3
- package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.js +19 -5
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.js +33 -16
- package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.js +8 -5
- package/lib/esm/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
- package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +3 -3
- package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.js +21 -7
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.js +34 -17
- package/lib/umd/react-ui.js +1 -1
- package/package.json +5 -5
|
@@ -67,6 +67,7 @@ function PrivateMessageComponent(inProps) {
|
|
|
67
67
|
const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.down('md'));
|
|
68
68
|
const [layout, setLayout] = (0, react_1.useState)('default');
|
|
69
69
|
const [obj, setObj] = (0, react_1.useState)(id !== null && id !== void 0 ? id : null);
|
|
70
|
+
const [type, setType] = (0, react_1.useState)(null);
|
|
70
71
|
const isNew = obj && obj === types_1.SCPrivateMessageStatusType.NEW;
|
|
71
72
|
const [openNewMessage, setOpenNewMessage] = (0, react_1.useState)(isNew !== null && isNew !== void 0 ? isNew : false);
|
|
72
73
|
const mobileSnippetsView = (layout === 'default' && !obj) || (layout === 'mobile' && !obj);
|
|
@@ -88,10 +89,12 @@ function PrivateMessageComponent(inProps) {
|
|
|
88
89
|
/**
|
|
89
90
|
* Handles thread opening on click
|
|
90
91
|
* @param item
|
|
92
|
+
* @param type
|
|
91
93
|
*/
|
|
92
|
-
const handleThreadOpening = (item) => {
|
|
93
|
-
onItemClick && onItemClick(messageReceiver(item, authUserId));
|
|
94
|
-
|
|
94
|
+
const handleThreadOpening = (item, type) => {
|
|
95
|
+
onItemClick && onItemClick(item.group ? item.group.id : messageReceiver(item, authUserId));
|
|
96
|
+
setType(type);
|
|
97
|
+
setObj(item.group ? item : messageReceiver(item, authUserId));
|
|
95
98
|
setOpenNewMessage(false);
|
|
96
99
|
};
|
|
97
100
|
/**
|
|
@@ -149,14 +152,14 @@ function PrivateMessageComponent(inProps) {
|
|
|
149
152
|
onSnippetClick: handleThreadOpening,
|
|
150
153
|
onNewMessageClick: handleOpenNewMessage,
|
|
151
154
|
onDeleteConfirm: handleDeleteThread
|
|
152
|
-
},
|
|
155
|
+
}, threadObj: obj, clearSearch: clear, elevation: 0 })));
|
|
153
156
|
}
|
|
154
157
|
/**
|
|
155
158
|
* Renders thread section
|
|
156
159
|
*/
|
|
157
160
|
function renderThread() {
|
|
158
161
|
return (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, md: 7, className: (0, classnames_1.default)(classes.threadBox, { [classes.hide]: isMobile && mobileSnippetsView }) },
|
|
159
|
-
react_1.default.createElement(PrivateMessageThread_1.default, {
|
|
162
|
+
react_1.default.createElement(PrivateMessageThread_1.default, { threadObj: obj, type: type, openNewMessage: openNewMessage, onNewMessageClose: handleMessageBack, onNewMessageSent: handleOnNewMessageSent, onSingleMessageOpen: handleSingleMessage, elevation: 0 })));
|
|
160
163
|
}
|
|
161
164
|
/**
|
|
162
165
|
* Renders the component (if not hidden by autoHide prop)
|
|
@@ -74,10 +74,12 @@ function PrivateMessageSnippetItem(inProps) {
|
|
|
74
74
|
// STATE
|
|
75
75
|
const hasBadge = () => {
|
|
76
76
|
var _a;
|
|
77
|
-
if (
|
|
78
|
-
|
|
77
|
+
if (message.receiver) {
|
|
78
|
+
if ((message === null || message === void 0 ? void 0 : message.receiver.id) !== ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
79
|
+
return message === null || message === void 0 ? void 0 : message.receiver.community_badge;
|
|
80
|
+
}
|
|
81
|
+
return message === null || message === void 0 ? void 0 : message.sender.community_badge;
|
|
79
82
|
}
|
|
80
|
-
return message === null || message === void 0 ? void 0 : message.sender.community_badge;
|
|
81
83
|
};
|
|
82
84
|
if (!message) {
|
|
83
85
|
return react_1.default.createElement(Skeleton_1.default, { elevation: 0 });
|
|
@@ -88,10 +90,13 @@ function PrivateMessageSnippetItem(inProps) {
|
|
|
88
90
|
return (react_1.default.createElement(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { secondaryAction: secondaryAction, disablePadding: true }),
|
|
89
91
|
react_1.default.createElement(material_1.ListItemButton, { onClick: onItemClick, classes: { root: (0, classnames_1.default)({ [classes.unread]: message.thread_status === types_1.SCPrivateMessageStatusType.NEW }) } },
|
|
90
92
|
react_1.default.createElement(material_1.ListItemAvatar, null,
|
|
91
|
-
react_1.default.createElement(UserAvatar_1.default, { hide: !hasBadge() },
|
|
92
|
-
react_1.default.createElement(material_1.Avatar, { alt: ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.username) === message.receiver.username ? message.sender.username : message.receiver.username, src: ((_b = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _b === void 0 ? void 0 : _b.username) === message.receiver.username ? message.sender.avatar : message.receiver.avatar }))),
|
|
93
|
+
react_1.default.createElement(UserAvatar_1.default, { hide: !hasBadge() }, message.group ? (react_1.default.createElement(material_1.Avatar, { alt: message.group.name, src: message.group.image_bigger })) : (react_1.default.createElement(material_1.Avatar, { alt: ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.username) === message.receiver.username ? message.sender.username : message.receiver.username, src: ((_b = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _b === void 0 ? void 0 : _b.username) === message.receiver.username ? message.sender.avatar : message.receiver.avatar })))),
|
|
93
94
|
react_1.default.createElement(material_1.ListItemText, { primary: react_1.default.createElement(react_1.default.Fragment, null,
|
|
94
|
-
react_1.default.createElement(material_1.Typography, { component: "span", className: classes.username },
|
|
95
|
+
react_1.default.createElement(material_1.Typography, { component: "span", className: classes.username }, message.group
|
|
96
|
+
? message.group.name
|
|
97
|
+
: ((_c = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _c === void 0 ? void 0 : _c.username) === message.receiver.username
|
|
98
|
+
? message.sender.username
|
|
99
|
+
: message.receiver.username),
|
|
95
100
|
hasBadge() && preferences && (react_1.default.createElement(material_1.Chip, { component: "span", className: classes.badgeLabel, size: "small", label: preferences[react_core_1.SCPreferences.STAFF_STAFF_BADGE_LABEL] })),
|
|
96
101
|
react_1.default.createElement(material_1.Typography, { color: "secondary", className: classes.time, component: "span" }, `${intl.formatDate(message.last_message_at, {
|
|
97
102
|
day: '2-digit',
|
|
@@ -20,7 +20,7 @@ export interface PrivateMessageSnippetsProps extends CardProps {
|
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
22
|
snippetActions?: {
|
|
23
|
-
onSnippetClick?: (msg: any) => void;
|
|
23
|
+
onSnippetClick?: (msg: any, type: any) => void;
|
|
24
24
|
onNewMessageClick?: () => void;
|
|
25
25
|
onDeleteConfirm?: (msg: any) => void;
|
|
26
26
|
};
|
|
@@ -29,10 +29,10 @@ export interface PrivateMessageSnippetsProps extends CardProps {
|
|
|
29
29
|
*/
|
|
30
30
|
[p: string]: any;
|
|
31
31
|
/**
|
|
32
|
-
* thread user object
|
|
32
|
+
* thread user/ group object
|
|
33
33
|
* @default null
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
threadObj?: any;
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* > API documentation for the Community-JS PrivateMessageSnippets component. Learn about the available props and the CSS API.
|
|
@@ -71,15 +71,16 @@ function PrivateMessageSnippets(inProps) {
|
|
|
71
71
|
props: inProps,
|
|
72
72
|
name: constants_1.PREFIX
|
|
73
73
|
});
|
|
74
|
-
const { className = null,
|
|
74
|
+
const { className = null, threadObj = null, snippetActions, clearSearch } = props, rest = tslib_1.__rest(props, ["className", "threadObj", "snippetActions", "clearSearch"]);
|
|
75
75
|
// STATE
|
|
76
76
|
const theme = (0, material_1.useTheme)();
|
|
77
77
|
const isMobile = (0, useMediaQuery_1.default)(theme.breakpoints.down('md'));
|
|
78
78
|
const { data, updateSnippets } = (0, react_core_1.useSCFetchPrivateMessageSnippets)({ cacheStrategy: utils_1.CacheStrategies.CACHE_FIRST });
|
|
79
79
|
const [search, setSearch] = (0, react_1.useState)('');
|
|
80
|
-
const isObj = typeof
|
|
80
|
+
const isObj = typeof threadObj === 'object';
|
|
81
81
|
const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
|
|
82
82
|
const authUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
83
|
+
const [type, setType] = (0, react_1.useState)(null);
|
|
83
84
|
// INTL
|
|
84
85
|
const intl = (0, react_intl_1.useIntl)();
|
|
85
86
|
// REFS
|
|
@@ -101,6 +102,18 @@ function PrivateMessageSnippets(inProps) {
|
|
|
101
102
|
}
|
|
102
103
|
return ((_b = item === null || item === void 0 ? void 0 : item.receiver) === null || _b === void 0 ? void 0 : _b.id) !== loggedUserId ? (_c = item === null || item === void 0 ? void 0 : item.receiver) === null || _c === void 0 ? void 0 : _c.id : (_d = item === null || item === void 0 ? void 0 : item.sender) === null || _d === void 0 ? void 0 : _d.id;
|
|
103
104
|
};
|
|
105
|
+
const isSelected = (0, react_1.useMemo)(() => {
|
|
106
|
+
return (message) => {
|
|
107
|
+
var _a, _b;
|
|
108
|
+
if (type === types_1.SCPrivateMessageType.GROUP) {
|
|
109
|
+
return ((_a = message === null || message === void 0 ? void 0 : message.group) === null || _a === void 0 ? void 0 : _a.id) === (isObj ? (_b = threadObj === null || threadObj === void 0 ? void 0 : threadObj.group) === null || _b === void 0 ? void 0 : _b.id : threadObj);
|
|
110
|
+
}
|
|
111
|
+
else if (type === types_1.SCPrivateMessageType.USER) {
|
|
112
|
+
return messageReceiver(message, authUserId) === (isObj ? messageReceiver(threadObj, authUserId) : threadObj);
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
};
|
|
116
|
+
}, [threadObj, authUserId, type]);
|
|
104
117
|
//HANDLERS
|
|
105
118
|
const handleChange = (event) => {
|
|
106
119
|
setSearch(event.target.value);
|
|
@@ -116,7 +129,9 @@ function PrivateMessageSnippets(inProps) {
|
|
|
116
129
|
snippetActions && snippetActions.onDeleteConfirm(msg);
|
|
117
130
|
};
|
|
118
131
|
function handleOpenThread(msg) {
|
|
119
|
-
|
|
132
|
+
const _type = msg.group !== null ? types_1.SCPrivateMessageType.GROUP : types_1.SCPrivateMessageType.USER;
|
|
133
|
+
setType(_type);
|
|
134
|
+
snippetActions && snippetActions.onSnippetClick(msg, _type);
|
|
120
135
|
handleClear();
|
|
121
136
|
updateSnippetsParams(msg.id, 'seen');
|
|
122
137
|
}
|
|
@@ -221,7 +236,6 @@ function PrivateMessageSnippets(inProps) {
|
|
|
221
236
|
} }),
|
|
222
237
|
react_1.default.createElement(material_1.List, null, filteredSnippets.map((message) => (react_1.default.createElement(PrivateMessageSnippetItem_1.default, { message: message, key: message.id, onItemClick: () => handleOpenThread(message), secondaryAction: react_1.default.createElement(react_1.default.Fragment, null,
|
|
223
238
|
message.thread_status === types_1.SCPrivateMessageStatusType.NEW && (react_1.default.createElement(material_1.Icon, { fontSize: "small", color: "secondary" }, "fiber_manual_record")),
|
|
224
|
-
!isMobile && (react_1.default.createElement(PrivateMessageSettingsIconButton_1.default, { threadToDelete: messageReceiver(message, authUserId), onItemDeleteConfirm: () => handleDeleteConversation(messageReceiver(message, authUserId)), user: messageReceiver(message, authUserId, true) }))), selected:
|
|
225
|
-
messageReceiver(message, authUserId) === (isObj ? messageReceiver(userObj, authUserId) : userObj) })))))))));
|
|
239
|
+
!isMobile && (react_1.default.createElement(PrivateMessageSettingsIconButton_1.default, { threadToDelete: messageReceiver(message, authUserId), onItemDeleteConfirm: () => handleDeleteConversation(messageReceiver(message, authUserId)), user: messageReceiver(message, authUserId, true) }))), selected: isSelected(message) })))))))));
|
|
226
240
|
}
|
|
227
241
|
exports.default = PrivateMessageSnippets;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { SCPrivateMessageType } from '@selfcommunity/types';
|
|
1
2
|
import { CardProps } from '@mui/material';
|
|
2
3
|
export interface PrivateMessageThreadProps extends CardProps {
|
|
3
4
|
/**
|
|
4
5
|
* Thread object or thread id
|
|
5
6
|
* default null
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
+
threadObj?: any;
|
|
8
9
|
/**
|
|
9
10
|
* Overrides or extends the styles applied to the component.
|
|
10
11
|
* @default null
|
|
@@ -30,6 +31,10 @@ export interface PrivateMessageThreadProps extends CardProps {
|
|
|
30
31
|
* @default null
|
|
31
32
|
*/
|
|
32
33
|
onSingleMessageOpen?: (open: boolean) => void;
|
|
34
|
+
/**
|
|
35
|
+
* The Thread type
|
|
36
|
+
*/
|
|
37
|
+
type?: SCPrivateMessageType;
|
|
33
38
|
/**
|
|
34
39
|
* Any other properties
|
|
35
40
|
*/
|
|
@@ -95,7 +95,7 @@ function PrivateMessageThread(inProps) {
|
|
|
95
95
|
props: inProps,
|
|
96
96
|
name: constants_1.PREFIX
|
|
97
97
|
});
|
|
98
|
-
const {
|
|
98
|
+
const { threadObj, openNewMessage = false, onNewMessageClose = null, onNewMessageSent = null, onSingleMessageOpen = null, className, type } = props, rest = tslib_1.__rest(props, ["threadObj", "openNewMessage", "onNewMessageClose", "onNewMessageSent", "onSingleMessageOpen", "className", "type"]);
|
|
99
99
|
// CONTEXT
|
|
100
100
|
const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
|
|
101
101
|
// STATE
|
|
@@ -106,7 +106,7 @@ function PrivateMessageThread(inProps) {
|
|
|
106
106
|
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
107
107
|
const [isHovered, setIsHovered] = (0, react_1.useState)({});
|
|
108
108
|
const [followers, setFollowers] = (0, react_1.useState)([]);
|
|
109
|
-
const isNew =
|
|
109
|
+
const isNew = threadObj && threadObj === types_1.SCPrivateMessageStatusType.NEW;
|
|
110
110
|
const authUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
111
111
|
const [singleMessageUser, setSingleMessageUser] = (0, react_1.useState)(null);
|
|
112
112
|
const [receiver, setReceiver] = (0, react_1.useState)(null);
|
|
@@ -115,7 +115,7 @@ function PrivateMessageThread(inProps) {
|
|
|
115
115
|
const [openDeleteMessageDialog, setOpenDeleteMessageDialog] = (0, react_1.useState)(false);
|
|
116
116
|
const [recipients, setRecipients] = (0, react_1.useState)([]);
|
|
117
117
|
const { enqueueSnackbar, closeSnackbar } = (0, notistack_1.useSnackbar)();
|
|
118
|
-
const isNumber = typeof
|
|
118
|
+
const isNumber = typeof threadObj === 'number';
|
|
119
119
|
const messageReceiver = (item, loggedUserId) => {
|
|
120
120
|
var _a, _b, _c;
|
|
121
121
|
return ((_a = item === null || item === void 0 ? void 0 : item.receiver) === null || _a === void 0 ? void 0 : _a.id) !== loggedUserId ? (_b = item === null || item === void 0 ? void 0 : item.receiver) === null || _b === void 0 ? void 0 : _b.id : (_c = item === null || item === void 0 ? void 0 : item.sender) === null || _c === void 0 ? void 0 : _c.id;
|
|
@@ -128,7 +128,7 @@ function PrivateMessageThread(inProps) {
|
|
|
128
128
|
// HOOKS
|
|
129
129
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
130
130
|
// @ts-ignore
|
|
131
|
-
const { scUser } = (0, react_core_1.useSCFetchUser)({ id:
|
|
131
|
+
const { scUser } = (0, react_core_1.useSCFetchUser)({ id: threadObj, threadObj });
|
|
132
132
|
const messagesEndRef = (0, react_1.useRef)(null);
|
|
133
133
|
const scrollToBottom = () => {
|
|
134
134
|
var _a;
|
|
@@ -256,9 +256,9 @@ function PrivateMessageThread(inProps) {
|
|
|
256
256
|
* Fetches thread
|
|
257
257
|
*/
|
|
258
258
|
function fetchThread() {
|
|
259
|
-
if (
|
|
259
|
+
if (threadObj && typeof threadObj !== 'string' && type !== types_1.SCPrivateMessageType.GROUP) {
|
|
260
260
|
setLoadingMessageObjs(true);
|
|
261
|
-
const _userObjId = isNumber ?
|
|
261
|
+
const _userObjId = isNumber ? threadObj : messageReceiver(threadObj, authUserId);
|
|
262
262
|
api_services_1.PrivateMessageService.getAThread({ user: _userObjId, limit: 10 })
|
|
263
263
|
.then((res) => {
|
|
264
264
|
setMessageObjs(res.results);
|
|
@@ -291,6 +291,19 @@ function PrivateMessageThread(inProps) {
|
|
|
291
291
|
utils_1.Logger.error(Errors_1.SCOPE_SC_UI, { error });
|
|
292
292
|
});
|
|
293
293
|
}
|
|
294
|
+
else if (type === types_1.SCPrivateMessageType.GROUP) {
|
|
295
|
+
api_services_1.PrivateMessageService.getAThread({ group: isNumber ? threadObj : threadObj.group.id, limit: 10 })
|
|
296
|
+
.then((res) => {
|
|
297
|
+
setMessageObjs(res.results);
|
|
298
|
+
setPrevious(res.next && updateAndDeleteURLParameters(res.next, 'before_message', res.results[0].id, 'offset'));
|
|
299
|
+
setLoadingMessageObjs(false);
|
|
300
|
+
})
|
|
301
|
+
.catch((error) => {
|
|
302
|
+
setLoadingMessageObjs(false);
|
|
303
|
+
console.log(error);
|
|
304
|
+
utils_1.Logger.error(Errors_1.SCOPE_SC_UI, { error });
|
|
305
|
+
});
|
|
306
|
+
}
|
|
294
307
|
}
|
|
295
308
|
const isNewerThan60Seconds = (creationTime) => {
|
|
296
309
|
const date = new Date(creationTime);
|
|
@@ -355,11 +368,15 @@ function PrivateMessageThread(inProps) {
|
|
|
355
368
|
.request({
|
|
356
369
|
url: api_services_1.Endpoints.SendMessage.url(),
|
|
357
370
|
method: api_services_1.Endpoints.SendMessage.method,
|
|
358
|
-
data: {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
371
|
+
data: Object.assign(Object.assign({}, (type === types_1.SCPrivateMessageType.GROUP
|
|
372
|
+
? { group: isNumber ? threadObj : threadObj.group.id }
|
|
373
|
+
: {
|
|
374
|
+
recipients: openNewMessage || isNew || singleMessageThread
|
|
375
|
+
? ids
|
|
376
|
+
: [isNumber && threadObj ? threadObj : messageReceiver(threadObj, authUserId)]
|
|
377
|
+
})), {
|
|
378
|
+
// recipients: openNewMessage || isNew || singleMessageThread ? ids : [isNumber && threadObj ? threadObj : messageReceiver(threadObj, authUserId)],
|
|
379
|
+
message: message, file_uuid: file && !message ? file : null })
|
|
363
380
|
})
|
|
364
381
|
.then((res) => {
|
|
365
382
|
const isOne = res.data.length <= 1;
|
|
@@ -405,13 +422,13 @@ function PrivateMessageThread(inProps) {
|
|
|
405
422
|
if (!authUserId) {
|
|
406
423
|
return;
|
|
407
424
|
}
|
|
408
|
-
if (
|
|
425
|
+
if (threadObj) {
|
|
409
426
|
fetchThread();
|
|
410
427
|
}
|
|
411
428
|
else {
|
|
412
429
|
reset();
|
|
413
430
|
}
|
|
414
|
-
}, [
|
|
431
|
+
}, [threadObj, authUserId, scUser]);
|
|
415
432
|
/**
|
|
416
433
|
* Notification subscriber
|
|
417
434
|
*/
|
|
@@ -426,7 +443,7 @@ function PrivateMessageThread(inProps) {
|
|
|
426
443
|
if (index !== -1) {
|
|
427
444
|
setMessageObjs((prev) => [...prev, res.notification_obj.message]);
|
|
428
445
|
}
|
|
429
|
-
if (isNumber ?
|
|
446
|
+
if (isNumber ? threadObj === res.thread_id : threadObj.id === res.thread_id) {
|
|
430
447
|
scrollToBottom();
|
|
431
448
|
}
|
|
432
449
|
};
|
|
@@ -457,7 +474,7 @@ function PrivateMessageThread(inProps) {
|
|
|
457
474
|
onMouseEnter: () => handleMouseEnter(msg.id),
|
|
458
475
|
onMouseLeave: () => handleMouseLeave(msg.id)
|
|
459
476
|
}, isHovering: isHovered[msg.id], showMenuIcon: authUserId === msg.sender.id, onMenuIconClick: () => handleOpenDeleteMessageDialog(msg) }))))))))),
|
|
460
|
-
react_1.default.createElement(PrivateMessageEditor_1.default, { className: classes.editor, send: handleSend, autoHide: !(scUser === null || scUser === void 0 ? void 0 : scUser.can_send_pm_to), autoHideDeletion: (receiver === null || receiver === void 0 ? void 0 : receiver.deleted) || (scUser === null || scUser === void 0 ? void 0 : scUser.deleted), onThreadChangeId: isNumber ?
|
|
477
|
+
react_1.default.createElement(PrivateMessageEditor_1.default, { className: classes.editor, send: handleSend, autoHide: type === types_1.SCPrivateMessageType.USER && !(scUser === null || scUser === void 0 ? void 0 : scUser.can_send_pm_to), autoHideDeletion: type === types_1.SCPrivateMessageType.USER && ((receiver === null || receiver === void 0 ? void 0 : receiver.deleted) || (scUser === null || scUser === void 0 ? void 0 : scUser.deleted)), onThreadChangeId: isNumber ? threadObj : type === types_1.SCPrivateMessageType.USER ? threadObj.receiver.id : threadObj.group.id, error: error, onErrorRemove: () => setError(false) }),
|
|
461
478
|
openDeleteMessageDialog && (react_1.default.createElement(ConfirmDialog_1.default, { open: openDeleteMessageDialog, title: react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.privateMessage.component.delete.message.dialog.msg", defaultMessage: "ui.privateMessage.component.delete.message.dialog.msg" }), btnConfirm: react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.privateMessage.component.delete.message.dialog.confirm", defaultMessage: "ui.privateMessage.component.delete.message.dialog.confirm" }), onConfirm: handleDeleteMessage, onClose: handleCloseDeleteMessageDialog }))));
|
|
462
479
|
}
|
|
463
480
|
/**
|
|
@@ -485,6 +502,6 @@ function PrivateMessageThread(inProps) {
|
|
|
485
502
|
/**
|
|
486
503
|
* Renders the component
|
|
487
504
|
*/
|
|
488
|
-
return (react_1.default.createElement(Root, Object.assign({}, rest, { className: (0, classnames_1.default)(classes.root, className) }),
|
|
505
|
+
return (react_1.default.createElement(Root, Object.assign({}, rest, { className: (0, classnames_1.default)(classes.root, className) }), threadObj !== null && !isNew && !singleMessageThread ? renderThread() : renderNewOrNoMessageBox()));
|
|
489
506
|
}
|
|
490
507
|
exports.default = PrivateMessageThread;
|
|
@@ -65,6 +65,7 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
65
65
|
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
66
66
|
const [layout, setLayout] = useState('default');
|
|
67
67
|
const [obj, setObj] = useState(id !== null && id !== void 0 ? id : null);
|
|
68
|
+
const [type, setType] = useState(null);
|
|
68
69
|
const isNew = obj && obj === SCPrivateMessageStatusType.NEW;
|
|
69
70
|
const [openNewMessage, setOpenNewMessage] = useState(isNew !== null && isNew !== void 0 ? isNew : false);
|
|
70
71
|
const mobileSnippetsView = (layout === 'default' && !obj) || (layout === 'mobile' && !obj);
|
|
@@ -86,10 +87,12 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
86
87
|
/**
|
|
87
88
|
* Handles thread opening on click
|
|
88
89
|
* @param item
|
|
90
|
+
* @param type
|
|
89
91
|
*/
|
|
90
|
-
const handleThreadOpening = (item) => {
|
|
91
|
-
onItemClick && onItemClick(messageReceiver(item, authUserId));
|
|
92
|
-
|
|
92
|
+
const handleThreadOpening = (item, type) => {
|
|
93
|
+
onItemClick && onItemClick(item.group ? item.group.id : messageReceiver(item, authUserId));
|
|
94
|
+
setType(type);
|
|
95
|
+
setObj(item.group ? item : messageReceiver(item, authUserId));
|
|
93
96
|
setOpenNewMessage(false);
|
|
94
97
|
};
|
|
95
98
|
/**
|
|
@@ -147,14 +150,14 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
147
150
|
onSnippetClick: handleThreadOpening,
|
|
148
151
|
onNewMessageClick: handleOpenNewMessage,
|
|
149
152
|
onDeleteConfirm: handleDeleteThread
|
|
150
|
-
},
|
|
153
|
+
}, threadObj: obj, clearSearch: clear, elevation: 0 })));
|
|
151
154
|
}
|
|
152
155
|
/**
|
|
153
156
|
* Renders thread section
|
|
154
157
|
*/
|
|
155
158
|
function renderThread() {
|
|
156
159
|
return (React.createElement(Grid, { item: true, xs: 12, md: 7, className: classNames(classes.threadBox, { [classes.hide]: isMobile && mobileSnippetsView }) },
|
|
157
|
-
React.createElement(PrivateMessageThread, {
|
|
160
|
+
React.createElement(PrivateMessageThread, { threadObj: obj, type: type, openNewMessage: openNewMessage, onNewMessageClose: handleMessageBack, onNewMessageSent: handleOnNewMessageSent, onSingleMessageOpen: handleSingleMessage, elevation: 0 })));
|
|
158
161
|
}
|
|
159
162
|
/**
|
|
160
163
|
* Renders the component (if not hidden by autoHide prop)
|
|
@@ -72,10 +72,12 @@ export default function PrivateMessageSnippetItem(inProps) {
|
|
|
72
72
|
// STATE
|
|
73
73
|
const hasBadge = () => {
|
|
74
74
|
var _a;
|
|
75
|
-
if (
|
|
76
|
-
|
|
75
|
+
if (message.receiver) {
|
|
76
|
+
if ((message === null || message === void 0 ? void 0 : message.receiver.id) !== ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
77
|
+
return message === null || message === void 0 ? void 0 : message.receiver.community_badge;
|
|
78
|
+
}
|
|
79
|
+
return message === null || message === void 0 ? void 0 : message.sender.community_badge;
|
|
77
80
|
}
|
|
78
|
-
return message === null || message === void 0 ? void 0 : message.sender.community_badge;
|
|
79
81
|
};
|
|
80
82
|
if (!message) {
|
|
81
83
|
return React.createElement(PrivateMessageSnippetItemSkeleton, { elevation: 0 });
|
|
@@ -86,10 +88,13 @@ export default function PrivateMessageSnippetItem(inProps) {
|
|
|
86
88
|
return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { secondaryAction: secondaryAction, disablePadding: true }),
|
|
87
89
|
React.createElement(ListItemButton, { onClick: onItemClick, classes: { root: classNames({ [classes.unread]: message.thread_status === SCPrivateMessageStatusType.NEW }) } },
|
|
88
90
|
React.createElement(ListItemAvatar, null,
|
|
89
|
-
React.createElement(UserAvatar, { hide: !hasBadge() },
|
|
90
|
-
React.createElement(Avatar, { alt: ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.username) === message.receiver.username ? message.sender.username : message.receiver.username, src: ((_b = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _b === void 0 ? void 0 : _b.username) === message.receiver.username ? message.sender.avatar : message.receiver.avatar }))),
|
|
91
|
+
React.createElement(UserAvatar, { hide: !hasBadge() }, message.group ? (React.createElement(Avatar, { alt: message.group.name, src: message.group.image_bigger })) : (React.createElement(Avatar, { alt: ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.username) === message.receiver.username ? message.sender.username : message.receiver.username, src: ((_b = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _b === void 0 ? void 0 : _b.username) === message.receiver.username ? message.sender.avatar : message.receiver.avatar })))),
|
|
91
92
|
React.createElement(ListItemText, { primary: React.createElement(React.Fragment, null,
|
|
92
|
-
React.createElement(Typography, { component: "span", className: classes.username },
|
|
93
|
+
React.createElement(Typography, { component: "span", className: classes.username }, message.group
|
|
94
|
+
? message.group.name
|
|
95
|
+
: ((_c = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _c === void 0 ? void 0 : _c.username) === message.receiver.username
|
|
96
|
+
? message.sender.username
|
|
97
|
+
: message.receiver.username),
|
|
93
98
|
hasBadge() && preferences && (React.createElement(Chip, { component: "span", className: classes.badgeLabel, size: "small", label: preferences[SCPreferences.STAFF_STAFF_BADGE_LABEL] })),
|
|
94
99
|
React.createElement(Typography, { color: "secondary", className: classes.time, component: "span" }, `${intl.formatDate(message.last_message_at, {
|
|
95
100
|
day: '2-digit',
|
|
@@ -20,7 +20,7 @@ export interface PrivateMessageSnippetsProps extends CardProps {
|
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
22
|
snippetActions?: {
|
|
23
|
-
onSnippetClick?: (msg: any) => void;
|
|
23
|
+
onSnippetClick?: (msg: any, type: any) => void;
|
|
24
24
|
onNewMessageClick?: () => void;
|
|
25
25
|
onDeleteConfirm?: (msg: any) => void;
|
|
26
26
|
};
|
|
@@ -29,10 +29,10 @@ export interface PrivateMessageSnippetsProps extends CardProps {
|
|
|
29
29
|
*/
|
|
30
30
|
[p: string]: any;
|
|
31
31
|
/**
|
|
32
|
-
* thread user object
|
|
32
|
+
* thread user/ group object
|
|
33
33
|
* @default null
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
threadObj?: any;
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* > API documentation for the Community-JS PrivateMessageSnippets component. Learn about the available props and the CSS API.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
|
-
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
4
|
import { Button, Card, CardContent, Icon, IconButton, List, TextField, useTheme } from '@mui/material';
|
|
5
5
|
import PubSub from 'pubsub-js';
|
|
6
|
-
import { SCNotificationTopicType, SCNotificationTypologyType, SCPrivateMessageStatusType } from '@selfcommunity/types';
|
|
6
|
+
import { SCNotificationTopicType, SCNotificationTypologyType, SCPrivateMessageStatusType, SCPrivateMessageType } from '@selfcommunity/types';
|
|
7
7
|
import PrivateMessageSnippetsSkeleton from './Skeleton';
|
|
8
8
|
import PrivateMessageSnippetItem from '../PrivateMessageSnippetItem';
|
|
9
9
|
import classNames from 'classnames';
|
|
@@ -69,15 +69,16 @@ export default function PrivateMessageSnippets(inProps) {
|
|
|
69
69
|
props: inProps,
|
|
70
70
|
name: PREFIX
|
|
71
71
|
});
|
|
72
|
-
const { className = null,
|
|
72
|
+
const { className = null, threadObj = null, snippetActions, clearSearch } = props, rest = __rest(props, ["className", "threadObj", "snippetActions", "clearSearch"]);
|
|
73
73
|
// STATE
|
|
74
74
|
const theme = useTheme();
|
|
75
75
|
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
76
76
|
const { data, updateSnippets } = useSCFetchPrivateMessageSnippets({ cacheStrategy: CacheStrategies.CACHE_FIRST });
|
|
77
77
|
const [search, setSearch] = useState('');
|
|
78
|
-
const isObj = typeof
|
|
78
|
+
const isObj = typeof threadObj === 'object';
|
|
79
79
|
const scUserContext = useContext(SCUserContext);
|
|
80
80
|
const authUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
81
|
+
const [type, setType] = useState(null);
|
|
81
82
|
// INTL
|
|
82
83
|
const intl = useIntl();
|
|
83
84
|
// REFS
|
|
@@ -99,6 +100,18 @@ export default function PrivateMessageSnippets(inProps) {
|
|
|
99
100
|
}
|
|
100
101
|
return ((_b = item === null || item === void 0 ? void 0 : item.receiver) === null || _b === void 0 ? void 0 : _b.id) !== loggedUserId ? (_c = item === null || item === void 0 ? void 0 : item.receiver) === null || _c === void 0 ? void 0 : _c.id : (_d = item === null || item === void 0 ? void 0 : item.sender) === null || _d === void 0 ? void 0 : _d.id;
|
|
101
102
|
};
|
|
103
|
+
const isSelected = useMemo(() => {
|
|
104
|
+
return (message) => {
|
|
105
|
+
var _a, _b;
|
|
106
|
+
if (type === SCPrivateMessageType.GROUP) {
|
|
107
|
+
return ((_a = message === null || message === void 0 ? void 0 : message.group) === null || _a === void 0 ? void 0 : _a.id) === (isObj ? (_b = threadObj === null || threadObj === void 0 ? void 0 : threadObj.group) === null || _b === void 0 ? void 0 : _b.id : threadObj);
|
|
108
|
+
}
|
|
109
|
+
else if (type === SCPrivateMessageType.USER) {
|
|
110
|
+
return messageReceiver(message, authUserId) === (isObj ? messageReceiver(threadObj, authUserId) : threadObj);
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
};
|
|
114
|
+
}, [threadObj, authUserId, type]);
|
|
102
115
|
//HANDLERS
|
|
103
116
|
const handleChange = (event) => {
|
|
104
117
|
setSearch(event.target.value);
|
|
@@ -114,7 +127,9 @@ export default function PrivateMessageSnippets(inProps) {
|
|
|
114
127
|
snippetActions && snippetActions.onDeleteConfirm(msg);
|
|
115
128
|
};
|
|
116
129
|
function handleOpenThread(msg) {
|
|
117
|
-
|
|
130
|
+
const _type = msg.group !== null ? SCPrivateMessageType.GROUP : SCPrivateMessageType.USER;
|
|
131
|
+
setType(_type);
|
|
132
|
+
snippetActions && snippetActions.onSnippetClick(msg, _type);
|
|
118
133
|
handleClear();
|
|
119
134
|
updateSnippetsParams(msg.id, 'seen');
|
|
120
135
|
}
|
|
@@ -219,6 +234,5 @@ export default function PrivateMessageSnippets(inProps) {
|
|
|
219
234
|
} }),
|
|
220
235
|
React.createElement(List, null, filteredSnippets.map((message) => (React.createElement(PrivateMessageSnippetItem, { message: message, key: message.id, onItemClick: () => handleOpenThread(message), secondaryAction: React.createElement(React.Fragment, null,
|
|
221
236
|
message.thread_status === SCPrivateMessageStatusType.NEW && (React.createElement(Icon, { fontSize: "small", color: "secondary" }, "fiber_manual_record")),
|
|
222
|
-
!isMobile && (React.createElement(PrivateMessageSettingsIconButton, { threadToDelete: messageReceiver(message, authUserId), onItemDeleteConfirm: () => handleDeleteConversation(messageReceiver(message, authUserId)), user: messageReceiver(message, authUserId, true) }))), selected:
|
|
223
|
-
messageReceiver(message, authUserId) === (isObj ? messageReceiver(userObj, authUserId) : userObj) })))))))));
|
|
237
|
+
!isMobile && (React.createElement(PrivateMessageSettingsIconButton, { threadToDelete: messageReceiver(message, authUserId), onItemDeleteConfirm: () => handleDeleteConversation(messageReceiver(message, authUserId)), user: messageReceiver(message, authUserId, true) }))), selected: isSelected(message) })))))))));
|
|
224
238
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { SCPrivateMessageType } from '@selfcommunity/types';
|
|
1
2
|
import { CardProps } from '@mui/material';
|
|
2
3
|
export interface PrivateMessageThreadProps extends CardProps {
|
|
3
4
|
/**
|
|
4
5
|
* Thread object or thread id
|
|
5
6
|
* default null
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
+
threadObj?: any;
|
|
8
9
|
/**
|
|
9
10
|
* Overrides or extends the styles applied to the component.
|
|
10
11
|
* @default null
|
|
@@ -30,6 +31,10 @@ export interface PrivateMessageThreadProps extends CardProps {
|
|
|
30
31
|
* @default null
|
|
31
32
|
*/
|
|
32
33
|
onSingleMessageOpen?: (open: boolean) => void;
|
|
34
|
+
/**
|
|
35
|
+
* The Thread type
|
|
36
|
+
*/
|
|
37
|
+
type?: SCPrivateMessageType;
|
|
33
38
|
/**
|
|
34
39
|
* Any other properties
|
|
35
40
|
*/
|