@selfcommunity/react-ui 0.8.0-live.75 → 0.8.0-live.78
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/CreateLiveStreamDialog/CreateLiveStreamDialog.js +1 -1
- package/lib/cjs/components/EventForm/EventAddress.d.ts +2 -1
- package/lib/cjs/components/EventForm/EventAddress.js +17 -7
- package/lib/cjs/components/EventForm/EventForm.d.ts +6 -0
- package/lib/cjs/components/EventForm/EventForm.js +12 -8
- package/lib/cjs/components/EventFormDialog/EventFormDialog.d.ts +1 -1
- package/lib/cjs/components/EventFormDialog/EventFormDialog.js +3 -3
- package/lib/cjs/components/LiveStreamForm/LiveStreamForm.js +10 -5
- package/lib/cjs/components/LiveStreamRoom/LiveStreamRoom.js +2 -2
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js +1 -1
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +0 -2
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js +2 -1
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +8 -8
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/RecordingIndicator.d.ts +1 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/RecordingIndicator.js +1 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.d.ts +3 -2
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +58 -15
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/useLiveStreamCheck.js +24 -7
- package/lib/cjs/components/LiveStreamRoom/constants.d.ts +1 -1
- package/lib/cjs/components/LiveStreamRoom/constants.js +1 -1
- package/lib/cjs/components/Notification/LiveStream/LiveStream.js +3 -1
- package/lib/cjs/shared/EventInfoDetails/index.js +9 -1
- package/lib/esm/components/CreateLiveStreamDialog/CreateLiveStreamDialog.js +1 -1
- package/lib/esm/components/EventForm/EventAddress.d.ts +2 -1
- package/lib/esm/components/EventForm/EventAddress.js +17 -7
- package/lib/esm/components/EventForm/EventForm.d.ts +6 -0
- package/lib/esm/components/EventForm/EventForm.js +12 -8
- package/lib/esm/components/EventFormDialog/EventFormDialog.d.ts +1 -1
- package/lib/esm/components/EventFormDialog/EventFormDialog.js +3 -3
- package/lib/esm/components/LiveStreamForm/LiveStreamForm.js +10 -5
- package/lib/esm/components/LiveStreamRoom/LiveStreamRoom.js +3 -3
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js +1 -1
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +0 -2
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js +2 -1
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +8 -8
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/RecordingIndicator.d.ts +1 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/RecordingIndicator.js +1 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.d.ts +3 -2
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +58 -15
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/useLiveStreamCheck.js +25 -8
- package/lib/esm/components/LiveStreamRoom/constants.d.ts +1 -1
- package/lib/esm/components/LiveStreamRoom/constants.js +1 -1
- package/lib/esm/components/Notification/LiveStream/LiveStream.js +3 -1
- package/lib/esm/shared/EventInfoDetails/index.js +12 -4
- package/lib/umd/react-ui.js +1 -1
- package/package.json +7 -7
|
@@ -9,6 +9,7 @@ const notistack_1 = require("notistack");
|
|
|
9
9
|
const react_intl_1 = require("react-intl");
|
|
10
10
|
const react_core_1 = require("@selfcommunity/react-core");
|
|
11
11
|
const constants_1 = require("../constants");
|
|
12
|
+
const livekit_client_1 = require("livekit-client");
|
|
12
13
|
/**
|
|
13
14
|
* Custom hook for monitoring livestream.
|
|
14
15
|
* @param {number} warningThreshold
|
|
@@ -16,20 +17,33 @@ const constants_1 = require("../constants");
|
|
|
16
17
|
* @param performDisconnect
|
|
17
18
|
*/
|
|
18
19
|
function useLivestreamCheck(warningThreshold = constants_1.WARNING_THRESHOLD_EXPIRING_SOON, showWarnings = true, performDisconnect = true) {
|
|
20
|
+
// STATE
|
|
21
|
+
const [timeRemaining, setTimeRemaining] = (0, react_1.useState)(60);
|
|
22
|
+
const [isExpiringSoon, setIsExpiringSoon] = (0, react_1.useState)(false);
|
|
23
|
+
const [isExpired, setIsExpired] = (0, react_1.useState)(false);
|
|
24
|
+
const intervalRef = (0, react_1.useRef)(null);
|
|
19
25
|
// HOOKS
|
|
20
26
|
const scUserContext = (0, react_core_1.useSCUser)();
|
|
21
|
-
const participants = (0, components_react_1.useParticipants)(
|
|
27
|
+
const participants = (0, components_react_1.useParticipants)({
|
|
28
|
+
updateOnlyOn: [
|
|
29
|
+
livekit_client_1.RoomEvent.ParticipantConnected,
|
|
30
|
+
livekit_client_1.RoomEvent.ParticipantDisconnected,
|
|
31
|
+
livekit_client_1.RoomEvent.ConnectionStateChanged,
|
|
32
|
+
livekit_client_1.RoomEvent.Connected,
|
|
33
|
+
livekit_client_1.RoomEvent.Disconnected,
|
|
34
|
+
livekit_client_1.RoomEvent.TrackSubscribed,
|
|
35
|
+
livekit_client_1.RoomEvent.TrackUnsubscribed
|
|
36
|
+
]
|
|
37
|
+
});
|
|
22
38
|
const { liveStream } = (0, LiveStreamProvider_1.useLiveStream)();
|
|
23
39
|
const { buttonProps } = (0, components_react_1.useDisconnectButton)({});
|
|
24
40
|
const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
|
|
25
41
|
const __DEBUG = (0, react_1.useRef)(true);
|
|
26
|
-
// STATE
|
|
27
|
-
const [timeRemaining, setTimeRemaining] = (0, react_1.useState)(60);
|
|
28
|
-
const [isExpiringSoon, setIsExpiringSoon] = (0, react_1.useState)(false);
|
|
29
|
-
const [isExpired, setIsExpired] = (0, react_1.useState)(false);
|
|
30
|
-
const intervalRef = (0, react_1.useRef)(null);
|
|
31
42
|
// INTL
|
|
32
43
|
const intl = (0, react_intl_1.useIntl)();
|
|
44
|
+
/**
|
|
45
|
+
* fetchLivestreamStatus
|
|
46
|
+
*/
|
|
33
47
|
const fetchLivestreamStatus = () => {
|
|
34
48
|
api_services_1.LiveStreamApiClient.getMonthlyDuration()
|
|
35
49
|
.then((r) => {
|
|
@@ -57,6 +71,9 @@ function useLivestreamCheck(warningThreshold = constants_1.WARNING_THRESHOLD_EXP
|
|
|
57
71
|
console.error('Error fetching live status:', error);
|
|
58
72
|
});
|
|
59
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Check live
|
|
76
|
+
*/
|
|
60
77
|
const check = (0, react_1.useCallback)(() => {
|
|
61
78
|
if (__DEBUG) {
|
|
62
79
|
console.log('Checking live status');
|
|
@@ -108,7 +125,7 @@ function useLivestreamCheck(warningThreshold = constants_1.WARNING_THRESHOLD_EXP
|
|
|
108
125
|
(0, react_1.useEffect)(() => {
|
|
109
126
|
intervalRef.current = setInterval(check, constants_1.LIVE_CHECKING_INTERVAL * 60000);
|
|
110
127
|
return () => intervalRef.current && clearInterval(intervalRef.current);
|
|
111
|
-
}, [isExpired, isExpiringSoon]);
|
|
128
|
+
}, [isExpired, isExpiringSoon, participants]);
|
|
112
129
|
return { timeRemaining, isExpiringSoon, isExpired };
|
|
113
130
|
}
|
|
114
131
|
exports.useLivestreamCheck = useLivestreamCheck;
|
|
@@ -7,7 +7,7 @@ export declare const defaultVideoOptions: {
|
|
|
7
7
|
* Checking live status on VideoLiveConference
|
|
8
8
|
* In minutes
|
|
9
9
|
*/
|
|
10
|
-
export declare const LIVE_CHECKING_INTERVAL =
|
|
10
|
+
export declare const LIVE_CHECKING_INTERVAL = 1;
|
|
11
11
|
/**
|
|
12
12
|
* Warning threshold expiring soon
|
|
13
13
|
* In minutes
|
|
@@ -44,7 +44,9 @@ function LiveStreamNotification(props) {
|
|
|
44
44
|
// CONST
|
|
45
45
|
const isSnippetTemplate = template === types_1.SCNotificationObjectTemplateType.SNIPPET;
|
|
46
46
|
const isToastTemplate = template === types_1.SCNotificationObjectTemplateType.TOAST;
|
|
47
|
-
const inProgress = Boolean(!notificationObject.live_stream.closed_at_by_host &&
|
|
47
|
+
const inProgress = Boolean(!notificationObject.live_stream.closed_at_by_host &&
|
|
48
|
+
notificationObject.live_stream.last_started_at &&
|
|
49
|
+
!notificationObject.live_stream.last_finished_at);
|
|
48
50
|
// RENDER
|
|
49
51
|
if (isSnippetTemplate) {
|
|
50
52
|
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.live_stream.host.deleted && {
|
|
@@ -12,6 +12,7 @@ const classes = {
|
|
|
12
12
|
iconTextWrapper: `${PREFIX}-icon-text-wrapper`,
|
|
13
13
|
inProgress: `${PREFIX}-in-progress`,
|
|
14
14
|
link: `${PREFIX}-link`,
|
|
15
|
+
joinLive: `${PREFIX}-join-live`,
|
|
15
16
|
url: `${PREFIX}-url`,
|
|
16
17
|
creationWrapper: `${PREFIX}-creation-wrapper`
|
|
17
18
|
};
|
|
@@ -30,6 +31,9 @@ function EventInfoDetails(inProps) {
|
|
|
30
31
|
// HOOKS
|
|
31
32
|
const intl = (0, react_intl_1.useIntl)();
|
|
32
33
|
const { scEvent } = (0, react_core_1.useSCFetchEvent)({ id: eventId, event });
|
|
34
|
+
// CONTEXT
|
|
35
|
+
const scRoutingContext = (0, react_core_1.useSCRouting)();
|
|
36
|
+
const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
|
|
33
37
|
const privacy = (0, react_1.useMemo)(() => (scEvent && scEvent.privacy === types_1.SCEventPrivacyType.PUBLIC ? 'ui.eventInfoDetails.privacy.public' : 'ui.eventInfoDetails.privacy.private'), [scEvent]);
|
|
34
38
|
const location = (0, react_1.useMemo)(() => scEvent && scEvent.location === types_1.SCEventLocationType.ONLINE ? 'ui.eventInfoDetails.location.virtual' : 'ui.eventInfoDetails.location.inPerson', [scEvent]);
|
|
35
39
|
if (!scEvent) {
|
|
@@ -43,7 +47,11 @@ function EventInfoDetails(inProps) {
|
|
|
43
47
|
month: 'long'
|
|
44
48
|
}),
|
|
45
49
|
start: intl.formatDate(scEvent.running ? scEvent.running_start_date : scEvent.next_start_date ? scEvent.next_start_date : scEvent.start_date, { hour: 'numeric', minute: 'numeric' })
|
|
46
|
-
} }) })) })), hasInProgress && scEvent.active && scEvent.running && ((0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventInfoDetails.inProgress", defaultMessage: "ui.eventInfoDetails.inProgress" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.inProgress }) })))] }))), beforeRecurringInfo, hasRecurringInfo && scEvent.recurring !== types_1.SCEventRecurrenceType.NEVER && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideRecurringIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "frequency" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder`, defaultMessage: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder` }) }))] }))), beforePrivacyInfo, hasPrivacyInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hidePrivacyIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: scEvent.privacy === types_1.SCEventPrivacyType.PUBLIC ? 'public' : 'private' })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: privacy, defaultMessage: privacy }) })), "-", (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: location, defaultMessage: location }) }))] }))), beforeLocationInfo, hasLocationInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideLocationIcon && ((0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: scEvent.location === types_1.SCEventLocationType.ONLINE ? 'play_circle_outline' : 'add_location_alt' }))), scEvent.location === types_1.SCEventLocationType.ONLINE ? (
|
|
50
|
+
} }) })) })), hasInProgress && scEvent.active && scEvent.running && ((0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventInfoDetails.inProgress", defaultMessage: "ui.eventInfoDetails.inProgress" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.inProgress }) })))] }))), beforeRecurringInfo, hasRecurringInfo && scEvent.recurring !== types_1.SCEventRecurrenceType.NEVER && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideRecurringIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "frequency" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder`, defaultMessage: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder` }) }))] }))), beforePrivacyInfo, hasPrivacyInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hidePrivacyIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: scEvent.privacy === types_1.SCEventPrivacyType.PUBLIC ? 'public' : 'private' })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: privacy, defaultMessage: privacy }) })), "-", (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: location, defaultMessage: location }) }))] }))), beforeLocationInfo, hasLocationInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideLocationIcon && ((0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: scEvent.location === types_1.SCEventLocationType.ONLINE ? 'play_circle_outline' : 'add_location_alt' }))), scEvent.location === types_1.SCEventLocationType.ONLINE ? (scEvent.live_stream ? ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "contained", color: "secondary", component: react_core_1.Link, disabled: Boolean(!scUserContext.user ||
|
|
51
|
+
(scEvent.live_stream.host.id !== scUserContext.user.id &&
|
|
52
|
+
!scEvent.live_stream.closed_at_by_host &&
|
|
53
|
+
scEvent.live_stream.last_started_at &&
|
|
54
|
+
!scEvent.live_stream.last_finished_at)), to: scRoutingContext.url(react_core_1.SCRoutes.LIVESTREAM_ROUTE_NAME, scEvent.live_stream), className: classes.joinLive }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.eventInfoDetails.live.join", id: "ui.eventInfoDetails.live.join" }) }))) : ((0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scEvent.link, target: "_blank", className: classes.link }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.link })) })))) : ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.geolocation })))] }))), beforeCreatedInfo, hasCreatedInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.creationWrapper }, { children: [!hideCreatedIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "create" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventInfoDetails.date.create", defaultMessage: "ui.eventInfoDetails.date.create", values: {
|
|
47
55
|
date: intl.formatDate(scEvent.created_at, {
|
|
48
56
|
weekday: 'long',
|
|
49
57
|
day: 'numeric',
|
|
@@ -96,5 +96,5 @@ export default function CreateLiveStreamDialog(inProps) {
|
|
|
96
96
|
/**
|
|
97
97
|
* Renders root object
|
|
98
98
|
*/
|
|
99
|
-
return (_jsx(Root, Object.assign({ DialogContentProps: { dividers: false }, maxWidth: 'md', title: _jsxs(Box, Object.assign({ className: classes.title, component: 'span' }, { children: [Boolean(step === CreateLiveStreamStep.CREATE_LIVE && canCreateEvent) && (_jsx(Button, Object.assign({ variant: "text", onClick: handleBack, startIcon: _jsx(Icon, { children: "arrow_back" }) }, { children: "Back" }))), _jsx(Box, Object.assign({ component: 'span' }, { children: _jsx(FormattedMessage, { id: "ui.createLivestreamDialog.title", defaultMessage: "ui.createLivestreamDialog.title" }) }))] })), fullWidth: true, open: open, scroll: 'paper', onClose: onClose, className: classNames(classes.root, className), TransitionComponent: Transition, PaperProps: { elevation: 0 } }, rest, { children: _jsxs(Box, Object.assign({ className: classes.content }, { children: [step === CreateLiveStreamStep.SELECT_TYPE && (_jsx(LiveStreamSelector, { liveSelected: liveType, onLiveSelected: handleLiveTypeSelected, onNext: handleLiveTypeSelectedNext })), step === CreateLiveStreamStep.CREATE_LIVE && (_jsx(_Fragment, { children: liveType === LiveStreamType.EVENT_LIVE ? (_jsx(EventForm, {
|
|
99
|
+
return (_jsx(Root, Object.assign({ DialogContentProps: { dividers: false }, maxWidth: 'md', title: _jsxs(Box, Object.assign({ className: classes.title, component: 'span' }, { children: [Boolean(step === CreateLiveStreamStep.CREATE_LIVE && canCreateEvent) && (_jsx(Button, Object.assign({ variant: "text", onClick: handleBack, startIcon: _jsx(Icon, { children: "arrow_back" }) }, { children: "Back" }))), _jsx(Box, Object.assign({ component: 'span' }, { children: _jsx(FormattedMessage, { id: "ui.createLivestreamDialog.title", defaultMessage: "ui.createLivestreamDialog.title" }) }))] })), fullWidth: true, open: open, scroll: 'paper', onClose: onClose, className: classNames(classes.root, className), TransitionComponent: Transition, PaperProps: { elevation: 0 } }, rest, { children: _jsxs(Box, Object.assign({ className: classes.content }, { children: [step === CreateLiveStreamStep.SELECT_TYPE && (_jsx(LiveStreamSelector, { liveSelected: liveType, onLiveSelected: handleLiveTypeSelected, onNext: handleLiveTypeSelectedNext })), step === CreateLiveStreamStep.CREATE_LIVE && (_jsx(_Fragment, { children: liveType === LiveStreamType.EVENT_LIVE ? (_jsx(EventForm, { EventAddressComponentProps: { locations: [SCEventLocationType.LIVESTREAM] }, onSuccess: handleSubmit })) : (_jsx(LiveStreamForm, { onSuccess: handleSubmit })) }))] })) })));
|
|
100
100
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { SCEventType } from '@selfcommunity/types';
|
|
1
|
+
import { SCEventLocationType, SCEventType } from '@selfcommunity/types';
|
|
2
2
|
import { Geolocation } from './types';
|
|
3
3
|
export interface EventAddressProps {
|
|
4
|
+
locations?: SCEventLocationType[];
|
|
4
5
|
event?: SCEventType | Partial<SCEventType>;
|
|
5
6
|
forwardGeolocationData: (data: Geolocation) => void;
|
|
6
7
|
forwardLivestreamSettingsData: (settings: any) => void;
|
|
@@ -11,7 +11,6 @@ import axios from 'axios';
|
|
|
11
11
|
import classNames from 'classnames';
|
|
12
12
|
import { useEffect, useMemo, useState } from 'react';
|
|
13
13
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
|
14
|
-
import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
|
|
15
14
|
import UrlTextField from '../../shared/UrlTextField';
|
|
16
15
|
import { PREFIX } from './constants';
|
|
17
16
|
import LiveStream from '../LiveStream';
|
|
@@ -40,7 +39,7 @@ const Root = styled(Box, {
|
|
|
40
39
|
slot: 'EventAddressRoot'
|
|
41
40
|
})(() => ({}));
|
|
42
41
|
export default function EventAddress(inProps) {
|
|
43
|
-
var _a;
|
|
42
|
+
var _a, _b;
|
|
44
43
|
//PROPS
|
|
45
44
|
const props = useThemeProps({
|
|
46
45
|
props: inProps,
|
|
@@ -49,9 +48,9 @@ export default function EventAddress(inProps) {
|
|
|
49
48
|
// INTL
|
|
50
49
|
const intl = useIntl();
|
|
51
50
|
// PROPS
|
|
52
|
-
const { className,
|
|
51
|
+
const { className, locations = [SCEventLocationType.PERSON, SCEventLocationType.ONLINE, SCEventLocationType.LIVESTREAM], event, forwardGeolocationData, forwardLivestreamSettingsData } = props;
|
|
53
52
|
// STATE
|
|
54
|
-
const [location, setLocation] = useState((event === null || event === void 0 ? void 0 : event.location) ||
|
|
53
|
+
const [location, setLocation] = useState((event === null || event === void 0 ? void 0 : event.location) || locations[0]);
|
|
55
54
|
const [geolocation, setGeoLocation] = useState(event ? { description: event.geolocation } : null);
|
|
56
55
|
const [inputValue, setInputValue] = useState('');
|
|
57
56
|
const [suggestions, setSuggestions] = useState([]);
|
|
@@ -82,6 +81,14 @@ export default function EventAddress(inProps) {
|
|
|
82
81
|
return (!isFreeTrialTier || (isFreeTrialTier && (scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) && (scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user.id) === 1)) &&
|
|
83
82
|
(((_b = (_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.create_live_stream) || event.live_stream);
|
|
84
83
|
}, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission, event]);
|
|
84
|
+
const isInPersonTabActive = useMemo(() => locations.includes(SCEventLocationType.PERSON) || event.location === SCEventLocationType.PERSON, [locations]);
|
|
85
|
+
const isOnlineTabActive = useMemo(() => locations.includes(SCEventLocationType.ONLINE) || event.location === SCEventLocationType.ONLINE, [locations]);
|
|
86
|
+
const isLiveTabActive = useMemo(() => {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
return locations.includes(SCEventLocationType.LIVESTREAM) &&
|
|
89
|
+
(!isFreeTrialTier || (isFreeTrialTier && (scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) && (scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user.id) === 1)) &&
|
|
90
|
+
(((_b = (_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.create_live_stream) || event.live_stream);
|
|
91
|
+
}, [(_b = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _b === void 0 ? void 0 : _b.permission, event]);
|
|
85
92
|
// HANDLERS
|
|
86
93
|
const handleChange = (_event, newValue) => {
|
|
87
94
|
setLocation(newValue);
|
|
@@ -143,9 +150,12 @@ export default function EventAddress(inProps) {
|
|
|
143
150
|
}
|
|
144
151
|
}, [inputValue]);
|
|
145
152
|
if (!geocodingApiKey && !isLoaded) {
|
|
146
|
-
return
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
if (!isInPersonTabActive && !isOnlineTabActive && !isLiveTabActive) {
|
|
156
|
+
return null;
|
|
147
157
|
}
|
|
148
|
-
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, { children: [_jsxs(Tabs, Object.assign({ className: classes.tabs, value: location, onChange: handleChange, indicatorColor: "secondary", textColor: "secondary", variant: "fullWidth" }, { children: [_jsx(Tab, { value: SCEventLocationType.PERSON, classes: { root: classes.tab }, icon: _jsx(Icon, { children: "add_location_alt" }), iconPosition: "start", label: _jsx(FormattedMessage, { id: "ui.eventForm.address.live.label", defaultMessage: "ui.eventForm.address.live.label" }) }), _jsx(Tab, { value: SCEventLocationType.ONLINE, classes: { root: classes.tab }, icon: _jsx(Icon, { children: "play_circle_outline" }), iconPosition: "start", label: _jsx(FormattedMessage, { id: "ui.eventForm.address.online.label", defaultMessage: "ui.eventForm.address.online.label" }) }), canViewLiveTab && (_jsx(Tab, { value: SCEventLocationType.LIVESTREAM, classes: { root: classes.tab }, icon: _jsx(Icon, { children: "photo_camera" }), iconPosition: "start", label: _jsx(_Fragment, { children: _jsx(FormattedMessage, { id: "ui.eventForm.address.liveStream.label", defaultMessage: "ui.eventForm.address.liveStream.label" }) }) }))] })), _jsxs(Box, Object.assign({ className: classes.tabContent }, { children: [location === SCEventLocationType.PERSON && (_jsx(Autocomplete, { size: "small", value: geolocation, onChange: handleSelection, inputValue: inputValue, onInputChange: handleLocationChange, options: suggestions, getOptionLabel: (option) => option.description || geolocation.description, noOptionsText: _jsx(FormattedMessage, { id: "ui.eventForm.address.live.noResults", defaultMessage: "ui.eventForm.address.live.noResults" }), isOptionEqualToValue: (option, value) => option.description === value.description, renderInput: (params) => (_jsx(TextField, Object.assign({}, params, { label: _jsx(FormattedMessage, { id: "ui.eventForm.address.live.placeholder", defaultMessage: "ui.eventForm.address.live.placeholder" }), variant: "outlined", fullWidth: true, InputProps: Object.assign(Object.assign({}, params.InputProps), { endAdornment: (_jsxs(_Fragment, { children: [_jsx(InputAdornment, Object.assign({ position: "start" }, { children: _jsx(Icon, { children: "add_location_alt" }) })), params.InputProps.endAdornment] })) }) }))) })), location === SCEventLocationType.ONLINE && (_jsx(UrlTextField, { size: "small", fullWidth: true, type: "url", placeholder: `${intl.formatMessage(messages.virtualPlaceholder)}`, helperText: _jsx(FormattedMessage, { id: "ui.eventForm.address.online.help", defaultMessage: "ui.eventForm.address.online.help" }), InputProps: {
|
|
158
|
+
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, { children: [_jsxs(Tabs, Object.assign({ className: classes.tabs, value: location, onChange: handleChange, indicatorColor: "secondary", textColor: "secondary", variant: "fullWidth" }, { children: [isInPersonTabActive && (_jsx(Tab, { value: SCEventLocationType.PERSON, classes: { root: classes.tab }, icon: _jsx(Icon, { children: "add_location_alt" }), iconPosition: "start", label: _jsx(FormattedMessage, { id: "ui.eventForm.address.live.label", defaultMessage: "ui.eventForm.address.live.label" }) })), isOnlineTabActive && (_jsx(Tab, { value: SCEventLocationType.ONLINE, classes: { root: classes.tab }, icon: _jsx(Icon, { children: "play_circle_outline" }), iconPosition: "start", label: _jsx(FormattedMessage, { id: "ui.eventForm.address.online.label", defaultMessage: "ui.eventForm.address.online.label" }) })), isLiveTabActive && canViewLiveTab && (_jsx(Tab, { value: SCEventLocationType.LIVESTREAM, classes: { root: classes.tab }, icon: _jsx(Icon, { children: "photo_camera" }), iconPosition: "start", label: _jsx(_Fragment, { children: _jsx(FormattedMessage, { id: "ui.eventForm.address.liveStream.label", defaultMessage: "ui.eventForm.address.liveStream.label" }) }) }))] })), _jsxs(Box, Object.assign({ className: classes.tabContent }, { children: [isInPersonTabActive && location === SCEventLocationType.PERSON && (_jsx(Autocomplete, { size: "small", value: geolocation, onChange: handleSelection, inputValue: inputValue, onInputChange: handleLocationChange, options: suggestions, getOptionLabel: (option) => option.description || geolocation.description, noOptionsText: _jsx(FormattedMessage, { id: "ui.eventForm.address.live.noResults", defaultMessage: "ui.eventForm.address.live.noResults" }), isOptionEqualToValue: (option, value) => option.description === value.description, renderInput: (params) => (_jsx(TextField, Object.assign({}, params, { label: _jsx(FormattedMessage, { id: "ui.eventForm.address.live.placeholder", defaultMessage: "ui.eventForm.address.live.placeholder" }), variant: "outlined", fullWidth: true, InputProps: Object.assign(Object.assign({}, params.InputProps), { endAdornment: (_jsxs(_Fragment, { children: [_jsx(InputAdornment, Object.assign({ position: "start" }, { children: _jsx(Icon, { children: "add_location_alt" }) })), params.InputProps.endAdornment] })) }) }))) })), isOnlineTabActive && location === SCEventLocationType.ONLINE && (_jsx(UrlTextField, { size: "small", fullWidth: true, type: "url", placeholder: `${intl.formatMessage(messages.virtualPlaceholder)}`, helperText: _jsx(FormattedMessage, { id: "ui.eventForm.address.online.help", defaultMessage: "ui.eventForm.address.online.help" }), InputProps: {
|
|
149
159
|
endAdornment: _jsx(Icon, { children: "play_circle_outline" })
|
|
150
|
-
}, onChange: handleLinkChange })), canViewLiveTab && location === SCEventLocationType.LIVESTREAM && (_jsxs(_Fragment, { children: [_jsx(LiveStream, { template: SCLiveStreamTemplateType.SNIPPET, liveStream: liveStream, actions: _jsx(_Fragment, {}) }), _jsx(LiveStreamFormSettings, { settings: liveStream.settings || LIVESTREAM_DEFAULT_SETTINGS, onChange: handleLiveStreamSettingsChange })] }))] }))] })));
|
|
160
|
+
}, onChange: handleLinkChange })), isLiveTabActive && canViewLiveTab && location === SCEventLocationType.LIVESTREAM && (_jsxs(_Fragment, { children: [_jsx(LiveStream, { template: SCLiveStreamTemplateType.SNIPPET, liveStream: liveStream, actions: _jsx(_Fragment, {}) }), _jsx(LiveStreamFormSettings, { settings: liveStream.settings || LIVESTREAM_DEFAULT_SETTINGS, onChange: handleLiveStreamSettingsChange })] }))] }))] })));
|
|
151
161
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BoxProps } from '@mui/material';
|
|
2
2
|
import { SCEventLocationType, SCEventType } from '@selfcommunity/types';
|
|
3
|
+
import { EventAddressProps } from './EventAddress';
|
|
3
4
|
export interface EventFormProps extends BoxProps {
|
|
4
5
|
/**
|
|
5
6
|
* Overrides or extends the styles applied to the component.
|
|
@@ -26,6 +27,11 @@ export interface EventFormProps extends BoxProps {
|
|
|
26
27
|
* @default null
|
|
27
28
|
*/
|
|
28
29
|
onError?: (error: any) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Props to spread to EventAddress component
|
|
32
|
+
* @default empty object
|
|
33
|
+
*/
|
|
34
|
+
EventAddressComponentProps?: Pick<EventAddressProps, 'locations'>;
|
|
29
35
|
/**
|
|
30
36
|
* Any other properties
|
|
31
37
|
*/
|
|
@@ -114,13 +114,13 @@ const Root = styled(Box, {
|
|
|
114
114
|
* @param inProps
|
|
115
115
|
*/
|
|
116
116
|
export default function EventForm(inProps) {
|
|
117
|
-
var _a, _b, _c, _d;
|
|
117
|
+
var _a, _b, _c, _d, _e;
|
|
118
118
|
//PROPS
|
|
119
119
|
const props = useThemeProps({
|
|
120
120
|
props: inProps,
|
|
121
121
|
name: PREFIX
|
|
122
122
|
});
|
|
123
|
-
const { className, onSuccess, onError, event, presetLocation =
|
|
123
|
+
const { className, onSuccess, onError, event, presetLocation, EventAddressComponentProps = {} } = props, rest = __rest(props, ["className", "onSuccess", "onError", "event", "presetLocation", "EventAddressComponentProps"]);
|
|
124
124
|
// CONTEXT
|
|
125
125
|
const scContext = useSCContext();
|
|
126
126
|
// INTL
|
|
@@ -140,14 +140,18 @@ export default function EventForm(inProps) {
|
|
|
140
140
|
? event.location === SCEventLocationType.ONLINE && event.live_stream
|
|
141
141
|
? SCEventLocationType.LIVESTREAM
|
|
142
142
|
: SCEventLocationType.ONLINE
|
|
143
|
-
:
|
|
143
|
+
: ((_a = EventAddressComponentProps.locations) === null || _a === void 0 ? void 0 : _a.length)
|
|
144
|
+
? presetLocation in EventAddressComponentProps.locations
|
|
145
|
+
? presetLocation
|
|
146
|
+
: EventAddressComponentProps.locations[0]
|
|
147
|
+
: SCEventLocationType.PERSON,
|
|
144
148
|
geolocation: (event === null || event === void 0 ? void 0 : event.geolocation) || '',
|
|
145
149
|
lat: (event === null || event === void 0 ? void 0 : event.geolocation_lat) || null,
|
|
146
150
|
lng: (event === null || event === void 0 ? void 0 : event.geolocation_lng) || null,
|
|
147
151
|
link: (event === null || event === void 0 ? void 0 : event.link) || '',
|
|
148
152
|
liveStreamSettings: (event === null || event === void 0 ? void 0 : event.live_stream) ? event === null || event === void 0 ? void 0 : event.live_stream.settings : null,
|
|
149
153
|
recurring: (event === null || event === void 0 ? void 0 : event.recurring) || SCEventRecurrenceType.NEVER,
|
|
150
|
-
isPublic: (
|
|
154
|
+
isPublic: (_b = (event === null || event === void 0 ? void 0 : event.privacy) === SCEventPrivacyType.PUBLIC) !== null && _b !== void 0 ? _b : true,
|
|
151
155
|
isSubmitting: false
|
|
152
156
|
};
|
|
153
157
|
// STATE
|
|
@@ -342,7 +346,7 @@ export default function EventForm(inProps) {
|
|
|
342
346
|
var _a;
|
|
343
347
|
return (_jsx(TextField, Object.assign({}, params, { InputProps: Object.assign(Object.assign({}, params.InputProps), { placeholder: `${intl.formatMessage(messages.endTime)}`, startAdornment: (_jsx(InputAdornment, Object.assign({ position: "start" }, { children: _jsx(IconButton, { children: _jsx(Icon, { children: "access_time" }) }) }))) }), error: Boolean(error['endDateError']), helperText: ((_a = error['endDateError']) === null || _a === void 0 ? void 0 : _a.error) ? (_jsx(FormattedMessage, { id: "ui.eventForm.time.end.error.invalid", defaultMessage: "ui.eventForm.time.end.error.invalid" })) : null })));
|
|
344
348
|
}
|
|
345
|
-
}, onChange: (value) => handleChangeDateTime(value, 'endTime'), shouldDisableTime: shouldDisabledTime })] })) })), _jsx(EventAddress, { forwardGeolocationData: handleGeoData, forwardLivestreamSettingsData: handleLiveStreamSettingsData, event: Object.assign(Object.assign({}, event), {
|
|
349
|
+
}, onChange: (value) => handleChangeDateTime(value, 'endTime'), shouldDisableTime: shouldDisabledTime })] })) })), _jsx(EventAddress, Object.assign({ forwardGeolocationData: handleGeoData, forwardLivestreamSettingsData: handleLiveStreamSettingsData, event: Object.assign(Object.assign({}, event), {
|
|
346
350
|
name: field.name,
|
|
347
351
|
start_date: field.startDate,
|
|
348
352
|
location: field.location,
|
|
@@ -352,7 +356,7 @@ export default function EventForm(inProps) {
|
|
|
352
356
|
created_at: field.startDate,
|
|
353
357
|
settings: field.liveStreamSettings
|
|
354
358
|
}
|
|
355
|
-
}) }), privateEnabled && (_jsxs(Box, Object.assign({ className: classes.privacySection }, { children: [_jsxs(Stack, Object.assign({ direction: "row", spacing: 1, alignItems: "center", justifyContent: "center" }, { children: [_jsxs(Typography, Object.assign({ className: classNames(classes.switchLabel, { [classes.active]: !field.isPublic }) }, { children: [_jsx(Icon, { children: "private" }), _jsx(FormattedMessage, { id: "ui.eventForm.privacy.private", defaultMessage: "ui.eventForm.privacy.private" })] })), _jsx(Switch, { className: classes.switch, checked: field.isPublic, onChange: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['isPublic']: !field.isPublic }))), disabled: event && !field.isPublic }), _jsxs(Typography, Object.assign({ className: classNames(classes.switchLabel, { [classes.active]: field.isPublic }) }, { children: [_jsx(Icon, { children: "public" }), _jsx(FormattedMessage, { id: "ui.eventForm.privacy.public", defaultMessage: "ui.eventForm.privacy.public" })] }))] })), _jsx(Typography, Object.assign({ variant: "body2", textAlign: "center", className: classes.privacySectionInfo }, { children: field.isPublic ? (_jsx(FormattedMessage, { id: "ui.eventForm.privacy.public.info", defaultMessage: "ui.eventForm.privacy.public.info", values: {
|
|
359
|
+
}) }, EventAddressComponentProps)), privateEnabled && (_jsxs(Box, Object.assign({ className: classes.privacySection }, { children: [_jsxs(Stack, Object.assign({ direction: "row", spacing: 1, alignItems: "center", justifyContent: "center" }, { children: [_jsxs(Typography, Object.assign({ className: classNames(classes.switchLabel, { [classes.active]: !field.isPublic }) }, { children: [_jsx(Icon, { children: "private" }), _jsx(FormattedMessage, { id: "ui.eventForm.privacy.private", defaultMessage: "ui.eventForm.privacy.private" })] })), _jsx(Switch, { className: classes.switch, checked: field.isPublic, onChange: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['isPublic']: !field.isPublic }))), disabled: event && !field.isPublic }), _jsxs(Typography, Object.assign({ className: classNames(classes.switchLabel, { [classes.active]: field.isPublic }) }, { children: [_jsx(Icon, { children: "public" }), _jsx(FormattedMessage, { id: "ui.eventForm.privacy.public", defaultMessage: "ui.eventForm.privacy.public" })] }))] })), _jsx(Typography, Object.assign({ variant: "body2", textAlign: "center", className: classes.privacySectionInfo }, { children: field.isPublic ? (_jsx(FormattedMessage, { id: "ui.eventForm.privacy.public.info", defaultMessage: "ui.eventForm.privacy.public.info", values: {
|
|
356
360
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
357
361
|
// @ts-ignore
|
|
358
362
|
b: (chunks) => _jsx("strong", { children: chunks })
|
|
@@ -361,8 +365,8 @@ export default function EventForm(inProps) {
|
|
|
361
365
|
// @ts-ignore
|
|
362
366
|
b: (chunks) => _jsx("strong", { children: chunks })
|
|
363
367
|
} })) }))] }))), _jsx(TextField, { multiline: true, className: classes.description, placeholder: `${intl.formatMessage(messages.description)}`, margin: "normal", value: field.description, name: "description", onChange: handleChange, InputProps: {
|
|
364
|
-
endAdornment: (_jsx(Typography, Object.assign({ variant: "body2" }, { children: ((
|
|
365
|
-
}, error: Boolean(((
|
|
368
|
+
endAdornment: (_jsx(Typography, Object.assign({ variant: "body2" }, { children: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) ? EVENT_DESCRIPTION_MAX_LENGTH - field.description.length : EVENT_DESCRIPTION_MAX_LENGTH })))
|
|
369
|
+
}, error: Boolean(((_d = field.description) === null || _d === void 0 ? void 0 : _d.length) > EVENT_DESCRIPTION_MAX_LENGTH), helperText: ((_e = field.description) === null || _e === void 0 ? void 0 : _e.length) > EVENT_DESCRIPTION_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.eventForm.description.error.maxLength", defaultMessage: "ui.eventForm.description.error.maxLength" })) : null }), genericError && (_jsx(Box, Object.assign({ className: classes.genericError }, { children: _jsx(Alert, Object.assign({ variant: "filled", severity: "error" }, { children: genericError })) }))), _jsx(Box, Object.assign({ className: classes.actions }, { children: _jsx(LoadingButton, Object.assign({ loading: field.isSubmitting, disabled: !field.name ||
|
|
366
370
|
!field.startDate ||
|
|
367
371
|
!field.startTime ||
|
|
368
372
|
!field.endDate ||
|
|
@@ -40,14 +40,14 @@ export default function EventFormDialog(inProps) {
|
|
|
40
40
|
props: inProps,
|
|
41
41
|
name: PREFIX
|
|
42
42
|
});
|
|
43
|
-
const { className, open = true, onClose, EventFormComponentProps
|
|
43
|
+
const { className, open = true, onClose, EventFormComponentProps } = props, rest = __rest(props, ["className", "open", "onClose", "EventFormComponentProps"]);
|
|
44
44
|
const handleSuccess = useCallback((event) => {
|
|
45
45
|
var _a;
|
|
46
|
-
(_a = EventFormComponentProps.onSuccess) === null || _a === void 0 ? void 0 : _a.call(EventFormComponentProps, event);
|
|
46
|
+
(_a = EventFormComponentProps === null || EventFormComponentProps === void 0 ? void 0 : EventFormComponentProps.onSuccess) === null || _a === void 0 ? void 0 : _a.call(EventFormComponentProps, event);
|
|
47
47
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
48
48
|
}, [onClose, EventFormComponentProps]);
|
|
49
49
|
/**
|
|
50
50
|
* Renders root object
|
|
51
51
|
*/
|
|
52
|
-
return (_jsx(Root, Object.assign({ DialogContentProps: { dividers: false }, title: (EventFormComponentProps === null || EventFormComponentProps === void 0 ? void 0 : EventFormComponentProps.event) ? (_jsx(FormattedMessage, { id: "ui.eventForm.title.edit", defaultMessage: "ui.eventForm.title.edit" })) : (_jsx(FormattedMessage, { id: "ui.eventForm.title", defaultMessage: "ui.eventForm.title" })), open: open, onClose: onClose, className: classNames(classes.root, className) }, rest, { children: _jsx(EventForm, Object.assign({}, EventFormComponentProps, { onSuccess: handleSuccess })) })));
|
|
52
|
+
return (_jsx(Root, Object.assign({ DialogContentProps: { dividers: false }, title: (EventFormComponentProps === null || EventFormComponentProps === void 0 ? void 0 : EventFormComponentProps.event) ? (_jsx(FormattedMessage, { id: "ui.eventForm.title.edit", defaultMessage: "ui.eventForm.title.edit" })) : (_jsx(FormattedMessage, { id: "ui.eventForm.title", defaultMessage: "ui.eventForm.title" })), open: open, onClose: onClose, className: classNames(classes.root, className) }, rest, { children: _jsx(EventForm, Object.assign({}, (EventFormComponentProps && EventFormComponentProps), { onSuccess: handleSuccess })) })));
|
|
53
53
|
}
|
|
@@ -152,12 +152,17 @@ export default function LiveStreamForm(inProps) {
|
|
|
152
152
|
else {
|
|
153
153
|
setGenericError(null);
|
|
154
154
|
}
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
let __errors = {};
|
|
156
|
+
if ('coverError' in _error) {
|
|
157
|
+
__errors = Object.assign(Object.assign({}, __errors), { ['coverError']: _jsx(FormattedMessage, { id: "ui.liveStreamForm.cover.error.invalid", defaultMessage: "ui.liveStreamForm.cover.error.invalid" }) });
|
|
157
158
|
}
|
|
158
|
-
if ('
|
|
159
|
-
|
|
159
|
+
if ('titleError' in _error) {
|
|
160
|
+
__errors = Object.assign(Object.assign({}, __errors), { ['titleError']: _jsx(FormattedMessage, { id: "ui.liveStreamForm.title.error.invalid", defaultMessage: "ui.liveStreamForm.title.error.invalid" }) });
|
|
160
161
|
}
|
|
162
|
+
if ('slugError' in _error) {
|
|
163
|
+
__errors = Object.assign(Object.assign({}, __errors), { ['slugError']: _jsx(FormattedMessage, { id: "ui.liveStreamForm.slug.error.invalid", defaultMessage: "ui.liveStreamForm.slug.error.invalid" }) });
|
|
164
|
+
}
|
|
165
|
+
setError(__errors);
|
|
161
166
|
setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: false })));
|
|
162
167
|
Logger.error(SCOPE_SC_UI, e);
|
|
163
168
|
onError === null || onError === void 0 ? void 0 : onError(e);
|
|
@@ -178,7 +183,7 @@ export default function LiveStreamForm(inProps) {
|
|
|
178
183
|
/**
|
|
179
184
|
* Renders root object
|
|
180
185
|
*/
|
|
181
|
-
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: [_jsx(Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: _jsx(UploadEventCover, { isCreationMode: true, onChange: handleChangeCover }) })), _jsxs(FormGroup, Object.assign({ className: classes.form }, { children: [_jsx(TextField, { required: true, className: classes.title, placeholder: `${intl.formatMessage(messages.title)}`, margin: "normal", value: field.title, name: "title", onChange: handleChange, InputProps: {
|
|
186
|
+
return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: [_jsx(Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: _jsx(UploadEventCover, { isCreationMode: true, onChange: handleChangeCover }) })), Boolean(error['coverError']) && _jsx(Typography, Object.assign({ color: "error" }, { children: error['coverError'] })), _jsxs(FormGroup, Object.assign({ className: classes.form }, { children: [_jsx(TextField, { required: true, className: classes.title, placeholder: `${intl.formatMessage(messages.title)}`, margin: "normal", value: field.title, name: "title", onChange: handleChange, InputProps: {
|
|
182
187
|
endAdornment: _jsx(Typography, Object.assign({ variant: "body2" }, { children: LIVE_STREAM_TITLE_MAX_LENGTH - field.title.length }))
|
|
183
188
|
}, error: Boolean(field.title.length > LIVE_STREAM_TITLE_MAX_LENGTH) || Boolean(error['titleError']), helperText: field.title.length > LIVE_STREAM_TITLE_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.liveStreamForm.title.error.maxLength", defaultMessage: "ui.liveStreamForm.title.error.maxLength" })) : error['titleError'] ? (error['titleError']) : null }), _jsx(TextField, { required: true, className: classes.slug, placeholder: `${intl.formatMessage(messages.slug)}`, margin: "normal", value: field.slug, name: "slug", onChange: handleChange, InputProps: {
|
|
184
189
|
endAdornment: _jsx(Typography, Object.assign({ variant: "body2" }, { children: LIVE_STREAM_SLUG_MAX_LENGTH - field.title.length }))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { Alert, Box, Button, CircularProgress, Stack, Typography } from '@mui/material';
|
|
3
|
+
import { Alert, AlertTitle, Box, Button, CircularProgress, Stack, Typography } from '@mui/material';
|
|
4
4
|
import { styled } from '@mui/material/styles';
|
|
5
5
|
import { useThemeProps } from '@mui/system';
|
|
6
6
|
import { Link, SCPreferences, useSCFetchLiveStream, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
|
|
@@ -69,7 +69,7 @@ const DialogRoot = styled(BaseDialog, {
|
|
|
69
69
|
* @param inProps
|
|
70
70
|
*/
|
|
71
71
|
export default function LiveStreamRoom(inProps) {
|
|
72
|
-
var _a, _b, _c, _d;
|
|
72
|
+
var _a, _b, _c, _d, _e, _f;
|
|
73
73
|
//PROPS
|
|
74
74
|
const props = useThemeProps({
|
|
75
75
|
props: inProps,
|
|
@@ -182,5 +182,5 @@ export default function LiveStreamRoom(inProps) {
|
|
|
182
182
|
}), camLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.camera', defaultMessage: 'ui.liveStreamRoom.preJoin.camera' }), userLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.username', defaultMessage: 'ui.liveStreamRoom.preJoin.username' }) }) })), loading && (_jsxs(Box, Object.assign({ className: classes.prejoinLoader }, { children: [_jsx(CircularProgress, {}), _jsx(Typography, Object.assign({ component: 'div', variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.connecting", defaultMessage: "ui.liveStreamRoom.connecting" }) }))] })))] })), _jsxs(Box, Object.assign({ className: classes.endPrejoinContent }, { children: [Boolean(scUserContext.user &&
|
|
183
183
|
scUserContext.user.id !== scLiveStream.host.id &&
|
|
184
184
|
scLiveStream &&
|
|
185
|
-
(((_a = scLiveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants) || (scLiveStream && ((_b = scLiveStream.settings) === null || _b === void 0 ? void 0 : _b.disableVideo)))) && (
|
|
185
|
+
(((_a = scLiveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants) || (scLiveStream && ((_b = scLiveStream.settings) === null || _b === void 0 ? void 0 : _b.disableVideo)))) && (_jsx(Stack, Object.assign({ sx: { width: '45%' }, spacing: 1 }, { children: scLiveStream && (((_c = scLiveStream.settings) === null || _c === void 0 ? void 0 : _c.muteParticipants) || ((_d = scLiveStream.settings) === null || _d === void 0 ? void 0 : _d.disableVideo)) && (_jsxs(Alert, Object.assign({ variant: "filled", severity: "info" }, { children: [_jsx(AlertTitle, { children: _jsx("b", { children: "Info" }) }), ((_e = scLiveStream.settings) === null || _e === void 0 ? void 0 : _e.muteParticipants) && (_jsxs(_Fragment, { children: ["-", ' ', _jsx(FormattedMessage, { id: "ui.liveStreamRoom.hostDisableMicrophone", defaultMessage: "ui.liveStreamRoom.hostDisableMicrophone" }), _jsx("br", {})] })), ((_f = scLiveStream.settings) === null || _f === void 0 ? void 0 : _f.disableVideo) && (_jsxs(_Fragment, { children: ["- ", _jsx(FormattedMessage, { id: "ui.liveStreamRoom.hostDisableVideo", defaultMessage: "ui.liveStreamRoom.hostDisableVideo" })] }))] }))) }))), endPrejoinContent] }))] })) : (_jsx(Box, Object.assign({ className: classes.conference }, { children: _jsx(LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: _jsx(LiveStreamVideoConference, Object.assign({ connectionDetails: connectionDetails, userChoices: preJoinChoices }, LiveStreamVideoConferenceComponentProps)) })) }))) }))) })));
|
|
186
186
|
}
|
package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js
CHANGED
|
@@ -2,5 +2,5 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
5
|
-
const SvgParticipantPlaceholder = (props) => (_jsxs("svg", Object.assign({ width:
|
|
5
|
+
const SvgParticipantPlaceholder = (props) => (_jsxs("svg", Object.assign({ width: 90, height: 90, viewBox: "0 0 320 320", preserveAspectRatio: "xMidYMid meet", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, props, { children: [_jsx("path", { d: "M160 180C204.182 180 240 144.183 240 100C240 55.8172 204.182 20 160 20C115.817 20 79.9997 55.8172 79.9997 100C79.9997 144.183 115.817 180 160 180Z", fill: "white", fillOpacity: 0.25 }), _jsx("path", { d: "M97.6542 194.614C103.267 191.818 109.841 192.481 115.519 195.141C129.025 201.466 144.1 205 159.999 205C175.899 205 190.973 201.466 204.48 195.141C210.158 192.481 216.732 191.818 222.345 194.614C262.703 214.719 291.985 253.736 298.591 300.062C300.15 310.997 291.045 320 280 320H39.9997C28.954 320 19.8495 310.997 21.4087 300.062C28.014 253.736 57.2966 214.72 97.6542 194.614Z", fill: "white", fillOpacity: 0.25 })] })));
|
|
6
6
|
export default SvgParticipantPlaceholder;
|
|
@@ -7,7 +7,6 @@ import { AudioTrack, ConnectionQualityIndicator, FocusToggle, LockLockedIcon, Pa
|
|
|
7
7
|
import ParticipantTileAvatar from './ParticipantTileAvatar';
|
|
8
8
|
import ParticipantTileActions from './ParticipantTileActions';
|
|
9
9
|
import { useSCUser } from '@selfcommunity/react-core';
|
|
10
|
-
import { useLiveStream } from './LiveStreamProvider';
|
|
11
10
|
/**
|
|
12
11
|
* The `ParticipantContextIfNeeded` component only creates a `ParticipantContext`
|
|
13
12
|
* if there is no `ParticipantContext` already.
|
|
@@ -41,7 +40,6 @@ export const ParticipantTile =
|
|
|
41
40
|
});
|
|
42
41
|
const isEncrypted = useIsEncrypted(trackReference.participant);
|
|
43
42
|
const layoutContext = useMaybeLayoutContext();
|
|
44
|
-
const { liveStream } = useLiveStream();
|
|
45
43
|
const autoManageSubscription = (_b = useFeatureContext()) === null || _b === void 0 ? void 0 : _b.autoSubscription;
|
|
46
44
|
const handleSubscribe = React.useCallback((subscribed) => {
|
|
47
45
|
if (trackReference.source &&
|
package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js
CHANGED
|
@@ -31,5 +31,6 @@ export default function ParticipantTileAvatar(inProps) {
|
|
|
31
31
|
const { className, user, participant } = props, rest = __rest(props, ["className", "user", "participant"]);
|
|
32
32
|
// CONTEXT
|
|
33
33
|
const scContext = useSCContext();
|
|
34
|
-
|
|
34
|
+
// RENDER
|
|
35
|
+
return (_jsx(Root, Object.assign({ className: classNames(className, classes.root) }, rest, { children: user ? (_jsx("img", { src: `${user.avatar}` })) : participant && participant.identity ? (_jsx("img", { src: `${scContext.settings.portal}/api/v2/avatar/${participant.identity}` })) : (_jsx(ParticipantPlaceholder, {})) })));
|
|
35
36
|
}
|
|
@@ -152,6 +152,8 @@ export function PreJoin(_a) {
|
|
|
152
152
|
const { liveStream } = useLiveStream();
|
|
153
153
|
const scUserContext = useSCUser();
|
|
154
154
|
const [userChoices, setUserChoices] = React.useState(defaultUserChoices);
|
|
155
|
+
const canUseAudio = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants))); }, [scUserContext, liveStream]);
|
|
156
|
+
const canUseVideo = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableVideo))); }, [scUserContext, liveStream]);
|
|
155
157
|
// TODO: Remove and pipe `defaults` object directly into `usePersistentUserChoices` once we fully switch from type `LocalUserChoices` to `UserChoices`.
|
|
156
158
|
const partialDefaults = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (defaults.audioDeviceId !== undefined && { audioDeviceId: defaults.audioDeviceId })), (defaults.videoDeviceId !== undefined && { videoDeviceId: defaults.videoDeviceId })), (defaults.audioEnabled !== undefined && { audioEnabled: defaults.audioEnabled })), (defaults.videoEnabled !== undefined && { videoEnabled: defaults.videoEnabled })), (defaults.username !== undefined && { username: defaults.username }));
|
|
157
159
|
const { userChoices: initialUserChoices, saveAudioInputDeviceId, saveAudioInputEnabled, saveVideoInputDeviceId, saveVideoInputEnabled, saveUsername } = usePersistentUserChoices({
|
|
@@ -160,18 +162,18 @@ export function PreJoin(_a) {
|
|
|
160
162
|
preventLoad: !persistUserChoices
|
|
161
163
|
});
|
|
162
164
|
// Initialize device settings
|
|
163
|
-
const [audioEnabled, setAudioEnabled] = React.useState(initialUserChoices.audioEnabled);
|
|
164
|
-
const [videoEnabled, setVideoEnabled] = React.useState(initialUserChoices.videoEnabled);
|
|
165
|
+
const [audioEnabled, setAudioEnabled] = React.useState(initialUserChoices.audioEnabled && canUseAudio);
|
|
166
|
+
const [videoEnabled, setVideoEnabled] = React.useState(initialUserChoices.videoEnabled && canUseVideo);
|
|
165
167
|
const [audioDeviceId, setAudioDeviceId] = React.useState(initialUserChoices.audioDeviceId);
|
|
166
168
|
const [videoDeviceId, setVideoDeviceId] = React.useState(initialUserChoices.videoDeviceId);
|
|
167
169
|
const [username, setUsername] = React.useState(initialUserChoices.username);
|
|
168
170
|
// Save user choices to persistent storage.
|
|
169
171
|
React.useEffect(() => {
|
|
170
|
-
saveAudioInputEnabled(audioEnabled);
|
|
171
|
-
}, [audioEnabled, saveAudioInputEnabled]);
|
|
172
|
+
saveAudioInputEnabled(audioEnabled && canUseAudio);
|
|
173
|
+
}, [audioEnabled, saveAudioInputEnabled, canUseAudio]);
|
|
172
174
|
React.useEffect(() => {
|
|
173
|
-
saveVideoInputEnabled(videoEnabled);
|
|
174
|
-
}, [videoEnabled, saveVideoInputEnabled]);
|
|
175
|
+
saveVideoInputEnabled(videoEnabled && canUseVideo);
|
|
176
|
+
}, [videoEnabled, saveVideoInputEnabled, canUseVideo]);
|
|
175
177
|
React.useEffect(() => {
|
|
176
178
|
saveAudioInputDeviceId(audioDeviceId);
|
|
177
179
|
}, [audioDeviceId, saveAudioInputDeviceId]);
|
|
@@ -239,7 +241,5 @@ export function PreJoin(_a) {
|
|
|
239
241
|
log.warn('Validation failed with: ', userChoices);
|
|
240
242
|
}
|
|
241
243
|
}
|
|
242
|
-
const canUseAudio = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants))); }, [scUserContext, liveStream]);
|
|
243
|
-
const canUseVideo = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableVideo))); }, [scUserContext, liveStream]);
|
|
244
244
|
return (_jsxs("div", Object.assign({ className: "lk-prejoin" }, htmlProps, { children: [_jsxs("div", Object.assign({ className: "lk-video-container" }, { children: [videoTrack && _jsx("video", { ref: videoEl, width: "1280", height: "720", "data-lk-facing-mode": facingMode }), (!videoTrack || !videoEnabled) && (_jsx("div", Object.assign({ className: "lk-camera-off-note" }, { children: _jsx(ParticipantTileAvatar, { user: scUserContext.user }) })))] })), _jsxs("div", Object.assign({ className: "lk-button-group-container" }, { children: [_jsxs("div", Object.assign({ className: "lk-button-group audio" }, { children: [_jsx(TrackToggle, Object.assign({ disabled: !canUseAudio, initialState: audioEnabled, source: Track.Source.Microphone, onChange: (enabled) => setAudioEnabled(enabled) }, { children: micLabel })), _jsx("div", Object.assign({ className: "lk-button-group-menu" }, { children: _jsx(MediaDeviceMenu, { initialSelection: audioDeviceId, kind: "audioinput", disabled: !audioTrack || !canUseAudio, tracks: { audioinput: audioTrack }, onActiveDeviceChange: (_, id) => setAudioDeviceId(id) }) }))] })), _jsxs("div", Object.assign({ className: "lk-button-group video" }, { children: [_jsx(TrackToggle, Object.assign({ disabled: !canUseVideo, initialState: videoEnabled, source: Track.Source.Camera, onChange: (enabled) => setVideoEnabled(enabled) }, { children: camLabel })), _jsx("div", Object.assign({ className: "lk-button-group-menu" }, { children: _jsx(MediaDeviceMenu, { initialSelection: videoDeviceId, kind: "videoinput", disabled: !videoTrack || !canUseVideo, tracks: { videoinput: videoTrack }, onActiveDeviceChange: (_, id) => setVideoDeviceId(id) }) }))] }))] })), _jsx("form", Object.assign({ className: "lk-username-container" }, { children: _jsx("button", Object.assign({ className: "lk-button lk-join-button", type: "submit", onClick: handleSubmit, disabled: !isValid }, { children: joinLabel })) })), debug && (_jsxs(_Fragment, { children: [_jsx("strong", { children: "User Choices:" }), _jsxs("ul", Object.assign({ className: "lk-list", style: { overflow: 'hidden', maxWidth: '15rem' } }, { children: [_jsxs("li", { children: ["Username: ", `${userChoices.username}`] }), _jsxs("li", { children: ["Video Enabled: ", `${userChoices.videoEnabled}`] }), _jsxs("li", { children: ["Audio Enabled: ", `${userChoices.audioEnabled}`] }), _jsxs("li", { children: ["Video Device: ", `${userChoices.videoDeviceId}`] }), _jsxs("li", { children: ["Audio Device: ", `${userChoices.audioDeviceId}`] })] }))] }))] })));
|
|
245
245
|
}
|
|
@@ -2,7 +2,8 @@ import * as React from 'react';
|
|
|
2
2
|
import type { MessageDecoder, MessageEncoder } from '@livekit/components-core';
|
|
3
3
|
import { MessageFormatter } from '@livekit/components-react';
|
|
4
4
|
import { SCUserType } from '@selfcommunity/types';
|
|
5
|
-
export interface VideoConferenceProps
|
|
5
|
+
export interface VideoConferenceProps {
|
|
6
|
+
className?: string;
|
|
6
7
|
chatMessageFormatter?: MessageFormatter;
|
|
7
8
|
chatMessageEncoder?: MessageEncoder;
|
|
8
9
|
chatMessageDecoder?: MessageDecoder;
|
|
@@ -22,4 +23,4 @@ export interface VideoConferenceProps extends React.HTMLAttributes<HTMLDivElemen
|
|
|
22
23
|
* of participants, basic non-persistent chat, screen sharing, and more.
|
|
23
24
|
*
|
|
24
25
|
*/
|
|
25
|
-
export declare function VideoConference(
|
|
26
|
+
export declare function VideoConference(inProps: VideoConferenceProps): JSX.Element;
|