@openeventkit/event-site 2.0.121 → 2.0.123

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openeventkit/event-site",
3
3
  "description": "Event Site",
4
- "version": "2.0.121",
4
+ "version": "2.0.123",
5
5
  "author": "Tipit LLC",
6
6
  "dependencies": {
7
7
  "@fortawesome/fontawesome-svg-core": "^6.5.2",
@@ -21,14 +21,14 @@
21
21
  "@sentry/integrations": "^7.39.0",
22
22
  "@sentry/react": "^7.39.0",
23
23
  "@sentry/webpack-plugin": "^1.20.0",
24
- "@supabase/supabase-js": "^1.35.6",
24
+ "@supabase/supabase-js": "2.45.1",
25
25
  "@types/googlemaps": "^3.39.9",
26
26
  "@types/markerclustererplus": "^2.1.33",
27
27
  "@types/react": "^16.9.42",
28
28
  "@vimeo/player": "^2.16.3",
29
29
  "ably": "^1.2.34",
30
30
  "assert": "^2.1.0",
31
- "attendee-to-attendee-widget": "3.1.0",
31
+ "attendee-to-attendee-widget": "3.1.1-beta.32",
32
32
  "autoprefixer": "10.4.14",
33
33
  "awesome-bootstrap-checkbox": "^1.0.1",
34
34
  "axios": "^0.19.2",
@@ -29,23 +29,14 @@ export const setEventLastUpdate = (lastUpdate) => (dispatch) => {
29
29
 
30
30
  /**
31
31
  * @param eventId
32
- * @param checkLocal
33
32
  * @returns {(function(*, *): Promise<*>)|*}
34
33
  */
35
34
  export const getEventById = (
36
35
  eventId
37
- ) => async (dispatch, getState) => {
36
+ ) => async (dispatch) => {
38
37
 
39
38
  dispatch(startLoading());
40
- // if we have it on the reducer , provide that first
41
- let {allSchedulesState: {allEvents}} = getState();
42
- const event = allEvents.find(ev => ev.id === parseInt(eventId));
43
-
44
- if (event) {
45
- dispatch(createAction(GET_EVENT_DATA)({event}));
46
- }
47
39
 
48
- // then refresh from api
49
40
  let accessToken;
50
41
  try {
51
42
  accessToken = await getAccessToken();
@@ -59,7 +59,13 @@ const AttendeesWidgetComponent = ({ user, event, chatSettings }) => {
59
59
  linked_in_profile,
60
60
  twitter_name,
61
61
  wechat_user,
62
- public_profile_show_fullname } = idpProfile || {};
62
+ public_profile_show_fullname,
63
+ public_profile_show_email,
64
+ public_profile_allow_chat_with_me,
65
+ public_profile_show_photo,
66
+ public_profile_show_social_media_info,
67
+ public_profile_show_bio
68
+ } = idpProfile || {};
63
69
 
64
70
  useEffect(() => {
65
71
  if (!user || !userProfile || !idpProfile) return;
@@ -127,6 +133,12 @@ const AttendeesWidgetComponent = ({ user, event, chatSettings }) => {
127
133
  .flatMap((st) => st.badge.features)
128
134
  .filter((v, i, a) => a.map((item) => item.id).indexOf(v.id) === i),
129
135
  bio: bio,
136
+ showEmail: public_profile_show_email === true,
137
+ allowChatWithMe: public_profile_allow_chat_with_me === true,
138
+ showFullName: public_profile_show_fullname === true,
139
+ showProfilePic: public_profile_show_photo === true,
140
+ showSocialInfo: public_profile_show_social_media_info === true,
141
+ showBio: public_profile_show_bio === true,
130
142
  hasPermission: (permission) => {
131
143
  const isAdmin = groups &&
132
144
  groups.map((g) => g.slug).filter((g) => adminGroups.includes(g))
@@ -186,6 +198,20 @@ const mapState = ({ settingState }) => ({
186
198
  export const AttendeesWidget = connect(mapState)(AttendeesWidgetComponent);
187
199
 
188
200
  const AccessTracker = ({ user, isLoggedUser, summitPhase, chatSettings }) => {
201
+ const chatProps = {
202
+ streamApiKey: getEnvVariable(STREAM_IO_API_KEY),
203
+ apiBaseUrl: getEnvVariable(IDP_BASE_URL),
204
+ chatApiBaseUrl: getEnvVariable(CHAT_API_BASE_URL),
205
+ onAuthError: (err, res) => console.log(err),
206
+ openDir: "left",
207
+ activity: null,
208
+ getAccessToken: async () => {
209
+ const accessToken = await getAccessToken();
210
+ //console.log("AttendeesList->getAccessToken", accessToken);
211
+ return accessToken;
212
+ },
213
+ };
214
+
189
215
  const trackerRef = useRef();
190
216
 
191
217
  const handleLogout = useCallback(() => {
@@ -237,11 +263,15 @@ const AccessTracker = ({ user, isLoggedUser, summitPhase, chatSettings }) => {
237
263
  wechat_user,
238
264
  public_profile_show_fullname,
239
265
  public_profile_show_email,
240
- public_profile_allow_chat_with_me
266
+ public_profile_allow_chat_with_me,
267
+ public_profile_show_photo,
268
+ public_profile_show_social_media_info,
269
+ public_profile_show_bio
241
270
  } = user.idpProfile;
242
271
 
243
272
  const widgetProps = {
244
273
  user: {
274
+ id: sub,
245
275
  idpUserId: sub,
246
276
  fullName: public_profile_show_fullname ? `${given_name} ${family_name}` : `${given_name}`,
247
277
  email: email,
@@ -260,11 +290,17 @@ const AccessTracker = ({ user, isLoggedUser, summitPhase, chatSettings }) => {
260
290
  .flatMap((st) => st.badge.features)
261
291
  .filter((v, i, a) => a.map((item) => item.id).indexOf(v.id) === i),
262
292
  bio: bio,
263
- showEmail: public_profile_show_email,
264
- allowChatWithMe: public_profile_allow_chat_with_me ?? true
293
+ showEmail: public_profile_show_email === true,
294
+ allowChatWithMe: public_profile_allow_chat_with_me === true,
295
+ showFullName: public_profile_show_fullname === true,
296
+ showProfilePic: public_profile_show_photo === true,
297
+ showSocialInfo: public_profile_show_social_media_info === true,
298
+ showBio: public_profile_show_bio === true
265
299
  },
266
300
  summitId: parseInt(getEnvVariable(SUMMIT_ID)),
267
- ...sbAuthProps,
301
+ keepAliveEnabled: true,
302
+ ...chatProps,
303
+ ...sbAuthProps
268
304
  };
269
305
 
270
306
  if (!chatSettings.enabled) return null;
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {getSynchWordsVideoFrameDdFromSrc} from "../utils/videoUtils";
4
+
5
+
6
+ class SynchWordsPlayer extends React.Component {
7
+
8
+ constructor(props) {
9
+ super(props);
10
+ }
11
+
12
+ componentDidMount() {
13
+ }
14
+
15
+ componentWillUnmount() {
16
+ }
17
+
18
+ render() {
19
+ const { video, className, autoplay } = this.props;
20
+ const id = getSynchWordsVideoFrameDdFromSrc(video);
21
+ console.log(`SynchWordsPlayer::render with id ${id}`);
22
+ let allow = "encrypted-media";
23
+ if(autoplay) allow = allow +';autoplay'
24
+ return (
25
+ <div className={className}>
26
+ <iframe id={id}
27
+ src={video}
28
+ frameBorder="0"
29
+ scrolling="no"
30
+ allow={allow}
31
+ allowFullScreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen
32
+ >
33
+ </iframe>
34
+ </div>
35
+ );
36
+ }
37
+ }
38
+
39
+ SynchWordsPlayer.propTypes = {
40
+ /**
41
+ * a video URL.
42
+ */
43
+ video: PropTypes.oneOfType([
44
+ PropTypes.number,
45
+ PropTypes.string,
46
+ ]),
47
+ /**
48
+ * CSS className for the player element.
49
+ */
50
+ className: PropTypes.string,
51
+ /**
52
+ * Automatically start playback of the video. Note that this won’t work on
53
+ * some devices.
54
+ */
55
+ autoplay: PropTypes.bool,
56
+ };
57
+
58
+ export default SynchWordsPlayer;
@@ -4,7 +4,8 @@ import VideoJSPlayer from './VideoJSPlayer';
4
4
  import VimeoPlayer from "./VimeoPlayer";
5
5
  import VideoMUXPlayer from './VideoMUXPlayer';
6
6
  import styles from '../styles/video.module.scss';
7
- import { isMuxVideo, isVimeoVideo, isYouTubeVideo } from '../utils/videoUtils';
7
+ import { isMuxVideo, isVimeoVideo, isYouTubeVideo, isSynchWordsVideo } from '../utils/videoUtils';
8
+ import SynchWordsPlayer from "./SyncWordsPlayer";
8
9
 
9
10
  /**
10
11
  * @param url
@@ -48,6 +49,14 @@ const VideoComponent = ({ url, title, namespace, isLive, firstHalf, autoPlay, st
48
49
  />
49
50
  );
50
51
  };
52
+ // synch words player
53
+ if(isSynchWordsVideo(url)){
54
+ return (<SynchWordsPlayer
55
+ video={url}
56
+ autoplay={autoPlay}
57
+ className={styles.synchWordsPlayer}
58
+ />);
59
+ }
51
60
 
52
61
  const defaultVideoJsOptions = isYouTubeVideo(url) ? {
53
62
  techOrder: ["youtube"],
@@ -99,7 +108,7 @@ VideoComponent.propTypes = {
99
108
  isLive: PropTypes.bool,
100
109
  firstHalf: PropTypes.bool,
101
110
  autoPlay: PropTypes.bool,
102
- start: PropTypes.number,
111
+ start: PropTypes.number,
103
112
  tokens: PropTypes.object,
104
113
  onError: PropTypes.func,
105
114
  };
@@ -108,7 +117,7 @@ VideoComponent.defaultProps = {
108
117
  title: '',
109
118
  namespace: '',
110
119
  firstHalf: true,
111
- autoPlay: false,
120
+ autoPlay: false,
112
121
  tokens: null,
113
122
  };
114
123
 
@@ -319,6 +319,11 @@ export const TicketPopupEditDetailsForm = ({
319
319
  onBlur={formik.handleBlur}
320
320
  onChange={!!initialValues[TicketKeys.company].name ? noop : formik.handleChange}
321
321
  disabled={!!initialValues[TicketKeys.company].name}
322
+ menuPortalTarget={document.body}
323
+ menuPosition="fixed"
324
+ styles={{
325
+ menuPortal: (base) => ({ ...base, zIndex: 9999 }),
326
+ }}
322
327
  tabSelectsValue={false}
323
328
  />
324
329
  {(formik.touched[TicketKeys.company] || triedSubmitting) && formik.errors[TicketKeys.company] &&
@@ -113,6 +113,9 @@
113
113
  margin: -3px 8px 0px;
114
114
  vertical-align: middle;
115
115
  }
116
+ &:hover {
117
+ color: var(--color_text_dark);
118
+ }
116
119
  }
117
120
 
118
121
  .buttons {
@@ -16,4 +16,24 @@
16
16
  width: 100%;
17
17
  height: 100%;
18
18
  }
19
- }
19
+ }
20
+
21
+ .synchWordsPlayer{
22
+ /* 16:9 */
23
+ --video--width: 960;
24
+ --video--height: 540;
25
+
26
+ position: relative;
27
+ padding-bottom: calc(var(--video--height) / var(--video--width) * 100%); /* 56.25% */
28
+ overflow: hidden;
29
+ max-width: 100%;
30
+ background: black;
31
+
32
+ iframe, object, embed{
33
+ position: absolute;
34
+ top: 0;
35
+ left: 0;
36
+ width: 100%;
37
+ height: 100%;
38
+ }
39
+ }
@@ -16,6 +16,7 @@ import withOrchestra from "../utils/widgetOrchestra";
16
16
  import LiteScheduleComponent from '../components/LiteScheduleComponent'
17
17
  import ProfilePopupComponent from '../components/ProfilePopupComponent'
18
18
  import ChangePasswordComponent from '../components/ChangePasswordComponent';
19
+ import AccessTracker from "../components/AttendeeToAttendeeWidgetComponent";
19
20
 
20
21
  import { updateProfilePicture, updateProfile, getIDPProfile, updatePassword } from '../actions/user-actions'
21
22
 
@@ -46,6 +47,10 @@ export const FullProfilePageTemplate = ({ user, getIDPProfile, updateProfile, up
46
47
  const [showFullName, setShowFullName] = useState(false);
47
48
  const [allowChatWithMe, setAllowChatWithMe] = useState(false)
48
49
  const [showEmail, setShowEmail] = useState(false);
50
+ const [showPicture, setShowPicture] = useState(false);
51
+ const [showBio, setShowBio] = useState(false);
52
+ const [showSocialMedia, setShowSocialMedia] = useState(false);
53
+ const [showTelephone, setShowTelephone] = useState(false);
49
54
  const [bio, setBio] = useState('');
50
55
  const [statementOfInterest, setStatementOfInterest] = useState('');
51
56
 
@@ -88,6 +93,10 @@ export const FullProfilePageTemplate = ({ user, getIDPProfile, updateProfile, up
88
93
  setShowFullName(user.idpProfile.public_profile_show_fullname);
89
94
  setAllowChatWithMe(user.idpProfile.public_profile_allow_chat_with_me);
90
95
  setShowEmail(user.idpProfile.public_profile_show_email);
96
+ setShowPicture(user.idpProfile.public_profile_show_photo);
97
+ setShowBio(user.idpProfile.public_profile_show_bio);
98
+ setShowSocialMedia(user.idpProfile.public_profile_show_social_media_info);
99
+ setShowTelephone(user.idpProfile.public_profile_show_telephone_number);
91
100
  setBio(user.idpProfile.bio || '');
92
101
  setStatementOfInterest(user.idpProfile.statement_of_interest || '');
93
102
  setAddress({
@@ -139,6 +148,10 @@ export const FullProfilePageTemplate = ({ user, getIDPProfile, updateProfile, up
139
148
  public_profile_show_fullname: showFullName,
140
149
  public_profile_allow_chat_with_me: allowChatWithMe,
141
150
  public_profile_show_email: showEmail,
151
+ public_profile_show_photo: showPicture,
152
+ public_profile_show_bio: showBio,
153
+ public_profile_show_social_media_info: showSocialMedia,
154
+ public_profile_show_telephone_number: showTelephone,
142
155
  bio: bio,
143
156
  statement_of_interest: statementOfInterest,
144
157
  address1: address.street,
@@ -204,6 +217,10 @@ export const FullProfilePageTemplate = ({ user, getIDPProfile, updateProfile, up
204
217
  setShowFullName(user.idpProfile.public_profile_show_fullname);
205
218
  setAllowChatWithMe(user.idpProfile.public_profile_allow_chat_with_me);
206
219
  setShowEmail(user.idpProfile.public_profile_show_email);
220
+ setShowPicture(user.idpProfile.public_profile_show_photo);
221
+ setShowBio(user.idpProfile.public_profile_show_bio);
222
+ setShowSocialMedia(user.idpProfile.public_profile_show_social_media_info);
223
+ setShowTelephone(user.idpProfile.public_profile_show_telephone_number);
207
224
  break;
208
225
  case 'bio':
209
226
  setBio(user.idpProfile.bio || '');
@@ -423,20 +440,53 @@ export const FullProfilePageTemplate = ({ user, getIDPProfile, updateProfile, up
423
440
  </div>
424
441
  </div>
425
442
  </div>
426
- <label className={styles.checkbox}>
427
- <input type="checkbox" checked={showFullName} onChange={e => setShowFullName(e.target.checked)} />
428
- Show full name on public profile
429
- </label>
430
- <br />
431
- <label className={styles.checkbox}>
432
- <input type="checkbox" checked={showEmail} onChange={e => setShowEmail(e.target.checked)} />
433
- Show email on public profile
434
- </label>
435
- <br />
436
- <label className={styles.checkbox}>
437
- <input type="checkbox" checked={allowChatWithMe} onChange={e => setAllowChatWithMe(e.target.checked)} />
438
- Allow people to chat with me?
439
- </label>
443
+ <div className={`columns is-mobile`}>
444
+ <div className={`column is-full`}>
445
+ <span>
446
+ By electing to show your information you are indicating that other attendees at the
447
+ event(s) you are registered for will be able to see this information.
448
+ </span>
449
+ </div>
450
+ </div>
451
+ <div className={`columns is-mobile`}>
452
+ <div className={`column is-half`}>
453
+ <label className={styles.checkbox}>
454
+ <input type="checkbox" checked={showFullName} onChange={e => setShowFullName(e.target.checked)} />
455
+ Show full name (first name is always shown)
456
+ </label>
457
+ <br />
458
+ <label className={styles.checkbox}>
459
+ <input type="checkbox" checked={showEmail} onChange={e => setShowEmail(e.target.checked)} />
460
+ Show email
461
+ </label>
462
+ <br />
463
+ <label className={styles.checkbox}>
464
+ <input type="checkbox" checked={showTelephone} onChange={e => setShowTelephone(e.target.checked)} />
465
+ Show telephone number
466
+ </label>
467
+ <br />
468
+ <label className={styles.checkbox}>
469
+ <input type="checkbox" checked={allowChatWithMe} onChange={e => setAllowChatWithMe(e.target.checked)} />
470
+ Allow people to chat with me
471
+ </label>
472
+ </div>
473
+ <div className={`column is-half`}>
474
+ <label className={styles.checkbox}>
475
+ <input type="checkbox" checked={showPicture} onChange={e => setShowPicture(e.target.checked)} />
476
+ Show picture
477
+ </label>
478
+ <br />
479
+ <label className={styles.checkbox}>
480
+ <input type="checkbox" checked={showBio} onChange={e => setShowBio(e.target.checked)} />
481
+ Show bio
482
+ </label>
483
+ <br />
484
+ <label className={styles.checkbox}>
485
+ <input type="checkbox" checked={showSocialMedia} onChange={e => setShowSocialMedia(e.target.checked)} />
486
+ Show social media info
487
+ </label>
488
+ </div>
489
+ </div>
440
490
  <div className={`columns is-mobile ${styles.buttons}`}>
441
491
  <div className={`column is-half`}>
442
492
  <button className={`button is-large ${styles.profileButton}`} onClick={() => discardChanges('profile')}>Discard</button>
@@ -602,6 +652,7 @@ export const FullProfilePageTemplate = ({ user, getIDPProfile, updateProfile, up
602
652
  closePopup={() => handleTogglePopup(!showProfile)}
603
653
  />
604
654
  }
655
+ <AccessTracker />
605
656
  </React.Fragment>
606
657
  )
607
658
  };
@@ -1,4 +1,5 @@
1
1
  const IS_MUX_VIDEO_REGEX = /https:\/\/stream.mux.com\/(.*).m3u8/;
2
+ const IS_SYNC_WORDS_VIDEO_REGEX = /https:\/\/player.syncwords.com\/iframe\/live\/(.*)\/(.*)/g;
2
3
 
3
4
  export const getMUXPlaybackId = (url) => {
4
5
  if(!url) return null;
@@ -25,3 +26,20 @@ export const isMuxVideo = (url) => {
25
26
  if(!url) return false;
26
27
  return url.match(IS_MUX_VIDEO_REGEX)
27
28
  }
29
+
30
+ export const isSynchWordsVideo = (url) => {
31
+ if(!url) return false;
32
+ return url.match(IS_SYNC_WORDS_VIDEO_REGEX);
33
+ }
34
+
35
+ /**
36
+ * @param src
37
+ * @returns {string|null}
38
+ */
39
+ export const getSynchWordsVideoFrameDdFromSrc = (src) => {
40
+ const m = [...src.matchAll(IS_SYNC_WORDS_VIDEO_REGEX)];
41
+ if(!m?.length) return null;
42
+ const parts = m[0];
43
+ if(parts.length < 3) return null;
44
+ return `${parts[1]}-live-${parts[2]}`;
45
+ }