@selfcommunity/react-ui 0.7.0-alpha.357 → 0.7.0-alpha.359
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/Composer/Attributes/Attributes.d.ts +1 -1
- package/lib/cjs/components/Composer/Attributes/Attributes.js +7 -1
- package/lib/cjs/components/Composer/Composer.js +5 -2
- package/lib/cjs/components/LocationAutocomplete/LocationAutocomplete.js +9 -3
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.js +5 -27
- package/lib/cjs/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +15 -10
- package/lib/cjs/shared/Media/Link/PreviewComponent.js +3 -1
- package/lib/esm/components/Composer/Attributes/Attributes.d.ts +1 -1
- package/lib/esm/components/Composer/Attributes/Attributes.js +7 -1
- package/lib/esm/components/Composer/Composer.js +5 -2
- package/lib/esm/components/LocationAutocomplete/LocationAutocomplete.js +10 -4
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.js +6 -28
- package/lib/esm/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +15 -10
- package/lib/esm/shared/Media/Link/PreviewComponent.js +3 -1
- package/lib/umd/react-ui.js +1 -1
- package/package.json +6 -6
|
@@ -16,7 +16,7 @@ export interface AttributesProps extends Omit<BoxProps, 'value' | 'onChange' | '
|
|
|
16
16
|
* @param value
|
|
17
17
|
* @default empty object
|
|
18
18
|
*/
|
|
19
|
-
onClick?: (attribute: 'categories' | 'addressing') => void;
|
|
19
|
+
onClick?: (attribute: 'categories' | 'addressing' | 'location') => void;
|
|
20
20
|
}
|
|
21
21
|
declare const _default: (props: AttributesProps) => JSX.Element;
|
|
22
22
|
export default _default;
|
|
@@ -32,10 +32,16 @@ exports.default = (props) => {
|
|
|
32
32
|
const handleClickTag = (0, react_1.useCallback)(() => {
|
|
33
33
|
onClick && onClick('addressing');
|
|
34
34
|
}, [onClick]);
|
|
35
|
+
const handleDeleteLocation = (0, react_1.useCallback)(() => {
|
|
36
|
+
onChange && onChange(Object.assign(Object.assign({}, value), { location: null }));
|
|
37
|
+
}, [value, onChange]);
|
|
38
|
+
const handleClickLocation = (0, react_1.useCallback)(() => {
|
|
39
|
+
onClick && onClick('location');
|
|
40
|
+
}, [onClick]);
|
|
35
41
|
return (react_1.default.createElement(Root, { className: (0, classnames_1.default)(classes.root, className) },
|
|
36
42
|
((_a = value === null || value === void 0 ? void 0 : value.categories) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
|
|
37
43
|
(value === null || value === void 0 ? void 0 : value.categories.map((c) => (react_1.default.createElement(material_1.Chip, { key: c.id, label: c.name, onDelete: handleDeleteCategory(c.id), icon: react_1.default.createElement(Icon_1.default, null, "category"), onClick: handleClickCategory })))),
|
|
38
44
|
((_b = value === null || value === void 0 ? void 0 : value.addressing) === null || _b === void 0 ? void 0 : _b.length) > 0 &&
|
|
39
45
|
(value === null || value === void 0 ? void 0 : value.addressing.map((t) => (react_1.default.createElement(TagChip_1.default, { key: t.id, tag: t, onDelete: handleDeleteTag(t.id), icon: react_1.default.createElement(Icon_1.default, null, "label"), onClick: handleClickTag })))),
|
|
40
|
-
(value === null || value === void 0 ? void 0 : value.location) && (react_1.default.createElement(material_1.Chip, { icon: react_1.default.createElement(Icon_1.default, null, "add_location_alt"), label: value === null || value === void 0 ? void 0 : value.location.location, onDelete:
|
|
46
|
+
(value === null || value === void 0 ? void 0 : value.location) && (react_1.default.createElement(material_1.Chip, { icon: react_1.default.createElement(Icon_1.default, null, "add_location_alt"), label: value === null || value === void 0 ? void 0 : value.location.location, onDelete: handleDeleteLocation, onClick: handleClickLocation }))));
|
|
41
47
|
};
|
|
@@ -342,8 +342,11 @@ function Composer(inProps) {
|
|
|
342
342
|
case 'addressing':
|
|
343
343
|
handleAddAudienceLayer();
|
|
344
344
|
break;
|
|
345
|
+
case 'location':
|
|
346
|
+
handleAddLocationLayer();
|
|
347
|
+
break;
|
|
345
348
|
}
|
|
346
|
-
}, [handleAddCategoryLayer, handleAddAudienceLayer]);
|
|
349
|
+
}, [handleAddCategoryLayer, handleAddAudienceLayer, handleAddLocationLayer]);
|
|
347
350
|
const handleSubmit = (0, react_1.useCallback)((event) => {
|
|
348
351
|
event.preventDefault();
|
|
349
352
|
event.stopPropagation();
|
|
@@ -476,7 +479,7 @@ function Composer(inProps) {
|
|
|
476
479
|
react_1.default.createElement(material_1.IconButton, { disabled: isSubmitting, onClick: handleAddCategoryLayer },
|
|
477
480
|
react_1.default.createElement(Icon_1.default, null, "category")),
|
|
478
481
|
react_1.default.createElement(material_1.IconButton, { disabled: isSubmitting || !features.includes(types_1.SCFeatureName.TAGGING), onClick: handleAddAudienceLayer }, addressing === null || addressing.length === 0 ? react_1.default.createElement(Icon_1.default, null, "public") : react_1.default.createElement(Icon_1.default, null, "label")),
|
|
479
|
-
preferences[react_core_1.SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED] && (react_1.default.createElement(material_1.IconButton, { disabled: isSubmitting, onClick: handleAddLocationLayer, color: location !== null ? 'primary' : 'default' },
|
|
482
|
+
preferences[react_core_1.SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED].value && (react_1.default.createElement(material_1.IconButton, { disabled: isSubmitting, onClick: handleAddLocationLayer, color: location !== null ? 'primary' : 'default' },
|
|
480
483
|
react_1.default.createElement(Icon_1.default, null, "add_location_alt"))))),
|
|
481
484
|
layer && react_1.default.createElement(LayerTransitionRoot, { className: classes.layerTransitionRoot, in: true, container: dialogRef.current, direction: "left" },
|
|
482
485
|
react_1.default.createElement(layer.Component, Object.assign({}, layer.ComponentProps)))));
|
|
@@ -88,16 +88,22 @@ function LocationAutocomplete(inProps) {
|
|
|
88
88
|
}, [value]);
|
|
89
89
|
// Handlers
|
|
90
90
|
const handleChange = (event, value) => {
|
|
91
|
-
setValue({ location: value.full_address, lat: value.lat,
|
|
91
|
+
setValue(value ? { location: value.full_address, lat: value.lat, lng: value.lng } : null);
|
|
92
92
|
onChange && onChange(value);
|
|
93
93
|
};
|
|
94
94
|
const handleSearch = (event, _search) => {
|
|
95
95
|
setSearch(_search);
|
|
96
96
|
};
|
|
97
97
|
// Render
|
|
98
|
-
|
|
98
|
+
const options = (0, react_1.useMemo)(() => {
|
|
99
|
+
if (!value || typeof value === 'string' || locations.find((loc) => value.lat === loc.lat && value.lng === loc.lng)) {
|
|
100
|
+
return locations;
|
|
101
|
+
}
|
|
102
|
+
return [...locations, { lat: value.lat, lng: value.lng, full_address: value.location }];
|
|
103
|
+
}, [value, locations]);
|
|
104
|
+
return (react_1.default.createElement(Root, Object.assign({ className: classes.root, options: options || [],
|
|
99
105
|
// @ts-ignore
|
|
100
|
-
getOptionLabel: (option) => (option === null || option === void 0 ? void 0 : option.full_address) || (option === null || option === void 0 ? void 0 : option.location) || '', filterOptions: (x) => x, autoComplete: true, includeInputInList: true,
|
|
106
|
+
getOptionLabel: (option) => (option === null || option === void 0 ? void 0 : option.full_address) || (option === null || option === void 0 ? void 0 : option.location) || '', filterOptions: (x) => x, autoComplete: true, includeInputInList: true, value: value || null, selectOnFocus: true, handleHomeEndKeys: true, disabled: disabled, noOptionsText: react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.locationAutocomplete.empty", defaultMessage: "ui.locationAutocomplete.empty" }), onChange: handleChange, onInputChange: handleSearch, isOptionEqualToValue: (option, value) => value.lat === option.lat && value.lng === option.lng, renderInput: (params) => {
|
|
101
107
|
return (react_1.default.createElement(TextField_1.default, Object.assign({}, params, TextFieldProps, { margin: "dense", InputProps: Object.assign(Object.assign({}, params.InputProps), { autoComplete: 'location', endAdornment: (react_1.default.createElement(react_1.default.Fragment, null,
|
|
102
108
|
isLoading ? react_1.default.createElement(CircularProgress_1.default, { color: "inherit", size: 20 }) : null,
|
|
103
109
|
params.InputProps.endAdornment)) }) })));
|
|
@@ -98,21 +98,6 @@ function PrivateMessageThread(inProps) {
|
|
|
98
98
|
const { userObj, openNewMessage = false, onNewMessageClose = null, onNewMessageSent = null, onSingleMessageOpen = null, className } = props, rest = tslib_1.__rest(props, ["userObj", "openNewMessage", "onNewMessageClose", "onNewMessageSent", "onSingleMessageOpen", "className"]);
|
|
99
99
|
// CONTEXT
|
|
100
100
|
const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
|
|
101
|
-
const role = react_core_1.UserUtils.getUserRole(scUserContext['user']);
|
|
102
|
-
const scPreferencesContext = (0, react_core_1.useSCPreferences)();
|
|
103
|
-
const followEnabled = (0, react_1.useMemo)(() => react_core_1.SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED in scPreferencesContext.preferences &&
|
|
104
|
-
scPreferencesContext.preferences[react_core_1.SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED].value, [scPreferencesContext.preferences]);
|
|
105
|
-
const manager = followEnabled
|
|
106
|
-
? scUserContext.managers.followers
|
|
107
|
-
: scUserContext.managers.connections;
|
|
108
|
-
function checkFollowerOrConnection(user) {
|
|
109
|
-
if ('isFollower' in manager) {
|
|
110
|
-
return manager.isFollower(user);
|
|
111
|
-
}
|
|
112
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
113
|
-
// @ts-ignore
|
|
114
|
-
return manager.status(user);
|
|
115
|
-
}
|
|
116
101
|
// STATE
|
|
117
102
|
const [value, setValue] = (0, react_1.useState)('');
|
|
118
103
|
const [previous, setPrevious] = (0, react_1.useState)(null);
|
|
@@ -121,7 +106,6 @@ function PrivateMessageThread(inProps) {
|
|
|
121
106
|
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
122
107
|
const [isHovered, setIsHovered] = (0, react_1.useState)({});
|
|
123
108
|
const [followers, setFollowers] = (0, react_1.useState)([]);
|
|
124
|
-
const [isFollower, setIsFollower] = (0, react_1.useState)(false);
|
|
125
109
|
const isNew = userObj && userObj === types_1.SCPrivateMessageStatusType.NEW;
|
|
126
110
|
const authUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
127
111
|
const [singleMessageUser, setSingleMessageUser] = (0, react_1.useState)(null);
|
|
@@ -274,7 +258,6 @@ function PrivateMessageThread(inProps) {
|
|
|
274
258
|
function fetchThread() {
|
|
275
259
|
if (userObj && typeof userObj !== 'string') {
|
|
276
260
|
setLoadingMessageObjs(true);
|
|
277
|
-
const _isFollower = (scUser && checkFollowerOrConnection(scUser)) || (scUser && scUser.community_badge);
|
|
278
261
|
const _userObjId = isNumber ? userObj : messageReceiver(userObj, authUserId);
|
|
279
262
|
api_services_1.PrivateMessageService.getAThread({ user: _userObjId, limit: 10 })
|
|
280
263
|
.then((res) => {
|
|
@@ -290,7 +273,7 @@ function PrivateMessageThread(inProps) {
|
|
|
290
273
|
setSingleMessageThread(false);
|
|
291
274
|
}
|
|
292
275
|
else {
|
|
293
|
-
if (
|
|
276
|
+
if (scUser === null || scUser === void 0 ? void 0 : scUser.can_send_pm_to) {
|
|
294
277
|
setSingleMessageThread(true);
|
|
295
278
|
setRecipients(_userObjId);
|
|
296
279
|
onSingleMessageOpen(true);
|
|
@@ -308,6 +291,9 @@ function PrivateMessageThread(inProps) {
|
|
|
308
291
|
utils_1.Logger.error(Errors_1.SCOPE_SC_UI, { error });
|
|
309
292
|
});
|
|
310
293
|
}
|
|
294
|
+
else {
|
|
295
|
+
setSingleMessageUser(scUser);
|
|
296
|
+
}
|
|
311
297
|
}
|
|
312
298
|
const isNewerThan60Seconds = (creationTime) => {
|
|
313
299
|
const date = new Date(creationTime);
|
|
@@ -415,14 +401,6 @@ function PrivateMessageThread(inProps) {
|
|
|
415
401
|
fetchResults();
|
|
416
402
|
}
|
|
417
403
|
}, [value]);
|
|
418
|
-
/**
|
|
419
|
-
* Checks is thread receiver is a user follower
|
|
420
|
-
*/
|
|
421
|
-
(0, react_1.useEffect)(() => {
|
|
422
|
-
if (receiver) {
|
|
423
|
-
!receiver.community_badge && scUser ? setIsFollower(checkFollowerOrConnection(scUser)) : setIsFollower(true);
|
|
424
|
-
}
|
|
425
|
-
});
|
|
426
404
|
/**
|
|
427
405
|
* On mount, if obj, fetches thread
|
|
428
406
|
*/
|
|
@@ -482,7 +460,7 @@ function PrivateMessageThread(inProps) {
|
|
|
482
460
|
onMouseEnter: () => handleMouseEnter(msg.id),
|
|
483
461
|
onMouseLeave: () => handleMouseLeave(msg.id)
|
|
484
462
|
}, isHovering: isHovered[msg.id], showMenuIcon: authUserId === msg.sender.id, onMenuIconClick: () => handleOpenDeleteMessageDialog(msg) }))))))))),
|
|
485
|
-
react_1.default.createElement(PrivateMessageEditor_1.default, { className: classes.editor, send: handleSend, autoHide: !
|
|
463
|
+
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 ? userObj : userObj.receiver.id, error: error, onErrorRemove: () => setError(false) }),
|
|
486
464
|
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 }))));
|
|
487
465
|
}
|
|
488
466
|
/**
|
|
@@ -121,6 +121,11 @@ function PrivateMessageThreadItem(inProps) {
|
|
|
121
121
|
return null;
|
|
122
122
|
}
|
|
123
123
|
let section = null;
|
|
124
|
+
const defaultSection = (react_1.default.createElement(material_1.Box, { className: classes.other },
|
|
125
|
+
react_1.default.createElement(material_1.Button, { onClick: () => handleDownload(m.file) },
|
|
126
|
+
react_1.default.createElement(Icon_1.default, null, "download"),
|
|
127
|
+
react_1.default.createElement(material_1.Typography, null, m.file.filename),
|
|
128
|
+
react_1.default.createElement(material_1.Typography, null, (0, sizeCoverter_1.bytesToSize)(m.file.filesize)))));
|
|
124
129
|
if (m.file) {
|
|
125
130
|
let type = m.file.mimetype;
|
|
126
131
|
switch (true) {
|
|
@@ -129,11 +134,15 @@ function PrivateMessageThreadItem(inProps) {
|
|
|
129
134
|
react_1.default.createElement("img", { src: m.file.thumbnail, loading: "lazy", alt: 'img', onClick: () => setOpenDialog(true) })));
|
|
130
135
|
break;
|
|
131
136
|
case type.startsWith(types_1.SCMessageFileType.VIDEO):
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
if (!(0, thumbnailCoverter_1.isSupportedVideoFormat)(m.file.filename)) {
|
|
138
|
+
section = defaultSection;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
section = (react_1.default.createElement(material_1.Box, { className: (0, classnames_1.default)(classes.img, classes.video) },
|
|
142
|
+
react_1.default.createElement("img", { src: m.file.thumbnail, loading: "lazy", alt: 'img' }),
|
|
143
|
+
react_1.default.createElement(material_1.IconButton, { onClick: () => setOpenDialog(true) },
|
|
144
|
+
react_1.default.createElement(Icon_1.default, null, "play_circle_outline"))));
|
|
145
|
+
}
|
|
137
146
|
break;
|
|
138
147
|
case type.startsWith(types_1.SCMessageFileType.DOCUMENT):
|
|
139
148
|
section = (react_1.default.createElement(material_1.Box, { className: m.file.filename.endsWith('.pdf') ? classes.document : classes.other },
|
|
@@ -145,11 +154,7 @@ function PrivateMessageThreadItem(inProps) {
|
|
|
145
154
|
break;
|
|
146
155
|
default:
|
|
147
156
|
// section = <Icon>hide_image</Icon>;
|
|
148
|
-
section =
|
|
149
|
-
react_1.default.createElement(material_1.Button, { onClick: () => handleDownload(m.file) },
|
|
150
|
-
react_1.default.createElement(Icon_1.default, null, "download"),
|
|
151
|
-
react_1.default.createElement(material_1.Typography, null, m.file.filename),
|
|
152
|
-
react_1.default.createElement(material_1.Typography, null, (0, sizeCoverter_1.bytesToSize)(m.file.filesize)))));
|
|
157
|
+
section = defaultSection;
|
|
153
158
|
break;
|
|
154
159
|
}
|
|
155
160
|
}
|
|
@@ -10,9 +10,11 @@ const react_sortablejs_1 = require("react-sortablejs");
|
|
|
10
10
|
const DisplayComponent_1 = tslib_1.__importDefault(require("./DisplayComponent"));
|
|
11
11
|
const constants_1 = require("./constants");
|
|
12
12
|
const filter_1 = tslib_1.__importDefault(require("./filter"));
|
|
13
|
+
const Media_1 = require("../../../constants/Media");
|
|
13
14
|
const classes = {
|
|
14
15
|
previewRoot: `${constants_1.PREFIX}-preview-root`,
|
|
15
16
|
media: `${constants_1.PREFIX}-media`,
|
|
17
|
+
video: `${constants_1.PREFIX}-media-video`,
|
|
16
18
|
delete: `${constants_1.PREFIX}-delete`
|
|
17
19
|
};
|
|
18
20
|
const Root = (0, styles_1.styled)(material_1.Box, {
|
|
@@ -29,7 +31,7 @@ const PreviewComponent = react_1.default.forwardRef((props, ref) => {
|
|
|
29
31
|
onChange && onChange([...value.filter((media) => medias.findIndex((m) => m.id === media.id) === -1), ...medias]);
|
|
30
32
|
}, [onChange, value]);
|
|
31
33
|
const handleDelete = (0, react_1.useCallback)((id) => () => onChange && onChange(value.filter((media) => media.id !== id)), [onChange, value]);
|
|
32
|
-
return react_1.default.createElement(Root, Object.assign({ ref: ref, className: (0, classnames_1.default)(className, classes.previewRoot) }, rest), medias.length > 0 && (react_1.default.createElement(react_sortablejs_1.ReactSortable, { list: medias, setList: handleSort }, medias.map((media) => (react_1.default.createElement(material_1.Box, { key: media.id, className: classes.media },
|
|
34
|
+
return react_1.default.createElement(Root, Object.assign({ ref: ref, className: (0, classnames_1.default)(className, classes.previewRoot) }, rest), medias.length > 0 && (react_1.default.createElement(react_sortablejs_1.ReactSortable, { list: medias, setList: handleSort }, medias.map((media) => (react_1.default.createElement(material_1.Box, { key: media.id, className: (0, classnames_1.default)(classes.media, { [classes.video]: media.embed.metadata && media.embed.metadata.type === Media_1.MEDIA_TYPE_VIDEO }) },
|
|
33
35
|
react_1.default.createElement(DisplayComponent_1.default, { medias: [media] }),
|
|
34
36
|
react_1.default.createElement(material_1.IconButton, { className: classes.delete, onClick: handleDelete(media.id), size: "small" },
|
|
35
37
|
react_1.default.createElement(Icon_1.default, null, "delete"))))))));
|
|
@@ -16,7 +16,7 @@ export interface AttributesProps extends Omit<BoxProps, 'value' | 'onChange' | '
|
|
|
16
16
|
* @param value
|
|
17
17
|
* @default empty object
|
|
18
18
|
*/
|
|
19
|
-
onClick?: (attribute: 'categories' | 'addressing') => void;
|
|
19
|
+
onClick?: (attribute: 'categories' | 'addressing' | 'location') => void;
|
|
20
20
|
}
|
|
21
21
|
declare const _default: (props: AttributesProps) => JSX.Element;
|
|
22
22
|
export default _default;
|
|
@@ -29,10 +29,16 @@ export default (props) => {
|
|
|
29
29
|
const handleClickTag = useCallback(() => {
|
|
30
30
|
onClick && onClick('addressing');
|
|
31
31
|
}, [onClick]);
|
|
32
|
+
const handleDeleteLocation = useCallback(() => {
|
|
33
|
+
onChange && onChange(Object.assign(Object.assign({}, value), { location: null }));
|
|
34
|
+
}, [value, onChange]);
|
|
35
|
+
const handleClickLocation = useCallback(() => {
|
|
36
|
+
onClick && onClick('location');
|
|
37
|
+
}, [onClick]);
|
|
32
38
|
return (React.createElement(Root, { className: classNames(classes.root, className) },
|
|
33
39
|
((_a = value === null || value === void 0 ? void 0 : value.categories) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
|
|
34
40
|
(value === null || value === void 0 ? void 0 : value.categories.map((c) => (React.createElement(Chip, { key: c.id, label: c.name, onDelete: handleDeleteCategory(c.id), icon: React.createElement(Icon, null, "category"), onClick: handleClickCategory })))),
|
|
35
41
|
((_b = value === null || value === void 0 ? void 0 : value.addressing) === null || _b === void 0 ? void 0 : _b.length) > 0 &&
|
|
36
42
|
(value === null || value === void 0 ? void 0 : value.addressing.map((t) => (React.createElement(TagChip, { key: t.id, tag: t, onDelete: handleDeleteTag(t.id), icon: React.createElement(Icon, null, "label"), onClick: handleClickTag })))),
|
|
37
|
-
(value === null || value === void 0 ? void 0 : value.location) && (React.createElement(Chip, { icon: React.createElement(Icon, null, "add_location_alt"), label: value === null || value === void 0 ? void 0 : value.location.location, onDelete:
|
|
43
|
+
(value === null || value === void 0 ? void 0 : value.location) && (React.createElement(Chip, { icon: React.createElement(Icon, null, "add_location_alt"), label: value === null || value === void 0 ? void 0 : value.location.location, onDelete: handleDeleteLocation, onClick: handleClickLocation }))));
|
|
38
44
|
};
|
|
@@ -340,8 +340,11 @@ export default function Composer(inProps) {
|
|
|
340
340
|
case 'addressing':
|
|
341
341
|
handleAddAudienceLayer();
|
|
342
342
|
break;
|
|
343
|
+
case 'location':
|
|
344
|
+
handleAddLocationLayer();
|
|
345
|
+
break;
|
|
343
346
|
}
|
|
344
|
-
}, [handleAddCategoryLayer, handleAddAudienceLayer]);
|
|
347
|
+
}, [handleAddCategoryLayer, handleAddAudienceLayer, handleAddLocationLayer]);
|
|
345
348
|
const handleSubmit = useCallback((event) => {
|
|
346
349
|
event.preventDefault();
|
|
347
350
|
event.stopPropagation();
|
|
@@ -474,7 +477,7 @@ export default function Composer(inProps) {
|
|
|
474
477
|
React.createElement(IconButton, { disabled: isSubmitting, onClick: handleAddCategoryLayer },
|
|
475
478
|
React.createElement(Icon, null, "category")),
|
|
476
479
|
React.createElement(IconButton, { disabled: isSubmitting || !features.includes(SCFeatureName.TAGGING), onClick: handleAddAudienceLayer }, addressing === null || addressing.length === 0 ? React.createElement(Icon, null, "public") : React.createElement(Icon, null, "label")),
|
|
477
|
-
preferences[SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED] && (React.createElement(IconButton, { disabled: isSubmitting, onClick: handleAddLocationLayer, color: location !== null ? 'primary' : 'default' },
|
|
480
|
+
preferences[SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED].value && (React.createElement(IconButton, { disabled: isSubmitting, onClick: handleAddLocationLayer, color: location !== null ? 'primary' : 'default' },
|
|
478
481
|
React.createElement(Icon, null, "add_location_alt"))))),
|
|
479
482
|
layer && React.createElement(LayerTransitionRoot, { className: classes.layerTransitionRoot, in: true, container: dialogRef.current, direction: "left" },
|
|
480
483
|
React.createElement(layer.Component, Object.assign({}, layer.ComponentProps)))));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
|
-
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { FormattedMessage } from 'react-intl';
|
|
4
4
|
import TextField from '@mui/material/TextField';
|
|
5
5
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
@@ -86,16 +86,22 @@ export default function LocationAutocomplete(inProps) {
|
|
|
86
86
|
}, [value]);
|
|
87
87
|
// Handlers
|
|
88
88
|
const handleChange = (event, value) => {
|
|
89
|
-
setValue({ location: value.full_address, lat: value.lat,
|
|
89
|
+
setValue(value ? { location: value.full_address, lat: value.lat, lng: value.lng } : null);
|
|
90
90
|
onChange && onChange(value);
|
|
91
91
|
};
|
|
92
92
|
const handleSearch = (event, _search) => {
|
|
93
93
|
setSearch(_search);
|
|
94
94
|
};
|
|
95
95
|
// Render
|
|
96
|
-
|
|
96
|
+
const options = useMemo(() => {
|
|
97
|
+
if (!value || typeof value === 'string' || locations.find((loc) => value.lat === loc.lat && value.lng === loc.lng)) {
|
|
98
|
+
return locations;
|
|
99
|
+
}
|
|
100
|
+
return [...locations, { lat: value.lat, lng: value.lng, full_address: value.location }];
|
|
101
|
+
}, [value, locations]);
|
|
102
|
+
return (React.createElement(Root, Object.assign({ className: classes.root, options: options || [],
|
|
97
103
|
// @ts-ignore
|
|
98
|
-
getOptionLabel: (option) => (option === null || option === void 0 ? void 0 : option.full_address) || (option === null || option === void 0 ? void 0 : option.location) || '', filterOptions: (x) => x, autoComplete: true, includeInputInList: true,
|
|
104
|
+
getOptionLabel: (option) => (option === null || option === void 0 ? void 0 : option.full_address) || (option === null || option === void 0 ? void 0 : option.location) || '', filterOptions: (x) => x, autoComplete: true, includeInputInList: true, value: value || null, selectOnFocus: true, handleHomeEndKeys: true, disabled: disabled, noOptionsText: React.createElement(FormattedMessage, { id: "ui.locationAutocomplete.empty", defaultMessage: "ui.locationAutocomplete.empty" }), onChange: handleChange, onInputChange: handleSearch, isOptionEqualToValue: (option, value) => value.lat === option.lat && value.lng === option.lng, renderInput: (params) => {
|
|
99
105
|
return (React.createElement(TextField, Object.assign({}, params, TextFieldProps, { margin: "dense", InputProps: Object.assign(Object.assign({}, params.InputProps), { autoComplete: 'location', endAdornment: (React.createElement(React.Fragment, null,
|
|
100
106
|
isLoading ? React.createElement(CircularProgress, { color: "inherit", size: 20 }) : null,
|
|
101
107
|
params.InputProps.endAdornment)) }) })));
|
|
@@ -2,7 +2,7 @@ import { __rest } from "tslib";
|
|
|
2
2
|
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
4
|
import { Endpoints, http, PrivateMessageService } from '@selfcommunity/api-services';
|
|
5
|
-
import {
|
|
5
|
+
import { SCUserContext, UserUtils, useSCFetchUser } from '@selfcommunity/react-core';
|
|
6
6
|
import { SCNotificationTopicType, SCNotificationTypologyType, SCPrivateMessageStatusType } from '@selfcommunity/types';
|
|
7
7
|
import PrivateMessageThreadItem, { PrivateMessageThreadItemSkeleton } from '../PrivateMessageThreadItem';
|
|
8
8
|
import PubSub from 'pubsub-js';
|
|
@@ -96,21 +96,6 @@ export default function PrivateMessageThread(inProps) {
|
|
|
96
96
|
const { userObj, openNewMessage = false, onNewMessageClose = null, onNewMessageSent = null, onSingleMessageOpen = null, className } = props, rest = __rest(props, ["userObj", "openNewMessage", "onNewMessageClose", "onNewMessageSent", "onSingleMessageOpen", "className"]);
|
|
97
97
|
// CONTEXT
|
|
98
98
|
const scUserContext = useContext(SCUserContext);
|
|
99
|
-
const role = UserUtils.getUserRole(scUserContext['user']);
|
|
100
|
-
const scPreferencesContext = useSCPreferences();
|
|
101
|
-
const followEnabled = useMemo(() => SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED in scPreferencesContext.preferences &&
|
|
102
|
-
scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED].value, [scPreferencesContext.preferences]);
|
|
103
|
-
const manager = followEnabled
|
|
104
|
-
? scUserContext.managers.followers
|
|
105
|
-
: scUserContext.managers.connections;
|
|
106
|
-
function checkFollowerOrConnection(user) {
|
|
107
|
-
if ('isFollower' in manager) {
|
|
108
|
-
return manager.isFollower(user);
|
|
109
|
-
}
|
|
110
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
111
|
-
// @ts-ignore
|
|
112
|
-
return manager.status(user);
|
|
113
|
-
}
|
|
114
99
|
// STATE
|
|
115
100
|
const [value, setValue] = useState('');
|
|
116
101
|
const [previous, setPrevious] = useState(null);
|
|
@@ -119,7 +104,6 @@ export default function PrivateMessageThread(inProps) {
|
|
|
119
104
|
const [loading, setLoading] = useState(false);
|
|
120
105
|
const [isHovered, setIsHovered] = useState({});
|
|
121
106
|
const [followers, setFollowers] = useState([]);
|
|
122
|
-
const [isFollower, setIsFollower] = useState(false);
|
|
123
107
|
const isNew = userObj && userObj === SCPrivateMessageStatusType.NEW;
|
|
124
108
|
const authUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
125
109
|
const [singleMessageUser, setSingleMessageUser] = useState(null);
|
|
@@ -272,7 +256,6 @@ export default function PrivateMessageThread(inProps) {
|
|
|
272
256
|
function fetchThread() {
|
|
273
257
|
if (userObj && typeof userObj !== 'string') {
|
|
274
258
|
setLoadingMessageObjs(true);
|
|
275
|
-
const _isFollower = (scUser && checkFollowerOrConnection(scUser)) || (scUser && scUser.community_badge);
|
|
276
259
|
const _userObjId = isNumber ? userObj : messageReceiver(userObj, authUserId);
|
|
277
260
|
PrivateMessageService.getAThread({ user: _userObjId, limit: 10 })
|
|
278
261
|
.then((res) => {
|
|
@@ -288,7 +271,7 @@ export default function PrivateMessageThread(inProps) {
|
|
|
288
271
|
setSingleMessageThread(false);
|
|
289
272
|
}
|
|
290
273
|
else {
|
|
291
|
-
if (
|
|
274
|
+
if (scUser === null || scUser === void 0 ? void 0 : scUser.can_send_pm_to) {
|
|
292
275
|
setSingleMessageThread(true);
|
|
293
276
|
setRecipients(_userObjId);
|
|
294
277
|
onSingleMessageOpen(true);
|
|
@@ -306,6 +289,9 @@ export default function PrivateMessageThread(inProps) {
|
|
|
306
289
|
Logger.error(SCOPE_SC_UI, { error });
|
|
307
290
|
});
|
|
308
291
|
}
|
|
292
|
+
else {
|
|
293
|
+
setSingleMessageUser(scUser);
|
|
294
|
+
}
|
|
309
295
|
}
|
|
310
296
|
const isNewerThan60Seconds = (creationTime) => {
|
|
311
297
|
const date = new Date(creationTime);
|
|
@@ -413,14 +399,6 @@ export default function PrivateMessageThread(inProps) {
|
|
|
413
399
|
fetchResults();
|
|
414
400
|
}
|
|
415
401
|
}, [value]);
|
|
416
|
-
/**
|
|
417
|
-
* Checks is thread receiver is a user follower
|
|
418
|
-
*/
|
|
419
|
-
useEffect(() => {
|
|
420
|
-
if (receiver) {
|
|
421
|
-
!receiver.community_badge && scUser ? setIsFollower(checkFollowerOrConnection(scUser)) : setIsFollower(true);
|
|
422
|
-
}
|
|
423
|
-
});
|
|
424
402
|
/**
|
|
425
403
|
* On mount, if obj, fetches thread
|
|
426
404
|
*/
|
|
@@ -480,7 +458,7 @@ export default function PrivateMessageThread(inProps) {
|
|
|
480
458
|
onMouseEnter: () => handleMouseEnter(msg.id),
|
|
481
459
|
onMouseLeave: () => handleMouseLeave(msg.id)
|
|
482
460
|
}, isHovering: isHovered[msg.id], showMenuIcon: authUserId === msg.sender.id, onMenuIconClick: () => handleOpenDeleteMessageDialog(msg) }))))))))),
|
|
483
|
-
React.createElement(PrivateMessageEditor, { className: classes.editor, send: handleSend, autoHide: !
|
|
461
|
+
React.createElement(PrivateMessageEditor, { 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 ? userObj : userObj.receiver.id, error: error, onErrorRemove: () => setError(false) }),
|
|
484
462
|
openDeleteMessageDialog && (React.createElement(ConfirmDialog, { open: openDeleteMessageDialog, title: React.createElement(FormattedMessage, { id: "ui.privateMessage.component.delete.message.dialog.msg", defaultMessage: "ui.privateMessage.component.delete.message.dialog.msg" }), btnConfirm: React.createElement(FormattedMessage, { id: "ui.privateMessage.component.delete.message.dialog.confirm", defaultMessage: "ui.privateMessage.component.delete.message.dialog.confirm" }), onConfirm: handleDeleteMessage, onClose: handleCloseDeleteMessageDialog }))));
|
|
485
463
|
}
|
|
486
464
|
/**
|
|
@@ -119,6 +119,11 @@ export default function PrivateMessageThreadItem(inProps) {
|
|
|
119
119
|
return null;
|
|
120
120
|
}
|
|
121
121
|
let section = null;
|
|
122
|
+
const defaultSection = (React.createElement(Box, { className: classes.other },
|
|
123
|
+
React.createElement(Button, { onClick: () => handleDownload(m.file) },
|
|
124
|
+
React.createElement(Icon, null, "download"),
|
|
125
|
+
React.createElement(Typography, null, m.file.filename),
|
|
126
|
+
React.createElement(Typography, null, bytesToSize(m.file.filesize)))));
|
|
122
127
|
if (m.file) {
|
|
123
128
|
let type = m.file.mimetype;
|
|
124
129
|
switch (true) {
|
|
@@ -127,11 +132,15 @@ export default function PrivateMessageThreadItem(inProps) {
|
|
|
127
132
|
React.createElement("img", { src: m.file.thumbnail, loading: "lazy", alt: 'img', onClick: () => setOpenDialog(true) })));
|
|
128
133
|
break;
|
|
129
134
|
case type.startsWith(SCMessageFileType.VIDEO):
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
if (!isSupportedVideoFormat(m.file.filename)) {
|
|
136
|
+
section = defaultSection;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
section = (React.createElement(Box, { className: classNames(classes.img, classes.video) },
|
|
140
|
+
React.createElement("img", { src: m.file.thumbnail, loading: "lazy", alt: 'img' }),
|
|
141
|
+
React.createElement(IconButton, { onClick: () => setOpenDialog(true) },
|
|
142
|
+
React.createElement(Icon, null, "play_circle_outline"))));
|
|
143
|
+
}
|
|
135
144
|
break;
|
|
136
145
|
case type.startsWith(SCMessageFileType.DOCUMENT):
|
|
137
146
|
section = (React.createElement(Box, { className: m.file.filename.endsWith('.pdf') ? classes.document : classes.other },
|
|
@@ -143,11 +152,7 @@ export default function PrivateMessageThreadItem(inProps) {
|
|
|
143
152
|
break;
|
|
144
153
|
default:
|
|
145
154
|
// section = <Icon>hide_image</Icon>;
|
|
146
|
-
section =
|
|
147
|
-
React.createElement(Button, { onClick: () => handleDownload(m.file) },
|
|
148
|
-
React.createElement(Icon, null, "download"),
|
|
149
|
-
React.createElement(Typography, null, m.file.filename),
|
|
150
|
-
React.createElement(Typography, null, bytesToSize(m.file.filesize)))));
|
|
155
|
+
section = defaultSection;
|
|
151
156
|
break;
|
|
152
157
|
}
|
|
153
158
|
}
|
|
@@ -8,9 +8,11 @@ import { ReactSortable } from 'react-sortablejs';
|
|
|
8
8
|
import DisplayComponent from './DisplayComponent';
|
|
9
9
|
import { PREFIX } from './constants';
|
|
10
10
|
import filter from './filter';
|
|
11
|
+
import { MEDIA_TYPE_VIDEO } from '../../../constants/Media';
|
|
11
12
|
const classes = {
|
|
12
13
|
previewRoot: `${PREFIX}-preview-root`,
|
|
13
14
|
media: `${PREFIX}-media`,
|
|
15
|
+
video: `${PREFIX}-media-video`,
|
|
14
16
|
delete: `${PREFIX}-delete`
|
|
15
17
|
};
|
|
16
18
|
const Root = styled(Box, {
|
|
@@ -27,7 +29,7 @@ const PreviewComponent = React.forwardRef((props, ref) => {
|
|
|
27
29
|
onChange && onChange([...value.filter((media) => medias.findIndex((m) => m.id === media.id) === -1), ...medias]);
|
|
28
30
|
}, [onChange, value]);
|
|
29
31
|
const handleDelete = useCallback((id) => () => onChange && onChange(value.filter((media) => media.id !== id)), [onChange, value]);
|
|
30
|
-
return React.createElement(Root, Object.assign({ ref: ref, className: classNames(className, classes.previewRoot) }, rest), medias.length > 0 && (React.createElement(ReactSortable, { list: medias, setList: handleSort }, medias.map((media) => (React.createElement(Box, { key: media.id, className: classes.media },
|
|
32
|
+
return React.createElement(Root, Object.assign({ ref: ref, className: classNames(className, classes.previewRoot) }, rest), medias.length > 0 && (React.createElement(ReactSortable, { list: medias, setList: handleSort }, medias.map((media) => (React.createElement(Box, { key: media.id, className: classNames(classes.media, { [classes.video]: media.embed.metadata && media.embed.metadata.type === MEDIA_TYPE_VIDEO }) },
|
|
31
33
|
React.createElement(DisplayComponent, { medias: [media] }),
|
|
32
34
|
React.createElement(IconButton, { className: classes.delete, onClick: handleDelete(media.id), size: "small" },
|
|
33
35
|
React.createElement(Icon, null, "delete"))))))));
|