├── example.config.json
├── public
├── images
│ ├── get-link.png
│ ├── camera.svg
│ ├── clippy.svg
│ ├── no-camera.svg
│ ├── mic.svg
│ ├── no-mic.svg
│ └── sgonline.svg
├── js
│ ├── util
│ │ ├── http.js
│ │ ├── es6-promise.auto.min.js
│ │ └── clipboard.min.js
│ ├── index.js
│ ├── broadcast.js
│ ├── guest.js
│ ├── viewer.js
│ └── host.js
└── css
│ └── styles.css
├── views
├── partials
│ ├── branding.ejs
│ ├── video-player.ejs
│ ├── live-chat.ejs
│ └── common-head.ejs
└── pages
│ ├── guest.ejs
│ ├── viewer.ejs
│ ├── broadcast.ejs
│ ├── host.ejs
│ └── index.ejs
├── src
├── scss
│ ├── _settings.scss
│ └── styles.scss
└── js
│ ├── index.js
│ ├── broadcast.js
│ ├── guest.js
│ ├── viewer.js
│ └── host.js
├── package.json
├── .gitignore
├── server.js
├── services
├── opentok-api.js
└── broadcast-api.js
├── gulpfile.js
└── README.md
/example.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "apiKey" : "",
3 | "apiSecret": ""
4 | }
--------------------------------------------------------------------------------
/public/images/get-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huijing/sgtechonline/HEAD/public/images/get-link.png
--------------------------------------------------------------------------------
/views/partials/branding.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 | SG Tech Online
4 |
--------------------------------------------------------------------------------
/views/partials/video-player.ejs:
--------------------------------------------------------------------------------
1 |
14 |
15 | Waiting for Broadcast to Begin
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/public/js/util/http.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | var http = {
3 | post: function (url, data) {
4 | var requestHeaders = {
5 | 'Accept': 'application/json',
6 | 'Content-Type': 'application/json'
7 | };
8 |
9 | var parseJSON = function (response) {
10 | return response.json();
11 | };
12 |
13 | var params = {
14 | method: 'POST',
15 | headers: requestHeaders,
16 | body: JSON.stringify(data)
17 | };
18 |
19 | return new Promise(function (resolve, reject) {
20 | fetch(url, params)
21 | .then(parseJSON)
22 | .then(function (json) {
23 | resolve(json);
24 | })
25 | .catch(function (error) {
26 | reject(error);
27 | });
28 | });
29 | }
30 | };
31 | window.http = http;
32 | }());
33 |
--------------------------------------------------------------------------------
/src/js/index.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | const formToJSON = elements => [].reduce.call(elements, (data, element) => {
3 | if (isValidElement(element) && isValidValue(element)) {
4 | data[element.name] = element.value;
5 | }
6 | return data;
7 | }, {});
8 |
9 | const isValidElement = element => {
10 | return element.name && element.value;
11 | };
12 |
13 | const isValidValue = element => {
14 | return (!['checkbox', 'radio'].includes(element.type) || element.checked);
15 | };
16 |
17 | const init = function () {
18 | const userForm = document.getElementById('registration');
19 | const handleFormSubmit = event => {
20 | event.preventDefault();
21 |
22 | const formBody = formToJSON(userForm.elements);
23 | location.assign(`/${formBody['user-type']}?name=${formBody['user-name']}`)
24 | };
25 | userForm.addEventListener('submit', handleFormSubmit, false);
26 | };
27 |
28 | document.addEventListener('DOMContentLoaded', init);
29 | }());
30 |
--------------------------------------------------------------------------------
/public/js/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | (function () {
4 | var formToJSON = function formToJSON(elements) {
5 | return [].reduce.call(elements, function (data, element) {
6 | if (isValidElement(element) && isValidValue(element)) {
7 | data[element.name] = element.value;
8 | }
9 |
10 | return data;
11 | }, {});
12 | };
13 |
14 | var isValidElement = function isValidElement(element) {
15 | return element.name && element.value;
16 | };
17 |
18 | var isValidValue = function isValidValue(element) {
19 | return !['checkbox', 'radio'].includes(element.type) || element.checked;
20 | };
21 |
22 | var init = function init() {
23 | var userForm = document.getElementById('registration');
24 |
25 | var handleFormSubmit = function handleFormSubmit(event) {
26 | event.preventDefault();
27 | var formBody = formToJSON(userForm.elements);
28 | location.assign("/".concat(formBody['user-type'], "?name=").concat(formBody['user-name']));
29 | };
30 |
31 | userForm.addEventListener('submit', handleFormSubmit, false);
32 | };
33 |
34 | document.addEventListener('DOMContentLoaded', init);
35 | })();
--------------------------------------------------------------------------------
/public/images/no-mic.svg:
--------------------------------------------------------------------------------
1 |