@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.
Files changed (46) hide show
  1. package/lib/cjs/components/CreateLiveStreamDialog/CreateLiveStreamDialog.js +1 -1
  2. package/lib/cjs/components/EventForm/EventAddress.d.ts +2 -1
  3. package/lib/cjs/components/EventForm/EventAddress.js +17 -7
  4. package/lib/cjs/components/EventForm/EventForm.d.ts +6 -0
  5. package/lib/cjs/components/EventForm/EventForm.js +12 -8
  6. package/lib/cjs/components/EventFormDialog/EventFormDialog.d.ts +1 -1
  7. package/lib/cjs/components/EventFormDialog/EventFormDialog.js +3 -3
  8. package/lib/cjs/components/LiveStreamForm/LiveStreamForm.js +10 -5
  9. package/lib/cjs/components/LiveStreamRoom/LiveStreamRoom.js +2 -2
  10. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js +1 -1
  11. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +0 -2
  12. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js +2 -1
  13. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +8 -8
  14. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/RecordingIndicator.d.ts +1 -0
  15. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/RecordingIndicator.js +1 -0
  16. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.d.ts +3 -2
  17. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +58 -15
  18. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/useLiveStreamCheck.js +24 -7
  19. package/lib/cjs/components/LiveStreamRoom/constants.d.ts +1 -1
  20. package/lib/cjs/components/LiveStreamRoom/constants.js +1 -1
  21. package/lib/cjs/components/Notification/LiveStream/LiveStream.js +3 -1
  22. package/lib/cjs/shared/EventInfoDetails/index.js +9 -1
  23. package/lib/esm/components/CreateLiveStreamDialog/CreateLiveStreamDialog.js +1 -1
  24. package/lib/esm/components/EventForm/EventAddress.d.ts +2 -1
  25. package/lib/esm/components/EventForm/EventAddress.js +17 -7
  26. package/lib/esm/components/EventForm/EventForm.d.ts +6 -0
  27. package/lib/esm/components/EventForm/EventForm.js +12 -8
  28. package/lib/esm/components/EventFormDialog/EventFormDialog.d.ts +1 -1
  29. package/lib/esm/components/EventFormDialog/EventFormDialog.js +3 -3
  30. package/lib/esm/components/LiveStreamForm/LiveStreamForm.js +10 -5
  31. package/lib/esm/components/LiveStreamRoom/LiveStreamRoom.js +3 -3
  32. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js +1 -1
  33. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +0 -2
  34. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js +2 -1
  35. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +8 -8
  36. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/RecordingIndicator.d.ts +1 -0
  37. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/RecordingIndicator.js +1 -0
  38. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.d.ts +3 -2
  39. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +58 -15
  40. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/useLiveStreamCheck.js +25 -8
  41. package/lib/esm/components/LiveStreamRoom/constants.d.ts +1 -1
  42. package/lib/esm/components/LiveStreamRoom/constants.js +1 -1
  43. package/lib/esm/components/Notification/LiveStream/LiveStream.js +3 -1
  44. package/lib/esm/shared/EventInfoDetails/index.js +12 -4
  45. package/lib/umd/react-ui.js +1 -1
  46. 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 = 3;
10
+ export declare const LIVE_CHECKING_INTERVAL = 1;
11
11
  /**
12
12
  * Warning threshold expiring soon
13
13
  * In minutes
@@ -10,7 +10,7 @@ exports.defaultVideoOptions = {
10
10
  * Checking live status on VideoLiveConference
11
11
  * In minutes
12
12
  */
13
- exports.LIVE_CHECKING_INTERVAL = 3;
13
+ exports.LIVE_CHECKING_INTERVAL = 1;
14
14
  /**
15
15
  * Warning threshold expiring soon
16
16
  * 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 && (notificationObject.live_stream.last_started_at && !notificationObject.live_stream.last_finished_at));
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 ? ((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: {
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, { presetLocation: SCEventLocationType.LIVESTREAM, onSuccess: handleSubmit })) : (_jsx(LiveStreamForm, { onSuccess: handleSubmit })) }))] })) })));
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, forwardGeolocationData, forwardLivestreamSettingsData, event } = props;
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) || SCEventLocationType.PERSON);
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 _jsx(HiddenPlaceholder, {});
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 = SCEventLocationType.PERSON } = props, rest = __rest(props, ["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
- : presetLocation,
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: (_a = (event === null || event === void 0 ? void 0 : event.privacy) === SCEventPrivacyType.PUBLIC) !== null && _a !== void 0 ? _a : true,
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: ((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) ? EVENT_DESCRIPTION_MAX_LENGTH - field.description.length : EVENT_DESCRIPTION_MAX_LENGTH })))
365
- }, error: Boolean(((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > EVENT_DESCRIPTION_MAX_LENGTH), helperText: ((_d = field.description) === null || _d === void 0 ? void 0 : _d.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 ||
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 ||
@@ -18,7 +18,7 @@ export interface EventFormDialogProps extends BaseDialogProps {
18
18
  onClose?: () => void;
19
19
  /**
20
20
  * Props to spread to EventForm component
21
- * @default {}
21
+ * @default undefined
22
22
  */
23
23
  EventFormComponentProps?: EventFormProps;
24
24
  /**
@@ -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 = {} } = props, rest = __rest(props, ["className", "open", "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
- if ('titleError' in Object.values(_error)) {
156
- setError(Object.assign(Object.assign({}, error), { ['titleError']: _jsx(FormattedMessage, { id: "ui.liveStreamForm.title.error.invalid", defaultMessage: "ui.liveStreamForm.title.error.invalid" }) }));
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 ('slugError' in Object.values(_error)) {
159
- setError(Object.assign(Object.assign({}, error), { ['slugError']: _jsx(FormattedMessage, { id: "ui.liveStreamForm.slug.error.invalid", defaultMessage: "ui.liveStreamForm.slug.error.invalid" }) }));
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)))) && (_jsxs(Stack, Object.assign({ sx: { width: '60%' }, spacing: 1 }, { children: [scLiveStream && ((_c = scLiveStream.settings) === null || _c === void 0 ? void 0 : _c.muteParticipants) && (_jsx(Alert, Object.assign({ variant: "filled", severity: "info", component: 'div' }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.hostDisableMicrophone", defaultMessage: "ui.liveStreamRoom.hostDisableMicrophone" }) }))), scLiveStream && ((_d = scLiveStream.settings) === null || _d === void 0 ? void 0 : _d.disableVideo) && (_jsx(Alert, Object.assign({ variant: "filled", severity: "info" }, { 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)) })) }))) }))) })));
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
  }
@@ -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: 320, height: 320, 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 })] })));
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 &&
@@ -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
- return (_jsx(Root, Object.assign({ className: classNames(className, classes.root) }, rest, { children: user ? (_jsx("img", { src: `${user.avatar}` })) : participant ? (_jsx("img", { src: `${scContext.settings.portal}/api/v2/avatar/${participant.identity}` })) : (_jsx(ParticipantPlaceholder, {})) })));
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
  }
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * RecordingIndicator
2
3
  * @alpha
3
4
  */
4
5
  export default function RecordingIndicator(): JSX.Element;
@@ -3,6 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useIsRecording } from '@livekit/components-react';
4
4
  import { useEffect, useState } from 'react';
5
5
  /**
6
+ * RecordingIndicator
6
7
  * @alpha
7
8
  */
8
9
  export default function RecordingIndicator() {
@@ -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 extends React.HTMLAttributes<HTMLDivElement> {
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({ chatMessageFormatter, chatMessageDecoder, chatMessageEncoder, SettingsComponent, speakerFocused, disableChat, disableMicrophone, disableCamera, disableShareScreen, hideParticipantsList, showSettings, ...props }: VideoConferenceProps): JSX.Element;
26
+ export declare function VideoConference(inProps: VideoConferenceProps): JSX.Element;