Merge branch 'MDL-68436' of https://github.com/timhunt/moodle
[moodle.git] / lib / editor / atto / plugins / recordrtc / yui / src / button / js / button.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15 //
17 /**
18  * Atto recordrtc library functions
19  *
20  * @package    atto_recordrtc
21  * @author     Jesus Federico (jesus [at] blindsidenetworks [dt] com)
22  * @author     Jacob Prud'homme (jacob [dt] prudhomme [at] blindsidenetworks [dt] com)
23  * @copyright  2017 Blindside Networks Inc.
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
27 /**
28  * @module moodle-atto_recordrtc-button
29  */
31 /**
32  * Atto text editor recordrtc plugin.
33  *
34  * @namespace M.atto_recordrtc
35  * @class button
36  * @extends M.editor_atto.EditorPlugin
37  */
39 // ESLint directives.
40 /* eslint-disable camelcase, spaced-comment */
42 // JSHint directives.
43 /*global M */
44 /*jshint onevar: false */
46 // Scrutinizer CI directives.
47 /** global: Y */
48 /** global: M */
50 var PLUGINNAME = 'atto_recordrtc',
51     TEMPLATE = '' +
52     '<div class="{{PLUGINNAME}} container-fluid">' +
53       '<div class="{{bs_row}} hide">' +
54         '<div class="{{bs_col}}12">' +
55           '<div id="alert-danger" class="alert {{bs_al_dang}}">' +
56             '<strong>{{insecurealert_title}}</strong> {{insecurealert}}' +
57           '</div>' +
58         '</div>' +
59       '</div>' +
60       '<div class="{{bs_row}} hide">' +
61         '{{#if isAudio}}' +
62           '<div class="{{bs_col}}1"></div>' +
63           '<div class="{{bs_col}}10">' +
64             '<audio id="player"></audio>' +
65           '</div>' +
66           '<div class="{{bs_col}}1"></div>' +
67         '{{else}}' +
68           '<div class="{{bs_col}}12">' +
69             '<video id="player"></video>' +
70           '</div>' +
71         '{{/if}}' +
72       '</div>' +
73       '<div class="{{bs_row}}">' +
74         '<div class="{{bs_col}}1"></div>' +
75         '<div class="{{bs_col}}10">' +
76           '<button id="start-stop" class="{{bs_ss_btn}}">{{startrecording}}</button>' +
77         '</div>' +
78         '<div class="{{bs_col}}1"></div>' +
79       '</div>' +
80       '<div class="{{bs_row}} hide">' +
81         '<div class="{{bs_col}}3"></div>' +
82         '<div class="{{bs_col}}6">' +
83           '<button id="upload" class="btn btn-primary btn-block">{{attachrecording}}</button>' +
84         '</div>' +
85         '<div class="{{bs_col}}3"></div>' +
86       '</div>' +
87     '</div>';
89 Y.namespace('M.atto_recordrtc').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
90     /**
91      * The current language by default.
92      */
93     _lang: 'en',
95     initializer: function() {
96         if (this.get('host').canShowFilepicker('media')) {
97             // Add audio and/or video buttons depending on the settings.
98             var allowedtypes = this.get('allowedtypes'),
99                 buttonadded = false;
100             if (allowedtypes === 'both' || allowedtypes === 'audio') {
101                 this._addButton('audio', this._audio);
102                 buttonadded = true;
103             }
104             if (allowedtypes === 'both' || allowedtypes === 'video') {
105                 this._addButton('video', this._video);
106                 buttonadded = true;
107             }
108             if (!buttonadded) {
109                 // Plugin not available here.
110                 return;
111             }
113             // Initialize the dialogue box.
114             var dialogue = this.getDialogue({
115                 width: 1000,
116                 focusAfterHide: null
117             });
119             dialogue.after('visibleChange', function() {
120                 var closed = !dialogue.get('visible'),
121                     m = M.atto_recordrtc.commonmodule;
123                 if (closed) {
124                     // If dialogue is closed during recording, do the following.
125                     window.clearInterval(m.countdownTicker);
127                     if (m.mediaRecorder && m.mediaRecorder.state !== 'inactive') {
128                         m.mediaRecorder.stop();
129                     }
131                     if (m.stream) {
132                         m.stream.getTracks().forEach(function(track) {
133                             if (track.readyState !== 'ended') {
134                                 track.stop();
135                             }
136                         });
137                     }
139                     // Because the player uses ids to identify things (this should be fixed)
140                     // we must make sure the dialogue contents only exist once in the DOM.
141                     // Therefore, when a dialogue is closed, we must remove its contents.
142                     this.getDialogue().set('bodyContent', '');
143                 }
145             }, this);
147             dialogue.on('click', function() {
148                 this.centered();
149             });
151             // Require adapter.js library.
152             window.require(['core/adapter'], function(adapter) {
153                 window.adapter = adapter;
154             });
155         }
156     },
158     /**
159      * Add the buttons to the Atto toolbar.
160      *
161      * @method _addButton
162      * @param {string} type
163      * @param {callback} callback
164      * @private
165      */
166     _addButton: function(type, callback) {
167         this.addButton({
168             buttonName: type,
169             icon: this.get(type + 'rtcicon'),
170             iconComponent: PLUGINNAME,
171             callback: callback,
172             title: type + 'rtc',
173             tags: type + 'rtc',
174             tagMatchRequiresAll: false
175         });
176     },
178     /**
179      * Toggle audiortc and normal display mode
180      *
181      * @method _audio
182      * @private
183      */
184     _audio: function() {
185         var dialogue = this.getDialogue();
187         dialogue.set('headerContent', M.util.get_string('audiortc', 'atto_recordrtc'));
188         dialogue.set('bodyContent', this._createContent('audio'));
190         dialogue.show();
192         M.atto_recordrtc.audiomodule.init(this);
193     },
195     /**
196      * Toggle videortc and normal display mode
197      *
198      * @method _video
199      * @private
200      */
201     _video: function() {
202         var dialogue = this.getDialogue();
204         dialogue.set('headerContent', M.util.get_string('videortc', 'atto_recordrtc'));
205         dialogue.set('bodyContent', this._createContent('video'));
207         dialogue.show();
209         M.atto_recordrtc.videomodule.init(this);
210     },
212     /**
213      * Create the HTML to be displayed in the dialogue box
214      *
215      * @method _createContent
216      * @param {string} type
217      * @returns {Object}
218      * @private
219      */
220     _createContent: function(type) {
221         var isAudio = (type === 'audio'),
222             bsRow = 'row',
223             bsCol = 'col-',
224             bsAlDang = 'alert-danger',
225             bsSsBtn = 'btn btn-lg btn-outline-danger btn-block';
227         var bodyContent = Y.Handlebars.compile(TEMPLATE)({
228             PLUGINNAME: PLUGINNAME,
229             isAudio: isAudio,
230             bs_row: bsRow,
231             bs_col: bsCol,
232             bs_al_dang: bsAlDang,
233             bs_ss_btn: bsSsBtn,
234             insecurealert_title: M.util.get_string('insecurealert_title', 'atto_recordrtc'),
235             insecurealert: M.util.get_string('insecurealert', 'atto_recordrtc'),
236             startrecording: M.util.get_string('startrecording', 'atto_recordrtc'),
237             attachrecording: M.util.get_string('attachrecording', 'atto_recordrtc')
238         });
240         return bodyContent;
241     },
243     /**
244      * Close the dialogue without further action.
245      *
246      * @method closeDialogue
247      * @param {Object} scope The "this" context of the editor.
248      */
249     closeDialogue: function(scope) {
250         scope.getDialogue().hide();
252         scope.editor.focus();
253     },
255     /**
256      * Insert the annotation link in the editor.
257      *
258      * @method setLink
259      * @param {Object} scope The "this" context of the editor.
260      * @param {string} annotation The HTML link to the recording.
261      */
262     setLink: function(scope, annotation) {
263         scope.getDialogue().hide();
265         scope.editor.focus();
266         scope.get('host').insertContentAtFocusPoint(annotation);
267         scope.markUpdated();
268     }
269 }, {
270     ATTRS: {
271         /**
272          * The contextid to use when generating this recordrtc.
273          *
274          * @attribute contextid
275          * @type String
276          */
277         contextid: {
278             value: null
279         },
281         /**
282          * The sesskey to use when generating this recordrtc.
283          *
284          * @attribute sesskey
285          * @type String
286          */
287         sesskey: {
288             value: null
289         },
291         /**
292          * The allowedtypes to use when generating this recordrtc.
293          *
294          * @attribute allowedtypes
295          * @type String
296          */
297         allowedtypes: {
298             value: null
299         },
301         /**
302          * The audiobitrate to use when generating this recordrtc.
303          *
304          * @attribute audiobitrate
305          * @type String
306          */
307         audiobitrate: {
308             value: null
309         },
311         /**
312          * The videobitrate to use when generating this recordrtc.
313          *
314          * @attribute videobitrate
315          * @type String
316          */
317         videobitrate: {
318             value: null
319         },
321         /**
322          * The timelimit to use when generating this recordrtc.
323          *
324          * @attribute timelimit
325          * @type String
326          */
327         timelimit: {
328             value: null
329         },
331         /**
332          * The audiortcicon to use when generating this recordrtc.
333          *
334          * @attribute audiortcicon
335          * @type String
336          */
337         audiortcicon: {
338             value: null
339         },
341         /**
342          * The videortcicon to use when generating this recordrtc.
343          *
344          * @attribute videortcicon
345          * @type String
346          */
347         videortcicon: {
348             value: null
349         },
351         /**
352          * Maximum upload size set on server, in bytes.
353          *
354          * @attribute maxrecsize
355          * @type String
356          */
357         maxrecsize: {
358             value: null
359         }
360     }
361 });