Page MenuHomePhorge

D2518.1775181952.diff
No OneTemporary

Authored By
Unknown
Size
56 KB
Referenced Files
None
Subscribers
None

D2518.1775181952.diff

diff --git a/src/resources/js/meet/app.js b/src/resources/js/meet/app.js
--- a/src/resources/js/meet/app.js
+++ b/src/resources/js/meet/app.js
@@ -42,6 +42,7 @@
let publishersContainer
let subscribersContainer
let scrollStop
+ let $t
OV = ovInit()
@@ -105,6 +106,7 @@
* onConnectionChange - Callback for participant changes, e.g. role update,
* onSessionDataUpdate - Callback for current user connection update,
* onMediaSetup - Called when user clicks the Media setup button
+ * translate - Translation function
*/
function joinRoom(data) {
// Create a container for subscribers and publishers
@@ -119,6 +121,8 @@
// avatar: undefined // avatar image
}
+ $t = data.translate
+
// Make sure all supported callbacks exist, so we don't have to check
// their existence everywhere anymore
let events = ['Success', 'Error', 'Destroy', 'Dismiss', 'JoinRequest', 'ConnectionChange',
@@ -999,10 +1003,10 @@
'<div class="meet-video">'
+ svgIcon('user', 'fas', 'watermark')
+ '<div class="controls">'
- + '<button type="button" class="btn btn-link link-setup hidden" title="Media setup">' + svgIcon('cog') + '</button>'
- + '<button type="button" class="btn btn-link link-audio hidden" title="Mute audio">' + svgIcon('volume-mute') + '</button>'
- + '<button type="button" class="btn btn-link link-fullscreen closed hidden" title="Full screen">' + svgIcon('expand') + '</button>'
- + '<button type="button" class="btn btn-link link-fullscreen open hidden" title="Full screen">' + svgIcon('compress') + '</button>'
+ + '<button type="button" class="btn btn-link link-setup hidden" title="' + $t('meet.media-setup') + '">' + svgIcon('cog') + '</button>'
+ + '<button type="button" class="btn btn-link link-audio hidden" title="' + $t('meet.menu-audio-mute') + '">' + svgIcon('volume-mute') + '</button>'
+ + '<button type="button" class="btn btn-link link-fullscreen closed hidden" title="' + $t('meet.menu-fullscreen') + '">' + svgIcon('expand') + '</button>'
+ + '<button type="button" class="btn btn-link link-fullscreen open hidden" title="' + $t('meet.menu-fullscreen') + '">' + svgIcon('compress') + '</button>'
+ '</div>'
+ '<div class="status">'
+ '<span class="bg-warning status-audio hidden">' + svgIcon('microphone-slash') + '</span>'
@@ -1214,7 +1218,7 @@
// Append languages selection options
Object.keys(sessionData.languages).forEach(code => {
- languages.push(`<option value="${code}">${sessionData.languages[code]}</option>`)
+ languages.push(`<option value="${code}">${$t(sessionData.languages[code])}</option>`)
})
// Create the element
@@ -1233,21 +1237,21 @@
+ '<a class="dropdown-item action-dismiss" href="#">Dismiss</a>'
+ '<div class="dropdown-divider permissions"></div>'
+ '<div class="permissions">'
- + '<h6 class="dropdown-header">Permissions</h6>'
+ + '<h6 class="dropdown-header">' + $t('meet.perm') + '</h6>'
+ '<label class="dropdown-item action-role-publisher custom-control custom-switch">'
+ '<input type="checkbox" class="custom-control-input">'
- + ' <span class="custom-control-label">Audio &amp; Video publishing</span>'
+ + ' <span class="custom-control-label">' + $t('meet.perm-av') + '</span>'
+ '</label>'
+ '<label class="dropdown-item action-role-moderator custom-control custom-switch">'
+ '<input type="checkbox" class="custom-control-input">'
- + ' <span class="custom-control-label">Moderation</span>'
+ + ' <span class="custom-control-label">' + $t('meet.perm-mod') + '</span>'
+ '</label>'
+ '</div>'
+ '<div class="dropdown-divider interpreting"></div>'
+ '<div class="interpreting">'
- + '<h6 class="dropdown-header">Language interpreter</h6>'
+ + '<h6 class="dropdown-header">' + $t('meet.lang-int') + '</h6>'
+ '<div class="ml-4 mr-4"><select class="custom-select">'
- + '<option value="">- none -</option>'
+ + '<option value="">- ' + $t('form.none') + ' -</option>'
+ languages.join('')
+ '</select></div>'
+ '</div>'
@@ -1257,7 +1261,7 @@
let nickname = element.find('.meet-nickname')
.addClass('btn btn-outline-' + (params.isSelf ? 'primary' : 'secondary'))
- .attr({title: 'Options', 'data-toggle': 'dropdown'})
+ .attr({title: $t('meet.menu-options'), 'data-toggle': 'dropdown'})
.dropdown({boundary: container.parentNode})
if (params.isSelf) {
diff --git a/src/resources/lang/de/ui.php b/src/resources/lang/de/ui.php
--- a/src/resources/lang/de/ui.php
+++ b/src/resources/lang/de/ui.php
@@ -2,19 +2,11 @@
return [
- 'buttons' => [
+ 'button' => [
'cancel' => "Stornieren",
'save' => "Speichern",
],
- 'menu' => [
- 'cockpit' => "Cockpit",
- 'login' => "Einloggen",
- 'logout' => "Ausloggen",
- 'signup' => "Signup",
- 'toggle' => "Navigation umschalten",
- ],
-
'lang' => [
'en' => "Englisch",
'de' => "Deutsch",
@@ -27,4 +19,12 @@
'webmail' => "Webmail",
],
+ 'menu' => [
+ 'cockpit' => "Cockpit",
+ 'login' => "Einloggen",
+ 'logout' => "Ausloggen",
+ 'signup' => "Signup",
+ 'toggle' => "Navigation umschalten",
+ ],
+
];
diff --git a/src/resources/lang/en/ui.php b/src/resources/lang/en/ui.php
--- a/src/resources/lang/en/ui.php
+++ b/src/resources/lang/en/ui.php
@@ -8,34 +8,171 @@
return [
- 'buttons' => [
+ 'button' => [
+ 'accept' => "Accept",
+ 'back' => "Back",
'cancel' => "Cancel",
- 'save' => "Save"
+ 'close' => "Close",
+ 'continue' => "Continue",
+ 'deny' => "Deny",
+ 'save' => "Save",
+ 'submit' => "Submit",
],
- 'menu' => [
- 'cockpit' => "Cockpit",
- 'login' => "Login",
- 'logout' => "Logout",
- 'signup' => "Signup",
- 'toggle' => "Toggle navigation"
+ 'dashboard' => [
+ 'beta' => "beta",
+ ],
+
+ 'distlist' => [
+ 'list-title' => "Distribution list | Distribution lists",
+ 'create' => "Create list",
+ 'delete' => "Delete list",
+ 'email' => "Email",
+ 'list-empty' => "There are no distribution lists in this account.",
+ 'new' => "New distribution list",
+ 'recipients' => "Recipients",
+ ],
+
+ 'form' => [
+ 'code' => "Confirmation Code",
+ 'email' => "Email Address",
+ 'none' => "none",
+ 'password' => "Password",
+ 'password-confirm' => "Confirm Password",
+ 'status' => "Status",
],
'lang' => [
'en' => "English",
'de' => "German",
- 'fr' => "French"
+ 'fr' => "French",
+ 'it' => "Italian",
],
'login' => [
'2fa' => "Second factor code",
'2fa_desc' => "Second factor code is optional for users with no 2-Factor Authentication setup.",
- 'email' => "Email address",
'forgot_password' => "Forgot password?",
'header' => "Please sign in",
- 'password' => "Password",
'sign_in' => "Sign in",
'webmail' => "Webmail"
],
+ 'meet' => [
+ 'title' => "Voice & Video Conferencing",
+ 'welcome' => "Welcome to our beta program for Voice & Video Conferencing.",
+ 'url' => "You have a room of your own at the URL below. This room is only open when you yourself are in attendance. Use this URL to invite people to join you.",
+ 'notice' => "This is a work in progress and more features will be added over time. Current features include:",
+ 'sharing' => "Screen Sharing",
+ 'sharing-text' => "Share your screen for presentations or show-and-tell.",
+ 'security' => "Room Security",
+ 'security-text' => "Increase the room security by setting a password that attendees will need to know"
+ . " before they can enter, or lock the door so attendees will have to knock, and a moderator can accept or deny those requests.",
+ 'qa' => "Raise Hand (Q&A)",
+ 'qa-text' => "Silent audience members can raise their hand to facilitate a Question & Answer session with the panel members.",
+ 'moderation' => "Moderator Delegation",
+ 'moderation-text' => "Delegate moderator authority for the session, so that a speaker is not needlessly"
+ . " interrupted with attendees knocking and other moderator duties.",
+ 'eject' => "Eject Attendees",
+ 'eject-text' => "Eject attendees from the session in order to force them to reconnect, or address policy"
+ . " violations. Click the user icon for effective dismissal.",
+ 'silent' => "Silent Audience Members",
+ 'silent-text' => "For a webinar-style session, configure the room to force all new attendees to be silent audience members.",
+ 'interpreters' => "Language Specific Audio Channels",
+ 'interpreters-text' => "Designate a participant to interpret the original audio to a target language, for sessions"
+ . " with multi-lingual attendees. The interpreter is expected to be able to relay the original audio, and override it.",
+ 'beta-notice' => "Keep in mind that this is still in beta and might come with some issues."
+ . " Should you encounter any on your way, let us know by contacting support.",
+
+ // Room options dialog
+ 'options' => "Room options",
+ 'password' => "Password",
+ 'password-none' => "none",
+ 'password-clear' => "Clear password",
+ 'password-set' => "Set password",
+ 'password-text' => "You can add a password to your meeting. Participants will have to provide the password before they are allowed to join the meeting.",
+ 'lock' => "Locked room",
+ 'lock-text' => "When the room is locked participants have to be approved by a moderator before they could join the meeting.",
+ 'nomedia' => "Subscribers only",
+ 'nomedia-text' => "Forces all participants to join as subscribers (with camera and microphone turned off)."
+ . " Moderators will be able to promote them to publishers throughout the session.",
+
+ // Room menu
+ 'partcnt' => "Number of participants",
+ 'menu-audio-mute' => "Mute audio",
+ 'menu-audio-unmute' => "Unmute audio",
+ 'menu-video-mute' => "Mute video",
+ 'menu-video-unmute' => "Unmute video",
+ 'menu-screen' => "Share screen",
+ 'menu-hand-lower' => "Lower hand",
+ 'menu-hand-raise' => "Raise hand",
+ 'menu-channel' => "Interpreted language channel",
+ 'menu-chat' => "Chat",
+ 'menu-fullscreen' => "Full screen",
+ 'menu-fullscreen-exit' => "Exit full screen",
+ 'menu-leave' => "Leave session",
+
+ // Room setup screen
+ 'setup-title' => "Set up your session",
+ 'mic' => "Microphone",
+ 'cam' => "Camera",
+ 'nick' => "Nickname",
+ 'nick-placeholder' => "Your name",
+ 'join' => "JOIN",
+ 'joinnow' => "JOIN NOW",
+ 'imaowner' => "I'm the owner",
+
+ // Room
+ 'qa' => "Q & A",
+ 'leave-title' => "Room closed",
+ 'leave-body' => "The session has been closed by the room owner.",
+ 'media-title' => "Media setup",
+ 'join-request' => "Join request",
+ 'join-requested' => "{user} requested to join.",
+
+ // Status messages
+ 'status-init' => "Checking the room...",
+ 'status-323' => "The room is closed. Please, wait for the owner to start the session.",
+ 'status-324' => "The room is closed. It will be open for others after you join.",
+ 'status-325' => "The room is ready. Please, provide a valid password.",
+ 'status-326' => "The room is locked. Please, enter your name and try again.",
+ 'status-327' => "Waiting for permission to join the room.",
+ 'status-404' => "The room does not exist.",
+ 'status-429' => "Too many requests. Please, wait.",
+ 'status-500' => "Failed to connect to the room. Server error.",
+
+ // Other menus
+ 'media-setup' => "Media setup",
+ 'perm' => "Permissions",
+ 'perm-av' => "Audio &amp; Video publishing",
+ 'perm-mod' => "Moderation",
+ 'lang-int' => "Language interpreter",
+ 'menu-options' => "Options",
+ ],
+
+ 'menu' => [
+ 'cockpit' => "Cockpit",
+ 'login' => "Login",
+ 'logout' => "Logout",
+ 'signup' => "Signup",
+ 'toggle' => "Toggle navigation",
+ ],
+
+ 'msg' => [
+ 'loading' => "Loading...",
+ 'notfound' => "Resource not found.",
+ ],
+
+ 'nav' => [
+ 'step' => "Step {i}/{n}",
+ ],
+
+ 'password' => [
+ 'reset' => "Password Reset",
+ 'reset-step1' => "Enter your email address to reset your password.",
+ 'reset-step1-hint' => "You may need to check your spam folder or unblock {email}.",
+ 'reset-step2' => "We sent out a confirmation code to your external email address."
+ . " Enter the code we sent you, or click the link in the message.",
+ ],
+
];
diff --git a/src/resources/views/layouts/app.blade.php b/src/resources/views/layouts/app.blade.php
--- a/src/resources/views/layouts/app.blade.php
+++ b/src/resources/views/layouts/app.blade.php
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no, maximum-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
- <title>{{ config('app.name') }} -- @yield('title')</title>
+ <title>{{ config('app.name') }}</title>
{{-- TODO: PWA disabled for now: @laravelPWA --}}
<link rel="icon" type="image/x-icon" href="@theme_asset(images/favicon.ico)">
diff --git a/src/resources/views/root.blade.php b/src/resources/views/root.blade.php
--- a/src/resources/views/root.blade.php
+++ b/src/resources/views/root.blade.php
@@ -1,5 +1,4 @@
@extends('layouts.app')
-@section('title', "Home")
@section('content')
<div id="app">
<menu-component mode="header"></menu-component>
diff --git a/src/resources/vue/Distlist/Info.vue b/src/resources/vue/Distlist/Info.vue
--- a/src/resources/vue/Distlist/Info.vue
+++ b/src/resources/vue/Distlist/Info.vue
@@ -5,33 +5,33 @@
<div class="card" id="distlist-info">
<div class="card-body">
<div class="card-title" v-if="list_id !== 'new'">
- Distribution list
+ {{ $tc('distlist.list-title', 1) }}
<button class="btn btn-outline-danger button-delete float-right" @click="deleteList()" tag="button">
- <svg-icon icon="trash-alt"></svg-icon> Delete list
+ <svg-icon icon="trash-alt"></svg-icon> {{ $t('distlist.delete') }}
</button>
</div>
- <div class="card-title" v-if="list_id === 'new'">New distribution list</div>
+ <div class="card-title" v-if="list_id === 'new'">{{ $t('distlist.new') }}</div>
<div class="card-text">
<form @submit.prevent="submit">
<div v-if="list_id !== 'new'" class="form-group row plaintext">
- <label for="status" class="col-sm-4 col-form-label">Status</label>
+ <label for="status" class="col-sm-4 col-form-label">{{ $t('form.status') }}</label>
<div class="col-sm-8">
<span :class="$root.distlistStatusClass(list) + ' form-control-plaintext'" id="status">{{ $root.distlistStatusText(list) }}</span>
</div>
</div>
<div class="form-group row">
- <label for="email" class="col-sm-4 col-form-label">Email</label>
+ <label for="email" class="col-sm-4 col-form-label">{{ $t('form.email') }}</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="email" :disabled="list_id !== 'new'" required v-model="list.email">
</div>
</div>
<div class="form-group row">
- <label for="members-input" class="col-sm-4 col-form-label">Recipients</label>
+ <label for="members-input" class="col-sm-4 col-form-label">{{ $t('distlist.recipients') }}</label>
<div class="col-sm-8">
<list-input id="members" :list="list.members"></list-input>
</div>
</div>
- <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> Submit</button>
+ <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> {{ $t('button.submit') }}</button>
</form>
</div>
</div>
diff --git a/src/resources/vue/Distlist/List.vue b/src/resources/vue/Distlist/List.vue
--- a/src/resources/vue/Distlist/List.vue
+++ b/src/resources/vue/Distlist/List.vue
@@ -3,16 +3,16 @@
<div class="card" id="distlist-list">
<div class="card-body">
<div class="card-title">
- Distribution lists
+ {{ $tc('distlist.list-title', 2) }}
<router-link class="btn btn-success float-right create-list" :to="{ path: 'distlist/new' }" tag="button">
- <svg-icon icon="users"></svg-icon> Create list
+ <svg-icon icon="users"></svg-icon> {{ $t('distlist.create') }}
</router-link>
</div>
<div class="card-text">
<table class="table table-sm table-hover">
<thead class="thead-light">
<tr>
- <th scope="col">Email</th>
+ <th scope="col">{{ $t('distlist.email') }}</th>
</tr>
</thead>
<tbody>
@@ -25,7 +25,7 @@
</tbody>
<tfoot class="table-fake-body">
<tr>
- <td>There are no distribution lists in this account.</td>
+ <td>{{ $t('distlist.list-empty') }}</td>
</tr>
</tfoot>
</table>
diff --git a/src/resources/vue/Login.vue b/src/resources/vue/Login.vue
--- a/src/resources/vue/Login.vue
+++ b/src/resources/vue/Login.vue
@@ -6,21 +6,21 @@
<div class="card-text">
<form class="form-signin" @submit.prevent="submitLogin">
<div class="form-group">
- <label for="inputEmail" class="sr-only">{{ $t('login.email') }}</label>
+ <label for="inputEmail" class="sr-only">{{ $t('form.email') }}</label>
<div class="input-group">
<span class="input-group-prepend">
<span class="input-group-text"><svg-icon icon="user"></svg-icon></span>
</span>
- <input type="email" id="inputEmail" class="form-control" :placeholder="$t('login.email')" required autofocus v-model="email">
+ <input type="email" id="inputEmail" class="form-control" :placeholder="$t('form.email')" required autofocus v-model="email">
</div>
</div>
<div class="form-group">
- <label for="inputPassword" class="sr-only">{{ $t('login.password') }}</label>
+ <label for="inputPassword" class="sr-only">{{ $t('form.password') }}</label>
<div class="input-group">
<span class="input-group-prepend">
<span class="input-group-text"><svg-icon icon="lock"></svg-icon></span>
</span>
- <input type="password" id="inputPassword" class="form-control" :placeholder="$t('login.password')" required v-model="password">
+ <input type="password" id="inputPassword" class="form-control" :placeholder="$t('form.password')" required v-model="password">
</div>
</div>
<div class="form-group pt-3" v-if="!$root.isAdmin">
diff --git a/src/resources/vue/Meet/Room.vue b/src/resources/vue/Meet/Room.vue
--- a/src/resources/vue/Meet/Room.vue
+++ b/src/resources/vue/Meet/Room.vue
@@ -1,48 +1,48 @@
<template>
<div id="meet-component">
<div id="meet-session-toolbar" class="hidden">
- <span id="meet-counter" title="Number of participants"><svg-icon icon="users"></svg-icon> <span></span></span>
+ <span id="meet-counter" :title="$t('meet.partcnt')"><svg-icon icon="users"></svg-icon> <span></span></span>
<span id="meet-session-logo" v-html="$root.logo()"></span>
<div id="meet-session-menu">
- <button :class="'btn link-audio' + (audioActive ? '' : ' on')" @click="switchSound" :disabled="!isPublisher()" :title="audioActive ? 'Mute audio' : 'Unmute audio'">
+ <button :class="'btn link-audio' + (audioActive ? '' : ' on')" @click="switchSound" :disabled="!isPublisher()" :title="$t('meet.menu-audio-' + (audioActive ? 'mute' : 'unmute'))">
<svg-icon :icon="audioActive ? 'microphone' : 'microphone-slash'"></svg-icon>
</button>
- <button :class="'btn link-video' + (videoActive ? '' : ' on')" @click="switchVideo" :disabled="!isPublisher()" :title="videoActive ? 'Mute video' : 'Unmute video'">
+ <button :class="'btn link-video' + (videoActive ? '' : ' on')" @click="switchVideo" :disabled="!isPublisher()" :title="$t('meet.menu-video-' + (videoActive ? 'mute' : 'unmute'))">
<svg-icon :icon="videoActive ? 'video' : 'video-slash'"></svg-icon>
</button>
- <button :class="'btn link-screen' + (screenShareActive ? ' on' : '')" @click="switchScreen" :disabled="!canShareScreen || !isPublisher()" title="Share screen">
+ <button :class="'btn link-screen' + (screenShareActive ? ' on' : '')" @click="switchScreen" :disabled="!canShareScreen || !isPublisher()" :title="$t('meet.menu-screen')">
<svg-icon icon="desktop"></svg-icon>
</button>
- <button :class="'btn link-hand' + (handRaised ? ' on' : '')" v-if="!isPublisher()" @click="switchHand" :title="handRaised ? 'Lower hand' : 'Raise hand'">
+ <button :class="'btn link-hand' + (handRaised ? ' on' : '')" v-if="!isPublisher()" @click="switchHand" :title="$t('meet.menu-hand-' + (handRaised ? 'lower' : 'raise'))">
<svg-icon icon="hand-paper"></svg-icon>
</button>
<span id="channel-select" :style="'display:' + (channels.length ? '' : 'none')" class="dropdown">
<button :class="'btn link-channel' + (session.channel ? ' on' : '')" data-toggle="dropdown"
- title="Interpreted language channel" aria-haspopup="true" aria-expanded="false"
+ :title="$t('meet.menu-channel')" aria-haspopup="true" aria-expanded="false"
>
<svg-icon icon="headphones"></svg-icon>
<span class="badge badge-danger" v-if="session.channel">{{ session.channel.toUpperCase() }}</span>
</button>
<div class="dropdown-menu">
- <a :class="'dropdown-item' + (!session.channel ? ' active' : '')" href="#" data-code="" @click="switchChannel">- none -</a>
+ <a :class="'dropdown-item' + (!session.channel ? ' active' : '')" href="#" data-code="" @click="switchChannel">- {{ $t('form.none') }} -</a>
<a v-for="code in channels" :key="code" href="#" @click="switchChannel" :data-code="code"
:class="'dropdown-item' + (session.channel == code ? ' active' : '')"
- >{{ languages[code] }}</a>
+ >{{ $t('lang.' + code) }}</a>
</div>
</span>
- <button :class="'btn link-chat' + (chatActive ? ' on' : '')" @click="switchChat" title="Chat">
+ <button :class="'btn link-chat' + (chatActive ? ' on' : '')" @click="switchChat" :title="$t('meet.menu-chat')">
<svg-icon icon="comment"></svg-icon>
</button>
- <button class="btn link-fullscreen closed hidden" @click="switchFullscreen" title="Full screen">
+ <button class="btn link-fullscreen closed hidden" @click="switchFullscreen" :title="$t('meet.menu-fullscreen')">
<svg-icon icon="expand"></svg-icon>
</button>
- <button class="btn link-fullscreen open hidden" @click="switchFullscreen" title="Exit full screen">
+ <button class="btn link-fullscreen open hidden" @click="switchFullscreen" :title="$t('meet.menu-fullscreen-exit')">
<svg-icon icon="compress"></svg-icon>
</button>
- <button class="btn link-options" v-if="isRoomOwner()" @click="roomOptions" title="Room options">
+ <button class="btn link-options" v-if="isRoomOwner()" @click="roomOptions" :title="$t('meet.options')">
<svg-icon icon="cog"></svg-icon>
</button>
- <button class="btn link-logout" @click="logout" title="Leave session">
+ <button class="btn link-logout" @click="logout" :title="$t('meet.menu-leave')">
<svg-icon icon="power-off"></svg-icon>
</button>
</div>
@@ -50,7 +50,7 @@
<div id="meet-setup" class="card container mt-2 mt-md-5 mb-5">
<div class="card-body">
- <div class="card-title">Set up your session</div>
+ <div class="card-title">{{ $t('meet.setup-title') }}</div>
<div class="card-text">
<form class="media-setup-form row" @submit.prevent="joinSession">
<div class="media-setup-preview col-sm-6 mb-3 mb-sm-0">
@@ -60,41 +60,41 @@
<div class="col-sm-6 align-self-center">
<div class="input-group">
<label for="setup-microphone" class="input-group-prepend mb-0">
- <span class="input-group-text" title="Microphone"><svg-icon icon="microphone"></svg-icon></span>
+ <span class="input-group-text" :title="$t('meet.mic')"><svg-icon icon="microphone"></svg-icon></span>
</label>
<select class="custom-select" id="setup-microphone" v-model="microphone" @change="setupMicrophoneChange">
- <option value="">None</option>
+ <option value="">{{ $t('form.none') }}</option>
<option v-for="mic in setup.microphones" :value="mic.deviceId" :key="mic.deviceId">{{ mic.label }}</option>
</select>
</div>
<div class="input-group mt-2">
<label for="setup-camera" class="input-group-prepend mb-0">
- <span class="input-group-text" title="Camera"><svg-icon icon="video"></svg-icon></span>
+ <span class="input-group-text" :title="$t('meet.cam')"><svg-icon icon="video"></svg-icon></span>
</label>
<select class="custom-select" id="setup-camera" v-model="camera" @change="setupCameraChange">
- <option value="">None</option>
+ <option value="">{{ $t('form.none') }}</option>
<option v-for="cam in setup.cameras" :value="cam.deviceId" :key="cam.deviceId">{{ cam.label }}</option>
</select>
</div>
<div class="input-group mt-2">
<label for="setup-nickname" class="input-group-prepend mb-0">
- <span class="input-group-text" title="Nickname"><svg-icon icon="user"></svg-icon></span>
+ <span class="input-group-text" :title="$t('meet.nick')"><svg-icon icon="user"></svg-icon></span>
</label>
- <input class="form-control" type="text" id="setup-nickname" v-model="nickname" placeholder="Your name">
+ <input class="form-control" type="text" id="setup-nickname" v-model="nickname" :placeholder="$t('meet.nick-placeholder')">
</div>
<div class="input-group mt-2" v-if="session.config && session.config.requires_password">
<label for="setup-password" class="input-group-prepend mb-0">
- <span class="input-group-text" title="Password"><svg-icon icon="key"></svg-icon></span>
+ <span class="input-group-text" :title="$t('form.password')"><svg-icon icon="key"></svg-icon></span>
</label>
- <input type="password" class="form-control" id="setup-password" v-model="password" placeholder="Password">
+ <input type="password" class="form-control" id="setup-password" v-model="password" :placeholder="$t('form.password')">
</div>
<div class="mt-3">
<button type="submit" id="join-button"
:class="'btn w-100 btn-' + (isRoomReady() ? 'success' : 'primary')"
>
- <span v-if="isRoomReady()">JOIN NOW</span>
- <span v-else-if="roomState == 323">I'm the owner</span>
- <span v-else>JOIN</span>
+ <span v-if="isRoomReady()">{{ $t('meet.joinnow') }}</span>
+ <span v-else-if="roomState == 323">{{ $t('meet.imaowner') }}</span>
+ <span v-else>{{ $t('meet.join') }}</span>
</button>
</div>
</div>
@@ -108,7 +108,7 @@
<div id="meet-session-layout" class="d-flex hidden">
<div id="meet-queue">
- <div class="head" title="Q &amp; A"><svg-icon icon="microphone-alt"></svg-icon></div>
+ <div class="head" :title="$t('meet.qa')"><svg-icon icon="microphone-alt"></svg-icon></div>
</div>
<div id="meet-session"></div>
<div id="meet-chat">
@@ -125,16 +125,16 @@
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
- <h5 class="modal-title">Room closed</h5>
- <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <h5 class="modal-title">{{ $t('meet.leave-title') }}</h5>
+ <button type="button" class="close" data-dismiss="modal" :aria-label="$t('button.close')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
- <p>The session has been closed by the room owner.</p>
+ <p>{{ $t('meet.leave-body') }}</p>
</div>
<div class="modal-footer">
- <button type="button" class="btn btn-danger modal-action" data-dismiss="modal">Close</button>
+ <button type="button" class="btn btn-danger modal-action" data-dismiss="modal">{{ $t('button.close') }}</button>
</div>
</div>
</div>
@@ -144,8 +144,8 @@
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
- <h5 class="modal-title">Media setup</h5>
- <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <h5 class="modal-title">{{ $t('meet.media-title') }}</h5>
+ <button type="button" class="close" data-dismiss="modal" :aria-label="$t('button.close')">
<span aria-hidden="true">&times;</span>
</button>
</div>
@@ -154,26 +154,26 @@
<div class="media-setup-preview"></div>
<div class="input-group mt-2">
<label for="setup-mic" class="input-group-prepend mb-0">
- <span class="input-group-text" title="Microphone"><svg-icon icon="microphone"></svg-icon></span>
+ <span class="input-group-text" :title="$t('meet.mic')"><svg-icon icon="microphone"></svg-icon></span>
</label>
<select class="custom-select" id="setup-mic" v-model="microphone" @change="setupMicrophoneChange">
- <option value="">None</option>
+ <option value="">{{ $t('form.none') }}</option>
<option v-for="mic in setup.microphones" :value="mic.deviceId" :key="mic.deviceId">{{ mic.label }}</option>
</select>
</div>
<div class="input-group mt-2">
<label for="setup-cam" class="input-group-prepend mb-0">
- <span class="input-group-text" title="Camera"><svg-icon icon="video"></svg-icon></span>
+ <span class="input-group-text" :title="$t('meet.cam')"><svg-icon icon="video"></svg-icon></span>
</label>
<select class="custom-select" id="setup-cam" v-model="camera" @change="setupCameraChange">
- <option value="">None</option>
+ <option value="">{{ $t('form.none') }}</option>
<option v-for="cam in setup.cameras" :value="cam.deviceId" :key="cam.deviceId">{{ cam.label }}</option>
</select>
</div>
</form>
</div>
<div class="modal-footer">
- <button type="button" class="btn btn-secondary modal-action" data-dismiss="modal">Close</button>
+ <button type="button" class="btn btn-secondary modal-action" data-dismiss="modal">{{ $t('button.close') }}</button>
</div>
</div>
</div>
@@ -252,10 +252,10 @@
camera: '',
channels: [],
languages: {
- en: 'English',
- de: 'German',
- fr: 'French',
- it: 'Italian'
+ en: 'lang.en',
+ de: 'lang.de',
+ fr: 'lang.fr',
+ it: 'lang.it'
},
meet: null,
microphone: '',
@@ -264,15 +264,15 @@
room: null,
roomState: 'init',
roomStateLabels: {
- init: 'Checking the room...',
- 323: 'The room is closed. Please, wait for the owner to start the session.',
- 324: 'The room is closed. It will be open for others after you join.',
- 325: 'The room is ready. Please, provide a valid password.',
- 326: 'The room is locked. Please, enter your name and try again.',
- 327: 'Waiting for permission to join the room.',
- 404: 'The room does not exist.',
- 429: 'Too many requests. Please, wait.',
- 500: 'Failed to connect to the room. Server error.'
+ 'init': 'meet.status-init',
+ 323: 'meet.status-323',
+ 324: 'meet.status-324',
+ 325: 'meet.status-325',
+ 326: 'meet.status-326',
+ 327: 'meet.status-327',
+ 404: 'meet.status-404',
+ 429: 'meet.status-429',
+ 500: 'meet.status-500'
},
session: {},
audioActive: false,
@@ -454,21 +454,21 @@
+ `<div class="content">`
+ `<p class="mb-2"></p>`
+ `<div class="text-right">`
- + `<button type="button" class="btn btn-sm btn-success accept">Accept</button>`
- + `<button type="button" class="btn btn-sm btn-danger deny ml-2">Deny</button>`
+ + `<button type="button" class="btn btn-sm btn-success accept">${this.$t('button.accept')}</button>`
+ + `<button type="button" class="btn btn-sm btn-danger deny ml-2">${this.$t('button.deny')}</button>`
)
this.$toast.message({
className: 'join-request',
icon: 'user',
timeout: 0,
- title: 'Join request',
+ title: this.$t('meet.join-request'),
// titleClassName: '',
body: body.html(),
onShow: element => {
const id = data.requestId
- $(element).find('p').text((data.nickname || '') + ' requested to join.')
+ $(element).find('p').text(this.$t('meet.join-requested', { user: data.nickname || '' }))
// add id attribute, so we can identify it
$(element).attr('id', 'i' + id)
@@ -510,6 +510,7 @@
this.session.chatElement = $('#meet-chat')[0]
this.session.queueElement = $('#meet-queue')[0]
this.session.counterElement = $('#meet-counter span')[0]
+ this.session.translate = (label, args) => this.$t(label, args)
this.session.onSuccess = () => {
$('#app').addClass('meet')
$('#meet-setup').addClass('hidden')
diff --git a/src/resources/vue/Meet/RoomOptions.vue b/src/resources/vue/Meet/RoomOptions.vue
--- a/src/resources/vue/Meet/RoomOptions.vue
+++ b/src/resources/vue/Meet/RoomOptions.vue
@@ -4,54 +4,51 @@
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
- <h5 class="modal-title">Room options</h5>
- <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <h5 class="modal-title">{{ $t('meet.options') }}</h5>
+ <button type="button" class="close" data-dismiss="modal" :aria-label="$t('button.close')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="room-options-password">
<div id="password-input" class="input-group input-group-activable">
- <span class="input-group-text label">Password:</span>
+ <span class="input-group-text label">{{ $t('meet.password') }}:</span>
<span v-if="config.password" id="password-input-text" class="input-group-text">{{ config.password }}</span>
- <span v-else id="password-input-text" class="input-group-text text-muted">none</span>
+ <span v-else id="password-input-text" class="input-group-text text-muted">{{ $t('meet.password-none') }}</span>
<input type="text" :value="config.password" name="password" class="form-control rounded-left activable">
<div class="input-group-append">
- <button type="button" @click="passwordSave" id="password-save-btn" class="btn btn-outline-primary activable rounded-right">Save</button>
- <button type="button" v-if="config.password" id="password-clear-btn" @click="passwordClear" class="btn btn-outline-danger rounded">Clear password</button>
- <button type="button" v-else @click="passwordSet" id="password-set-btn" class="btn btn-outline-primary rounded">Set password</button>
+ <button type="button" @click="passwordSave" id="password-save-btn" class="btn btn-outline-primary activable rounded-right">{{ $t('button.save') }}</button>
+ <button type="button" v-if="config.password" id="password-clear-btn" @click="passwordClear" class="btn btn-outline-danger rounded">{{ $t('meet.password-clear') }}</button>
+ <button type="button" v-else @click="passwordSet" id="password-set-btn" class="btn btn-outline-primary rounded">{{ $t('meet.password-set') }}</button>
</div>
</div>
<small class="form-text text-muted">
- You can add a password to your meeting. Participants will have to provide
- the password before they are allowed to join the meeting.
+ {{ $t('meet.password-text') }}
</small>
</form>
<hr>
<form id="room-options-lock">
<div id="room-lock">
- <label for="room-lock-input">Locked room:</label>
+ <label for="room-lock-input">{{ $t('meet.lock') }}:</label>
<input type="checkbox" id="room-lock-input" name="lock" value="1" :checked="config.locked" @click="lockSave">
</div>
<small class="form-text text-muted">
- When the room is locked participants have to be approved by a moderator
- before they could join the meeting.
+ {{ $t('meet.lock-text') }}
</small>
</form>
<hr>
<form id="room-options-nomedia">
<div id="room-nomedia">
- <label for="room-nomedia-input">Subscribers only:</label>
+ <label for="room-nomedia-input">{{ $t('meet.nomedia') }}:</label>
<input type="checkbox" id="room-nomedia-input" name="lock" value="1" :checked="config.nomedia" @click="nomediaSave">
</div>
<small class="form-text text-muted">
- Forces all participants to join as subscribers (with camera and microphone turned off).
- Moderators will be able to promote them to publishers throughout the session.
+ {{ $t('meet.nomedia-text') }}
</small>
</form>
</div>
<div class="modal-footer">
- <button type="button" class="btn btn-secondary modal-action" data-dismiss="modal">Close</button>
+ <button type="button" class="btn btn-secondary modal-action" data-dismiss="modal">{{ $t('button.close') }}</button>
</div>
</div>
</div>
diff --git a/src/resources/vue/PasswordReset.vue b/src/resources/vue/PasswordReset.vue
--- a/src/resources/vue/PasswordReset.vue
+++ b/src/resources/vue/PasswordReset.vue
@@ -2,35 +2,34 @@
<div class="container">
<div class="card" id="step1">
<div class="card-body">
- <h4 class="card-title">Password Reset - Step 1/3</h4>
+ <h4 class="card-title">{{ $t('password.reset') }} - {{ $t('nav.step', { i: 1, n: 3 }) }}</h4>
<p class="card-text">
- Enter your email address to reset your password.
- <span v-if="fromEmail">You may need to check your spam folder or unblock {{ fromEmail }}.</span>
+ {{ $t('password.reset-step1') }}
+ <span v-if="fromEmail">{{ $t('password.reset-step1-hint', { email: fromEmail }) }}</span>
</p>
<form @submit.prevent="submitStep1" data-validation-prefix="reset_">
<div class="form-group">
- <label for="reset_email" class="sr-only">Email Address</label>
- <input type="text" class="form-control" id="reset_email" placeholder="Email Address" required v-model="email">
+ <label for="reset_email" class="sr-only">{{ $t('form.email') }}</label>
+ <input type="text" class="form-control" id="reset_email" :placeholder="$t('form.email')" required v-model="email">
</div>
- <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> Continue</button>
+ <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> {{ $t('button.continue') }}</button>
</form>
</div>
</div>
<div class="card d-none" id="step2">
<div class="card-body">
- <h4 class="card-title">Password Reset - Step 2/3</h4>
+ <h4 class="card-title">{{ $t('password.reset') }} - {{ $t('nav.step', { i: 2, n: 3 }) }}</h4>
<p class="card-text">
- We sent out a confirmation code to your external email address.
- Enter the code we sent you, or click the link in the message.
+ {{ $t('password.reset-step2') }}
</p>
<form @submit.prevent="submitStep2" data-validation-prefix="reset_">
<div class="form-group">
- <label for="reset_short_code" class="sr-only">Confirmation Code</label>
- <input type="text" class="form-control" id="reset_short_code" placeholder="Confirmation Code" required v-model="short_code">
+ <label for="reset_short_code" class="sr-only">{{ $t('form.code') }}</label>
+ <input type="text" class="form-control" id="reset_short_code" :placeholder="$t('form.code')" required v-model="short_code">
</div>
- <button class="btn btn-secondary" type="button" @click="stepBack">Back</button>
- <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> Continue</button>
+ <button class="btn btn-secondary" type="button" @click="stepBack">{{ $t('button.back') }}</button>
+ <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> {{ $t('button.continue') }}</button>
<input type="hidden" id="reset_code" v-model="code" />
</form>
</div>
@@ -38,20 +37,20 @@
<div class="card d-none" id="step3">
<div class="card-body">
- <h4 class="card-title">Password Reset - Step 3/3</h4>
+ <h4 class="card-title">{{ $t('password.reset') }} - {{ $t('nav.step', { i: 3, n: 3 }) }}</h4>
<p class="card-text">
</p>
<form @submit.prevent="submitStep3" data-validation-prefix="reset_">
<div class="form-group">
- <label for="reset_password" class="sr-only">Password</label>
- <input type="password" class="form-control" id="reset_password" placeholder="Password" required v-model="password">
+ <label for="reset_password" class="sr-only">{{ $t('form.password') }}</label>
+ <input type="password" class="form-control" id="reset_password" :placeholder="$t('form.password')" required v-model="password">
</div>
<div class="form-group">
- <label for="reset_confirm" class="sr-only">Confirm Password</label>
- <input type="password" class="form-control" id="reset_confirm" placeholder="Confirm Password" required v-model="password_confirmation">
+ <label for="reset_confirm" class="sr-only">{{ $t('form.password-confirm') }}</label>
+ <input type="password" class="form-control" id="reset_confirm" :placeholder="$t('form.password-confirm')" required v-model="password_confirmation">
</div>
- <button class="btn btn-secondary" type="button" @click="stepBack">Back</button>
- <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> Submit</button>
+ <button class="btn btn-secondary" type="button" @click="stepBack">{{ $t('button.back') }}</button>
+ <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> {{ $t('button.submit') }}</button>
</form>
</div>
</div>
diff --git a/src/resources/vue/Rooms.vue b/src/resources/vue/Rooms.vue
--- a/src/resources/vue/Rooms.vue
+++ b/src/resources/vue/Rooms.vue
@@ -2,69 +2,29 @@
<div class="container" dusk="rooms-component">
<div id="meet-rooms" class="card">
<div class="card-body">
- <div class="card-title">Voice &amp; Video Conferencing <small><sup class="badge badge-primary">beta</sup></small></div>
+ <div class="card-title">{{ $t('meet.title') }} <small><sup class="badge badge-primary">{{ $t('dashboard.beta') }}</sup></small></div>
<div class="card-text">
- <p>
- Welcome to our beta program for Voice &amp; Video Conferencing.
- </p>
- <p>
- You have a room of your own at the URL below. This room is only open when you yourself are in
- attendance. Use this URL to invite people to join you.
- </p>
- <p>
- <router-link v-if="href" :to="roomRoute">{{ href }}</router-link>
- </p>
- <p>
- This is a work in progress and more features will be added over time. Current features include:
- </p>
+ <p>{{ $t('meet.welcome') }}</p>
+ <p>{{ $t('meet.url') }}</p>
+ <p><router-link v-if="href" :to="roomRoute">{{ href }}</router-link></p>
+ <p>{{ $t('meet.notice') }}</p>
<dl>
- <dt>Screen Sharing</dt>
- <dd>
- Share your screen for presentations or show-and-tell.
- </dd>
-
- <dt>Room Security</dt>
- <dd>
- Increase the room security by setting a password that attendees will need to know
- before they can enter, or lock the door so attendees will have to knock, and a moderator
- can accept or deny those requests.
- </dd>
-
- <dt>Raise Hand (Q&amp;A)</dt>
- <dd>
- Silent audience members can raise their hand to facilitate a Question &amp; Answer session
- with the panel members.
- </dd>
-
- <dt>Moderator Delegation</dt>
- <dd>
- Delegate moderator authority for the session, so that a speaker is not needlessly
- interrupted with attendees knocking and other moderator duties.
- </dd>
-
- <dt>Eject Attendees</dt>
- <dd>
- Eject attendees from the session in order to force them to reconnect, or address policy
- violations. Click the user icon for effective dismissal.
- </dd>
-
- <dt>Silent Audience Members</dt>
- <dd>
- For a webinar-style session, configure the room to force all new attendees to be silent
- audience members.
- </dd>
-
- <dt>Language Specific Audio Channels</dt>
- <dd>
- Designate a participant to interpret the original audio to a target language, for sessions
- with multi-lingual attendees. The interpreter is expected to be able to relay the original
- audio, and override it.
- </dd>
+ <dt>{{ $t('meet.sharing') }}</dt>
+ <dd>{{ $t('meet.sharing-text') }}</dd>
+ <dt>{{ $t('meet.security') }}</dt>
+ <dd>{{ $t('meet.security-text') }}</dd>
+ <dt>{{ $t('meet.qa') }}</dt>
+ <dd>{{ $t('meet.qa-text') }}</dd>
+ <dt>{{ $t('meet.moderation') }}</dt>
+ <dd>{{ $t('meet.moderation-text') }}</dd>
+ <dt>{{ $t('meet.eject') }}</dt>
+ <dd>{{ $t('meet.eject-text') }}</dd>
+ <dt>{{ $t('meet.silent') }}</dt>
+ <dd>{{ $t('meet.silent-text') }}</dd>
+ <dt>{{ $t('meet.interpreters') }}</dt>
+ <dd>{{ $t('meet.interpreters-text') }}</dd>
</dl>
- <p>
- Keep in mind that this is still in beta and might come with some issues.
- Should you encounter any on your way, let us know by contacting support.
- </p>
+ <p>{{ $t('meet.beta-notice') }}</p>
</div>
</div>
</div>
diff --git a/src/resources/vue/Widgets/StatusMessage.vue b/src/resources/vue/Widgets/StatusMessage.vue
--- a/src/resources/vue/Widgets/StatusMessage.vue
+++ b/src/resources/vue/Widgets/StatusMessage.vue
@@ -6,14 +6,14 @@
<span v-if="status == 'init'">{{ statusLabel() }}</span>
<svg-icon v-if="status != 'init' && statusLabel()" :icon="Number(status) >= 400 ? 'exclamation-circle' : 'info-circle'"></svg-icon>
- <span v-if="status != 'init' && statusLabel()">{{ statusLabel() }}</span>
+ <span v-if="status != 'init' && statusLabel()">{{ $t(statusLabel()) }}</span>
</div>
</template>
<script>
const defaultLabels = {
- init: 'Loading...',
- 404: 'Resource not found.'
+ init: 'msg.loading',
+ 404: 'msg.notfound'
}
export default {

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 2:05 AM (4 d, 11 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18822077
Default Alt Text
D2518.1775181952.diff (56 KB)

Event Timeline