feat(liveStreamting) add configuration to customize streaming dialog
This commit is contained in:
parent
3f0e50a9cd
commit
87f6d27fb2
20
config.js
20
config.js
|
@ -310,9 +310,6 @@ var config = {
|
|||
// DEPRECATED. Use recordingService.sharingEnabled instead.
|
||||
// fileRecordingsServiceSharingEnabled: false,
|
||||
|
||||
// Whether to enable live streaming or not.
|
||||
// liveStreamingEnabled: false,
|
||||
|
||||
// Local recording configuration.
|
||||
// localRecording: {
|
||||
// // Whether to disable local recording or not.
|
||||
|
@ -325,6 +322,23 @@ var config = {
|
|||
// disableSelfRecording: false,
|
||||
// },
|
||||
|
||||
// Customize the Live Streaming dialog. Can be modified for a non-YouTube provider.
|
||||
// liveStreaming: {
|
||||
// // Whether to enable live streaming or not.
|
||||
// enabled: false,
|
||||
// // Terms link
|
||||
// termsLink: 'https://www.youtube.com/t/terms',
|
||||
// // Data privacy link
|
||||
// dataPrivacyLink: 'https://policies.google.com/privacy',
|
||||
// // RegExp string that validates the stream key input field
|
||||
// validatorRegExpString: '^(?:[a-zA-Z0-9]{4}(?:-(?!$)|$)){4}',
|
||||
// // Documentation reference for the live streaming feature.
|
||||
// helpLink: 'https://jitsi.org/live'
|
||||
// },
|
||||
|
||||
// DEPRECATED. Use liveStreaming.enabled instead.
|
||||
// liveStreamingEnabled: false,
|
||||
|
||||
// DEPRECATED. Use transcription.enabled instead.
|
||||
// transcribingEnabled: false,
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ var interfaceConfig = {
|
|||
JITSI_WATERMARK_LINK: 'https://jitsi.org',
|
||||
|
||||
LANG_DETECTION: true, // Allow i18n to detect the system language
|
||||
LIVE_STREAMING_HELP_LINK: 'https://jitsi.org/live', // Documentation reference for the live streaming feature.
|
||||
LOCAL_THUMBNAIL_RATIO: 16 / 9, // 16:9
|
||||
|
||||
/**
|
||||
|
@ -248,6 +247,10 @@ var interfaceConfig = {
|
|||
// Moved to config.js as `toolbarConfig.initialTimeout`.
|
||||
// INITIAL_TOOLBAR_TIMEOUT: 20000,
|
||||
|
||||
// Please use `liveStreaming.helpLink` from config.js
|
||||
// Documentation reference for the live streaming feature.
|
||||
// LIVE_STREAMING_HELP_LINK: 'https://jitsi.org/live',
|
||||
|
||||
// Moved to config.js as `toolbarConfig.alwaysVisible`.
|
||||
// TOOLBAR_ALWAYS_VISIBLE: false,
|
||||
|
||||
|
|
|
@ -332,6 +332,13 @@ export interface IConfig {
|
|||
lastNLimits?: {
|
||||
[key: number]: number;
|
||||
};
|
||||
liveStreaming?: {
|
||||
dataPrivacyLink?: string;
|
||||
enabled?: boolean;
|
||||
helpLink?: string;
|
||||
termsLink?: string;
|
||||
validatorRegExpString?: string;
|
||||
};
|
||||
liveStreamingEnabled?: boolean;
|
||||
localRecording?: {
|
||||
disable?: boolean;
|
||||
|
|
|
@ -183,6 +183,7 @@ export default [
|
|||
'iceTransportPolicy',
|
||||
'ignoreStartMuted',
|
||||
'inviteAppName',
|
||||
'liveStreaming',
|
||||
'liveStreamingEnabled',
|
||||
'localRecording',
|
||||
'localSubject',
|
||||
|
|
|
@ -420,6 +420,26 @@ function _translateLegacyConfig(oldValue: IConfig) {
|
|||
};
|
||||
}
|
||||
|
||||
newValue.liveStreaming = newValue.liveStreaming || {};
|
||||
|
||||
// Migrate config.liveStreamingEnabled
|
||||
if (oldValue.liveStreamingEnabled !== undefined) {
|
||||
newValue.liveStreaming = {
|
||||
...newValue.liveStreaming,
|
||||
enabled: oldValue.liveStreamingEnabled
|
||||
};
|
||||
}
|
||||
|
||||
// Migrate interfaceConfig.LIVE_STREAMING_HELP_LINK
|
||||
if (oldValue.liveStreaming === undefined
|
||||
&& typeof interfaceConfig === 'object'
|
||||
&& interfaceConfig.hasOwnProperty('LIVE_STREAMING_HELP_LINK')) {
|
||||
newValue.liveStreaming = {
|
||||
...newValue.liveStreaming,
|
||||
helpLink: interfaceConfig.LIVE_STREAMING_HELP_LINK
|
||||
};
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { getShareInfoText } from '../invite';
|
||||
import { getLiveStreaming } from '../recording/components/LiveStream/functions';
|
||||
|
||||
import {
|
||||
SET_GOOGLE_API_PROFILE,
|
||||
|
@ -36,15 +37,16 @@ export function loadGoogleAPI() {
|
|||
googleApi.get()
|
||||
.then(() => {
|
||||
const {
|
||||
liveStreamingEnabled,
|
||||
enableCalendarIntegration,
|
||||
googleApiApplicationClientID
|
||||
} = getState()['features/base/config'];
|
||||
|
||||
const liveStreaming = getLiveStreaming(getState());
|
||||
|
||||
if (getState()['features/google-api'].googleAPIState
|
||||
=== GOOGLE_API_STATES.NEEDS_LOADING) {
|
||||
return googleApi.initializeClient(
|
||||
googleApiApplicationClientID, liveStreamingEnabled, enableCalendarIntegration);
|
||||
googleApiApplicationClientID, liveStreaming.enabled, enableCalendarIntegration);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
|
|
|
@ -12,6 +12,8 @@ import { maybeShowPremiumFeatureDialog } from '../../../jaas/actions';
|
|||
import { FEATURES } from '../../../jaas/constants';
|
||||
import { getActiveSession } from '../../functions';
|
||||
|
||||
import { getLiveStreaming } from './functions';
|
||||
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of
|
||||
|
@ -141,12 +143,12 @@ export function _mapStateToProps(state: Object, ownProps: Props) {
|
|||
// its own to be visible or not.
|
||||
const isModerator = isLocalParticipantModerator(state);
|
||||
const {
|
||||
enableFeaturesBasedOnToken,
|
||||
liveStreamingEnabled
|
||||
enableFeaturesBasedOnToken
|
||||
} = state['features/base/config'];
|
||||
const liveStreaming = getLiveStreaming(state);
|
||||
const { features = {} } = getLocalParticipant(state);
|
||||
|
||||
visible = isModerator && liveStreamingEnabled;
|
||||
visible = isModerator && liveStreaming.enabled;
|
||||
|
||||
if (enableFeaturesBasedOnToken) {
|
||||
visible = visible && String(features.livestreaming) === 'true';
|
||||
|
|
|
@ -3,21 +3,35 @@
|
|||
import debounce from 'lodash/debounce';
|
||||
import { Component } from 'react';
|
||||
|
||||
declare var interfaceConfig: Object;
|
||||
import { getLiveStreaming } from './functions';
|
||||
|
||||
/**
|
||||
* The live streaming help link to display. On web it comes from
|
||||
* interfaceConfig, but we don't have that on mobile.
|
||||
*
|
||||
* FIXME: This is in props now to prepare for the Redux-based interfaceConfig.
|
||||
*/
|
||||
const LIVE_STREAMING_HELP_LINK = 'https://jitsi.org/live';
|
||||
|
||||
export type LiveStreaming = {
|
||||
enabled: boolean,
|
||||
helpLink: string, // Documentation reference for the live streaming feature.
|
||||
termsLink: string, // Terms link
|
||||
dataPrivacyLink: string, // Data privacy link
|
||||
validatorRegExpString: string // RegExp string that validates the stream key input field
|
||||
}
|
||||
|
||||
export type LiveStreamingProps = {
|
||||
enabled: boolean,
|
||||
helpURL: string,
|
||||
termsURL: string,
|
||||
dataPrivacyURL: string,
|
||||
streamLinkRegexp: RegExp
|
||||
}
|
||||
|
||||
/**
|
||||
* The props of the component.
|
||||
*/
|
||||
export type Props = {
|
||||
|
||||
/**
|
||||
* The live streaming dialog properties.
|
||||
*/
|
||||
_liveStreaming: LiveStreamingProps,
|
||||
|
||||
/**
|
||||
* Callback invoked when the entered stream key has changed.
|
||||
*/
|
||||
|
@ -54,7 +68,7 @@ type State = {
|
|||
*/
|
||||
export default class AbstractStreamKeyForm<P: Props>
|
||||
extends Component<P, State> {
|
||||
helpURL: string;
|
||||
|
||||
_debouncedUpdateValidationErrorVisibility: Function;
|
||||
|
||||
/**
|
||||
|
@ -70,10 +84,6 @@ export default class AbstractStreamKeyForm<P: Props>
|
|||
&& !this._validateStreamKey(this.props.value)
|
||||
};
|
||||
|
||||
this.helpURL = (typeof interfaceConfig !== 'undefined'
|
||||
&& interfaceConfig.LIVE_STREAMING_HELP_LINK)
|
||||
|| LIVE_STREAMING_HELP_LINK;
|
||||
|
||||
this._debouncedUpdateValidationErrorVisibility = debounce(
|
||||
this._updateValidationErrorVisibility.bind(this),
|
||||
800,
|
||||
|
@ -150,9 +160,22 @@ export default class AbstractStreamKeyForm<P: Props>
|
|||
*/
|
||||
_validateStreamKey(streamKey = '') {
|
||||
const trimmedKey = streamKey.trim();
|
||||
const fourGroupsDashSeparated = /^(?:[a-zA-Z0-9]{4}(?:-(?!$)|$)){4}/;
|
||||
const match = fourGroupsDashSeparated.exec(trimmedKey);
|
||||
const match = this.props._liveStreaming.streamLinkRegexp.exec(trimmedKey);
|
||||
|
||||
return Boolean(match);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the component's props.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _liveStreaming: LiveStreamingProps
|
||||
* }}
|
||||
*/
|
||||
export function _mapStateToProps(state: Object) {
|
||||
return {
|
||||
_liveStreaming: getLiveStreaming(state)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,3 +13,14 @@ export const YOUTUBE_LIVE_DASHBOARD_URL = 'https://www.youtube.com/live_dashboar
|
|||
* The URL for YouTube terms and conditions.
|
||||
*/
|
||||
export const YOUTUBE_TERMS_URL = 'https://www.youtube.com/t/terms';
|
||||
|
||||
/**
|
||||
* The live streaming help link to display.
|
||||
*/
|
||||
export const JITSI_LIVE_STREAMING_HELP_LINK = 'https://jitsi.org/live';
|
||||
|
||||
/**
|
||||
* The YouTube stream link RegExp.
|
||||
*/
|
||||
export const FOUR_GROUPS_DASH_SEPARATED = /^(?:[a-zA-Z0-9]{4}(?:-(?!$)|$)){4}/;
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import {
|
||||
FOUR_GROUPS_DASH_SEPARATED,
|
||||
GOOGLE_PRIVACY_POLICY,
|
||||
JITSI_LIVE_STREAMING_HELP_LINK,
|
||||
YOUTUBE_TERMS_URL
|
||||
} from './constants';
|
||||
|
||||
/**
|
||||
* Get the live streaming options.
|
||||
*
|
||||
* @param {Object} state - The global state.
|
||||
* @returns {LiveStreaming}
|
||||
*/
|
||||
export function getLiveStreaming(state: Object) {
|
||||
const { liveStreaming = {} } = state['features/base/config'];
|
||||
|
||||
const regexp = liveStreaming.validatorRegExpString
|
||||
&& new RegExp(liveStreaming.validatorRegExpString);
|
||||
|
||||
return {
|
||||
enabled: Boolean(liveStreaming.enabled),
|
||||
helpURL: liveStreaming.helpLink || JITSI_LIVE_STREAMING_HELP_LINK,
|
||||
termsURL: liveStreaming.termsLink || YOUTUBE_TERMS_URL,
|
||||
dataPrivacyURL: liveStreaming.dataPrivacyLink || GOOGLE_PRIVACY_POLICY,
|
||||
streamLinkRegexp: regexp || FOUR_GROUPS_DASH_SEPARATED
|
||||
};
|
||||
}
|
|
@ -10,7 +10,9 @@ import { StyleType } from '../../../../base/styles';
|
|||
import AbstractStreamKeyForm, {
|
||||
type Props as AbstractProps
|
||||
} from '../AbstractStreamKeyForm';
|
||||
import { GOOGLE_PRIVACY_POLICY, YOUTUBE_TERMS_URL } from '../constants';
|
||||
import { getLiveStreaming } from '../functions';
|
||||
|
||||
import styles, { PLACEHOLDER_COLOR } from './styles';
|
||||
|
||||
type Props = AbstractProps & {
|
||||
|
||||
|
@ -20,8 +22,6 @@ type Props = AbstractProps & {
|
|||
_dialogStyles: StyleType
|
||||
};
|
||||
|
||||
import styles, { PLACEHOLDER_COLOR } from './styles';
|
||||
|
||||
/**
|
||||
* A React Component for entering a key for starting a YouTube live stream.
|
||||
*
|
||||
|
@ -148,7 +148,7 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onOpenGooglePrivacyPolicy() {
|
||||
Linking.openURL(GOOGLE_PRIVACY_POLICY);
|
||||
Linking.openURL(this.props._liveStreaming.dataPrivacyURL);
|
||||
}
|
||||
|
||||
_onOpenHelp: () => void;
|
||||
|
@ -161,7 +161,7 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onOpenHelp() {
|
||||
const { helpURL } = this;
|
||||
const helpURL = this.props._liveStreaming.helpURL;
|
||||
|
||||
if (typeof helpURL === 'string') {
|
||||
Linking.openURL(helpURL);
|
||||
|
@ -177,8 +177,25 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onOpenYoutubeTerms() {
|
||||
Linking.openURL(YOUTUBE_TERMS_URL);
|
||||
Linking.openURL(this.props._liveStreaming.termsURL);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(connect(_abstractMapStateToProps)(StreamKeyForm));
|
||||
/**
|
||||
* Maps (parts of) the redux state to the associated props for the
|
||||
* {@code StreamKeyForm} component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _liveStreaming: LiveStreamingProps
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state: Object) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_liveStreaming: getLiveStreaming(state)
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(StreamKeyForm));
|
||||
|
|
|
@ -4,10 +4,10 @@ import { FieldTextStateless } from '@atlaskit/field-text';
|
|||
import React from 'react';
|
||||
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { connect } from '../../../../base/redux';
|
||||
import AbstractStreamKeyForm, {
|
||||
type Props
|
||||
type Props, _mapStateToProps
|
||||
} from '../AbstractStreamKeyForm';
|
||||
import { GOOGLE_PRIVACY_POLICY, YOUTUBE_TERMS_URL } from '../constants';
|
||||
|
||||
/**
|
||||
* A React Component for entering a key for starting a YouTube live stream.
|
||||
|
@ -62,7 +62,7 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
|||
</span>
|
||||
: null
|
||||
}
|
||||
{ this.helpURL
|
||||
{ this.props._liveStreaming.helpURL
|
||||
? <a
|
||||
aria-label = { t('liveStreaming.streamIdHelp') }
|
||||
className = 'helper-link'
|
||||
|
@ -77,14 +77,14 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
|||
</div>
|
||||
<a
|
||||
className = 'helper-link'
|
||||
href = { YOUTUBE_TERMS_URL }
|
||||
href = { this.props._liveStreaming.termsURL }
|
||||
rel = 'noopener noreferrer'
|
||||
target = '_blank'>
|
||||
{ t('liveStreaming.youtubeTerms') }
|
||||
</a>
|
||||
<a
|
||||
className = 'helper-link'
|
||||
href = { GOOGLE_PRIVACY_POLICY }
|
||||
href = { this.props._liveStreaming.dataPrivacyURL }
|
||||
rel = 'noopener noreferrer'
|
||||
target = '_blank'>
|
||||
{ t('liveStreaming.googlePrivacyPolicy') }
|
||||
|
@ -106,7 +106,7 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onOpenHelp() {
|
||||
window.open(this.helpURL, '_blank', 'noopener');
|
||||
window.open(this.props._liveStreaming.helpURL, '_blank', 'noopener');
|
||||
}
|
||||
|
||||
_onOpenHelpKeyPress: () => void;
|
||||
|
@ -128,4 +128,4 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(StreamKeyForm);
|
||||
export default translate(connect(_mapStateToProps)(StreamKeyForm));
|
||||
|
|
Loading…
Reference in New Issue