├── public
├── favicon.ico
├── robots.txt
├── img
│ ├── logo.png
│ ├── mike.png
│ ├── video.png
│ ├── 7AF2Qzt.png
│ ├── enablex.png
│ ├── end-call.png
│ ├── loader.gif
│ ├── mute-mike.png
│ ├── mute-video.png
│ ├── player-bg.gif
│ ├── volume_off.svg
│ ├── volume_on.svg
│ ├── video_on.svg
│ └── video_off.svg
├── assets
│ ├── loader.gif
│ ├── mute48.png
│ ├── sound48.png
│ ├── logo.svg
│ ├── css
│ │ ├── dark-knight.css
│ │ ├── classic.css
│ │ ├── box.css
│ │ └── default.css
│ └── star.svg
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ └── fontawesome-webfont.woff2
├── .htaccess
├── js
│ ├── util.js
│ ├── room.js
│ ├── index.js
│ ├── confo.js
│ └── jquery.toast.js
├── web.config
├── index.php
└── css
│ ├── confo.css
│ ├── jquery.toast.css
│ ├── style.min.css
│ └── style.css
├── bootstrap
├── cache
│ └── .gitignore
└── app.php
├── storage
├── logs
│ └── .gitignore
├── app
│ ├── public
│ │ └── .gitignore
│ └── .gitignore
└── framework
│ ├── testing
│ └── .gitignore
│ ├── views
│ └── .gitignore
│ ├── cache
│ ├── data
│ │ └── .gitignore
│ └── .gitignore
│ ├── sessions
│ └── .gitignore
│ └── .gitignore
├── database
├── .gitignore
├── seeds
│ └── DatabaseSeeder.php
├── migrations
│ ├── 2014_10_12_100000_create_password_resets_table.php
│ └── 2014_10_12_000000_create_users_table.php
└── factories
│ └── UserFactory.php
├── .gitattributes
├── resources
├── sass
│ ├── app.scss
│ └── _variables.scss
├── lang
│ └── en
│ │ ├── pagination.php
│ │ ├── auth.php
│ │ ├── passwords.php
│ │ └── validation.php
├── js
│ ├── components
│ │ └── ExampleComponent.vue
│ ├── app.js
│ └── bootstrap.js
└── views
│ ├── index.blade.php
│ └── confo.blade.php
├── .gitignore
├── tests
├── TestCase.php
├── Unit
│ └── ExampleTest.php
├── Feature
│ └── ExampleTest.php
└── CreatesApplication.php
├── routes
├── api.php
├── channels.php
├── console.php
└── web.php
├── .styleci.yml
├── .editorconfig
├── app
├── Http
│ ├── Middleware
│ │ ├── EncryptCookies.php
│ │ ├── cors.php
│ │ ├── CheckForMaintenanceMode.php
│ │ ├── TrimStrings.php
│ │ ├── TrustProxies.php
│ │ ├── Authenticate.php
│ │ ├── VerifyCsrfToken.php
│ │ └── RedirectIfAuthenticated.php
│ ├── Controllers
│ │ ├── Controller.php
│ │ ├── Auth
│ │ │ ├── ForgotPasswordController.php
│ │ │ ├── LoginController.php
│ │ │ ├── ResetPasswordController.php
│ │ │ ├── VerificationController.php
│ │ │ └── RegisterController.php
│ │ └── EnxRtc
│ │ │ └── RoomController.php
│ └── Kernel.php
├── Providers
│ ├── BroadcastServiceProvider.php
│ ├── AppServiceProvider.php
│ ├── AuthServiceProvider.php
│ ├── EventServiceProvider.php
│ └── RouteServiceProvider.php
├── User.php
├── Console
│ └── Kernel.php
├── EnxRtc
│ └── Errors.php
└── Exceptions
│ └── Handler.php
├── webpack.mix.js
├── server.php
├── .env.example
├── config
├── view.php
├── services.php
├── cors.php
├── hashing.php
├── broadcasting.php
├── filesystems.php
├── queue.php
├── logging.php
├── cache.php
├── auth.php
├── mail.php
├── database.php
├── session.php
└── app.php
├── package.json
├── phpunit.xml
├── artisan
├── composer.json
└── readme.md
/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/bootstrap/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/database/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite
2 | *.sqlite-journal
3 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/storage/app/public/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/app/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !public/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/storage/framework/testing/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/views/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/cache/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/sessions/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !data/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.css linguist-vendored
3 | *.scss linguist-vendored
4 | *.js linguist-vendored
5 | CHANGELOG.md export-ignore
6 |
--------------------------------------------------------------------------------
/public/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/logo.png
--------------------------------------------------------------------------------
/public/img/mike.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/mike.png
--------------------------------------------------------------------------------
/public/img/video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/video.png
--------------------------------------------------------------------------------
/public/img/7AF2Qzt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/7AF2Qzt.png
--------------------------------------------------------------------------------
/public/img/enablex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/enablex.png
--------------------------------------------------------------------------------
/public/img/end-call.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/end-call.png
--------------------------------------------------------------------------------
/public/img/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/loader.gif
--------------------------------------------------------------------------------
/public/assets/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/assets/loader.gif
--------------------------------------------------------------------------------
/public/assets/mute48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/assets/mute48.png
--------------------------------------------------------------------------------
/public/assets/sound48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/assets/sound48.png
--------------------------------------------------------------------------------
/public/img/mute-mike.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/mute-mike.png
--------------------------------------------------------------------------------
/public/img/mute-video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/mute-video.png
--------------------------------------------------------------------------------
/public/img/player-bg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/img/player-bg.gif
--------------------------------------------------------------------------------
/public/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/storage/framework/.gitignore:
--------------------------------------------------------------------------------
1 | config.php
2 | routes.php
3 | schedule-*
4 | compiled.php
5 | services.json
6 | events.scanned.php
7 | routes.scanned.php
8 | down
9 |
--------------------------------------------------------------------------------
/public/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/public/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/public/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/public/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel/HEAD/public/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/resources/sass/app.scss:
--------------------------------------------------------------------------------
1 | // Fonts
2 | @import url('https://fonts.googleapis.com/css?family=Nunito');
3 |
4 | // Variables
5 | @import 'variables';
6 |
7 | // Bootstrap
8 | @import '~bootstrap/scss/bootstrap';
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /public/hot
3 | /public/storage
4 | /storage/*.key
5 | /vendor
6 | .env
7 | .phpunit.result.cache
8 | Homestead.json
9 | Homestead.yaml
10 | npm-debug.log
11 | yarn-error.log
12 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | call(UsersTableSeeder::class);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/Http/Middleware/EncryptCookies.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/resources/sass/_variables.scss:
--------------------------------------------------------------------------------
1 | // Body
2 | $body-bg: #f8fafc;
3 |
4 | // Typography
5 | $font-family-sans-serif: 'Nunito', sans-serif;
6 | $font-size-base: 0.9rem;
7 | $line-height-base: 1.6;
8 |
9 | // Colors
10 | $blue: #3490dc;
11 | $indigo: #6574cd;
12 | $purple: #9561e2;
13 | $pink: #f66d9b;
14 | $red: #e3342f;
15 | $orange: #f6993f;
16 | $yellow: #ffed4a;
17 | $green: #38c172;
18 | $teal: #4dc0b5;
19 | $cyan: #6cb2eb;
20 |
--------------------------------------------------------------------------------
/app/Http/Middleware/cors.php:
--------------------------------------------------------------------------------
1 | get('/');
18 |
19 | $response->assertStatus(200);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/public/img/volume_off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/CreatesApplication.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class)->bootstrap();
19 |
20 | return $app;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/Providers/BroadcastServiceProvider.php:
--------------------------------------------------------------------------------
1 | expectsJson()) {
18 | return route('login');
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/Providers/AppServiceProvider.php:
--------------------------------------------------------------------------------
1 | id === (int) $id;
16 | });
17 |
--------------------------------------------------------------------------------
/app/Http/Middleware/VerifyCsrfToken.php:
--------------------------------------------------------------------------------
1 | '« Previous',
17 | 'next' => 'Next »',
18 |
19 | ];
20 |
--------------------------------------------------------------------------------
/routes/console.php:
--------------------------------------------------------------------------------
1 | comment(Inspiring::quote());
18 | })->describe('Display an inspiring quote');
19 |
--------------------------------------------------------------------------------
/routes/web.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 |
10 | $uri = urldecode(
11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
12 | );
13 |
14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the
15 | // built-in PHP web server. This provides a convenient way to test a Laravel
16 | // application without having installed a "real" web server software here.
17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
18 | return false;
19 | }
20 |
21 | require_once __DIR__.'/public/index.php';
22 |
--------------------------------------------------------------------------------
/app/Http/Middleware/RedirectIfAuthenticated.php:
--------------------------------------------------------------------------------
1 | check()) {
21 | return redirect('/home');
22 | }
23 |
24 | return $next($request);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/resources/js/components/ExampleComponent.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | I'm an example component.
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
24 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 |
3 | Options -MultiViews -Indexes
4 |
5 |
6 | RewriteEngine On
7 |
8 | # Handle Authorization Header
9 | RewriteCond %{HTTP:Authorization} .
10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
11 |
12 | # Redirect Trailing Slashes If Not A Folder...
13 | RewriteCond %{REQUEST_FILENAME} !-d
14 | RewriteCond %{REQUEST_URI} (.+)/$
15 | RewriteRule ^ %1 [L,R=307]
16 |
17 | # Handle Front Controller...
18 | RewriteCond %{REQUEST_FILENAME} !-d
19 | RewriteCond %{REQUEST_FILENAME} !-f
20 | RewriteRule ^ index.php [L]
21 |
22 |
--------------------------------------------------------------------------------
/resources/lang/en/auth.php:
--------------------------------------------------------------------------------
1 | 'These credentials do not match our records.',
17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
18 |
19 | ];
20 |
--------------------------------------------------------------------------------
/app/Providers/AuthServiceProvider.php:
--------------------------------------------------------------------------------
1 | 'App\Policies\ModelPolicy',
17 | ];
18 |
19 | /**
20 | * Register any authentication / authorization services.
21 | *
22 | * @return void
23 | */
24 | public function boot()
25 | {
26 | $this->registerPolicies();
27 |
28 | //
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/public/img/volume_on.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/migrations/2014_10_12_100000_create_password_resets_table.php:
--------------------------------------------------------------------------------
1 | string('email')->index();
18 | $table->string('token');
19 | $table->timestamp('created_at')->nullable();
20 | });
21 | }
22 |
23 | /**
24 | * Reverse the migrations.
25 | *
26 | * @return void
27 | */
28 | public function down()
29 | {
30 | Schema::dropIfExists('password_resets');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/Providers/EventServiceProvider.php:
--------------------------------------------------------------------------------
1 | [
19 | SendEmailVerificationNotification::class,
20 | ],
21 | ];
22 |
23 | /**
24 | * Register any events for your application.
25 | *
26 | * @return void
27 | */
28 | public function boot()
29 | {
30 | parent::boot();
31 |
32 | //
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/resources/lang/en/passwords.php:
--------------------------------------------------------------------------------
1 | 'Passwords must be at least eight characters and match the confirmation.',
17 | 'reset' => 'Your password has been reset!',
18 | 'sent' => 'We have e-mailed your password reset link!',
19 | 'token' => 'This password reset token is invalid.',
20 | 'user' => "We can't find a user with that e-mail address.",
21 |
22 | ];
23 |
--------------------------------------------------------------------------------
/app/User.php:
--------------------------------------------------------------------------------
1 | 'datetime',
38 | ];
39 | }
40 |
--------------------------------------------------------------------------------
/database/factories/UserFactory.php:
--------------------------------------------------------------------------------
1 | define(User::class, function (Faker $faker) {
20 | return [
21 | 'name' => $faker->name,
22 | 'email' => $faker->unique()->safeEmail,
23 | 'email_verified_at' => now(),
24 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
25 | 'remember_token' => Str::random(10),
26 | ];
27 | });
28 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/ForgotPasswordController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/database/migrations/2014_10_12_000000_create_users_table.php:
--------------------------------------------------------------------------------
1 | bigIncrements('id');
18 | $table->string('name');
19 | $table->string('email')->unique();
20 | $table->timestamp('email_verified_at')->nullable();
21 | $table->string('password');
22 | $table->rememberToken();
23 | $table->timestamps();
24 | });
25 | }
26 |
27 | /**
28 | * Reverse the migrations.
29 | *
30 | * @return void
31 | */
32 | public function down()
33 | {
34 | Schema::dropIfExists('users');
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/Console/Kernel.php:
--------------------------------------------------------------------------------
1 | command('inspire')
28 | // ->hourly();
29 | }
30 |
31 | /**
32 | * Register the commands for the application.
33 | *
34 | * @return void
35 | */
36 | protected function commands()
37 | {
38 | $this->load(__DIR__.'/Commands');
39 |
40 | require base_path('routes/console.php');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | APP_NAME=Laravel
2 | APP_ENV=local
3 | APP_KEY=
4 | APP_DEBUG=true
5 | APP_URL=http://localhost
6 |
7 | LOG_CHANNEL=stack
8 |
9 | DB_CONNECTION=mysql
10 | DB_HOST=127.0.0.1
11 | DB_PORT=3306
12 | DB_DATABASE=homestead
13 | DB_USERNAME=homestead
14 | DB_PASSWORD=secret
15 |
16 | BROADCAST_DRIVER=log
17 | CACHE_DRIVER=file
18 | QUEUE_CONNECTION=sync
19 | SESSION_DRIVER=file
20 | SESSION_LIFETIME=120
21 |
22 | REDIS_HOST=127.0.0.1
23 | REDIS_PASSWORD=null
24 | REDIS_PORT=6379
25 |
26 | MAIL_DRIVER=smtp
27 | MAIL_HOST=smtp.mailtrap.io
28 | MAIL_PORT=2525
29 | MAIL_USERNAME=null
30 | MAIL_PASSWORD=null
31 | MAIL_ENCRYPTION=null
32 |
33 | AWS_ACCESS_KEY_ID=
34 | AWS_SECRET_ACCESS_KEY=
35 | AWS_DEFAULT_REGION=us-east-1
36 | AWS_BUCKET=
37 |
38 | PUSHER_APP_ID=
39 | PUSHER_APP_KEY=
40 | PUSHER_APP_SECRET=
41 | PUSHER_APP_CLUSTER=mt1
42 |
43 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
44 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
45 |
46 | ENABLEX_API_URL = "https://api.enablex.io/v1"
47 | ENABLEX_APP_ID = "YOUR_APP_ID"
48 | ENABLEX_APP_KEY = "YOUR_APP_KEY"
49 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/LoginController.php:
--------------------------------------------------------------------------------
1 | middleware('guest')->except('logout');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/public/js/util.js:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////
2 | //
3 | // File: util.js
4 | // To create a token for a room
5 | //
6 | /////////////////////////////////////////////////////
7 |
8 | var createToken = function (details, callback) {
9 | var xhttp = new XMLHttpRequest();
10 | xhttp.onreadystatechange = function () {
11 | if (this.readyState == 4 && this.status == 200) {
12 | var response = JSON.parse(this.responseText);
13 | if(response.error){
14 | $.toast({
15 | heading: 'Error',
16 | text: response.error,
17 | showHideTransition: 'fade',
18 | icon: 'error',
19 | position: 'top-right',
20 | showHideTransition: 'slide'
21 | });
22 | }
23 | else {
24 | callback(response.token);
25 | }
26 | }
27 | };
28 | xhttp.open("POST", "/api/createToken/", true);
29 | xhttp.setRequestHeader('Content-Type', 'application/json');
30 | xhttp.send(JSON.stringify(details));
31 | };
32 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/ResetPasswordController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/config/view.php:
--------------------------------------------------------------------------------
1 | [
17 | resource_path('views'),
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Compiled View Path
23 | |--------------------------------------------------------------------------
24 | |
25 | | This option determines where all the compiled Blade templates will be
26 | | stored for your application. Typically, this is within the storage
27 | | directory. However, as usual, you are free to change this value.
28 | |
29 | */
30 |
31 | 'compiled' => env(
32 | 'VIEW_COMPILED_PATH',
33 | realpath(storage_path('framework/views'))
34 | ),
35 |
36 | ];
37 |
--------------------------------------------------------------------------------
/public/js/room.js:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////
2 | //
3 | // File: room.js
4 | // This function fetches Room-Information to which the user is logging in
5 | //
6 | // Last Updated: 29-11-2018
7 | // Reformat, Indentation, Inline Comments
8 | //
9 | /////////////////////////////////////////////////////
10 |
11 |
12 | var joinRoom = function (roomName, callback) {
13 | var xhttp = new XMLHttpRequest();
14 | xhttp.onreadystatechange = function () {
15 | if (this.readyState == 4 && this.status == 200) {
16 | var response = JSON.parse(this.responseText);
17 | if(response.error){
18 | $.toast({
19 | heading: 'Error',
20 | text: response.error,
21 | showHideTransition: 'fade',
22 | icon: 'error',
23 | position: 'top-right',
24 | showHideTransition: 'slide'
25 | });
26 | }
27 | else {
28 | callback(response.room);
29 | }
30 |
31 |
32 | }
33 | };
34 | xhttp.open("GET", "../api/getRoom/" + roomName, true);
35 | xhttp.send();
36 | };
37 |
38 |
--------------------------------------------------------------------------------
/app/EnxRtc/Errors.php:
--------------------------------------------------------------------------------
1 | ["result" => "4001", "error" => "Required parameter missing"],
9 | 4002 => ["result" => "4002", "error" => "Required JSON Body missing"],
10 | 4003 => ["result" => "4003", "error" => "JSON Body Error"],
11 | 4004 => ["result" => "4004", "error" => "Required Key missing in JSON Body"],
12 | 4005 => ["result" => "4005", "error" => "Invalid Key value JSON Body"],
13 | 4006 => ["result" => "4006", "error" => "Forbidden. Not privileged to access data"],
14 | 1001 => ["result" => "1001", "error" => "Authentication failed"],
15 | 1002 => ["result" => "1002", "error" => "Requested Data not found"],
16 | 1003 => ["result" => "1003", "error" => "Mailing Error"],
17 | 1004 => ["result" => "1004", "error" => "Data Error"],
18 | 5001 => ["result" => "5001", "error" => "Invalid HTTP Request"],
19 | 5001 => ["result" => "5002", "error" => "System Settings/DB Setup Issues"],
20 |
21 | ];
22 |
23 | public static function getError($code)
24 | {
25 | return self::$errors[$code];
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "npm run development",
5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
6 | "watch": "npm run development -- --watch",
7 | "watch-poll": "npm run watch -- --watch-poll",
8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
9 | "prod": "npm run production",
10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
11 | },
12 | "devDependencies": {
13 | "axios": "^0.18",
14 | "bootstrap": "^4.1.0",
15 | "cross-env": "^5.1",
16 | "jquery": "^3.2",
17 | "laravel-mix": "^4.0.7",
18 | "lodash": "^4.17.5",
19 | "popper.js": "^1.12",
20 | "resolve-url-loader": "^2.3.1",
21 | "sass": "^1.15.2",
22 | "sass-loader": "^7.1.0",
23 | "vue": "^2.5.17"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/resources/js/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * First we will load all of this project's JavaScript dependencies which
3 | * includes Vue and other libraries. It is a great starting point when
4 | * building robust, powerful web applications using Vue and Laravel.
5 | */
6 |
7 | require('./bootstrap');
8 |
9 | window.Vue = require('vue');
10 |
11 | /**
12 | * The following block of code may be used to automatically register your
13 | * Vue components. It will recursively scan this directory for the Vue
14 | * components and automatically register them with their "basename".
15 | *
16 | * Eg. ./components/ExampleComponent.vue ->
17 | */
18 |
19 | // const files = require.context('./', true, /\.vue$/i);
20 | // files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default));
21 |
22 | Vue.component('example-component', require('./components/ExampleComponent.vue').default);
23 |
24 | /**
25 | * Next, we will create a fresh Vue application instance and attach it to
26 | * the page. Then, you may begin adding components to this application
27 | * or customize the JavaScript scaffolding to fit your unique needs.
28 | */
29 |
30 | const app = new Vue({
31 | el: '#app',
32 | });
33 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/VerificationController.php:
--------------------------------------------------------------------------------
1 | middleware('auth');
38 | $this->middleware('signed')->only('verify');
39 | $this->middleware('throttle:6,1')->only('verify', 'resend');
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | ./tests/Unit
14 |
15 |
16 |
17 | ./tests/Feature
18 |
19 |
20 |
21 |
22 | ./app
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/public/web.config:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/config/services.php:
--------------------------------------------------------------------------------
1 | [
18 | 'domain' => env('MAILGUN_DOMAIN'),
19 | 'secret' => env('MAILGUN_SECRET'),
20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
21 | ],
22 |
23 | 'postmark' => [
24 | 'token' => env('POSTMARK_TOKEN'),
25 | ],
26 |
27 | 'ses' => [
28 | 'key' => env('AWS_ACCESS_KEY_ID'),
29 | 'secret' => env('AWS_SECRET_ACCESS_KEY'),
30 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
31 | ],
32 |
33 | 'sparkpost' => [
34 | 'secret' => env('SPARKPOST_SECRET'),
35 | ],
36 |
37 | 'stripe' => [
38 | 'model' => App\User::class,
39 | 'key' => env('STRIPE_KEY'),
40 | 'secret' => env('STRIPE_SECRET'),
41 | 'webhook' => [
42 | 'secret' => env('STRIPE_WEBHOOK_SECRET'),
43 | 'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300),
44 | ],
45 | ],
46 |
47 | ];
48 |
--------------------------------------------------------------------------------
/config/cors.php:
--------------------------------------------------------------------------------
1 | Spatie\Cors\CorsProfile\DefaultProfile::class,
14 |
15 | /*
16 | * This configuration is used by `DefaultProfile`.
17 | */
18 | 'default_profile' => [
19 |
20 | 'allow_credentials' => true,
21 |
22 | 'allow_origins' => [
23 | '*',
24 | 'https://localhost:8080'
25 | ],
26 |
27 | 'allow_methods' => [
28 | 'POST',
29 | 'GET',
30 | 'OPTIONS',
31 | 'PUT',
32 | 'PATCH',
33 | 'DELETE',
34 | ],
35 |
36 | 'allow_headers' => [
37 | 'Content-Type',
38 | 'X-Auth-Token',
39 | 'Origin',
40 | 'Authorization',
41 | ],
42 |
43 | 'expose_headers' => [
44 | 'Cache-Control',
45 | 'Content-Language',
46 | 'Content-Type',
47 | 'Expires',
48 | 'Last-Modified',
49 | 'Pragma',
50 | ],
51 |
52 | 'forbidden_response' => [
53 | 'message' => 'Forbidden (cors).',
54 | 'status' => 403,
55 | ],
56 |
57 | /*
58 | * Preflight request will respond with value for the max age header.
59 | */
60 | 'max_age' => 60 * 60 * 24,
61 | ],
62 | ];
63 |
--------------------------------------------------------------------------------
/public/img/video_on.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/config/hashing.php:
--------------------------------------------------------------------------------
1 | 'bcrypt',
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Bcrypt Options
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may specify the configuration options that should be used when
26 | | passwords are hashed using the Bcrypt algorithm. This will allow you
27 | | to control the amount of time it takes to hash the given password.
28 | |
29 | */
30 |
31 | 'bcrypt' => [
32 | 'rounds' => env('BCRYPT_ROUNDS', 10),
33 | ],
34 |
35 | /*
36 | |--------------------------------------------------------------------------
37 | | Argon Options
38 | |--------------------------------------------------------------------------
39 | |
40 | | Here you may specify the configuration options that should be used when
41 | | passwords are hashed using the Argon algorithm. These will allow you
42 | | to control the amount of time it takes to hash the given password.
43 | |
44 | */
45 |
46 | 'argon' => [
47 | 'memory' => 1024,
48 | 'threads' => 2,
49 | 'time' => 2,
50 | ],
51 |
52 | ];
53 |
--------------------------------------------------------------------------------
/bootstrap/app.php:
--------------------------------------------------------------------------------
1 | singleton(
30 | Illuminate\Contracts\Http\Kernel::class,
31 | App\Http\Kernel::class
32 | );
33 |
34 | $app->singleton(
35 | Illuminate\Contracts\Console\Kernel::class,
36 | App\Console\Kernel::class
37 | );
38 |
39 | $app->singleton(
40 | Illuminate\Contracts\Debug\ExceptionHandler::class,
41 | App\Exceptions\Handler::class
42 | );
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Return The Application
47 | |--------------------------------------------------------------------------
48 | |
49 | | This script returns the application instance. The instance is given to
50 | | the calling script so we can separate the building of the instances
51 | | from the actual running of the application and sending responses.
52 | |
53 | */
54 |
55 | return $app;
56 |
--------------------------------------------------------------------------------
/config/broadcasting.php:
--------------------------------------------------------------------------------
1 | env('BROADCAST_DRIVER', 'null'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Broadcast Connections
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may define all of the broadcast connections that will be used
26 | | to broadcast events to other systems or over websockets. Samples of
27 | | each available type of connection are provided inside this array.
28 | |
29 | */
30 |
31 | 'connections' => [
32 |
33 | 'pusher' => [
34 | 'driver' => 'pusher',
35 | 'key' => env('PUSHER_APP_KEY'),
36 | 'secret' => env('PUSHER_APP_SECRET'),
37 | 'app_id' => env('PUSHER_APP_ID'),
38 | 'options' => [
39 | 'cluster' => env('PUSHER_APP_CLUSTER'),
40 | 'encrypted' => true,
41 | ],
42 | ],
43 |
44 | 'redis' => [
45 | 'driver' => 'redis',
46 | 'connection' => 'default',
47 | ],
48 |
49 | 'log' => [
50 | 'driver' => 'log',
51 | ],
52 |
53 | 'null' => [
54 | 'driver' => 'null',
55 | ],
56 |
57 | ],
58 |
59 | ];
60 |
--------------------------------------------------------------------------------
/app/Providers/RouteServiceProvider.php:
--------------------------------------------------------------------------------
1 | mapApiRoutes();
39 |
40 | $this->mapWebRoutes();
41 |
42 | //
43 | }
44 |
45 | /**
46 | * Define the "web" routes for the application.
47 | *
48 | * These routes all receive session state, CSRF protection, etc.
49 | *
50 | * @return void
51 | */
52 | protected function mapWebRoutes()
53 | {
54 | Route::middleware('web')
55 | ->namespace($this->namespace)
56 | ->group(base_path('routes/web.php'));
57 | }
58 |
59 | /**
60 | * Define the "api" routes for the application.
61 | *
62 | * These routes are typically stateless.
63 | *
64 | * @return void
65 | */
66 | protected function mapApiRoutes()
67 | {
68 | Route::prefix('api')
69 | ->middleware('api')
70 | ->namespace($this->namespace)
71 | ->group(base_path('routes/api.php'));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/artisan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | make(Illuminate\Contracts\Console\Kernel::class);
34 |
35 | $status = $kernel->handle(
36 | $input = new Symfony\Component\Console\Input\ArgvInput,
37 | new Symfony\Component\Console\Output\ConsoleOutput
38 | );
39 |
40 | /*
41 | |--------------------------------------------------------------------------
42 | | Shutdown The Application
43 | |--------------------------------------------------------------------------
44 | |
45 | | Once Artisan has finished running, we will fire off the shutdown events
46 | | so that any final work may be done by the application before we shut
47 | | down the process. This is the last thing to happen to the request.
48 | |
49 | */
50 |
51 | $kernel->terminate($input, $status);
52 |
53 | exit($status);
54 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "laravel/laravel",
3 | "type": "project",
4 | "description": "The Laravel Framework.",
5 | "keywords": [
6 | "framework",
7 | "laravel"
8 | ],
9 | "license": "MIT",
10 | "require": {
11 | "php": "^7.1.3",
12 | "fideloper/proxy": "^4.0",
13 | "guzzlehttp/guzzle": "~6.0",
14 | "laravel/framework": "5.8.*",
15 | "laravel/tinker": "^1.0",
16 | "spatie/laravel-cors": "^1.5"
17 | },
18 | "require-dev": {
19 | "beyondcode/laravel-dump-server": "^1.0",
20 | "filp/whoops": "^2.0",
21 | "fzaninotto/faker": "^1.4",
22 | "mockery/mockery": "^1.0",
23 | "nunomaduro/collision": "^3.0",
24 | "phpunit/phpunit": "^7.5"
25 | },
26 | "config": {
27 | "optimize-autoloader": true,
28 | "preferred-install": "dist",
29 | "sort-packages": true
30 | },
31 | "extra": {
32 | "laravel": {
33 | "dont-discover": []
34 | }
35 | },
36 | "autoload": {
37 | "psr-4": {
38 | "App\\": "app/"
39 | },
40 | "classmap": [
41 | "database/seeds",
42 | "database/factories"
43 | ]
44 | },
45 | "autoload-dev": {
46 | "psr-4": {
47 | "Tests\\": "tests/"
48 | }
49 | },
50 | "minimum-stability": "dev",
51 | "prefer-stable": true,
52 | "scripts": {
53 | "post-autoload-dump": [
54 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
55 | "@php artisan package:discover --ansi"
56 | ],
57 | "post-root-package-install": [
58 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
59 | ],
60 | "post-create-project-cmd": [
61 | "@php artisan key:generate --ansi"
62 | ]
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/public/img/video_off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/Exceptions/Handler.php:
--------------------------------------------------------------------------------
1 | json([
54 | 'error' => true,
55 | 'message' => 'Method is not allowed for the requested route',
56 | ], 405);
57 | }
58 | elseif($exception instanceof NotFoundHttpException){
59 | return response()->json([
60 | 'error' => true,
61 | 'message' => 'Intended route is not found.',
62 | ], 405);
63 | }
64 |
65 | return parent::render($request, $exception);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/resources/js/bootstrap.js:
--------------------------------------------------------------------------------
1 | window._ = require('lodash');
2 |
3 | /**
4 | * We'll load jQuery and the Bootstrap jQuery plugin which provides support
5 | * for JavaScript based Bootstrap features such as modals and tabs. This
6 | * code may be modified to fit the specific needs of your application.
7 | */
8 |
9 | try {
10 | window.Popper = require('popper.js').default;
11 | window.$ = window.jQuery = require('jquery');
12 |
13 | require('bootstrap');
14 | } catch (e) {}
15 |
16 | /**
17 | * We'll load the axios HTTP library which allows us to easily issue requests
18 | * to our Laravel back-end. This library automatically handles sending the
19 | * CSRF token as a header based on the value of the "XSRF" token cookie.
20 | */
21 |
22 | window.axios = require('axios');
23 |
24 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
25 |
26 | /**
27 | * Next we will register the CSRF Token as a common header with Axios so that
28 | * all outgoing HTTP requests automatically have it attached. This is just
29 | * a simple convenience so we don't have to attach every token manually.
30 | */
31 |
32 | let token = document.head.querySelector('meta[name="csrf-token"]');
33 |
34 | if (token) {
35 | window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
36 | } else {
37 | console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
38 | }
39 |
40 | /**
41 | * Echo exposes an expressive API for subscribing to channels and listening
42 | * for events that are broadcast by Laravel. Echo and event broadcasting
43 | * allows your team to easily build robust real-time web applications.
44 | */
45 |
46 | // import Echo from 'laravel-echo'
47 |
48 | // window.Pusher = require('pusher-js');
49 |
50 | // window.Echo = new Echo({
51 | // broadcaster: 'pusher',
52 | // key: process.env.MIX_PUSHER_APP_KEY,
53 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER,
54 | // encrypted: true
55 | // });
56 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | define('LARAVEL_START', microtime(true));
12 |
13 | /*
14 | |--------------------------------------------------------------------------
15 | | Register The Auto Loader
16 | |--------------------------------------------------------------------------
17 | |
18 | | Composer provides a convenient, automatically generated class loader for
19 | | our application. We just need to utilize it! We'll simply require it
20 | | into the script here so that we don't have to worry about manual
21 | | loading any of our classes later on. It feels great to relax.
22 | |
23 | */
24 |
25 | require __DIR__.'/../vendor/autoload.php';
26 |
27 | /*
28 | |--------------------------------------------------------------------------
29 | | Turn On The Lights
30 | |--------------------------------------------------------------------------
31 | |
32 | | We need to illuminate PHP development, so let us turn on the lights.
33 | | This bootstraps the framework and gets it ready for use, then it
34 | | will load up this application so that we can run it and send
35 | | the responses back to the browser and delight our users.
36 | |
37 | */
38 |
39 | $app = require_once __DIR__.'/../bootstrap/app.php';
40 |
41 | /*
42 | |--------------------------------------------------------------------------
43 | | Run The Application
44 | |--------------------------------------------------------------------------
45 | |
46 | | Once we have the application, we can handle the incoming request
47 | | through the kernel, and send the associated response back to
48 | | the client's browser allowing them to enjoy the creative
49 | | and wonderful application we have prepared for them.
50 | |
51 | */
52 |
53 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
54 |
55 | $response = $kernel->handle(
56 | $request = Illuminate\Http\Request::capture()
57 | );
58 |
59 | $response->send();
60 |
61 | $kernel->terminate($request, $response);
62 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/RegisterController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
41 | }
42 |
43 | /**
44 | * Get a validator for an incoming registration request.
45 | *
46 | * @param array $data
47 | * @return \Illuminate\Contracts\Validation\Validator
48 | */
49 | protected function validator(array $data)
50 | {
51 | return Validator::make($data, [
52 | 'name' => ['required', 'string', 'max:255'],
53 | 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
54 | 'password' => ['required', 'string', 'min:8', 'confirmed'],
55 | ]);
56 | }
57 |
58 | /**
59 | * Create a new user instance after a valid registration.
60 | *
61 | * @param array $data
62 | * @return \App\User
63 | */
64 | protected function create(array $data)
65 | {
66 | return User::create([
67 | 'name' => $data['name'],
68 | 'email' => $data['email'],
69 | 'password' => Hash::make($data['password']),
70 | ]);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/config/filesystems.php:
--------------------------------------------------------------------------------
1 | env('FILESYSTEM_DRIVER', 'local'),
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Default Cloud Filesystem Disk
21 | |--------------------------------------------------------------------------
22 | |
23 | | Many applications store files both locally and in the cloud. For this
24 | | reason, you may specify a default "cloud" driver here. This driver
25 | | will be bound as the Cloud disk implementation in the container.
26 | |
27 | */
28 |
29 | 'cloud' => env('FILESYSTEM_CLOUD', 's3'),
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Filesystem Disks
34 | |--------------------------------------------------------------------------
35 | |
36 | | Here you may configure as many filesystem "disks" as you wish, and you
37 | | may even configure multiple disks of the same driver. Defaults have
38 | | been setup for each driver as an example of the required options.
39 | |
40 | | Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
41 | |
42 | */
43 |
44 | 'disks' => [
45 |
46 | 'local' => [
47 | 'driver' => 'local',
48 | 'root' => storage_path('app'),
49 | ],
50 |
51 | 'public' => [
52 | 'driver' => 'local',
53 | 'root' => storage_path('app/public'),
54 | 'url' => env('APP_URL').'/storage',
55 | 'visibility' => 'public',
56 | ],
57 |
58 | 's3' => [
59 | 'driver' => 's3',
60 | 'key' => env('AWS_ACCESS_KEY_ID'),
61 | 'secret' => env('AWS_SECRET_ACCESS_KEY'),
62 | 'region' => env('AWS_DEFAULT_REGION'),
63 | 'bucket' => env('AWS_BUCKET'),
64 | 'url' => env('AWS_URL'),
65 | ],
66 |
67 | ],
68 |
69 | ];
70 |
--------------------------------------------------------------------------------
/public/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
30 |
--------------------------------------------------------------------------------
/resources/views/index.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Sample App: 1-To-1 Conference using EnableX and Laravel
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Loading....
16 |
47 |
48 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/resources/views/confo.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Sample App: 1-To-1 Conference using EnableX and Laravel
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
40 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/config/queue.php:
--------------------------------------------------------------------------------
1 | env('QUEUE_CONNECTION', 'sync'),
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Queue Connections
21 | |--------------------------------------------------------------------------
22 | |
23 | | Here you may configure the connection information for each server that
24 | | is used by your application. A default configuration has been added
25 | | for each back-end shipped with Laravel. You are free to add more.
26 | |
27 | | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
28 | |
29 | */
30 |
31 | 'connections' => [
32 |
33 | 'sync' => [
34 | 'driver' => 'sync',
35 | ],
36 |
37 | 'database' => [
38 | 'driver' => 'database',
39 | 'table' => 'jobs',
40 | 'queue' => 'default',
41 | 'retry_after' => 90,
42 | ],
43 |
44 | 'beanstalkd' => [
45 | 'driver' => 'beanstalkd',
46 | 'host' => 'localhost',
47 | 'queue' => 'default',
48 | 'retry_after' => 90,
49 | 'block_for' => 0,
50 | ],
51 |
52 | 'sqs' => [
53 | 'driver' => 'sqs',
54 | 'key' => env('AWS_ACCESS_KEY_ID'),
55 | 'secret' => env('AWS_SECRET_ACCESS_KEY'),
56 | 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
57 | 'queue' => env('SQS_QUEUE', 'your-queue-name'),
58 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
59 | ],
60 |
61 | 'redis' => [
62 | 'driver' => 'redis',
63 | 'connection' => 'default',
64 | 'queue' => env('REDIS_QUEUE', 'default'),
65 | 'retry_after' => 90,
66 | 'block_for' => null,
67 | ],
68 |
69 | ],
70 |
71 | /*
72 | |--------------------------------------------------------------------------
73 | | Failed Queue Jobs
74 | |--------------------------------------------------------------------------
75 | |
76 | | These options configure the behavior of failed queue job logging so you
77 | | can control which database and table are used to store the jobs that
78 | | have failed. You may change them to any database / table you wish.
79 | |
80 | */
81 |
82 | 'failed' => [
83 | 'database' => env('DB_CONNECTION', 'mysql'),
84 | 'table' => 'failed_jobs',
85 | ],
86 |
87 | ];
88 |
--------------------------------------------------------------------------------
/config/logging.php:
--------------------------------------------------------------------------------
1 | env('LOG_CHANNEL', 'stack'),
20 |
21 | /*
22 | |--------------------------------------------------------------------------
23 | | Log Channels
24 | |--------------------------------------------------------------------------
25 | |
26 | | Here you may configure the log channels for your application. Out of
27 | | the box, Laravel uses the Monolog PHP logging library. This gives
28 | | you a variety of powerful log handlers / formatters to utilize.
29 | |
30 | | Available Drivers: "single", "daily", "slack", "syslog",
31 | | "errorlog", "monolog",
32 | | "custom", "stack"
33 | |
34 | */
35 |
36 | 'channels' => [
37 | 'stack' => [
38 | 'driver' => 'stack',
39 | 'channels' => ['daily'],
40 | 'ignore_exceptions' => false,
41 | ],
42 |
43 | 'single' => [
44 | 'driver' => 'single',
45 | 'path' => storage_path('logs/laravel.log'),
46 | 'level' => 'debug',
47 | ],
48 |
49 | 'daily' => [
50 | 'driver' => 'daily',
51 | 'path' => storage_path('logs/laravel.log'),
52 | 'level' => 'debug',
53 | 'days' => 14,
54 | ],
55 |
56 | 'slack' => [
57 | 'driver' => 'slack',
58 | 'url' => env('LOG_SLACK_WEBHOOK_URL'),
59 | 'username' => 'Laravel Log',
60 | 'emoji' => ':boom:',
61 | 'level' => 'critical',
62 | ],
63 |
64 | 'papertrail' => [
65 | 'driver' => 'monolog',
66 | 'level' => 'debug',
67 | 'handler' => SyslogUdpHandler::class,
68 | 'handler_with' => [
69 | 'host' => env('PAPERTRAIL_URL'),
70 | 'port' => env('PAPERTRAIL_PORT'),
71 | ],
72 | ],
73 |
74 | 'stderr' => [
75 | 'driver' => 'monolog',
76 | 'handler' => StreamHandler::class,
77 | 'formatter' => env('LOG_STDERR_FORMATTER'),
78 | 'with' => [
79 | 'stream' => 'php://stderr',
80 | ],
81 | ],
82 |
83 | 'syslog' => [
84 | 'driver' => 'syslog',
85 | 'level' => 'debug',
86 | ],
87 |
88 | 'errorlog' => [
89 | 'driver' => 'errorlog',
90 | 'level' => 'debug',
91 | ],
92 | ],
93 |
94 | ];
95 |
--------------------------------------------------------------------------------
/public/assets/css/dark-knight.css:
--------------------------------------------------------------------------------
1 | .dark-knight_vcx_player{
2 | width:100%;
3 | height:100%;
4 | position:relative;
5 | background-color:black;
6 | overflow:hidden;
7 | border-radius: 8px 8px 8px 8px;
8 | }
9 | .dark-knight_vcx_player_loader{
10 | width:100%;
11 | height:100%;
12 | position:absolute;
13 | }
14 | .dark-knight_vcx_player_screen_saver{
15 | width:100%;
16 | height:100%;
17 | position:absolute;
18 | z-index: 1;
19 | }
20 | .dark-knight_vcx_stream{
21 | width:100%;
22 | height:100%;
23 | position:absolute;
24 | object-fit: fill;
25 | }
26 | .vcx_toolbar_auto div {
27 | display: none;
28 | }
29 |
30 | .vcx_toolbar_auto:hover > div {
31 | display: block;
32 | }
33 | .dark-knight_vcx_bar{
34 | height:100%;
35 | width:100%;
36 | position:absolute;
37 | }
38 | .dark-knight_vcx_subbar_bottom{
39 | width:100%;
40 | height:15%;
41 | max-height:30px;
42 | color:#aaa;
43 | font-size: 0.9em;
44 | position:absolute;
45 | bottom:0;
46 | border-radius: 8px 8px 8px 8px;
47 | text-shadow: 2px 2px 0 #222;
48 | background: linear-gradient( to bottom, #444, #222 );
49 | background-position: bottom;
50 | z-index: 2;
51 | background-position: bottom;
52 | }
53 | .dark-knight_vcx_subbar_top{
54 | width:100%;
55 | height:15%;
56 | max-height:30px;
57 | color:#aaa;
58 | font-size: 0.9em;
59 | position:absolute;
60 | top:0;
61 | border-radius: 8px 8px 8px 8px;
62 | background: linear-gradient( to bottom, #444, #222 );
63 | text-shadow: 2px 2px 0 #222;
64 | background-position: top !important;
65 | z-index: 2;
66 | background-position: bottom;
67 | }
68 | .dark-knight_vcx_subbar_left{
69 | width:15%;
70 | height:100%;
71 | max-width:30px;
72 | color:#aaa;
73 | font-size: 0.9em;
74 | position:absolute;
75 | left:0;
76 | border-radius: 8px 8px 8px 8px;
77 | background: linear-gradient( to bottom, #444, #222 );
78 | background-position: bottom;
79 | }
80 | .dark-knight_vcx_subbar_right{
81 | width:15%;
82 | height:100%;
83 | font-size: 0.9em;
84 | max-width:30px;
85 | color:#aaa;
86 | position:absolute;
87 | right:0;
88 | border-radius: 8px 8px 8px 8px;
89 | background-position: bottom;
90 | }
91 | .dark-knight_icon{
92 | margin:7px;
93 | max-width:30px;
94 | cursor:pointer
95 | }
96 | .dark-knight_icon:hover{
97 | color:#ccc;
98 | }
99 | .dark-knight_icon_record{
100 | margin:7px;
101 | max-width:30px;
102 | color:#f00;
103 | cursor:pointer
104 | }
105 | .dark-knight_icon_play{
106 | font-size: 1em;
107 | margin-left: 12px;
108 | }
109 | .dark-knight_brand_logo{
110 | max-width: 30px;
111 | max-height: 20px;
112 | cursor: pointer;
113 | position: absolute;
114 | right: 0px;
115 | margin: 5px 11px 5px 5px;
116 | }
117 | .dark-knight_theater_view{
118 | margin: 0px !important;
119 | width: 100% !important;
120 | height: 500px !important;
121 | }
122 | .dark-knight_full_view{
123 | width: 100% !important;
124 | height: 100% !important;
125 | margin: 0px !important;
126 | top: 0px;
127 | left: 0px;
128 | position: fixed !important;
129 | z-index : 3;
130 | }
--------------------------------------------------------------------------------
/app/Http/Kernel.php:
--------------------------------------------------------------------------------
1 | [
32 | \App\Http\Middleware\EncryptCookies::class,
33 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
34 | \Illuminate\Session\Middleware\StartSession::class,
35 | // \Illuminate\Session\Middleware\AuthenticateSession::class,
36 | \Illuminate\View\Middleware\ShareErrorsFromSession::class,
37 | \App\Http\Middleware\VerifyCsrfToken::class,
38 | \Illuminate\Routing\Middleware\SubstituteBindings::class,
39 | ],
40 |
41 | 'api' => [
42 | 'throttle:60,1',
43 | 'bindings',
44 | \Spatie\Cors\Cors::class,
45 | ],
46 | ];
47 |
48 | /**
49 | * The application's route middleware.
50 | *
51 | * These middleware may be assigned to groups or used individually.
52 | *
53 | * @var array
54 | */
55 | protected $routeMiddleware = [
56 | 'auth' => \App\Http\Middleware\Authenticate::class,
57 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
58 | 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
59 | 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
60 | 'can' => \Illuminate\Auth\Middleware\Authorize::class,
61 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
62 | 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
63 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
64 | 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
65 | ];
66 |
67 | /**
68 | * The priority-sorted list of middleware.
69 | *
70 | * This forces non-global middleware to always be in the given order.
71 | *
72 | * @var array
73 | */
74 | protected $middlewarePriority = [
75 | \Illuminate\Session\Middleware\StartSession::class,
76 | \Illuminate\View\Middleware\ShareErrorsFromSession::class,
77 | \App\Http\Middleware\Authenticate::class,
78 | \Illuminate\Session\Middleware\AuthenticateSession::class,
79 | \Illuminate\Routing\Middleware\SubstituteBindings::class,
80 | \Illuminate\Auth\Middleware\Authorize::class,
81 | ];
82 | }
83 |
--------------------------------------------------------------------------------
/public/assets/css/classic.css:
--------------------------------------------------------------------------------
1 | .classic_vcx_player{
2 | width:104%;
3 | height:100%;
4 | position:relative;
5 | background-color:black;
6 | overflow:hidden;
7 | }
8 | .classic_vcx_player_loader{
9 | width:100%;
10 | height:100%;
11 | position:absolute;
12 | }
13 | .classic_vcx_player_screen_saver{
14 | width:100%;
15 | height:100%;
16 | position:absolute;
17 | z-index: 1;
18 | }
19 | .classic_vcx_stream{
20 | width:100%;
21 | height:100%;
22 | position:absolute;
23 | }
24 | .classic_vcx_bar{
25 | height:100%;
26 | width:100%;
27 | position:absolute;
28 | }
29 | .classic_vcx_subbar_bottom{
30 | width:100%;
31 | height: 16.5%;
32 | max-height: 60px;
33 | color:#000;
34 | font-size: 0.9em;
35 | position:absolute;
36 | bottom:0;
37 | background-position: bottom;
38 | z-index: 2;
39 | background-position: bottom;
40 | }
41 | .classic_vcx_subbar_top{
42 | width:100%;
43 | height: 16.5%;
44 | max-height: 60px;
45 | color:#aaa;
46 | font-size: 0.9em;
47 | position:absolute;
48 | top:0;
49 | background-position: top !important;
50 | z-index: 2;
51 | background-position: bottom;
52 | }
53 | .classic_vcx_subbar_left{
54 | width:15%;
55 | height:100%;
56 | max-width:30px;
57 | color:#aaa;
58 | font-size: 0.9em;
59 | position:absolute;
60 | left:0;
61 | border-radius: 8px 8px 8px 8px;
62 | background: linear-gradient( to bottom, #444, #222 );
63 | background-position: bottom;
64 | }
65 | .classic_vcx_subbar_right{
66 | width:15%;
67 | height:100%;
68 | font-size: 0.9em;
69 | max-width:30px;
70 | color:#aaa;
71 | position:absolute;
72 | right:0;
73 | border-radius: 8px 8px 8px 8px;
74 | background-position: bottom;
75 | }
76 | .classic_icon{
77 | margin: 1.3%;
78 | max-width: 6%;
79 | cursor: pointer;
80 | padding: 2.1%;
81 | border: 1px solid;
82 | border-radius: 50%;
83 | }
84 | .classic_icon:hover{
85 | color:#423c3c;
86 | }
87 | .classic_icon_record{
88 | max-width:30px;
89 | color:#f00;
90 | cursor:pointer
91 | }
92 | .classic_icon_play{
93 | font-size: 1.3em;
94 | margin-left: 12px;
95 | }
96 | .classic_brand_logo{
97 | max-width: 40px;
98 | max-height: 40px;
99 | cursor: pointer;
100 | position: absolute;
101 | right: 0px;
102 | margin: 3px 3px 5px 5px;
103 | }
104 | .classic_theater_view{
105 | margin: 0px !important;
106 | width: 100% !important;
107 | height: 80% !important;
108 | }
109 | .classic_theater_view i {
110 | padding: 14px;
111 | margin: 0.5%;
112 | }
113 | .classic_theater_view .vcx_subbar{
114 | height: 27%;
115 | max-height: 60px;
116 | }
117 | .classic_theater_view .classic_brand_logo {
118 | max-width: 50px;
119 | max-height: 50px;
120 | height: 45px;
121 | width: 45px;
122 | margin: 7px 11px 5px 5px;
123 | }
124 | .classic_full_view{
125 | width: 100% !important;
126 | height: 100% !important;
127 | margin: 0px !important;
128 | top: 0px;
129 | left: 0px;
130 | position: fixed !important;
131 | z-index : 3;
132 | }
133 | .classic_full_view i {
134 | padding: 17px;
135 | margin: 0.5%;
136 | }
137 | .classic_full_view .vcx_subbar {
138 | height: 23%;
139 | max-height: 70px;
140 | }
141 | .classic_full_view .classic_brand_logo {
142 | max-width: 50px;
143 | max-height: 50px;
144 | height: 50px;
145 | width: 50px;
146 | margin: 8px 11px 5px 5px;
147 | }
--------------------------------------------------------------------------------
/public/assets/css/box.css:
--------------------------------------------------------------------------------
1 | .box_vcx_player{
2 | width:100%;
3 | height:100%;
4 | position:relative;
5 | background-color:black;
6 | overflow:hidden;
7 | }
8 | .box_vcx_player_loader{
9 | width:100%;
10 | height:100%;
11 | position:absolute;
12 | }
13 | .box_vcx_player_screen_saver{
14 | width:100%;
15 | height:100%;
16 | position:absolute;
17 | z-index: 1;
18 | }
19 | .box_vcx_stream{
20 | width:100%;
21 | height:100%;
22 | position:absolute;
23 | object-fit: fill;
24 | }
25 | .box_vcx_bar{
26 | height:100%;
27 | width:100%;
28 | position:absolute;
29 | }
30 | .box_vcx_subbar_bottom{
31 | width:100%;
32 | height: 16.5%;
33 | max-height: 60px;
34 | color:#aaa;
35 | font-size: 0.9em;
36 | position:absolute;
37 | bottom:0;
38 | text-shadow: 2px 2px 0 #222;
39 | background: linear-gradient( to bottom, #444, #222 );
40 | background-position: bottom;
41 | z-index: 2;
42 | background-position: bottom;
43 | }
44 | .box_vcx_subbar_top{
45 | width:100%;
46 | height: 16.5%;
47 | max-height: 60px;
48 | color:#aaa;
49 | font-size: 0.9em;
50 | position:absolute;
51 | top:0;
52 | background: linear-gradient( to bottom, #444, #222 );
53 | text-shadow: 2px 2px 0 #222;
54 | background-position: top !important;
55 | z-index: 2;
56 | background-position: bottom;
57 | }
58 | .box_vcx_subbar_left{
59 | width:15%;
60 | height:100%;
61 | max-width:30px;
62 | color:#aaa;
63 | font-size: 0.9em;
64 | position:absolute;
65 | left:0;
66 | border-radius: 8px 8px 8px 8px;
67 | background: linear-gradient( to bottom, #444, #222 );
68 | background-position: bottom;
69 | }
70 | .box_vcx_subbar_right{
71 | width:15%;
72 | height:100%;
73 | font-size: 0.9em;
74 | max-width:30px;
75 | color:#aaa;
76 | position:absolute;
77 | right:0;
78 | border-radius: 8px 8px 8px 8px;
79 | background-position: bottom;
80 | }
81 | .box_icon{
82 | margin: 3px;
83 | max-width: 6%;
84 | cursor: pointer;
85 | padding: 5px;
86 | border: 1px solid;
87 | position:relative;
88 | top: calc(50% - 18px);
89 | }
90 | .box_icon:hover{
91 | color:#ccc;
92 | }
93 | .box_icon_record{
94 | max-width:30px;
95 | color:#f00;
96 | cursor:pointer
97 | }
98 | .box_icon_play{
99 | font-size: 1.3em;
100 | margin-left: 12px;
101 | }
102 | .box_brand_logo{
103 | max-width: 40px;
104 | max-height: 40px;
105 | cursor: pointer;
106 | position: absolute;
107 | right: 0px;
108 | margin: 3px 3px 5px 5px;
109 | }
110 | .box_theater_view{
111 | margin: 0px !important;
112 | width: 100% !important;
113 | height: 80% !important;
114 | }
115 | .box_theater_view i {
116 | padding: 14px;
117 | margin: 0.5%;
118 | }
119 | .box_theater_view .vcx_subbar{
120 | height: 27%;
121 | max-height: 60px;
122 | }
123 | .box_theater_view .box_brand_logo {
124 | max-width: 50px;
125 | max-height: 50px;
126 | height: 45px;
127 | width: 45px;
128 | margin: 7px 11px 5px 5px;
129 | }
130 | .box_full_view{
131 | width: 100% !important;
132 | height: 100% !important;
133 | margin: 0px !important;
134 | top: 0px;
135 | left: 0px;
136 | position: fixed !important;
137 | z-index : 3;
138 | }
139 | .box_full_view i {
140 | padding: 17px;
141 | margin: 0.5%;
142 | }
143 | .box_full_view .vcx_subbar {
144 | height: 23%;
145 | max-height: 70px;
146 | }
147 | .box_full_view .box_brand_logo {
148 | max-width: 50px;
149 | max-height: 50px;
150 | height: 50px;
151 | width: 50px;
152 | margin: 8px 11px 5px 5px;
153 | }
--------------------------------------------------------------------------------
/public/assets/css/default.css:
--------------------------------------------------------------------------------
1 | .default_vcx_player{
2 | width:100%;
3 | height:100%;
4 | position:relative;
5 | background-color:black;
6 | overflow:hidden;
7 | }
8 | .default_vcx_player_loader{
9 | width:100%;
10 | height:100%;
11 | position:absolute;
12 | }
13 | .default_vcx_player_screen_saver{
14 | width:100%;
15 | height:100%;
16 | position:absolute;
17 | z-index: 1;
18 | }
19 | .default_vcx_stream{
20 | width:100%;
21 | height:100%;
22 | position:absolute;
23 | }
24 | .default_vcx_bar{
25 | height:100%;
26 | width:100%;
27 | position:absolute;
28 | }
29 | .default_vcx_subbar_bottom{
30 | width:100%;
31 | height:15%;
32 | max-height:33px;
33 | color:#aaa;
34 | position:absolute;
35 | bottom:0;
36 | background-repeat: repeat-x;
37 | background-image: url('../bar_back.png');
38 | -webkit-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
39 | transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
40 | -moz-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
41 | background-position: bottom;
42 | padding-top: 50px;
43 | z-index: 2;
44 | background-position: bottom;
45 | }
46 | .default_vcx_subbar_top{
47 | width:100%;
48 | height:15%;
49 | max-height:30px;
50 | color:#aaa;
51 | position:absolute;
52 | top:0;
53 | background-repeat: repeat-x;
54 | background-image: url('../bar_back.png');
55 | transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
56 | -webkit-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
57 | -moz-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
58 | background-position: top !important;
59 | padding-bottom: 50px;
60 | z-index: 2;
61 | background-position: bottom;
62 | }
63 | .default_vcx_subbar_left{
64 | width:15%;
65 | height:100%;
66 | max-width:30px;
67 | color:#aaa;
68 | position:absolute;
69 | left:0;
70 | background-repeat: repeat-x;
71 | background-image: url('../bar_back.png');
72 | transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
73 | -webkit-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
74 | -moz-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
75 | background-position: bottom;
76 | }
77 | .default_vcx_subbar_right{
78 | width:15%;
79 | height:100%;
80 | max-width:30px;
81 | color:#aaa;
82 | position:absolute;
83 | right:0;
84 | /*background:-webkit-linear-gradient(rgba(131,131,131,0.62),rgba(77,77,77,0.62))*/
85 | background-repeat: repeat-x;
86 | background-image: url('../bar_back.png');
87 | transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
88 | -webkit-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
89 | -moz-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
90 | background-position: bottom;
91 | }
92 | .default_icon{
93 | margin:7px;
94 | max-width:30px;
95 | cursor:pointer
96 | }
97 | .default_icon_record{
98 | margin:7px;
99 | max-width:30px;
100 | color:#f00;
101 | cursor:pointer
102 | }
103 | .default_icon_volume{
104 | margin:7px;
105 | max-width:30px;
106 | cursor:pointer
107 | }
108 | .default_brand_logo{
109 | max-width: 30px;
110 | max-height: 30px;
111 | cursor: pointer;
112 | position: absolute;
113 | right: 0px;
114 | margin: 5px;
115 | }
116 | .default_theater_view{
117 | width: 100% !important;
118 | height: 80% !important;
119 | }
120 | .default_full_view{
121 | width: 100% !important;
122 | height: 100% !important;
123 | top: 0px;
124 | left: 0px;
125 | position: fixed !important;
126 | z-index : 3;
127 | }
--------------------------------------------------------------------------------
/config/cache.php:
--------------------------------------------------------------------------------
1 | env('CACHE_DRIVER', 'file'),
22 |
23 | /*
24 | |--------------------------------------------------------------------------
25 | | Cache Stores
26 | |--------------------------------------------------------------------------
27 | |
28 | | Here you may define all of the cache "stores" for your application as
29 | | well as their drivers. You may even define multiple stores for the
30 | | same cache driver to group types of items stored in your caches.
31 | |
32 | */
33 |
34 | 'stores' => [
35 |
36 | 'apc' => [
37 | 'driver' => 'apc',
38 | ],
39 |
40 | 'array' => [
41 | 'driver' => 'array',
42 | ],
43 |
44 | 'database' => [
45 | 'driver' => 'database',
46 | 'table' => 'cache',
47 | 'connection' => null,
48 | ],
49 |
50 | 'file' => [
51 | 'driver' => 'file',
52 | 'path' => storage_path('framework/cache/data'),
53 | ],
54 |
55 | 'memcached' => [
56 | 'driver' => 'memcached',
57 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
58 | 'sasl' => [
59 | env('MEMCACHED_USERNAME'),
60 | env('MEMCACHED_PASSWORD'),
61 | ],
62 | 'options' => [
63 | // Memcached::OPT_CONNECT_TIMEOUT => 2000,
64 | ],
65 | 'servers' => [
66 | [
67 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'),
68 | 'port' => env('MEMCACHED_PORT', 11211),
69 | 'weight' => 100,
70 | ],
71 | ],
72 | ],
73 |
74 | 'redis' => [
75 | 'driver' => 'redis',
76 | 'connection' => 'cache',
77 | ],
78 |
79 | 'dynamodb' => [
80 | 'driver' => 'dynamodb',
81 | 'key' => env('AWS_ACCESS_KEY_ID'),
82 | 'secret' => env('AWS_SECRET_ACCESS_KEY'),
83 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
84 | 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
85 | ],
86 |
87 | ],
88 |
89 | /*
90 | |--------------------------------------------------------------------------
91 | | Cache Key Prefix
92 | |--------------------------------------------------------------------------
93 | |
94 | | When utilizing a RAM based store such as APC or Memcached, there might
95 | | be other applications utilizing the same cache. So, we'll specify a
96 | | value to get prefixed to all our keys so we can avoid collisions.
97 | |
98 | */
99 |
100 | 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
101 |
102 | ];
103 |
--------------------------------------------------------------------------------
/public/css/confo.css:
--------------------------------------------------------------------------------
1 | body{
2 | background-color: #333 !important;
3 | }
4 | .card_div{
5 | padding: 10px;
6 | border: 1px solid #ccc;
7 | margin: 10px;
8 | border-radius: 10px;
9 | }
10 | .vedio_container_div{
11 | padding-top: 25px;
12 | /*border: 14px solid #ccc;*/
13 | /*margin: 10px;*/
14 | /*box-shadow: 1px 3px 5px #aaa;*/
15 | }
16 | .publish_div p{
17 | text-align: center;
18 | margin-top: 20px ;
19 | }
20 | .nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover{
21 | border:none !important;
22 | }
23 | ul.nav.nav-tabs li.active{
24 | border-bottom: 3px solid #0af;
25 | }
26 | .action_div ul{
27 | margin-top:10px;
28 | }
29 | label.label_right{
30 | float: right;
31 | font-weight: normal !important;
32 | }
33 | div.message_div .row{
34 | padding: 10px;
35 | }
36 | div.message_div{
37 | padding-right: 20px;
38 | }
39 | textarea{
40 | resize: none;
41 | }
42 | #multi_video_container_div{
43 | /*position: absolute;*/
44 | /*right: 0px;*/
45 | /*overflow: auto;*/
46 | /*z-index: 9002;*/
47 | /*height: 400px;*/
48 | /*width: 130px;*/
49 | top: 0px;
50 | }
51 | #multi_video_container_div .live_stream_div{
52 | float: left;
53 | height:100px;
54 | width:100px;
55 |
56 | margin-left:10px;
57 | }
58 | @keyframes textAppearence {
59 | 0% {top:8px;}
60 | 25% {top:6px;}
61 | 50% {top:4px;}
62 | 75% { top:2px;}
63 | 100% { top:0px;}
64 | }
65 | .multi_text_container_div{
66 | position: absolute;
67 | overflow: auto;
68 | z-index: 9002;
69 | margin:5px;
70 | height: 400px;
71 | width: 130px;
72 | color:#fff;
73 | padding: 5px;
74 | }
75 | .show_none{
76 | display: none;
77 | }
78 | #local_video_div{
79 | height:400px;
80 | width: 100%;
81 | }
82 | .full_width{
83 | width:100%;
84 | }
85 | .run-text-animation {
86 | animation: textAppearence 4s;
87 | }
88 | .fullScreen {
89 | position:fixed !important;
90 | z-index:9009 !important;
91 | left:0 !important;
92 | width:100% !important;
93 | height:100% !important;
94 | margin-top:-100px !important;
95 | }
96 | .small_loader {
97 | height: 120px;
98 | width: 120px;
99 | }
100 | .vcx_bar{
101 | cursor:pointer;
102 | }
103 |
104 | .name-div{
105 | position: absolute;
106 | top:5%;
107 | left:5%;
108 | color:#fff;
109 | }
110 |
111 | @media screen and (min-width: 1690px) {
112 | .classic_vcx_stream
113 | {
114 | height: 700px !important;
115 | width: 900px !important;
116 |
117 | }
118 | }
119 |
120 |
121 | @media screen and (max-width: 1690px) {
122 | .classic_vcx_stream
123 | {
124 | height: 450px !important;
125 | width: 650px !important;
126 |
127 | }
128 | }
129 | @media screen and (max-width: 1280px) {
130 | .classic_vcx_stream
131 | {
132 | height: 400px !important;
133 | width: 500px !important;
134 |
135 | }
136 | }
137 | @media screen and (max-width: 980px) {
138 | .classic_vcx_stream
139 | {
140 | height: 500px !important;
141 | width: 500px !important;
142 |
143 | }
144 | }
145 | @media screen and (max-width: 736px) {
146 | .classic_vcx_stream
147 | {
148 | height: 400px !important;
149 | width: 500px !important;
150 |
151 | }
152 | }
153 | @media screen and (max-width: 480px) {
154 | .classic_vcx_stream
155 | {
156 | height: 300px !important;
157 | width: 400px !important;
158 |
159 | }
160 | }
161 |
162 |
--------------------------------------------------------------------------------
/public/js/index.js:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////
2 | //
3 | // File: index.js
4 | // This is application file for login page to accept login credentials
5 | //
6 | // Last Updated: 29-11-2018
7 | // Reformat, Indentation, Inline Comments
8 | //
9 | /////////////////////////////////////////////////////
10 |
11 |
12 | window.onload = function () {
13 | $(".login_join_div").show();
14 |
15 | }
16 | var username = "demo";
17 | var password = "enablex";
18 |
19 | // Verifies login credentials before moving to Conference page
20 |
21 | document.getElementById('login_form').addEventListener('submit', function (event) {
22 | event.preventDefault();
23 | var name = document.querySelector('#nameText'), room = document.querySelector('#roomName'), agree = document.querySelector('[name="agree"]'), errors = [];
24 | if (name.value.trim() === '') {
25 | errors.push('Enter your name.');
26 | }
27 | if (room.value.trim() === '') {
28 | errors.push('Enter your Room Id.')
29 | }
30 |
31 | if (!agree.checked ) {
32 | errors.push('Accept terms of use and privacy policy.')
33 | }
34 |
35 | if (errors.length > 0) {
36 | var mappederrors = errors.map(function (item) {
37 | return item + "";
38 | });
39 | var allerrors = mappederrors.join('').toString();
40 | $.toast({
41 | heading: 'Error',
42 | text: allerrors,
43 | showHideTransition: 'fade',
44 | icon: 'error',
45 | position: 'top-right',
46 | showHideTransition: 'slide'
47 | });
48 | return false;
49 | }
50 |
51 |
52 | joinRoom(document.getElementById('roomName').value, function (data) {
53 | console.log('data:' , data)
54 | if (!jQuery.isEmptyObject(data)) {
55 | var user_ref = document.getElementById('nameText').value;
56 | // window.location.href = "confo.html?roomId=" + data.room_id + "&usertype=participant&user_ref=" + user_ref;
57 | window.location.href = "confo/" + data.room_id + "/participant/" + user_ref;
58 | } else {
59 | alert('No room found');
60 | }
61 | });
62 | });
63 |
64 | var loadingElem = document.querySelector('.loading');
65 | document.getElementById('create_room').addEventListener('click', function (event) {
66 | loadingElem.classList.add('yes');
67 | createRoom(function (result) {
68 | document.getElementById("roomName").value = result;
69 | document.getElementById("create_room_div").style.display = "none";
70 | document.getElementById("message").innerHTML = "We have prefilled the form with room-id. Share it with someone you want to talk to";
71 | });
72 | });
73 |
74 |
75 | var createRoom = function (callback) {
76 | var xhttp = new XMLHttpRequest();
77 | xhttp.onreadystatechange = function () {
78 | if (this.readyState == 4 && this.status == 200) {
79 | var response = JSON.parse(this.responseText);
80 | if(response.error){
81 | $.toast({
82 | heading: 'Error',
83 | text: response.error,
84 | showHideTransition: 'fade',
85 | icon: 'error',
86 | position: 'top-right'
87 | });
88 |
89 | }
90 | else {
91 | callback(response.room.room_id);
92 | loadingElem.classList.remove('yes');
93 | }
94 | }
95 | };
96 | xhttp.open("POST", "../api/createRoom/", true);
97 | xhttp.setRequestHeader('Content-Type', 'application/json');
98 | xhttp.send();
99 | };
100 |
101 |
102 |
--------------------------------------------------------------------------------
/app/Http/Controllers/EnxRtc/RoomController.php:
--------------------------------------------------------------------------------
1 | "Sample Room: " . $random_name,
40 | "owner_ref" => $random_name,
41 | "settings" => array(
42 | "description" => "",
43 | "quality" => "SD",
44 | "mode" => "group",
45 | "participants" => "2",
46 | "duration" => "60",
47 | "scheduled" => false,
48 | "auto_recording" => false,
49 | "active_talker" => true,
50 | "wait_moderator" => false,
51 | "adhoc" => false,
52 | ),
53 | "sip" => array(
54 | "enabled" => false,
55 | ),
56 | );
57 |
58 | $Room_Meta = json_encode($Room);
59 | $response = $this->curlOperations(['type' => 'POST', 'url' => '/rooms', 'data' => $Room_Meta]);
60 | return response($response);
61 |
62 | }
63 |
64 | public function getRoom(Request $request)
65 | {
66 | $roomId = $request->route('room');
67 | if (!$roomId) {
68 | $error = Errors::getError(4001);
69 | $error["desc"] = "Failed to get roomId from URL";
70 | return response()->json($error);
71 | }
72 |
73 | $response = $this->curlOperations(['type' => 'GET', 'url' => "/rooms/" . $roomId]);
74 | return response($response);
75 | }
76 |
77 | public function createToken(Request $request)
78 | {
79 | if (!$request->name && !$request->role && !$request->roomId) {
80 | $error = Errors::getError(4004); // Required JSON Key missing
81 | $error["desc"] = "JSON keys missing: name, role or roomId";
82 | return response()->json($error);
83 | }
84 | $Token = array(
85 | "name" => $request->name,
86 | "role" => $request->role,
87 | "user_ref" => $request->user_ref,
88 | );
89 |
90 | $Token_Payload = json_encode($Token);
91 |
92 | $response = $this->curlOperations(['type' => 'POST', 'url' => "/rooms/" . $request->roomId . "/tokens", 'data' => $Token_Payload]);
93 | return response($response);
94 |
95 | }
96 |
97 | public function confo(Request $request, $room, $type, $ref)
98 | {
99 | return \view('confo')->with(['roomId' => $room, 'user_ref' => $ref, 'usertype' => $type]);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/config/auth.php:
--------------------------------------------------------------------------------
1 | [
17 | 'guard' => 'web',
18 | 'passwords' => 'users',
19 | ],
20 |
21 | /*
22 | |--------------------------------------------------------------------------
23 | | Authentication Guards
24 | |--------------------------------------------------------------------------
25 | |
26 | | Next, you may define every authentication guard for your application.
27 | | Of course, a great default configuration has been defined for you
28 | | here which uses session storage and the Eloquent user provider.
29 | |
30 | | All authentication drivers have a user provider. This defines how the
31 | | users are actually retrieved out of your database or other storage
32 | | mechanisms used by this application to persist your user's data.
33 | |
34 | | Supported: "session", "token"
35 | |
36 | */
37 |
38 | 'guards' => [
39 | 'web' => [
40 | 'driver' => 'session',
41 | 'provider' => 'users',
42 | ],
43 |
44 | 'api' => [
45 | 'driver' => 'token',
46 | 'provider' => 'users',
47 | 'hash' => false,
48 | ],
49 | ],
50 |
51 | /*
52 | |--------------------------------------------------------------------------
53 | | User Providers
54 | |--------------------------------------------------------------------------
55 | |
56 | | All authentication drivers have a user provider. This defines how the
57 | | users are actually retrieved out of your database or other storage
58 | | mechanisms used by this application to persist your user's data.
59 | |
60 | | If you have multiple user tables or models you may configure multiple
61 | | sources which represent each model / table. These sources may then
62 | | be assigned to any extra authentication guards you have defined.
63 | |
64 | | Supported: "database", "eloquent"
65 | |
66 | */
67 |
68 | 'providers' => [
69 | 'users' => [
70 | 'driver' => 'eloquent',
71 | 'model' => App\User::class,
72 | ],
73 |
74 | // 'users' => [
75 | // 'driver' => 'database',
76 | // 'table' => 'users',
77 | // ],
78 | ],
79 |
80 | /*
81 | |--------------------------------------------------------------------------
82 | | Resetting Passwords
83 | |--------------------------------------------------------------------------
84 | |
85 | | You may specify multiple password reset configurations if you have more
86 | | than one user table or model in the application and you want to have
87 | | separate password reset settings based on the specific user types.
88 | |
89 | | The expire time is the number of minutes that the reset token should be
90 | | considered valid. This security feature keeps tokens short-lived so
91 | | they have less time to be guessed. You may change this as needed.
92 | |
93 | */
94 |
95 | 'passwords' => [
96 | 'users' => [
97 | 'provider' => 'users',
98 | 'table' => 'password_resets',
99 | 'expire' => 60,
100 | ],
101 | ],
102 |
103 | ];
104 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Building a 1-to-1 Real-Time Communication Web App with Laravel (PHP Framework) and EnableX Web Toolkit
2 |
3 | 1-to-1 RTC Web App: Laravel (PHP Framework) and EnableX Web Toolkit
4 |
5 | Experience a Sample Web App that showcases the usage of EnableX platform APIs for seamless 1-to-1 RTC (Real-Time Communication). This application aims to demonstrate API usage while enabling developers to accelerate app development by hosting it on their personal devices instead of relying on external servers.
6 |
7 | RTC Applications hosted on the EnableX platform are fully compatible with supported web browsers, eliminating the need for additional plugin downloads.
8 |
9 | This basic 1-to-1 Video Chat Application is meticulously crafted using HTML, CSS, Bootstrap, JavaScript, jQuery, Laravel, and EnxRtc (EnableX Web Toolkit)
10 |
11 | ## 1. Important!
12 |
13 | When developing a Client Application with EnxRtc.js make sure to include the updated EnxRtc.js polyfills for RTCPeerConnection and getUserMedia otherwise your application will not work in web browsers.
14 |
15 | ## 2. Trial
16 |
17 | Sign up for a free trial https://www.enablex.io/free-trial/ or try our multiparty video chat https://try.enablex.io/
18 |
19 | ## 3. Installation
20 |
21 | ### 3.1 Pre-Requisites
22 |
23 | #### 3.1.1 App Id and App Key
24 |
25 | * Register with EnableX https://www.enablex.io/free-trial/
26 | * Create your Application
27 | * Get your App ID and App Key delivered to your Email
28 | * Clone or download this Repository [https://github.com/EnableX/WebRTC-Open-Source-One-To-One-Video-Chat-Application-in-Laravel.git] & follow the steps further
29 | * You can copy the app into any sub-directory of hosted Website on Apache
30 |
31 | #### 3.1.2 SSL Certificates
32 |
33 | The Application needs to run on https. So, you need to use a valid SSL Certificate for your Domain and point your application to use them.
34 |
35 | However you may use self-signed Certificate to run this application locally. There are many Web Sites to get a Self-Signed Certificate generated for you, Google it. Few among them are:
36 | * https://letsencrypt.org/
37 | * https://www.sslchecker.com/csr/self_signed
38 | * https://www.akadia.com/services/ssh_test_certificate.html
39 |
40 | As you have Certificate or created a Self-Signed Certificate, create a directory "certs" under your Sample Web App Directory. Copy your Certificate files (.key and .crt files) to this directory.
41 |
42 |
43 | #### 3.1.3 Configure
44 |
45 | Before you you try accessing the `/client` routes using Browser, configure the API Service by editing `.env` file to meet your requirement:
46 |
47 | ```php
48 | ENABLEX_API_URL = "https://api.enablex.io/v1"
49 | ENABLEX_APP_ID = "YOUR_APP_ID"
50 | ENABLEX_APP_KEY = "YOUR_APP_KEY"
51 | ```
52 |
53 | ### 3.2 Test
54 |
55 | * Open a browser and go to [https://yourdomain.com:4443/path-to-sample-app/client](https://yourdomain.com:4443/path-to-sample-app/client). The browser should load the App.
56 | * Allow access to Camera and Mic as and when prompted to start your first RTC Call through EnableX
57 | * You need to Room ID to join. We have added a "Create Room" link below the login form. Click it to get a Room-Id prefilled in the form.
58 | * You can share the Room-ID with anyone to join your Conference.
59 |
60 |
61 |
62 | ## 4 Server API
63 |
64 | EnableX Server API is a Rest API service meant to be called from Partners' Application Server to provision video enabled
65 | meeting rooms. API Access is given to each Application through the assigned App ID and App Key. So, the App ID and App Key
66 | are to be used as Username and Password respectively to pass as HTTP Basic Authentication header to access Server API.
67 |
68 | For this application, the following Server API calls are used:
69 | * https://developer.enablex.io/docs/references/apis/video-api/content/api-routes/#create-a-room - To create room to carry out a video session
70 | * https://developer.enablex.io/video-api/server-api/rooms-route/#create-token - To create Token for the given Room to join a session
71 |
72 | To know more about Server API, go to:
73 | https://developer.enablex.io/video-api/server-api/
74 |
75 |
76 | ## 5 Client API
77 |
78 | Client End Point Application uses Web Toolkit EnxRtc.js to communicate with EnableX Servers to initiate and manage RTC Communications.
79 |
80 | To know more about Client API, go to:
81 | https://developer.enablex.io/docs/references/sdks/video-sdk/web-sdk/index/
82 |
--------------------------------------------------------------------------------
/public/assets/star.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
55 |
--------------------------------------------------------------------------------
/public/css/jquery.toast.css:
--------------------------------------------------------------------------------
1 | /**
2 | * jQuery toast plugin created by Kamran Ahmed copyright MIT license 2014
3 | */
4 | .jq-toast-wrap { display: block; position: fixed; width: 250px; pointer-events: none !important; margin: 0; padding: 0; letter-spacing: normal; z-index: 9000 !important; }
5 | .jq-toast-wrap * { margin: 0; padding: 0; }
6 |
7 | .jq-toast-wrap.bottom-left { bottom: 20px; left: 20px; }
8 | .jq-toast-wrap.bottom-right { bottom: 20px; right: 40px; }
9 | .jq-toast-wrap.top-left { top: 20px; left: 20px; }
10 | .jq-toast-wrap.top-right { top: 20px; right: 40px; }
11 |
12 | .jq-toast-single { display: block; width: 100%; padding: 10px; margin: 0px 0px 5px; border-radius: 4px; font-size: 12px; font-family: arial, sans-serif; line-height: 17px; position: relative; pointer-events: all !important; background-color: #444444; color: white; }
13 |
14 | .jq-toast-single h2 { font-family: arial, sans-serif; font-size: 14px; margin: 0px 0px 7px; background: none; color: inherit; line-height: inherit; letter-spacing: normal; }
15 | .jq-toast-single a { color: #eee; text-decoration: none; font-weight: bold; border-bottom: 1px solid white; padding-bottom: 3px; font-size: 12px; }
16 |
17 | .jq-toast-single ul { margin: 0px 0px 0px 15px; background: none; padding:0px; }
18 | .jq-toast-single ul li { list-style-type: disc !important; line-height: 17px; background: none; margin: 0; padding: 0; letter-spacing: normal; }
19 |
20 | .close-jq-toast-single { position: absolute; top: 3px; right: 7px; font-size: 14px; cursor: pointer; }
21 |
22 | .jq-toast-loader { display: block; position: absolute; top: -2px; height: 5px; width: 0%; left: 0; border-radius: 5px; background: red; }
23 | .jq-toast-loaded { width: 100%; }
24 | .jq-has-icon { padding: 10px 10px 10px 50px; background-repeat: no-repeat; background-position: 10px; }
25 | .jq-icon-info { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII='); background-color: #31708f; color: #d9edf7; border-color: #bce8f1; }
26 | .jq-icon-warning { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII='); background-color: #8a6d3b; color: #fcf8e3; border-color: #faebcc; }
27 | .jq-icon-error { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII='); background-color: #a94442; color: #f2dede; border-color: #ebccd1; }
28 | .jq-icon-success { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg=='); color: #dff0d8; background-color: #3c763d; border-color: #d6e9c6; }
--------------------------------------------------------------------------------
/config/mail.php:
--------------------------------------------------------------------------------
1 | env('MAIL_DRIVER', 'smtp'),
20 |
21 | /*
22 | |--------------------------------------------------------------------------
23 | | SMTP Host Address
24 | |--------------------------------------------------------------------------
25 | |
26 | | Here you may provide the host address of the SMTP server used by your
27 | | applications. A default option is provided that is compatible with
28 | | the Mailgun mail service which will provide reliable deliveries.
29 | |
30 | */
31 |
32 | 'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
33 |
34 | /*
35 | |--------------------------------------------------------------------------
36 | | SMTP Host Port
37 | |--------------------------------------------------------------------------
38 | |
39 | | This is the SMTP port used by your application to deliver e-mails to
40 | | users of the application. Like the host we have set this value to
41 | | stay compatible with the Mailgun e-mail application by default.
42 | |
43 | */
44 |
45 | 'port' => env('MAIL_PORT', 587),
46 |
47 | /*
48 | |--------------------------------------------------------------------------
49 | | Global "From" Address
50 | |--------------------------------------------------------------------------
51 | |
52 | | You may wish for all e-mails sent by your application to be sent from
53 | | the same address. Here, you may specify a name and address that is
54 | | used globally for all e-mails that are sent by your application.
55 | |
56 | */
57 |
58 | 'from' => [
59 | 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
60 | 'name' => env('MAIL_FROM_NAME', 'Example'),
61 | ],
62 |
63 | /*
64 | |--------------------------------------------------------------------------
65 | | E-Mail Encryption Protocol
66 | |--------------------------------------------------------------------------
67 | |
68 | | Here you may specify the encryption protocol that should be used when
69 | | the application send e-mail messages. A sensible default using the
70 | | transport layer security protocol should provide great security.
71 | |
72 | */
73 |
74 | 'encryption' => env('MAIL_ENCRYPTION', 'tls'),
75 |
76 | /*
77 | |--------------------------------------------------------------------------
78 | | SMTP Server Username
79 | |--------------------------------------------------------------------------
80 | |
81 | | If your SMTP server requires a username for authentication, you should
82 | | set it here. This will get used to authenticate with your server on
83 | | connection. You may also set the "password" value below this one.
84 | |
85 | */
86 |
87 | 'username' => env('MAIL_USERNAME'),
88 |
89 | 'password' => env('MAIL_PASSWORD'),
90 |
91 | /*
92 | |--------------------------------------------------------------------------
93 | | Sendmail System Path
94 | |--------------------------------------------------------------------------
95 | |
96 | | When using the "sendmail" driver to send e-mails, we will need to know
97 | | the path to where Sendmail lives on this server. A default path has
98 | | been provided here, which will work well on most of your systems.
99 | |
100 | */
101 |
102 | 'sendmail' => '/usr/sbin/sendmail -bs',
103 |
104 | /*
105 | |--------------------------------------------------------------------------
106 | | Markdown Mail Settings
107 | |--------------------------------------------------------------------------
108 | |
109 | | If you are using Markdown based email rendering, you may configure your
110 | | theme and component paths here, allowing you to customize the design
111 | | of the emails. Or, you may simply stick with the Laravel defaults!
112 | |
113 | */
114 |
115 | 'markdown' => [
116 | 'theme' => 'default',
117 |
118 | 'paths' => [
119 | resource_path('views/vendor/mail'),
120 | ],
121 | ],
122 |
123 | /*
124 | |--------------------------------------------------------------------------
125 | | Log Channel
126 | |--------------------------------------------------------------------------
127 | |
128 | | If you are using the "log" driver, you may specify the logging channel
129 | | if you prefer to keep mail messages separate from other log entries
130 | | for simpler reading. Otherwise, the default channel will be used.
131 | |
132 | */
133 |
134 | 'log_channel' => env('MAIL_LOG_CHANNEL'),
135 |
136 | ];
137 |
--------------------------------------------------------------------------------
/config/database.php:
--------------------------------------------------------------------------------
1 | env('DB_CONNECTION', 'mysql'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Database Connections
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here are each of the database connections setup for your application.
26 | | Of course, examples of configuring each database platform that is
27 | | supported by Laravel is shown below to make development simple.
28 | |
29 | |
30 | | All database work in Laravel is done through the PHP PDO facilities
31 | | so make sure you have the driver for your particular database of
32 | | choice installed on your machine before you begin development.
33 | |
34 | */
35 |
36 | 'connections' => [
37 |
38 | 'sqlite' => [
39 | 'driver' => 'sqlite',
40 | 'url' => env('DATABASE_URL'),
41 | 'database' => env('DB_DATABASE', database_path('database.sqlite')),
42 | 'prefix' => '',
43 | 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
44 | ],
45 |
46 | 'mysql' => [
47 | 'driver' => 'mysql',
48 | 'url' => env('DATABASE_URL'),
49 | 'host' => env('DB_HOST', '127.0.0.1'),
50 | 'port' => env('DB_PORT', '3306'),
51 | 'database' => env('DB_DATABASE', 'forge'),
52 | 'username' => env('DB_USERNAME', 'forge'),
53 | 'password' => env('DB_PASSWORD', ''),
54 | 'unix_socket' => env('DB_SOCKET', ''),
55 | 'charset' => 'utf8mb4',
56 | 'collation' => 'utf8mb4_unicode_ci',
57 | 'prefix' => '',
58 | 'prefix_indexes' => true,
59 | 'strict' => true,
60 | 'engine' => null,
61 | 'options' => extension_loaded('pdo_mysql') ? array_filter([
62 | PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
63 | ]) : [],
64 | ],
65 |
66 | 'pgsql' => [
67 | 'driver' => 'pgsql',
68 | 'url' => env('DATABASE_URL'),
69 | 'host' => env('DB_HOST', '127.0.0.1'),
70 | 'port' => env('DB_PORT', '5432'),
71 | 'database' => env('DB_DATABASE', 'forge'),
72 | 'username' => env('DB_USERNAME', 'forge'),
73 | 'password' => env('DB_PASSWORD', ''),
74 | 'charset' => 'utf8',
75 | 'prefix' => '',
76 | 'prefix_indexes' => true,
77 | 'schema' => 'public',
78 | 'sslmode' => 'prefer',
79 | ],
80 |
81 | 'sqlsrv' => [
82 | 'driver' => 'sqlsrv',
83 | 'url' => env('DATABASE_URL'),
84 | 'host' => env('DB_HOST', 'localhost'),
85 | 'port' => env('DB_PORT', '1433'),
86 | 'database' => env('DB_DATABASE', 'forge'),
87 | 'username' => env('DB_USERNAME', 'forge'),
88 | 'password' => env('DB_PASSWORD', ''),
89 | 'charset' => 'utf8',
90 | 'prefix' => '',
91 | 'prefix_indexes' => true,
92 | ],
93 |
94 | ],
95 |
96 | /*
97 | |--------------------------------------------------------------------------
98 | | Migration Repository Table
99 | |--------------------------------------------------------------------------
100 | |
101 | | This table keeps track of all the migrations that have already run for
102 | | your application. Using this information, we can determine which of
103 | | the migrations on disk haven't actually been run in the database.
104 | |
105 | */
106 |
107 | 'migrations' => 'migrations',
108 |
109 | /*
110 | |--------------------------------------------------------------------------
111 | | Redis Databases
112 | |--------------------------------------------------------------------------
113 | |
114 | | Redis is an open source, fast, and advanced key-value store that also
115 | | provides a richer body of commands than a typical key-value system
116 | | such as APC or Memcached. Laravel makes it easy to dig right in.
117 | |
118 | */
119 |
120 | 'redis' => [
121 |
122 | 'client' => env('REDIS_CLIENT', 'predis'),
123 |
124 | 'options' => [
125 | 'cluster' => env('REDIS_CLUSTER', 'predis'),
126 | 'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_').'_database_',
127 | ],
128 |
129 | 'default' => [
130 | 'host' => env('REDIS_HOST', '127.0.0.1'),
131 | 'password' => env('REDIS_PASSWORD', null),
132 | 'port' => env('REDIS_PORT', 6379),
133 | 'database' => env('REDIS_DB', 0),
134 | ],
135 |
136 | 'cache' => [
137 | 'host' => env('REDIS_HOST', '127.0.0.1'),
138 | 'password' => env('REDIS_PASSWORD', null),
139 | 'port' => env('REDIS_PORT', 6379),
140 | 'database' => env('REDIS_CACHE_DB', 1),
141 | ],
142 |
143 | ],
144 |
145 | ];
146 |
--------------------------------------------------------------------------------
/public/css/style.min.css:
--------------------------------------------------------------------------------
1 | body{background:#293840;color:#000;font:14px Arial;margin:0 auto;padding:0;position:relative}h1{font-size:28px}h2{font-size:26px}h3{font-size:18px}h4{font-size:16px}h5{font-size:14px}h6{font-size:12px}h1,h2,h3,h4,h5,h6{color:#563d64}small{font-size:10px}b,strong{font-weight:bold}a{text-decoration:none}a:hover{text-decoration:underline}.left{float:left}.right{float:right}.alignleft{float:left;margin-right:15px}.alignright{float:right;margin-left:15px}.clearfix:after,form:after{content:".";display:block;height:0;clear:both;visibility:hidden}.container{margin:25px auto;position:relative;width:900px}#content{background:#f9f9f9;background:-moz-linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);background:-webkit-linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);background:-o-linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);background:-ms-linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);background:linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8',endColorstr='#f9f9f9',GradientType=0);-webkit-box-shadow:0 1px 0 #fff inset;-moz-box-shadow:0 1px 0 #fff inset;-ms-box-shadow:0 1px 0 #fff inset;-o-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border:1px solid #c4c6ca;margin:0 auto;padding:25px 0 0;position:relative;text-align:center;text-shadow:0 1px 0 #fff;width:400px}#content h1{color:#7e7e7e;font:bold 25px Helvetica,Arial,sans-serif;letter-spacing:-.05em;line-height:20px;margin:10px 0 30px}#content h1:before,#content h1:after{content:"";height:1px;position:absolute;top:17px;width:27%}#content h1:after{background:rgb(126,126,126);background:-moz-linear-gradient(left,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);background:-webkit-linear-gradient(left,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);background:-o-linear-gradient(left,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);background:-ms-linear-gradient(left,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);background:linear-gradient(left,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);right:0}#content h1:before{background:rgb(126,126,126);background:-moz-linear-gradient(right,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);background:-webkit-linear-gradient(right,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);background:-o-linear-gradient(right,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);background:-ms-linear-gradient(right,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);background:linear-gradient(right,rgba(126,126,126,1)0,rgba(255,255,255,1)100%);left:0}#content:after,#content:before{background:#f9f9f9;background:-moz-linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);background:-webkit-linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);background:-o-linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);background:-ms-linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);background:linear-gradient(top,rgba(248,248,248,1)0,rgba(249,249,249,1)100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8',endColorstr='#f9f9f9',GradientType=0);border:1px solid #c4c6ca;content:"";display:block;height:100%;left:-1px;position:absolute;width:100%}#content:after{-webkit-transform:rotate(2deg);-moz-transform:rotate(2deg);-ms-transform:rotate(2deg);-o-transform:rotate(2deg);transform:rotate(2deg);top:0;z-index:-1}#content:before{-webkit-transform:rotate(-3deg);-moz-transform:rotate(-3deg);-ms-transform:rotate(-3deg);-o-transform:rotate(-3deg);transform:rotate(-3deg);top:0;z-index:-2}#content form{margin:0 20px;position:relative}#content form input[type="text"],#content form input[type="password"]{-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 #fff,0 -2px 5px rgba(0,0,0,.08)inset;-moz-box-shadow:0 1px 0 #fff,0 -2px 5px rgba(0,0,0,.08)inset;-ms-box-shadow:0 1px 0 #fff,0 -2px 5px rgba(0,0,0,.08)inset;-o-box-shadow:0 1px 0 #fff,0 -2px 5px rgba(0,0,0,.08)inset;box-shadow:0 1px 0 #fff,0 -2px 5px rgba(0,0,0,.08)inset;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-ms-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease;border:1px solid #c8c8c8;color:#777;font:13px Helvetica,Arial,sans-serif;margin:0 0 10px;padding:15px 10px 15px 40px;width:80%}#content form input[type="text"]:focus,#content form input[type="password"]:focus{-webkit-box-shadow:0 0 2px #ed1c24 inset;-moz-box-shadow:0 0 2px #ed1c24 inset;-ms-box-shadow:0 0 2px #ed1c24 inset;-o-box-shadow:0 0 2px #ed1c24 inset;box-shadow:0 0 2px #ed1c24 inset;background-color:#fff;border:1px solid #ed1c24;outline:0}#username{background-position:10px 10px!important}#password{background-position:10px -53px!important}#content form div a{color:#004a80;// float:right;font-size:12px;// margin:30px 15px 0 0;text-decoration:none}.button{background:rgb(247,249,250);background:-moz-linear-gradient(top,rgba(247,249,250,1)0,rgba(240,240,240,1)100%);background:-webkit-linear-gradient(top,rgba(247,249,250,1)0,rgba(240,240,240,1)100%);background:-o-linear-gradient(top,rgba(247,249,250,1)0,rgba(240,240,240,1)100%);background:-ms-linear-gradient(top,rgba(247,249,250,1)0,rgba(240,240,240,1)100%);background:linear-gradient(top,rgba(247,249,250,1)0,rgba(240,240,240,1)100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7f9fa',endColorstr='#f0f0f0',GradientType=0);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.1)inset;-moz-box-shadow:0 1px 2px rgba(0,0,0,.1)inset;-ms-box-shadow:0 1px 2px rgba(0,0,0,.1)inset;-o-box-shadow:0 1px 2px rgba(0,0,0,.1)inset;box-shadow:0 1px 2px rgba(0,0,0,.1)inset;-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;-o-border-radius:0 0 5px 5px;-ms-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;border-top:1px solid #cfd5d9;padding:15px 0}.button a{color:#7e7e7e;font-size:17px;padding:2px 0 2px 40px;text-decoration:none;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;-o-transition:all .3s ease;transition:all .3s ease}.button a:hover{background-position:0 -135px;color:#00aeef}.login_buttons{width:95%;margin:5px;height:47px;color:#d6d6d6;background:#444;border-radius:3px;box-shadow:0 1px 0 #fff,0 -2px 5px rgba(0,0,0,.08)inset;cursor:pointer;border:1px solid #c8c8c8;border-radius:5px}.login_buttons:hover{box-shadow:0 6px 0 #fff,0 -4px 15px rgba(0,0,0,.08)inset}.login_buttons:active{box-shadow:0 6px 0 #fff,0 -4px 15px rgba(0,0,0,.08)inset}.login_join_div{display:none}.loading{display:none}.loading.yes{display:block}
--------------------------------------------------------------------------------
/config/session.php:
--------------------------------------------------------------------------------
1 | env('SESSION_DRIVER', 'file'),
22 |
23 | /*
24 | |--------------------------------------------------------------------------
25 | | Session Lifetime
26 | |--------------------------------------------------------------------------
27 | |
28 | | Here you may specify the number of minutes that you wish the session
29 | | to be allowed to remain idle before it expires. If you want them
30 | | to immediately expire on the browser closing, set that option.
31 | |
32 | */
33 |
34 | 'lifetime' => env('SESSION_LIFETIME', 120),
35 |
36 | 'expire_on_close' => false,
37 |
38 | /*
39 | |--------------------------------------------------------------------------
40 | | Session Encryption
41 | |--------------------------------------------------------------------------
42 | |
43 | | This option allows you to easily specify that all of your session data
44 | | should be encrypted before it is stored. All encryption will be run
45 | | automatically by Laravel and you can use the Session like normal.
46 | |
47 | */
48 |
49 | 'encrypt' => false,
50 |
51 | /*
52 | |--------------------------------------------------------------------------
53 | | Session File Location
54 | |--------------------------------------------------------------------------
55 | |
56 | | When using the native session driver, we need a location where session
57 | | files may be stored. A default has been set for you but a different
58 | | location may be specified. This is only needed for file sessions.
59 | |
60 | */
61 |
62 | 'files' => storage_path('framework/sessions'),
63 |
64 | /*
65 | |--------------------------------------------------------------------------
66 | | Session Database Connection
67 | |--------------------------------------------------------------------------
68 | |
69 | | When using the "database" or "redis" session drivers, you may specify a
70 | | connection that should be used to manage these sessions. This should
71 | | correspond to a connection in your database configuration options.
72 | |
73 | */
74 |
75 | 'connection' => env('SESSION_CONNECTION', null),
76 |
77 | /*
78 | |--------------------------------------------------------------------------
79 | | Session Database Table
80 | |--------------------------------------------------------------------------
81 | |
82 | | When using the "database" session driver, you may specify the table we
83 | | should use to manage the sessions. Of course, a sensible default is
84 | | provided for you; however, you are free to change this as needed.
85 | |
86 | */
87 |
88 | 'table' => 'sessions',
89 |
90 | /*
91 | |--------------------------------------------------------------------------
92 | | Session Cache Store
93 | |--------------------------------------------------------------------------
94 | |
95 | | When using the "apc", "memcached", or "dynamodb" session drivers you may
96 | | list a cache store that should be used for these sessions. This value
97 | | must match with one of the application's configured cache "stores".
98 | |
99 | */
100 |
101 | 'store' => env('SESSION_STORE', null),
102 |
103 | /*
104 | |--------------------------------------------------------------------------
105 | | Session Sweeping Lottery
106 | |--------------------------------------------------------------------------
107 | |
108 | | Some session drivers must manually sweep their storage location to get
109 | | rid of old sessions from storage. Here are the chances that it will
110 | | happen on a given request. By default, the odds are 2 out of 100.
111 | |
112 | */
113 |
114 | 'lottery' => [2, 100],
115 |
116 | /*
117 | |--------------------------------------------------------------------------
118 | | Session Cookie Name
119 | |--------------------------------------------------------------------------
120 | |
121 | | Here you may change the name of the cookie used to identify a session
122 | | instance by ID. The name specified here will get used every time a
123 | | new session cookie is created by the framework for every driver.
124 | |
125 | */
126 |
127 | 'cookie' => env(
128 | 'SESSION_COOKIE',
129 | Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
130 | ),
131 |
132 | /*
133 | |--------------------------------------------------------------------------
134 | | Session Cookie Path
135 | |--------------------------------------------------------------------------
136 | |
137 | | The session cookie path determines the path for which the cookie will
138 | | be regarded as available. Typically, this will be the root path of
139 | | your application but you are free to change this when necessary.
140 | |
141 | */
142 |
143 | 'path' => '/',
144 |
145 | /*
146 | |--------------------------------------------------------------------------
147 | | Session Cookie Domain
148 | |--------------------------------------------------------------------------
149 | |
150 | | Here you may change the domain of the cookie used to identify a session
151 | | in your application. This will determine which domains the cookie is
152 | | available to in your application. A sensible default has been set.
153 | |
154 | */
155 |
156 | 'domain' => env('SESSION_DOMAIN', null),
157 |
158 | /*
159 | |--------------------------------------------------------------------------
160 | | HTTPS Only Cookies
161 | |--------------------------------------------------------------------------
162 | |
163 | | By setting this option to true, session cookies will only be sent back
164 | | to the server if the browser has a HTTPS connection. This will keep
165 | | the cookie from being sent to you if it can not be done securely.
166 | |
167 | */
168 |
169 | 'secure' => env('SESSION_SECURE_COOKIE', false),
170 |
171 | /*
172 | |--------------------------------------------------------------------------
173 | | HTTP Access Only
174 | |--------------------------------------------------------------------------
175 | |
176 | | Setting this value to true will prevent JavaScript from accessing the
177 | | value of the cookie and the cookie will only be accessible through
178 | | the HTTP protocol. You are free to modify this option if needed.
179 | |
180 | */
181 |
182 | 'http_only' => true,
183 |
184 | /*
185 | |--------------------------------------------------------------------------
186 | | Same-Site Cookies
187 | |--------------------------------------------------------------------------
188 | |
189 | | This option determines how your cookies behave when cross-site requests
190 | | take place, and can be used to mitigate CSRF attacks. By default, we
191 | | do not enable this as other CSRF protection services are in place.
192 | |
193 | | Supported: "lax", "strict"
194 | |
195 | */
196 |
197 | 'same_site' => null,
198 |
199 | ];
200 |
--------------------------------------------------------------------------------
/resources/lang/en/validation.php:
--------------------------------------------------------------------------------
1 | 'The :attribute must be accepted.',
17 | 'active_url' => 'The :attribute is not a valid URL.',
18 | 'after' => 'The :attribute must be a date after :date.',
19 | 'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
20 | 'alpha' => 'The :attribute may only contain letters.',
21 | 'alpha_dash' => 'The :attribute may only contain letters, numbers, dashes and underscores.',
22 | 'alpha_num' => 'The :attribute may only contain letters and numbers.',
23 | 'array' => 'The :attribute must be an array.',
24 | 'before' => 'The :attribute must be a date before :date.',
25 | 'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
26 | 'between' => [
27 | 'numeric' => 'The :attribute must be between :min and :max.',
28 | 'file' => 'The :attribute must be between :min and :max kilobytes.',
29 | 'string' => 'The :attribute must be between :min and :max characters.',
30 | 'array' => 'The :attribute must have between :min and :max items.',
31 | ],
32 | 'boolean' => 'The :attribute field must be true or false.',
33 | 'confirmed' => 'The :attribute confirmation does not match.',
34 | 'date' => 'The :attribute is not a valid date.',
35 | 'date_equals' => 'The :attribute must be a date equal to :date.',
36 | 'date_format' => 'The :attribute does not match the format :format.',
37 | 'different' => 'The :attribute and :other must be different.',
38 | 'digits' => 'The :attribute must be :digits digits.',
39 | 'digits_between' => 'The :attribute must be between :min and :max digits.',
40 | 'dimensions' => 'The :attribute has invalid image dimensions.',
41 | 'distinct' => 'The :attribute field has a duplicate value.',
42 | 'email' => 'The :attribute must be a valid email address.',
43 | 'ends_with' => 'The :attribute must end with one of the following: :values',
44 | 'exists' => 'The selected :attribute is invalid.',
45 | 'file' => 'The :attribute must be a file.',
46 | 'filled' => 'The :attribute field must have a value.',
47 | 'gt' => [
48 | 'numeric' => 'The :attribute must be greater than :value.',
49 | 'file' => 'The :attribute must be greater than :value kilobytes.',
50 | 'string' => 'The :attribute must be greater than :value characters.',
51 | 'array' => 'The :attribute must have more than :value items.',
52 | ],
53 | 'gte' => [
54 | 'numeric' => 'The :attribute must be greater than or equal :value.',
55 | 'file' => 'The :attribute must be greater than or equal :value kilobytes.',
56 | 'string' => 'The :attribute must be greater than or equal :value characters.',
57 | 'array' => 'The :attribute must have :value items or more.',
58 | ],
59 | 'image' => 'The :attribute must be an image.',
60 | 'in' => 'The selected :attribute is invalid.',
61 | 'in_array' => 'The :attribute field does not exist in :other.',
62 | 'integer' => 'The :attribute must be an integer.',
63 | 'ip' => 'The :attribute must be a valid IP address.',
64 | 'ipv4' => 'The :attribute must be a valid IPv4 address.',
65 | 'ipv6' => 'The :attribute must be a valid IPv6 address.',
66 | 'json' => 'The :attribute must be a valid JSON string.',
67 | 'lt' => [
68 | 'numeric' => 'The :attribute must be less than :value.',
69 | 'file' => 'The :attribute must be less than :value kilobytes.',
70 | 'string' => 'The :attribute must be less than :value characters.',
71 | 'array' => 'The :attribute must have less than :value items.',
72 | ],
73 | 'lte' => [
74 | 'numeric' => 'The :attribute must be less than or equal :value.',
75 | 'file' => 'The :attribute must be less than or equal :value kilobytes.',
76 | 'string' => 'The :attribute must be less than or equal :value characters.',
77 | 'array' => 'The :attribute must not have more than :value items.',
78 | ],
79 | 'max' => [
80 | 'numeric' => 'The :attribute may not be greater than :max.',
81 | 'file' => 'The :attribute may not be greater than :max kilobytes.',
82 | 'string' => 'The :attribute may not be greater than :max characters.',
83 | 'array' => 'The :attribute may not have more than :max items.',
84 | ],
85 | 'mimes' => 'The :attribute must be a file of type: :values.',
86 | 'mimetypes' => 'The :attribute must be a file of type: :values.',
87 | 'min' => [
88 | 'numeric' => 'The :attribute must be at least :min.',
89 | 'file' => 'The :attribute must be at least :min kilobytes.',
90 | 'string' => 'The :attribute must be at least :min characters.',
91 | 'array' => 'The :attribute must have at least :min items.',
92 | ],
93 | 'not_in' => 'The selected :attribute is invalid.',
94 | 'not_regex' => 'The :attribute format is invalid.',
95 | 'numeric' => 'The :attribute must be a number.',
96 | 'present' => 'The :attribute field must be present.',
97 | 'regex' => 'The :attribute format is invalid.',
98 | 'required' => 'The :attribute field is required.',
99 | 'required_if' => 'The :attribute field is required when :other is :value.',
100 | 'required_unless' => 'The :attribute field is required unless :other is in :values.',
101 | 'required_with' => 'The :attribute field is required when :values is present.',
102 | 'required_with_all' => 'The :attribute field is required when :values are present.',
103 | 'required_without' => 'The :attribute field is required when :values is not present.',
104 | 'required_without_all' => 'The :attribute field is required when none of :values are present.',
105 | 'same' => 'The :attribute and :other must match.',
106 | 'size' => [
107 | 'numeric' => 'The :attribute must be :size.',
108 | 'file' => 'The :attribute must be :size kilobytes.',
109 | 'string' => 'The :attribute must be :size characters.',
110 | 'array' => 'The :attribute must contain :size items.',
111 | ],
112 | 'starts_with' => 'The :attribute must start with one of the following: :values',
113 | 'string' => 'The :attribute must be a string.',
114 | 'timezone' => 'The :attribute must be a valid zone.',
115 | 'unique' => 'The :attribute has already been taken.',
116 | 'uploaded' => 'The :attribute failed to upload.',
117 | 'url' => 'The :attribute format is invalid.',
118 | 'uuid' => 'The :attribute must be a valid UUID.',
119 |
120 | /*
121 | |--------------------------------------------------------------------------
122 | | Custom Validation Language Lines
123 | |--------------------------------------------------------------------------
124 | |
125 | | Here you may specify custom validation messages for attributes using the
126 | | convention "attribute.rule" to name the lines. This makes it quick to
127 | | specify a specific custom language line for a given attribute rule.
128 | |
129 | */
130 |
131 | 'custom' => [
132 | 'attribute-name' => [
133 | 'rule-name' => 'custom-message',
134 | ],
135 | ],
136 |
137 | /*
138 | |--------------------------------------------------------------------------
139 | | Custom Validation Attributes
140 | |--------------------------------------------------------------------------
141 | |
142 | | The following language lines are used to swap our attribute placeholder
143 | | with something more reader friendly such as "E-Mail Address" instead
144 | | of "email". This simply helps us make our message more expressive.
145 | |
146 | */
147 |
148 | 'attributes' => [],
149 |
150 | ];
151 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 | env('APP_NAME', 'Laravel'),
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Application Environment
21 | |--------------------------------------------------------------------------
22 | |
23 | | This value determines the "environment" your application is currently
24 | | running in. This may determine how you prefer to configure various
25 | | services the application utilizes. Set this in your ".env" file.
26 | |
27 | */
28 |
29 | 'env' => env('APP_ENV', 'production'),
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Application Debug Mode
34 | |--------------------------------------------------------------------------
35 | |
36 | | When your application is in debug mode, detailed error messages with
37 | | stack traces will be shown on every error that occurs within your
38 | | application. If disabled, a simple generic error page is shown.
39 | |
40 | */
41 |
42 | 'debug' => env('APP_DEBUG', false),
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Application URL
47 | |--------------------------------------------------------------------------
48 | |
49 | | This URL is used by the console to properly generate URLs when using
50 | | the Artisan command line tool. You should set this to the root of
51 | | your application so that it is used when running Artisan tasks.
52 | |
53 | */
54 |
55 | 'url' => env('APP_URL', 'http://localhost'),
56 |
57 | 'asset_url' => env('ASSET_URL', null),
58 |
59 | /*
60 | |--------------------------------------------------------------------------
61 | | Application Timezone
62 | |--------------------------------------------------------------------------
63 | |
64 | | Here you may specify the default timezone for your application, which
65 | | will be used by the PHP date and date-time functions. We have gone
66 | | ahead and set this to a sensible default for you out of the box.
67 | |
68 | */
69 |
70 | 'timezone' => 'UTC',
71 |
72 | /*
73 | |--------------------------------------------------------------------------
74 | | Application Locale Configuration
75 | |--------------------------------------------------------------------------
76 | |
77 | | The application locale determines the default locale that will be used
78 | | by the translation service provider. You are free to set this value
79 | | to any of the locales which will be supported by the application.
80 | |
81 | */
82 |
83 | 'locale' => 'en',
84 |
85 | /*
86 | |--------------------------------------------------------------------------
87 | | Application Fallback Locale
88 | |--------------------------------------------------------------------------
89 | |
90 | | The fallback locale determines the locale to use when the current one
91 | | is not available. You may change the value to correspond to any of
92 | | the language folders that are provided through your application.
93 | |
94 | */
95 |
96 | 'fallback_locale' => 'en',
97 |
98 | /*
99 | |--------------------------------------------------------------------------
100 | | Faker Locale
101 | |--------------------------------------------------------------------------
102 | |
103 | | This locale will be used by the Faker PHP library when generating fake
104 | | data for your database seeds. For example, this will be used to get
105 | | localized telephone numbers, street address information and more.
106 | |
107 | */
108 |
109 | 'faker_locale' => 'en_US',
110 |
111 | /*
112 | |--------------------------------------------------------------------------
113 | | Encryption Key
114 | |--------------------------------------------------------------------------
115 | |
116 | | This key is used by the Illuminate encrypter service and should be set
117 | | to a random, 32 character string, otherwise these encrypted strings
118 | | will not be safe. Please do this before deploying an application!
119 | |
120 | */
121 |
122 | 'key' => env('APP_KEY'),
123 |
124 | 'cipher' => 'AES-256-CBC',
125 |
126 | /*
127 | |--------------------------------------------------------------------------
128 | | Autoloaded Service Providers
129 | |--------------------------------------------------------------------------
130 | |
131 | | The service providers listed here will be automatically loaded on the
132 | | request to your application. Feel free to add your own services to
133 | | this array to grant expanded functionality to your applications.
134 | |
135 | */
136 |
137 | 'providers' => [
138 |
139 | /*
140 | * Laravel Framework Service Providers...
141 | */
142 | Illuminate\Auth\AuthServiceProvider::class,
143 | Illuminate\Broadcasting\BroadcastServiceProvider::class,
144 | Illuminate\Bus\BusServiceProvider::class,
145 | Illuminate\Cache\CacheServiceProvider::class,
146 | Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
147 | Illuminate\Cookie\CookieServiceProvider::class,
148 | Illuminate\Database\DatabaseServiceProvider::class,
149 | Illuminate\Encryption\EncryptionServiceProvider::class,
150 | Illuminate\Filesystem\FilesystemServiceProvider::class,
151 | Illuminate\Foundation\Providers\FoundationServiceProvider::class,
152 | Illuminate\Hashing\HashServiceProvider::class,
153 | Illuminate\Mail\MailServiceProvider::class,
154 | Illuminate\Notifications\NotificationServiceProvider::class,
155 | Illuminate\Pagination\PaginationServiceProvider::class,
156 | Illuminate\Pipeline\PipelineServiceProvider::class,
157 | Illuminate\Queue\QueueServiceProvider::class,
158 | Illuminate\Redis\RedisServiceProvider::class,
159 | Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
160 | Illuminate\Session\SessionServiceProvider::class,
161 | Illuminate\Translation\TranslationServiceProvider::class,
162 | Illuminate\Validation\ValidationServiceProvider::class,
163 | Illuminate\View\ViewServiceProvider::class,
164 |
165 | /*
166 | * Package Service Providers...
167 | */
168 |
169 | /*
170 | * Application Service Providers...
171 | */
172 | App\Providers\AppServiceProvider::class,
173 | App\Providers\AuthServiceProvider::class,
174 | // App\Providers\BroadcastServiceProvider::class,
175 | App\Providers\EventServiceProvider::class,
176 | App\Providers\RouteServiceProvider::class,
177 |
178 | ],
179 |
180 | /*
181 | |--------------------------------------------------------------------------
182 | | Class Aliases
183 | |--------------------------------------------------------------------------
184 | |
185 | | This array of class aliases will be registered when this application
186 | | is started. However, feel free to register as many as you wish as
187 | | the aliases are "lazy" loaded so they don't hinder performance.
188 | |
189 | */
190 |
191 | 'aliases' => [
192 |
193 | 'App' => Illuminate\Support\Facades\App::class,
194 | 'Arr' => Illuminate\Support\Arr::class,
195 | 'Artisan' => Illuminate\Support\Facades\Artisan::class,
196 | 'Auth' => Illuminate\Support\Facades\Auth::class,
197 | 'Blade' => Illuminate\Support\Facades\Blade::class,
198 | 'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
199 | 'Bus' => Illuminate\Support\Facades\Bus::class,
200 | 'Cache' => Illuminate\Support\Facades\Cache::class,
201 | 'Config' => Illuminate\Support\Facades\Config::class,
202 | 'Cookie' => Illuminate\Support\Facades\Cookie::class,
203 | 'Crypt' => Illuminate\Support\Facades\Crypt::class,
204 | 'DB' => Illuminate\Support\Facades\DB::class,
205 | 'Eloquent' => Illuminate\Database\Eloquent\Model::class,
206 | 'Event' => Illuminate\Support\Facades\Event::class,
207 | 'File' => Illuminate\Support\Facades\File::class,
208 | 'Gate' => Illuminate\Support\Facades\Gate::class,
209 | 'Hash' => Illuminate\Support\Facades\Hash::class,
210 | 'Lang' => Illuminate\Support\Facades\Lang::class,
211 | 'Log' => Illuminate\Support\Facades\Log::class,
212 | 'Mail' => Illuminate\Support\Facades\Mail::class,
213 | 'Notification' => Illuminate\Support\Facades\Notification::class,
214 | 'Password' => Illuminate\Support\Facades\Password::class,
215 | 'Queue' => Illuminate\Support\Facades\Queue::class,
216 | 'Redirect' => Illuminate\Support\Facades\Redirect::class,
217 | 'Redis' => Illuminate\Support\Facades\Redis::class,
218 | 'Request' => Illuminate\Support\Facades\Request::class,
219 | 'Response' => Illuminate\Support\Facades\Response::class,
220 | 'Route' => Illuminate\Support\Facades\Route::class,
221 | 'Schema' => Illuminate\Support\Facades\Schema::class,
222 | 'Session' => Illuminate\Support\Facades\Session::class,
223 | 'Storage' => Illuminate\Support\Facades\Storage::class,
224 | 'Str' => Illuminate\Support\Str::class,
225 | 'URL' => Illuminate\Support\Facades\URL::class,
226 | 'Validator' => Illuminate\Support\Facades\Validator::class,
227 | 'View' => Illuminate\Support\Facades\View::class,
228 |
229 | ],
230 |
231 | /**
232 | * Enablex CREDS
233 | */
234 | 'enx_url' => env('ENABLEX_API_URL'),
235 | 'enx_app_id' => env('ENABLEX_APP_ID'),
236 | 'enx_app_key' => env('ENABLEX_APP_KEY'),
237 | ];
238 |
--------------------------------------------------------------------------------
/public/js/confo.js:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////
2 | //
3 | // File: confo.js
4 | // This is the main application file for client end point. It tries to use Enablex Web Toolkit to
5 | // communicate with EnableX Servers
6 | //
7 | //
8 | /////////////////////////////////////////////////////
9 |
10 | var localStream = null;
11 | var username = null;
12 | var room;
13 | const SUPPORT_URL = "https://developer.enablex.io";
14 | // Player Options
15 | var options = {
16 | id: "vcx_1001",
17 | attachMode: "",
18 | player: {
19 | autoplay: "",
20 | name: "",
21 | nameDisplayMode: "",
22 | frameFitMode: "bestFit",
23 | skin: "classic",
24 | class: "player_mode",
25 | aspectRatio: "",
26 | volume: 0,
27 | media: "",
28 | loader: {
29 | show: false,
30 | url: window.site_url + "/img/loader.gif",
31 | style: "default",
32 | class: ""
33 | },
34 | backgroundImg: window.site_url + "/img/player-bg.gif"
35 | },
36 | toolbar: {
37 | displayMode: "auto",
38 | autoDisplayTimeout: 0,
39 | position: "top",
40 | skin: "default",
41 | iconset: "default",
42 | class: "",
43 | buttons: {
44 | play: false,
45 | share: false,
46 | mic: false,
47 | resize: false,
48 | volume: false,
49 | mute: false,
50 | record: false,
51 | playtime: false,
52 | zoom: false
53 | },
54 | branding: {
55 | display: false,
56 | clickthru: "https://www.enablex.io",
57 | target: "new",
58 | logo: window.site_url + "/img/enablex.png",
59 | title: "EnableX",
60 | position: "right"
61 | }
62 | }
63 | };
64 |
65 | window.onload = function() {
66 | EnxRtc.Logger.setLogLevel(4);
67 | var name = urlData.user_ref;
68 | var config = {
69 | audio: true,
70 | video: true,
71 | data: true,
72 | videoSize: [320, 180, 640, 480],
73 | attributes: {
74 | name: name
75 | },
76 | options: options
77 | };
78 |
79 | var countStream = 0;
80 | var username;
81 | var localStreamId = null;
82 | var setLiveStream = function(stream, userName) {
83 | // Listening to Text Data
84 | stream.addEventListener("stream-data", function(e) {
85 | var text = e.msg.textMessage;
86 | var html = $("#multi_text_container_div").html();
87 | $("#multi_text_container_div").html(html + text + "
");
88 | });
89 |
90 | if (!stream.local) {
91 | var newStreamDiv = document.createElement("div");
92 | newStreamDiv.setAttribute("id", "liveStream_" + countStream);
93 | newStreamDiv.setAttribute("class", "live_stream_div");
94 | document
95 | .getElementById("multi_video_container_div")
96 | .appendChild(newStreamDiv);
97 | stream.show("liveStream_" + countStream, options);
98 | var node = document.createElement("div");
99 | if (userName !== "") {
100 | node.innerHTML = userName;
101 | node.classList.add("name-div");
102 | document
103 | .getElementById("multi_video_container_div")
104 | .appendChild(node);
105 | }
106 |
107 | countStream++;
108 | } else {
109 | username = stream.getAttributes().name;
110 | options.player.loader.class = "";
111 | options.player.loader.show = false;
112 | stream.show("local_video_div", options);
113 | var node = document.createElement("div");
114 | node.innerHTML = username;
115 | node.classList.add("name-div");
116 | document.getElementById("local_video_div").appendChild(node);
117 | }
118 | };
119 | // Function: To create user-json for Token Request
120 | var createDataJson = function(url) {
121 | username = urlData.user_ref;
122 | var retData = {
123 | name: urlData.user_ref,
124 | role: urlData.usertype,
125 | roomId: urlData.roomId,
126 | user_ref: urlData.user_ref
127 | };
128 | return retData;
129 | };
130 |
131 | // Function: Create Token
132 | createToken(createDataJson(window.location.href), function(response) {
133 | var token = response;
134 | var ATList = [];
135 |
136 | // JOin Room
137 | localStream = EnxRtc.joinRoom(token, config, function(success, error) {
138 | if (error && error != null) {
139 | }
140 | if (success && success != null) {
141 | room = success.room;
142 | var ownId = success.publishId;
143 | setLiveStream(localStream);
144 | for (var i = 0; i < success.streams.length; i++) {
145 | room.subscribe(success.streams[i]);
146 | }
147 |
148 | // Active Talker list is updated
149 | room.addEventListener("active-talkers-updated", function(
150 | event
151 | ) {
152 | ATList = event.message.activeList;
153 | var video_player_len = document.querySelector(
154 | "#multi_video_container_div"
155 | ).childNodes;
156 | if (
157 | event.message &&
158 | event.message !== null &&
159 | event.message.activeList &&
160 | event.message.activeList !== null
161 | ) {
162 | if (ATList.length == video_player_len.length) {
163 | return;
164 | } else {
165 | document.querySelector(
166 | "#multi_video_container_div"
167 | ).innerHTML = "";
168 | for (stream in room.remoteStreams.getAll()) {
169 | var st = room.remoteStreams.getAll()[stream];
170 | for (j = 0; j < ATList.length; j++) {
171 | if (ATList[j].streamId == st.getID()) {
172 | setLiveStream(st, ATList[j].name);
173 | }
174 | }
175 | }
176 | }
177 | }
178 | console.log(
179 | "Active Talker List :- " + JSON.stringify(event)
180 | );
181 | });
182 |
183 | // Stream has been subscribed successfully
184 | room.addEventListener("stream-subscribed", function(
185 | streamEvent
186 | ) {
187 | var stream =
188 | streamEvent.data && streamEvent.data.stream
189 | ? streamEvent.data.stream
190 | : streamEvent.stream;
191 | for (k = 0; k < ATList.length; k++) {
192 | if (ATList[k].streamId == stream.getID()) {
193 | setLiveStream(stream, ATList[k].name);
194 | }
195 | }
196 | });
197 |
198 | // Listening to Incoming Data
199 | room.addEventListener("active-talker-data-in", function(data) {
200 | console.log("active-talker-data-in" + data);
201 | var obj = {
202 | msg: data.message.message,
203 | timestamp: data.message.timestamp,
204 | username: data.message.from
205 | };
206 | // Handle UI to display message
207 | });
208 |
209 | // Stream went out of Room
210 | room.addEventListener("stream-removed", function(event) {
211 | console.log(event);
212 | });
213 | }
214 | });
215 | });
216 | };
217 |
218 | $(document).on("click", "div.vcx_bar", function(e) {
219 | $(this)
220 | .parent()
221 | .parent()
222 | .toggleClass("fullScreen");
223 | });
224 |
225 | $(document).on("click", ".nav-tabs li a", function(e) {
226 | $(document)
227 | .find(".nav-tabs li")
228 | .removeClass("active");
229 | $(this)
230 | .parent()
231 | .addClass("active");
232 | $(document)
233 | .find("div.tab-pane")
234 | .removeClass("active");
235 | var activeDivId = $(this).attr("href");
236 | $(activeDivId).addClass("active");
237 | });
238 |
239 | $(document).on("click", "#sendText", function(e) {
240 | var rawText = $("#textArea").val();
241 | var text = username + ": " + rawText;
242 | $("#textArea").val("");
243 | localStream.sendData({ textMessage: text });
244 | });
245 |
246 | $(document).on("click", "#user_radio", function(e) {
247 | $(document)
248 | .find(".user_select_div")
249 | .show();
250 | });
251 |
252 | $(document).on("click", "#all_user_radio", function(e) {
253 | $(document)
254 | .find(".user_select_div")
255 | .hide();
256 | });
257 |
258 | function audioMute() {
259 | var elem = document.getElementsByClassName("icon-confo-mute")[0];
260 | var onImgPath = window.site_url + "/img/mike.png",
261 | onImgName = "mike.png";
262 | var offImgPath = window.site_url + "/img/mute-mike.png",
263 | offImgName = "mute-mike.png";
264 | var currentImgPath = elem.src.split("/")[elem.src.split("/").length - 1];
265 | if (currentImgPath === offImgName) {
266 | localStream.unmuteAudio(function(arg) {
267 | elem.src = onImgPath;
268 | elem.title = "mute audio";
269 | });
270 | } else if (currentImgPath === onImgName) {
271 | localStream.muteAudio(function(arg) {
272 | elem.src = offImgPath;
273 | elem.title = "unmute audio";
274 | });
275 | }
276 | }
277 | function videoMute() {
278 | var elem = document.getElementsByClassName("icon-confo-video-mute")[0];
279 | var onImgPath = window.site_url + "/img/video.png",
280 | onImgName = "video.png";
281 | var offImgPath = window.site_url + "/img/mute-video.png",
282 | offImgName = "mute-video.png";
283 | var currentImgPath = elem.src.split("/")[elem.src.split("/").length - 1];
284 | if (currentImgPath === offImgName) {
285 | localStream.unmuteVideo(function(res) {
286 | var streamId = localStream.getID();
287 | var player = document.getElementById("stream" + streamId);
288 | player.srcObject = localStream.stream;
289 | player.play();
290 | elem.src = onImgPath;
291 | elem.title = "mute video";
292 | });
293 | } else if (currentImgPath === onImgName) {
294 | localStream.muteVideo(function(res) {
295 | elem.src = offImgPath;
296 | elem.title = "unmute video";
297 | });
298 | }
299 | }
300 |
301 | function endCall() {
302 | var r = confirm("You want to quit?");
303 | if (r == true) {
304 | window.location.href = SUPPORT_URL;
305 | }
306 | }
307 |
--------------------------------------------------------------------------------
/public/css/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: #293840;
3 | color: #000;
4 | font: 14px Arial;
5 | margin: 0 auto;
6 | padding: 0;
7 | position: relative;
8 | }
9 | h1 {
10 | font-size: 28px;
11 | }
12 | h2 {
13 | font-size: 26px;
14 | }
15 | h3 {
16 | font-size: 18px;
17 | }
18 | h4 {
19 | font-size: 16px;
20 | }
21 | h5 {
22 | font-size: 14px;
23 | }
24 | h6 {
25 | font-size: 12px;
26 | }
27 | h1,
28 | h2,
29 | h3,
30 | h4,
31 | h5,
32 | h6 {
33 | color: #563d64;
34 | }
35 | small {
36 | font-size: 10px;
37 | }
38 | b,
39 | strong {
40 | font-weight: bold;
41 | }
42 | a {
43 | text-decoration: none;
44 | }
45 | a:hover {
46 | text-decoration: underline;
47 | }
48 | .left {
49 | float: left;
50 | }
51 | .right {
52 | float: right;
53 | }
54 | .alignleft {
55 | float: left;
56 | margin-right: 15px;
57 | }
58 | .alignright {
59 | float: right;
60 | margin-left: 15px;
61 | }
62 | .clearfix:after,
63 | form:after {
64 | content: ".";
65 | display: block;
66 | height: 0;
67 | clear: both;
68 | visibility: hidden;
69 | }
70 | .container {
71 | margin: 25px auto;
72 | position: relative;
73 | width: 900px;
74 | }
75 | #content {
76 | background: #f9f9f9;
77 | background: -moz-linear-gradient(
78 | top,
79 | rgba(248, 248, 248, 1) 0%,
80 | rgba(249, 249, 249, 1) 100%
81 | );
82 | background: -webkit-linear-gradient(
83 | top,
84 | rgba(248, 248, 248, 1) 0%,
85 | rgba(249, 249, 249, 1) 100%
86 | );
87 | background: -o-linear-gradient(
88 | top,
89 | rgba(248, 248, 248, 1) 0%,
90 | rgba(249, 249, 249, 1) 100%
91 | );
92 | background: -ms-linear-gradient(
93 | top,
94 | rgba(248, 248, 248, 1) 0%,
95 | rgba(249, 249, 249, 1) 100%
96 | );
97 | background: linear-gradient(
98 | top,
99 | rgba(248, 248, 248, 1) 0%,
100 | rgba(249, 249, 249, 1) 100%
101 | );
102 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8f8f8', endColorstr='#f9f9f9',GradientType=0 );
103 | -webkit-box-shadow: 0 1px 0 #fff inset;
104 | -moz-box-shadow: 0 1px 0 #fff inset;
105 | -ms-box-shadow: 0 1px 0 #fff inset;
106 | -o-box-shadow: 0 1px 0 #fff inset;
107 | box-shadow: 0 1px 0 #fff inset;
108 | border: 1px solid #c4c6ca;
109 | margin: 0 auto;
110 | padding: 25px 0 0;
111 | position: relative;
112 | text-align: center;
113 | text-shadow: 0 1px 0 #fff;
114 | width: 400px;
115 | }
116 | #content h1 {
117 | color: #7e7e7e;
118 | font: bold 25px Helvetica, Arial, sans-serif;
119 | letter-spacing: -0.05em;
120 | line-height: 20px;
121 | margin: 10px 0 30px;
122 | }
123 | #content h1:before,
124 | #content h1:after {
125 | content: "";
126 | height: 1px;
127 | position: absolute;
128 | top: 17px;
129 | width: 27%;
130 | }
131 |
132 | #content h1:after {
133 | background: rgb(126, 126, 126);
134 | background: -moz-linear-gradient(
135 | left,
136 | rgba(126, 126, 126, 1) 0%,
137 | rgba(255, 255, 255, 1) 100%
138 | );
139 | background: -webkit-linear-gradient(
140 | left,
141 | rgba(126, 126, 126, 1) 0%,
142 | rgba(255, 255, 255, 1) 100%
143 | );
144 | background: -o-linear-gradient(
145 | left,
146 | rgba(126, 126, 126, 1) 0%,
147 | rgba(255, 255, 255, 1) 100%
148 | );
149 | background: -ms-linear-gradient(
150 | left,
151 | rgba(126, 126, 126, 1) 0%,
152 | rgba(255, 255, 255, 1) 100%
153 | );
154 | background: linear-gradient(
155 | left,
156 | rgba(126, 126, 126, 1) 0%,
157 | rgba(255, 255, 255, 1) 100%
158 | );
159 | right: 0;
160 | }
161 | #content h1:before {
162 | background: rgb(126, 126, 126);
163 | background: -moz-linear-gradient(
164 | right,
165 | rgba(126, 126, 126, 1) 0%,
166 | rgba(255, 255, 255, 1) 100%
167 | );
168 | background: -webkit-linear-gradient(
169 | right,
170 | rgba(126, 126, 126, 1) 0%,
171 | rgba(255, 255, 255, 1) 100%
172 | );
173 | background: -o-linear-gradient(
174 | right,
175 | rgba(126, 126, 126, 1) 0%,
176 | rgba(255, 255, 255, 1) 100%
177 | );
178 | background: -ms-linear-gradient(
179 | right,
180 | rgba(126, 126, 126, 1) 0%,
181 | rgba(255, 255, 255, 1) 100%
182 | );
183 | background: linear-gradient(
184 | right,
185 | rgba(126, 126, 126, 1) 0%,
186 | rgba(255, 255, 255, 1) 100%
187 | );
188 | left: 0;
189 | }
190 | #content:after,
191 | #content:before {
192 | background: #f9f9f9;
193 | background: -moz-linear-gradient(
194 | top,
195 | rgba(248, 248, 248, 1) 0%,
196 | rgba(249, 249, 249, 1) 100%
197 | );
198 | background: -webkit-linear-gradient(
199 | top,
200 | rgba(248, 248, 248, 1) 0%,
201 | rgba(249, 249, 249, 1) 100%
202 | );
203 | background: -o-linear-gradient(
204 | top,
205 | rgba(248, 248, 248, 1) 0%,
206 | rgba(249, 249, 249, 1) 100%
207 | );
208 | background: -ms-linear-gradient(
209 | top,
210 | rgba(248, 248, 248, 1) 0%,
211 | rgba(249, 249, 249, 1) 100%
212 | );
213 | background: linear-gradient(
214 | top,
215 | rgba(248, 248, 248, 1) 0%,
216 | rgba(249, 249, 249, 1) 100%
217 | );
218 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8f8f8', endColorstr='#f9f9f9',GradientType=0 );
219 | border: 1px solid #c4c6ca;
220 | content: "";
221 | display: block;
222 | height: 100%;
223 | left: -1px;
224 | position: absolute;
225 | width: 100%;
226 | }
227 | #content:after {
228 | -webkit-transform: rotate(2deg);
229 | -moz-transform: rotate(2deg);
230 | -ms-transform: rotate(2deg);
231 | -o-transform: rotate(2deg);
232 | transform: rotate(2deg);
233 | top: 0;
234 | z-index: -1;
235 | }
236 | #content:before {
237 | -webkit-transform: rotate(-3deg);
238 | -moz-transform: rotate(-3deg);
239 | -ms-transform: rotate(-3deg);
240 | -o-transform: rotate(-3deg);
241 | transform: rotate(-3deg);
242 | top: 0;
243 | z-index: -2;
244 | }
245 | #content form {
246 | margin: 0 20px;
247 | position: relative;
248 | }
249 | #content form input[type="text"],
250 | #content form input[type="password"] {
251 | -webkit-border-radius: 3px;
252 | -moz-border-radius: 3px;
253 | -ms-border-radius: 3px;
254 | -o-border-radius: 3px;
255 | border-radius: 3px;
256 | -webkit-box-shadow: 0 1px 0 #fff, 0 -2px 5px rgba(0, 0, 0, 0.08) inset;
257 | -moz-box-shadow: 0 1px 0 #fff, 0 -2px 5px rgba(0, 0, 0, 0.08) inset;
258 | -ms-box-shadow: 0 1px 0 #fff, 0 -2px 5px rgba(0, 0, 0, 0.08) inset;
259 | -o-box-shadow: 0 1px 0 #fff, 0 -2px 5px rgba(0, 0, 0, 0.08) inset;
260 | box-shadow: 0 1px 0 #fff, 0 -2px 5px rgba(0, 0, 0, 0.08) inset;
261 | -webkit-transition: all 0.5s ease;
262 | -moz-transition: all 0.5s ease;
263 | -ms-transition: all 0.5s ease;
264 | -o-transition: all 0.5s ease;
265 | transition: all 0.5s ease;
266 |
267 | border: 1px solid #c8c8c8;
268 | color: #777;
269 | font: 13px Helvetica, Arial, sans-serif;
270 | margin: 0 0 10px;
271 | padding: 15px 10px 15px 40px;
272 | width: 80%;
273 | }
274 | #content form input[type="text"]:focus,
275 | #content form input[type="password"]:focus {
276 | -webkit-box-shadow: 0 0 2px #ed1c24 inset;
277 | -moz-box-shadow: 0 0 2px #ed1c24 inset;
278 | -ms-box-shadow: 0 0 2px #ed1c24 inset;
279 | -o-box-shadow: 0 0 2px #ed1c24 inset;
280 | box-shadow: 0 0 2px #ed1c24 inset;
281 | background-color: #fff;
282 | border: 1px solid #ed1c24;
283 | outline: none;
284 | }
285 | #username {
286 | background-position: 10px 10px !important;
287 | }
288 | #password {
289 | background-position: 10px -53px !important;
290 | }
291 | /*#content form input[type="submit"] {*/
292 | /*background: rgb(254,231,154);*/
293 | /*background: -moz-linear-gradient(top, rgba(254,231,154,1) 0%, rgba(254,193,81,1) 100%);*/
294 | /*background: -webkit-linear-gradient(top, rgba(254,231,154,1) 0%,rgba(254,193,81,1) 100%);*/
295 | /*background: -o-linear-gradient(top, rgba(254,231,154,1) 0%,rgba(254,193,81,1) 100%);*/
296 | /*background: -ms-linear-gradient(top, rgba(254,231,154,1) 0%,rgba(254,193,81,1) 100%);*/
297 | /*background: linear-gradient(top, rgba(254,231,154,1) 0%,rgba(254,193,81,1) 100%);*/
298 | /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fee79a', endColorstr='#fec151',GradientType=0 );*/
299 | /*-webkit-border-radius: 30px;*/
300 | /*-moz-border-radius: 30px;*/
301 | /*-ms-border-radius: 30px;*/
302 | /*-o-border-radius: 30px;*/
303 | /*border-radius: 30px;*/
304 | /*-webkit-box-shadow: 0 1px 0 rgba(255,255,255,0.8) inset;*/
305 | /*-moz-box-shadow: 0 1px 0 rgba(255,255,255,0.8) inset;*/
306 | /*-ms-box-shadow: 0 1px 0 rgba(255,255,255,0.8) inset;*/
307 | /*-o-box-shadow: 0 1px 0 rgba(255,255,255,0.8) inset;*/
308 | /*box-shadow: 0 1px 0 rgba(255,255,255,0.8) inset;*/
309 | /*border: 1px solid #D69E31;*/
310 | /*color: #85592e;*/
311 | /*cursor: pointer;*/
312 | /*float: left;*/
313 | /*font: bold 15px Helvetica, Arial, sans-serif;*/
314 | /*height: 35px;*/
315 | /*margin: 20px 0 35px 15px;*/
316 | /*position: relative;*/
317 | /*text-shadow: 0 1px 0 rgba(255,255,255,0.5);*/
318 | /*width: 120px;*/
319 | /*}*/
320 | /*#content form input[type="submit"]:hover {*/
321 | /*background: rgb(254,193,81);*/
322 | /*background: -moz-linear-gradient(top, rgba(254,193,81,1) 0%, rgba(254,231,154,1) 100%);*/
323 | /*background: -webkit-linear-gradient(top, rgba(254,193,81,1) 0%,rgba(254,231,154,1) 100%);*/
324 | /*background: -o-linear-gradient(top, rgba(254,193,81,1) 0%,rgba(254,231,154,1) 100%);*/
325 | /*background: -ms-linear-gradient(top, rgba(254,193,81,1) 0%,rgba(254,231,154,1) 100%);*/
326 | /*background: linear-gradient(top, rgba(254,193,81,1) 0%,rgba(254,231,154,1) 100%);*/
327 | /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fec151', endColorstr='#fee79a',GradientType=0 );*/
328 | /*}*/
329 | #content form div a {
330 | color: #004a80;
331 | // float: right;
332 | font-size: 12px;
333 | // margin: 30px 15px 0 0;
334 | text-decoration: none;
335 | }
336 | .button {
337 | background: rgb(247, 249, 250);
338 | background: -moz-linear-gradient(
339 | top,
340 | rgba(247, 249, 250, 1) 0%,
341 | rgba(240, 240, 240, 1) 100%
342 | );
343 | background: -webkit-linear-gradient(
344 | top,
345 | rgba(247, 249, 250, 1) 0%,
346 | rgba(240, 240, 240, 1) 100%
347 | );
348 | background: -o-linear-gradient(
349 | top,
350 | rgba(247, 249, 250, 1) 0%,
351 | rgba(240, 240, 240, 1) 100%
352 | );
353 | background: -ms-linear-gradient(
354 | top,
355 | rgba(247, 249, 250, 1) 0%,
356 | rgba(240, 240, 240, 1) 100%
357 | );
358 | background: linear-gradient(
359 | top,
360 | rgba(247, 249, 250, 1) 0%,
361 | rgba(240, 240, 240, 1) 100%
362 | );
363 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7f9fa', endColorstr='#f0f0f0',GradientType=0 );
364 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
365 | -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
366 | -ms-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
367 | -o-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
368 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
369 | -webkit-border-radius: 0 0 5px 5px;
370 | -moz-border-radius: 0 0 5px 5px;
371 | -o-border-radius: 0 0 5px 5px;
372 | -ms-border-radius: 0 0 5px 5px;
373 | border-radius: 0 0 5px 5px;
374 | border-top: 1px solid #cfd5d9;
375 | padding: 15px 0;
376 | }
377 | .button a {
378 | color: #7e7e7e;
379 | font-size: 17px;
380 | padding: 2px 0 2px 40px;
381 | text-decoration: none;
382 | -webkit-transition: all 0.3s ease;
383 | -moz-transition: all 0.3s ease;
384 | -ms-transition: all 0.3s ease;
385 | -o-transition: all 0.3s ease;
386 | transition: all 0.3s ease;
387 | }
388 | .button a:hover {
389 | background-position: 0 -135px;
390 | color: #00aeef;
391 | }
392 | .login_buttons {
393 | width: 95%;
394 | margin: 5px;
395 | height: 47px;
396 | color: #d6d6d6;
397 | background: #444;
398 | border-radius: 3px;
399 | box-shadow: 0 1px 0 #fff, 0 -2px 5px rgba(0, 0, 0, 0.08) inset;
400 | cursor: pointer;
401 | border: 1px solid #c8c8c8;
402 | border-radius: 5px;
403 | }
404 | .login_buttons:hover {
405 | box-shadow: 0 6px 0 #fff, 0 -4px 15px rgba(0, 0, 0, 0.08) inset;
406 | }
407 | .login_buttons:active {
408 | box-shadow: 0 6px 0 #fff, 0 -4px 15px rgba(0, 0, 0, 0.08) inset;
409 | }
410 | .login_join_div {
411 | display: none;
412 | }
413 |
414 | .loading {
415 | display: none;
416 | }
417 |
418 | .loading.yes {
419 | display: block;
420 | }
421 |
--------------------------------------------------------------------------------
/public/js/jquery.toast.js:
--------------------------------------------------------------------------------
1 | // jQuery toast plugin created by Kamran Ahmed copyright MIT license 2015
2 | if ( typeof Object.create !== 'function' ) {
3 | Object.create = function( obj ) {
4 | function F() {}
5 | F.prototype = obj;
6 | return new F();
7 | };
8 | }
9 |
10 | (function( $, window, document, undefined ) {
11 |
12 | "use strict";
13 |
14 | var Toast = {
15 |
16 | _positionClasses : ['bottom-left', 'bottom-right', 'top-right', 'top-left', 'bottom-center', 'top-center', 'mid-center'],
17 | _defaultIcons : ['success', 'error', 'info', 'warning'],
18 |
19 | init: function (options, elem) {
20 | this.prepareOptions(options, $.toast.options);
21 | this.process();
22 | },
23 |
24 | prepareOptions: function(options, options_to_extend) {
25 | var _options = {};
26 | if ( ( typeof options === 'string' ) || ( options instanceof Array ) ) {
27 | _options.text = options;
28 | } else {
29 | _options = options;
30 | }
31 | this.options = $.extend( {}, options_to_extend, _options );
32 | },
33 |
34 | process: function () {
35 | this.setup();
36 | this.addToDom();
37 | this.position();
38 | this.bindToast();
39 | this.animate();
40 | },
41 |
42 | setup: function () {
43 |
44 | var _toastContent = '';
45 |
46 | this._toastEl = this._toastEl || $('', {
47 | class : 'jq-toast-single'
48 | });
49 |
50 | // For the loader on top
51 | _toastContent += '';
52 |
53 | if ( this.options.allowToastClose ) {
54 | _toastContent += '×';
55 | };
56 |
57 | if ( this.options.text instanceof Array ) {
58 |
59 | if ( this.options.heading ) {
60 | _toastContent +='' + this.options.heading + '
';
61 | };
62 |
63 | _toastContent += '';
64 | for (var i = 0; i < this.options.text.length; i++) {
65 | _toastContent += '- ' + this.options.text[i] + '
';
66 | }
67 | _toastContent += '
';
68 |
69 | } else {
70 | if ( this.options.heading ) {
71 | _toastContent +='' + this.options.heading + '
';
72 | };
73 | _toastContent += this.options.text;
74 | }
75 |
76 | this._toastEl.html( _toastContent );
77 |
78 | if ( this.options.bgColor !== false ) {
79 | this._toastEl.css("background-color", this.options.bgColor);
80 | };
81 |
82 | if ( this.options.textColor !== false ) {
83 | this._toastEl.css("color", this.options.textColor);
84 | };
85 |
86 | if ( this.options.textAlign ) {
87 | this._toastEl.css('text-align', this.options.textAlign);
88 | }
89 |
90 | if ( this.options.icon !== false ) {
91 | this._toastEl.addClass('jq-has-icon');
92 |
93 | if ( $.inArray(this.options.icon, this._defaultIcons) !== -1 ) {
94 | this._toastEl.addClass('jq-icon-' + this.options.icon);
95 | };
96 | };
97 |
98 | if ( this.options.class !== false ){
99 | this._toastEl.addClass(this.options.class)
100 | }
101 | },
102 |
103 | position: function () {
104 | if ( ( typeof this.options.position === 'string' ) && ( $.inArray( this.options.position, this._positionClasses) !== -1 ) ) {
105 |
106 | if ( this.options.position === 'bottom-center' ) {
107 | this._container.css({
108 | left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2,
109 | bottom: 20
110 | });
111 | } else if ( this.options.position === 'top-center' ) {
112 | this._container.css({
113 | left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2,
114 | top: 20
115 | });
116 | } else if ( this.options.position === 'mid-center' ) {
117 | this._container.css({
118 | left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2,
119 | top: ( $(window).outerHeight() / 2 ) - this._container.outerHeight()/2
120 | });
121 | } else {
122 | this._container.addClass( this.options.position );
123 | }
124 |
125 | } else if ( typeof this.options.position === 'object' ) {
126 | this._container.css({
127 | top : this.options.position.top ? this.options.position.top : 'auto',
128 | bottom : this.options.position.bottom ? this.options.position.bottom : 'auto',
129 | left : this.options.position.left ? this.options.position.left : 'auto',
130 | right : this.options.position.right ? this.options.position.right : 'auto'
131 | });
132 | } else {
133 | this._container.addClass( 'bottom-left' );
134 | }
135 | },
136 |
137 | bindToast: function () {
138 |
139 | var that = this;
140 |
141 | this._toastEl.on('afterShown', function () {
142 | that.processLoader();
143 | });
144 |
145 | this._toastEl.find('.close-jq-toast-single').on('click', function ( e ) {
146 |
147 | e.preventDefault();
148 |
149 | if( that.options.showHideTransition === 'fade') {
150 | that._toastEl.trigger('beforeHide');
151 | that._toastEl.fadeOut(function () {
152 | that._toastEl.trigger('afterHidden');
153 | });
154 | } else if ( that.options.showHideTransition === 'slide' ) {
155 | that._toastEl.trigger('beforeHide');
156 | that._toastEl.slideUp(function () {
157 | that._toastEl.trigger('afterHidden');
158 | });
159 | } else {
160 | that._toastEl.trigger('beforeHide');
161 | that._toastEl.hide(function () {
162 | that._toastEl.trigger('afterHidden');
163 | });
164 | }
165 | });
166 |
167 | if ( typeof this.options.beforeShow == 'function' ) {
168 | this._toastEl.on('beforeShow', function () {
169 | that.options.beforeShow(that._toastEl);
170 | });
171 | };
172 |
173 | if ( typeof this.options.afterShown == 'function' ) {
174 | this._toastEl.on('afterShown', function () {
175 | that.options.afterShown(that._toastEl);
176 | });
177 | };
178 |
179 | if ( typeof this.options.beforeHide == 'function' ) {
180 | this._toastEl.on('beforeHide', function () {
181 | that.options.beforeHide(that._toastEl);
182 | });
183 | };
184 |
185 | if ( typeof this.options.afterHidden == 'function' ) {
186 | this._toastEl.on('afterHidden', function () {
187 | that.options.afterHidden(that._toastEl);
188 | });
189 | };
190 |
191 | if ( typeof this.options.onClick == 'function' ) {
192 | this._toastEl.on('click', function () {
193 | that.options.onClick(that._toastEl);
194 | });
195 | };
196 | },
197 |
198 | addToDom: function () {
199 |
200 | var _container = $('.jq-toast-wrap');
201 |
202 | if ( _container.length === 0 ) {
203 |
204 | _container = $('',{
205 | class: "jq-toast-wrap",
206 | role: "alert",
207 | "aria-live": "polite"
208 | });
209 |
210 | $('body').append( _container );
211 |
212 | } else if ( !this.options.stack || isNaN( parseInt(this.options.stack, 10) ) ) {
213 | _container.empty();
214 | }
215 |
216 | _container.find('.jq-toast-single:hidden').remove();
217 |
218 | _container.append( this._toastEl );
219 |
220 | if ( this.options.stack && !isNaN( parseInt( this.options.stack ), 10 ) ) {
221 |
222 | var _prevToastCount = _container.find('.jq-toast-single').length,
223 | _extToastCount = _prevToastCount - this.options.stack;
224 |
225 | if ( _extToastCount > 0 ) {
226 | $('.jq-toast-wrap').find('.jq-toast-single').slice(0, _extToastCount).remove();
227 | };
228 |
229 | }
230 |
231 | this._container = _container;
232 | },
233 |
234 | canAutoHide: function () {
235 | return ( this.options.hideAfter !== false ) && !isNaN( parseInt( this.options.hideAfter, 10 ) );
236 | },
237 |
238 | processLoader: function () {
239 | // Show the loader only, if auto-hide is on and loader is demanded
240 | if (!this.canAutoHide() || this.options.loader === false) {
241 | return false;
242 | }
243 |
244 | var loader = this._toastEl.find('.jq-toast-loader');
245 |
246 | // 400 is the default time that jquery uses for fade/slide
247 | // Divide by 1000 for milliseconds to seconds conversion
248 | var transitionTime = (this.options.hideAfter - 400) / 1000 + 's';
249 | var loaderBg = this.options.loaderBg;
250 |
251 | var style = loader.attr('style') || '';
252 | style = style.substring(0, style.indexOf('-webkit-transition')); // Remove the last transition definition
253 |
254 | style += '-webkit-transition: width ' + transitionTime + ' ease-in; \
255 | -o-transition: width ' + transitionTime + ' ease-in; \
256 | transition: width ' + transitionTime + ' ease-in; \
257 | background-color: ' + loaderBg + ';';
258 |
259 |
260 | loader.attr('style', style).addClass('jq-toast-loaded');
261 | },
262 |
263 | animate: function () {
264 |
265 | var that = this;
266 |
267 | this._toastEl.hide();
268 |
269 | this._toastEl.trigger('beforeShow');
270 |
271 | if ( this.options.showHideTransition.toLowerCase() === 'fade' ) {
272 | this._toastEl.fadeIn(function ( ){
273 | that._toastEl.trigger('afterShown');
274 | });
275 | } else if ( this.options.showHideTransition.toLowerCase() === 'slide' ) {
276 | this._toastEl.slideDown(function ( ){
277 | that._toastEl.trigger('afterShown');
278 | });
279 | } else {
280 | this._toastEl.show(function ( ){
281 | that._toastEl.trigger('afterShown');
282 | });
283 | }
284 |
285 | if (this.canAutoHide()) {
286 |
287 | var that = this;
288 |
289 | window.setTimeout(function(){
290 |
291 | if ( that.options.showHideTransition.toLowerCase() === 'fade' ) {
292 | that._toastEl.trigger('beforeHide');
293 | that._toastEl.fadeOut(function () {
294 | that._toastEl.trigger('afterHidden');
295 | });
296 | } else if ( that.options.showHideTransition.toLowerCase() === 'slide' ) {
297 | that._toastEl.trigger('beforeHide');
298 | that._toastEl.slideUp(function () {
299 | that._toastEl.trigger('afterHidden');
300 | });
301 | } else {
302 | that._toastEl.trigger('beforeHide');
303 | that._toastEl.hide(function () {
304 | that._toastEl.trigger('afterHidden');
305 | });
306 | }
307 |
308 | }, this.options.hideAfter);
309 | };
310 | },
311 |
312 | reset: function ( resetWhat ) {
313 |
314 | if ( resetWhat === 'all' ) {
315 | $('.jq-toast-wrap').remove();
316 | } else {
317 | this._toastEl.remove();
318 | }
319 |
320 | },
321 |
322 | update: function(options) {
323 | this.prepareOptions(options, this.options);
324 | this.setup();
325 | this.bindToast();
326 | },
327 |
328 | close: function() {
329 | this._toastEl.find('.close-jq-toast-single').click();
330 | }
331 | };
332 |
333 | $.toast = function(options) {
334 | var toast = Object.create(Toast);
335 | toast.init(options, this);
336 |
337 | return {
338 |
339 | reset: function ( what ) {
340 | toast.reset( what );
341 | },
342 |
343 | update: function( options ) {
344 | toast.update( options );
345 | },
346 |
347 | close: function( ) {
348 | toast.close( );
349 | }
350 | }
351 | };
352 |
353 | $.toast.options = {
354 | text: '',
355 | heading: '',
356 | showHideTransition: 'fade',
357 | allowToastClose: true,
358 | hideAfter: 3000,
359 | loader: true,
360 | loaderBg: '#9EC600',
361 | stack: 5,
362 | position: 'bottom-left',
363 | bgColor: false,
364 | textColor: false,
365 | textAlign: 'left',
366 | icon: false,
367 | beforeShow: function () {},
368 | afterShown: function () {},
369 | beforeHide: function () {},
370 | afterHidden: function () {},
371 | onClick: function () {}
372 | };
373 |
374 | })( jQuery, window, document );
375 |
--------------------------------------------------------------------------------