Merge branch 'MDL-68436' of https://github.com/timhunt/moodle
[moodle.git] / lib / editor / atto / plugins / recordrtc / yui / src / button / js / button.js
CommitLineData
b4bbf31b 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//
16
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 */
26
27/**
28 * @module moodle-atto_recordrtc-button
29 */
30
31/**
32 * Atto text editor recordrtc plugin.
33 *
34 * @namespace M.atto_recordrtc
35 * @class button
36 * @extends M.editor_atto.EditorPlugin
37 */
38
39// ESLint directives.
40/* eslint-disable camelcase, spaced-comment */
41
42// JSHint directives.
43/*global M */
44/*jshint onevar: false */
45
46// Scrutinizer CI directives.
47/** global: Y */
48/** global: M */
49
50var PLUGINNAME = 'atto_recordrtc',
51 TEMPLATE = '' +
52 '<div class="{{PLUGINNAME}} container-fluid">' +
b4bbf31b 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>';
88
89Y.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',
94
95 initializer: function() {
96 if (this.get('host').canShowFilepicker('media')) {
97 // Add audio and/or video buttons depending on the settings.
f4ef2345
TH
98 var allowedtypes = this.get('allowedtypes'),
99 buttonadded = false;
b4bbf31b 100 if (allowedtypes === 'both' || allowedtypes === 'audio') {
101 this._addButton('audio', this._audio);
f4ef2345 102 buttonadded = true;
b4bbf31b 103 }
104 if (allowedtypes === 'both' || allowedtypes === 'video') {
105 this._addButton('video', this._video);
f4ef2345
TH
106 buttonadded = true;
107 }
108 if (!buttonadded) {
109 // Plugin not available here.
110 return;
b4bbf31b 111 }
112
113 // Initialize the dialogue box.
114 var dialogue = this.getDialogue({
115 width: 1000,
116 focusAfterHide: null
117 });
118
b4bbf31b 119 dialogue.after('visibleChange', function() {
120 var closed = !dialogue.get('visible'),
121 m = M.atto_recordrtc.commonmodule;
122
123 if (closed) {
157c85c2 124 // If dialogue is closed during recording, do the following.
b4bbf31b 125 window.clearInterval(m.countdownTicker);
126
127 if (m.mediaRecorder && m.mediaRecorder.state !== 'inactive') {
128 m.mediaRecorder.stop();
129 }
130
131 if (m.stream) {
132 m.stream.getTracks().forEach(function(track) {
133 if (track.readyState !== 'ended') {
134 track.stop();
135 }
136 });
137 }
157c85c2
TH
138
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', '');
b4bbf31b 143 }
144
157c85c2 145 }, this);
b4bbf31b 146
147 dialogue.on('click', function() {
148 this.centered();
149 });
150
a8d022d8 151 // Require adapter.js library.
8be5742c 152 window.require(['core/adapter'], function(adapter) {
b4bbf31b 153 window.adapter = adapter;
154 });
b4bbf31b 155 }
156 },
157
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 },
177
178 /**
179 * Toggle audiortc and normal display mode
180 *
181 * @method _audio
182 * @private
183 */
184 _audio: function() {
185 var dialogue = this.getDialogue();
186
187 dialogue.set('headerContent', M.util.get_string('audiortc', 'atto_recordrtc'));
188 dialogue.set('bodyContent', this._createContent('audio'));
189
190 dialogue.show();
191
192 M.atto_recordrtc.audiomodule.init(this);
193 },
194
195 /**
196 * Toggle videortc and normal display mode
197 *
198 * @method _video
199 * @private
200 */
201 _video: function() {
202 var dialogue = this.getDialogue();
203
204 dialogue.set('headerContent', M.util.get_string('videortc', 'atto_recordrtc'));
205 dialogue.set('bodyContent', this._createContent('video'));
206
207 dialogue.show();
208
209 M.atto_recordrtc.videomodule.init(this);
210 },
211
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'),
0174e72b 222 bsRow = 'row',
9396731e 223 bsCol = 'col-',
0174e72b
MN
224 bsAlDang = 'alert-danger',
225 bsSsBtn = 'btn btn-lg btn-outline-danger btn-block';
b4bbf31b 226
227 var bodyContent = Y.Handlebars.compile(TEMPLATE)({
228 PLUGINNAME: PLUGINNAME,
229 isAudio: isAudio,
230 bs_row: bsRow,
231 bs_col: bsCol,
b4bbf31b 232 bs_al_dang: bsAlDang,
233 bs_ss_btn: bsSsBtn,
b4bbf31b 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 });
239
240 return bodyContent;
241 },
242
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();
251
252 scope.editor.focus();
253 },
254
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();
264
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 },
280
281 /**
282 * The sesskey to use when generating this recordrtc.
283 *
284 * @attribute sesskey
285 * @type String
286 */
287 sesskey: {
288 value: null
289 },
290
291 /**
292 * The allowedtypes to use when generating this recordrtc.
293 *
294 * @attribute allowedtypes
295 * @type String
296 */
297 allowedtypes: {
298 value: null
299 },
300
301 /**
302 * The audiobitrate to use when generating this recordrtc.
303 *
304 * @attribute audiobitrate
305 * @type String
306 */
307 audiobitrate: {
308 value: null
309 },
310
311 /**
312 * The videobitrate to use when generating this recordrtc.
313 *
314 * @attribute videobitrate
315 * @type String
316 */
317 videobitrate: {
318 value: null
319 },
320
321 /**
322 * The timelimit to use when generating this recordrtc.
323 *
324 * @attribute timelimit
325 * @type String
326 */
327 timelimit: {
328 value: null
329 },
330
331 /**
332 * The audiortcicon to use when generating this recordrtc.
333 *
334 * @attribute audiortcicon
335 * @type String
336 */
337 audiortcicon: {
338 value: null
339 },
340
341 /**
342 * The videortcicon to use when generating this recordrtc.
343 *
344 * @attribute videortcicon
345 * @type String
346 */
347 videortcicon: {
348 value: null
349 },
350
b4bbf31b 351 /**
7dfa238c 352 * Maximum upload size set on server, in bytes.
b4bbf31b 353 *
354 * @attribute maxrecsize
355 * @type String
356 */
357 maxrecsize: {
358 value: null
359 }
360 }
361});