瀏覽代碼

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.
master
Leonard Kim 6 年之前
父節點
當前提交
07bcb38dd6

+ 9
- 11
css/_recording.scss 查看文件

@@ -95,17 +95,15 @@
95 95
         padding-bottom: 10px;
96 96
     }
97 97
 
98
-    .stream-key-form {
99
-        .helper-link {
100
-            cursor: pointer;
101
-            display: inline-block;
102
-            flex-shrink: 0;
103
-            margin-left: auto;
104
-        }
98
+    .helper-link {
99
+        cursor: pointer;
100
+        display: inline-block;
101
+        flex-shrink: 0;
102
+        margin-left: auto;
103
+    }
105 104
 
106
-        .validation-error {
107
-            color:#FFD740;
108
-            font-size: 12px;
109
-        }
105
+    .warning-text {
106
+        color:#FFD740;
107
+        font-size: 12px;
110 108
     }
111 109
 }

+ 1
- 0
lang/main.json 查看文件

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

+ 6
- 0
react/features/recording/components/LiveStream/constants.js 查看文件

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

+ 38
- 2
react/features/recording/components/LiveStream/native/StreamKeyPicker.js 查看文件

@@ -1,10 +1,18 @@
1 1
 // @flow
2 2
 
3 3
 import React, { Component } from 'react';
4
-import { Text, TouchableHighlight, View } from 'react-native';
4
+import {
5
+    Linking,
6
+    Text,
7
+    TouchableHighlight,
8
+    TouchableOpacity,
9
+    View
10
+} from 'react-native';
5 11
 
6 12
 import { translate } from '../../../../base/i18n';
7 13
 
14
+import { YOUTUBE_LIVE_DASHBOARD_URL } from '../constants';
15
+
8 16
 import styles, { ACTIVE_OPACITY, TOUCHABLE_UNDERLAY } from './styles';
9 17
 
10 18
 type Props = {
@@ -56,6 +64,7 @@ class StreamKeyPicker extends Component<Props, State> {
56 64
             streamKey: null
57 65
         };
58 66
 
67
+        this._onOpenYoutubeDashboard = this._onOpenYoutubeDashboard.bind(this);
59 68
         this._onStreamPick = this._onStreamPick.bind(this);
60 69
     }
61 70
 
@@ -67,10 +76,24 @@ class StreamKeyPicker extends Component<Props, State> {
67 76
     render() {
68 77
         const { broadcasts } = this.props;
69 78
 
70
-        if (!broadcasts || !broadcasts.length) {
79
+        if (!broadcasts) {
71 80
             return null;
72 81
         }
73 82
 
83
+        if (!broadcasts.length) {
84
+            return (
85
+                <View style = { styles.formWrapper }>
86
+                    <TouchableOpacity
87
+                        onPress = { this._onOpenYoutubeDashboard }>
88
+                        <Text style = { styles.warningText }>
89
+                            { this.props.t(
90
+                                'liveStreaming.getStreamKeyManually') }
91
+                        </Text>
92
+                    </TouchableOpacity>
93
+                </View>
94
+            );
95
+        }
96
+
74 97
         return (
75 98
             <View style = { styles.formWrapper }>
76 99
                 <View style = { styles.streamKeyPickerCta }>
@@ -100,6 +123,19 @@ class StreamKeyPicker extends Component<Props, State> {
100 123
         );
101 124
     }
102 125
 
126
+    _onOpenYoutubeDashboard: () => void;
127
+
128
+    /**
129
+     * Opens the link which should display the YouTube broadcast live stream
130
+     * key.
131
+     *
132
+     * @private
133
+     * @returns {void}
134
+     */
135
+    _onOpenYoutubeDashboard() {
136
+        Linking.openURL(YOUTUBE_LIVE_DASHBOARD_URL);
137
+    }
138
+
103 139
     _onStreamPick: string => Function
104 140
 
105 141
     /**

+ 15
- 6
react/features/recording/components/LiveStream/web/StartLiveStreamDialog.js 查看文件

@@ -280,12 +280,21 @@ class StartLiveStreamDialog
280 280
             break;
281 281
 
282 282
         case GOOGLE_API_STATES.SIGNED_IN:
283
-            googleContent = (
284
-                <StreamKeyPicker
285
-                    broadcasts = { broadcasts }
286
-                    onBroadcastSelected = { this._onYouTubeBroadcastIDSelected }
287
-                    selectedBoundStreamID = { selectedBoundStreamID } />
288
-            );
283
+            if (broadcasts) {
284
+                googleContent = (
285
+                    <StreamKeyPicker
286
+                        broadcasts = { broadcasts }
287
+                        onBroadcastSelected
288
+                            = { this._onYouTubeBroadcastIDSelected }
289
+                        selectedBoundStreamID = { selectedBoundStreamID } />
290
+                );
291
+            } else {
292
+                googleContent = (
293
+                    <Spinner
294
+                        isCompleting = { false }
295
+                        size = 'medium' />
296
+                );
297
+            }
289 298
 
290 299
             /**
291 300
              * FIXME: Ideally this help text would be one translation string

+ 1
- 1
react/features/recording/components/LiveStream/web/StreamKeyForm.js 查看文件

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

+ 14
- 0
react/features/recording/components/LiveStream/web/StreamKeyPicker.js 查看文件

@@ -9,6 +9,8 @@ import React, { PureComponent } from 'react';
9 9
 
10 10
 import { translate } from '../../../../base/i18n';
11 11
 
12
+import { YOUTUBE_LIVE_DASHBOARD_URL } from '../constants';
13
+
12 14
 /**
13 15
  * The type of the React {@code Component} props of {@link StreamKeyPicker}.
14 16
  */
@@ -95,6 +97,18 @@ class StreamKeyPicker extends PureComponent<Props, State> {
95 97
     render() {
96 98
         const { broadcasts, selectedBoundStreamID, t } = this.props;
97 99
 
100
+        if (!broadcasts.length) {
101
+            return (
102
+                <a
103
+                    className = 'warning-text'
104
+                    href = { YOUTUBE_LIVE_DASHBOARD_URL }
105
+                    rel = 'noopener noreferrer'
106
+                    target = '_blank'>
107
+                    { t('liveStreaming.getStreamKeyManually') }
108
+                </a>
109
+            );
110
+        }
111
+
98 112
         const dropdownItems
99 113
             = broadcasts.map(broadcast => (
100 114
                 <DropdownItem

Loading…
取消
儲存