fix(live-streaming): show message if no broadcasts are found

It's possible for the YouTube api to return zero broadcasts
or broadcasts without any streams--streams are what are
associated with stream keys. In this case, instead of showing
an empty selector or no selector, show a message with a link
to where the stream key can be obtained.
This commit is contained in:
Leonard Kim 2018-12-17 20:21:18 -08:00 committed by Zoltan Bettenbuk
parent 699b13066e
commit 07bcb38dd6
7 changed files with 84 additions and 20 deletions

View File

@ -95,17 +95,15 @@
padding-bottom: 10px;
}
.stream-key-form {
.helper-link {
cursor: pointer;
display: inline-block;
flex-shrink: 0;
margin-left: auto;
}
.helper-link {
cursor: pointer;
display: inline-block;
flex-shrink: 0;
margin-left: auto;
}
.validation-error {
color:#FFD740;
font-size: 12px;
}
.warning-text {
color:#FFD740;
font-size: 12px;
}
}

View File

@ -516,6 +516,7 @@
"expandedPending": "The live streaming is being started...",
"failedToStart": "Live Streaming failed to start",
"invalidStreamKey": "Live stream key may be incorrect.",
"getStreamKeyManually": "We werent able to fetch any live streams. Try getting your live stream key from YouTube.",
"off": "Live Streaming stopped",
"on": "Live Streaming",
"pending": "Starting Live Stream...",

View File

@ -0,0 +1,6 @@
/**
* The URL that is the main landing page for YouTube live streaming and should
* have a user's live stream key.
*/
export const YOUTUBE_LIVE_DASHBOARD_URL
= 'https://www.youtube.com/live_dashboard';

View File

@ -1,10 +1,18 @@
// @flow
import React, { Component } from 'react';
import { Text, TouchableHighlight, View } from 'react-native';
import {
Linking,
Text,
TouchableHighlight,
TouchableOpacity,
View
} from 'react-native';
import { translate } from '../../../../base/i18n';
import { YOUTUBE_LIVE_DASHBOARD_URL } from '../constants';
import styles, { ACTIVE_OPACITY, TOUCHABLE_UNDERLAY } from './styles';
type Props = {
@ -56,6 +64,7 @@ class StreamKeyPicker extends Component<Props, State> {
streamKey: null
};
this._onOpenYoutubeDashboard = this._onOpenYoutubeDashboard.bind(this);
this._onStreamPick = this._onStreamPick.bind(this);
}
@ -67,10 +76,24 @@ class StreamKeyPicker extends Component<Props, State> {
render() {
const { broadcasts } = this.props;
if (!broadcasts || !broadcasts.length) {
if (!broadcasts) {
return null;
}
if (!broadcasts.length) {
return (
<View style = { styles.formWrapper }>
<TouchableOpacity
onPress = { this._onOpenYoutubeDashboard }>
<Text style = { styles.warningText }>
{ this.props.t(
'liveStreaming.getStreamKeyManually') }
</Text>
</TouchableOpacity>
</View>
);
}
return (
<View style = { styles.formWrapper }>
<View style = { styles.streamKeyPickerCta }>
@ -100,6 +123,19 @@ class StreamKeyPicker extends Component<Props, State> {
);
}
_onOpenYoutubeDashboard: () => void;
/**
* Opens the link which should display the YouTube broadcast live stream
* key.
*
* @private
* @returns {void}
*/
_onOpenYoutubeDashboard() {
Linking.openURL(YOUTUBE_LIVE_DASHBOARD_URL);
}
_onStreamPick: string => Function
/**

View File

@ -280,12 +280,21 @@ class StartLiveStreamDialog
break;
case GOOGLE_API_STATES.SIGNED_IN:
googleContent = (
<StreamKeyPicker
broadcasts = { broadcasts }
onBroadcastSelected = { this._onYouTubeBroadcastIDSelected }
selectedBoundStreamID = { selectedBoundStreamID } />
);
if (broadcasts) {
googleContent = (
<StreamKeyPicker
broadcasts = { broadcasts }
onBroadcastSelected
= { this._onYouTubeBroadcastIDSelected }
selectedBoundStreamID = { selectedBoundStreamID } />
);
} else {
googleContent = (
<Spinner
isCompleting = { false }
size = 'medium' />
);
}
/**
* FIXME: Ideally this help text would be one translation string

View File

@ -55,7 +55,7 @@ class StreamKeyForm extends AbstractStreamKeyForm {
<div className = 'form-footer'>
{
this.state.showValidationError
? <span className = 'validation-error'>
? <span className = 'warning-text'>
{ t('liveStreaming.invalidStreamKey') }
</span>
: null

View File

@ -9,6 +9,8 @@ import React, { PureComponent } from 'react';
import { translate } from '../../../../base/i18n';
import { YOUTUBE_LIVE_DASHBOARD_URL } from '../constants';
/**
* The type of the React {@code Component} props of {@link StreamKeyPicker}.
*/
@ -95,6 +97,18 @@ class StreamKeyPicker extends PureComponent<Props, State> {
render() {
const { broadcasts, selectedBoundStreamID, t } = this.props;
if (!broadcasts.length) {
return (
<a
className = 'warning-text'
href = { YOUTUBE_LIVE_DASHBOARD_URL }
rel = 'noopener noreferrer'
target = '_blank'>
{ t('liveStreaming.getStreamKeyManually') }
</a>
);
}
const dropdownItems
= broadcasts.map(broadcast => (
<DropdownItem