Compare commits

...

41 Commits

Author SHA1 Message Date
Boris Grozev
528204fb81 ref: Clean up password generation, use 16 characters. 2020-04-05 16:04:18 -05:00
Dara Poon
0e16008085 Use regexes to match ALPN protocols (#5651)
nginx presents the client's list of ALPN protocols as
$ssl_preread_alpn_protocols, a comma-separated string.  Use regular
expressions to match each item in the list, rather than the exact value
of the entire list at once.
2020-04-05 09:23:43 -05:00
Дамян Минков
f66a919e08 Fix weblate (#5672)
* Added translation using Weblate (Icelandic)

* Added translation using Weblate (Icelandic)

* Added translation using Weblate (Sardinian)

* Deleted translation using Weblate (Sardinian)

* Added translation using Weblate (Sardinian)

* Translated using Weblate (Sardinian)

Currently translated at 0.0% (0 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/sc/

* Added translation using Weblate (Sardinian)

* Translated using Weblate (Sardinian)

Currently translated at 0.0% (0 of 32 strings)

Translation: Jitsi/languages
Translate-URL: https://hosted.weblate.org/projects/jitsi/languages/sc/

* Translated using Weblate (Icelandic)

Currently translated at 100.0% (32 of 32 strings)

Translation: Jitsi/languages
Translate-URL: https://hosted.weblate.org/projects/jitsi/languages/is/

* Translated using Weblate (Icelandic)

Currently translated at 100.0% (672 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/is/

* Translated using Weblate (Bulgarian)

Currently translated at 99.8% (671 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/bg/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (672 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/ca/

* Translated using Weblate (Bulgarian)

Currently translated at 99.8% (671 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/bg/

* Translated using Weblate (Czech)

Currently translated at 36.7% (247 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Turkish)

Currently translated at 23.3% (157 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/tr/

* Translated using Weblate (ptbr (generated))

Currently translated at 100.0% (672 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/ptbr/

* Translated using Weblate (Sardinian)

Currently translated at 99.8% (671 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/sc/

* Translated using Weblate (Czech)

Currently translated at 39.8% (268 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 46.8% (315 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 46.8% (315 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 46.8% (315 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 47.0% (316 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 47.0% (316 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 50.5% (340 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 50.7% (341 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 50.8% (342 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 52.8% (355 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Czech)

Currently translated at 72.6% (488 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/cs/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (32 of 32 strings)

Translation: Jitsi/languages
Translate-URL: https://hosted.weblate.org/projects/jitsi/languages/tr/

* Translated using Weblate (Danish)

Currently translated at 95.6% (643 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/da/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 40.6% (13 of 32 strings)

Translation: Jitsi/languages
Translate-URL: https://hosted.weblate.org/projects/jitsi/languages/nb_NO/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 20.8% (140 of 672 strings)

Translation: Jitsi/main
Translate-URL: https://hosted.weblate.org/projects/jitsi/main/nb_NO/

Co-authored-by: Sveinn í Felli <sv1@fellsnet.is>
Co-authored-by: Václav Zbránek <vaclav@weblate.org>
Co-authored-by: Joan Montané <joan@montane.cat>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Rafael Fontenelle <rafaelff@gnome.org>
Co-authored-by: Adrià Martín <adriamartinmor@gmail.com>
Co-authored-by: Tomas Apeltauer <tomas.apeltauer@gmail.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Lukáš Jelínek <devel@aiken.cz>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
2020-04-05 08:58:21 -05:00
Saúl Ibarra Corretgé
8115fb5e78 config: remove aspect ratio constraint from config example
Some cameras may not be able to satisfy it and gUM will fail.

Refs: https://github.com/jitsi/lib-jitsi-meet/pull/1066
2020-04-05 08:46:51 +02:00
Weblate (bot)
c9f26dc7ac lang: improved translattions with weblate
Icelandic, Sardinian, Bulgarian, Czech, Catalan, Turkish.

Translate-URL: https://hosted.weblate.org/projects/jitsi/main/

Co-authored-by: Sveinn í Felli <sv1@fellsnet.is>
Co-authored-by: Václav Zbránek <vaclav@weblate.org>
Co-authored-by: Damian Minkov <damencho@jitsi.org>
Co-authored-by: Joan Montané <joan@montane.cat>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Rafael Fontenelle <rafaelff@gnome.org>
Co-authored-by: Adrià Martín <adriamartinmor@gmail.com>
Co-authored-by: Tomas Apeltauer <tomas.apeltauer@gmail.com>
2020-04-04 22:14:00 +02:00
damencho
7321f706bb Fix wrong UTF file. 2020-04-03 18:21:04 -05:00
Hristo Terezov
9b5f135dae fix(livestreaming): window.open params
The target parameter from window.open was missing which was causing
reload in electron.
2020-04-03 16:55:05 -05:00
Hristo Terezov
dbbdcb0b00 feat(live-streaming): Add T&C. 2020-04-03 16:54:50 -05:00
Ruben Kerkhof
06ae1861ee log: fix showing verbatim %s
So turn 'hover in %s 1a5cd940' into 'hover in 1a5cd940'
2020-04-03 15:41:30 +02:00
Alexander Neumann
e0afd8fadb lang: fix german translation
This commit fixes a few translation errors, especially in the
kickParticipantTitle.
2020-04-03 15:39:38 +02:00
Michael Telatynski
953f838a2a Improve accessibility of Buttons in Webapp (#5432)
* Expose toggle buttons better via ARIA

* Wire up the divs/li as role=button as per ARIA patterns

* Add flow annotations to appease the linter

* For role=button use aria-pressed not aria-checked
2020-04-03 08:19:32 -05:00
ljo
bf5f1f0168 lang: improve sv translation 2020-04-03 15:13:26 +02:00
Saúl Ibarra Corretgé
cdf977ff3f doc: add documentation index 2020-04-03 14:57:40 +02:00
Joris Bodin
ee1dc9dd8e lang: update translation for fr, de, es, it for mobile app 2020-04-03 12:14:21 +02:00
Ali Karpuzoglu
7bec68e492 doc: fix typo 2020-04-03 12:13:20 +02:00
Bettenbuk Zoltan
97fff02c15 web: use password i18n placeholder 2020-04-03 11:22:11 +02:00
Дамян Минков
b372b2ccf2 Fix turn file link (#5601)
* debian: Does not add a link of turnserver will not be configured. Fixes #5596.

* debian: Partially reverts 990c77bd.

* debian: Skip filename duplication, use variable.
2020-04-02 18:20:41 -05:00
Bettenbuk Zoltan
d00ead932b feat: better room lock prompt 2020-04-02 17:27:22 +02:00
Saúl Ibarra Corretgé
bb2b1b58ec conference: add room name to browser title
Re-do of
86ebfe8dad
2020-04-02 16:33:39 +02:00
GK2
ceeea7314c debian: fix typo 2020-04-02 15:27:19 +02:00
Andrei Gavrilescu
9d6a93119b feat(screenSharing): Add support for audio screen sharing on electron 2020-04-02 16:18:10 +03:00
GK2
08be68cda4 debian: fix install-letsencrypt-cert.sh to create misssing directory
Update install-letsencrypt-cert.sh to fix missing cron.weekly
REFS : https://github.com/jitsi/jitsi-meet/issues/5576
2020-04-02 15:10:27 +02:00
Bettenbuk Zoltan
3a2081ffed ref: change Chat to JitsiModal 2020-04-02 12:40:12 +02:00
Bettenbuk Zoltan
57d14d9517 feat: help centre 2020-04-02 12:40:12 +02:00
Saúl Ibarra Corretgé
c5e693f14a rn,invite: use custom clear button also on iOS
Otherwise it won't be visible if Dark Mode is enabled.
2020-04-02 11:46:29 +02:00
Saúl Ibarra Corretgé
a9da047d3a rn,invite: fix bottom padding on AddPeopleDialog on Android 2020-04-02 11:46:29 +02:00
bgrozev
171b065db1 Revert "Add room name to browser tab title" (#5560)
Because it displays "undefined" in the title.

This reverts commit 86ebfe8dad.
2020-04-01 22:03:14 -05:00
Jaya Allamsetty
9da0b7fee3 deps(ljm): Bump adapter.js to 7.5.0 and validate ice candidate info 2020-04-01 18:28:30 -04:00
damencho
716c9eb46f debian: Change coturn unit file to start on 443. 2020-04-01 17:11:55 -05:00
Stefan
a85c72d859 doc: use sudo 2020-04-01 22:57:08 +02:00
Kenneth Peiruza
0ba567856e lang: fix catalan translation
There was a huge mistake in Catalan translation. Stop streaming and recording said "start" (inicia) instead of "stop" (atura).

Then, 1 small fix on a more polite way of refering to "using a software" -> *emprar* rather than *usar*.
2020-04-01 22:51:38 +02:00
Horatiu Muresan
7f1eb83dbd feat(notifications): Manage audio notifications 2020-04-01 22:40:07 +02:00
damencho
6e4c1f64d8 debian: Adds syslog logging. 2020-04-01 15:18:49 -05:00
damencho
82aa51770a debian: Skip turn config if other sites are available listening on 443. 2020-04-01 15:18:49 -05:00
damencho
990c77bd3d debian: Skip turnserver config if it is already configured. 2020-04-01 15:18:49 -05:00
bgrozev
5bb23b2d17 chore(package.json): Update js-utils (#5541) 2020-04-01 15:09:11 -05:00
Saúl Ibarra Corretgé
9cc05ef838 config: remove unneeded option 2020-04-01 20:40:18 +02:00
Saúl Ibarra Corretgé
a21e3a1946 Merge pull request #5510 from rubenk/add-roomname-to-title
Add room name to browser tab title
2020-04-01 20:08:05 +02:00
Vlad Piersec
c05ca1d9fc fix(prejoin_page) Add labels for video & more UI fixes 2020-04-01 19:57:04 +02:00
Vlad Piersec
1b05d7269c feat(prejoin_page) Add settings buttons
This reverts commit faf24ca7ec.
2020-04-01 19:57:04 +02:00
Ruben Kerkhof
86ebfe8dad Add room name to browser tab title
Fixes #5480

Signed-off-by: Ruben Kerkhof <ruben@rubenkerkhof.com>
2020-03-31 13:58:12 +02:00
106 changed files with 5424 additions and 730 deletions

View File

@@ -111,11 +111,10 @@ var config = {
// w3c spec-compliant video constraints to use for video capture. Currently
// used by browsers that return true from lib-jitsi-meet's
// util#browser#usesNewGumFlow. The constraints are independent from
// this config's resolution value. Defaults to requesting an ideal aspect
// ratio of 16:9 with an ideal resolution of 720.
// this config's resolution value. Defaults to requesting an ideal
// resolution of 720p.
// constraints: {
// video: {
// aspectRatio: 16 / 9,
// height: {
// ideal: 720,
// max: 720,
@@ -390,6 +389,9 @@ var config = {
// userRegion: "asia"
},
// Decides whether the start/stop recording audio notifications should play on record.
// disableRecordAudioNotification: false,
// Information for the chrome extension banner
// chromeExtensionBanner: {
// // The chrome extension to be installed address

130
css/_audio-preview.css Normal file
View File

@@ -0,0 +1,130 @@
.audio-preview {
&-content {
font-size: 15px;
line-height: 24px;
max-height: 456px;
overflow: auto;
width: 328px;
}
&-header {
color: #fff;
display: flex;
padding: 16px;
&-icon {
display: inline-block;
}
&-text {
font-weight: bold;
margin-left: 8px;
}
}
&-entry {
align-items: center;
color: #fff;
cursor: pointer;
display: flex;
padding: 12px 0;
margin-left: 48px;
&--selected {
background: rgba(28,32,37,0.5);
cursor: initial;
margin-left: 0;
padding-left: 21px;
}
&-text {
color: #fff;
font-size: 15px;
display: inline-block;
line-height: 24px;
text-overflow: ellipsis;
max-width: 213px;
overflow: hidden;
white-space: nowrap;
}
}
&-speaker {
position: relative;
&:hover {
.audio-preview-entry {
background: rgba(255,255,255, 0.2);
margin-left: 0;
padding-left: 48px;
&--selected {
padding-left: 21px;
}
}
.audio-preview-test-button {
display: inline-block;
}
}
.audio-preview-entry-text {
max-width: 256px;
}
}
&-microphone {
position: relative;
}
&-icon {
border-radius: 50%;
display: inline-block;
width: 14px;
& svg {
fill: #1C2025;
}
&--check {
background: #31B76A;
margin-right: 13px;
}
&--exclamation {
margin-left: 6px;
& svg {
fill: #E54B4B;
}
}
}
&-test-button {
display: none;
background: #FFF;
border: 1px solid #D1DBE8;
border-radius: 3px;
color: #1C2025;
cursor: pointer;
font-weight: 600;
font-size: 15px;
line-height: 24px;
padding: 4px 16px;
position: absolute;
right: 16px;
top: 8px;
}
&-meter-mic {
position: absolute;
right: 16px;
top: 18px;
}
// Override @atlaskit/InlineDialog container which is made with styled components
& > div > div:nth-child(2) > div > div {
outline: none;
padding: 0;
}
}

30
css/_meter.css Normal file
View File

@@ -0,0 +1,30 @@
.jitsi-icon {
&.metr {
display: inline-block;
& > svg {
fill: #4E5E6C;
width: 38px;
}
}
&.metr--disabled {
& > svg {
fill: #4E5E6C;
}
}
}
.metr-l-0 {
rect:first-child {
fill: #31B76A;
}
}
@for $i from 1 through 7 {
.metr-l-#{$i} {
rect:nth-child(-n+#{$i+1}) {
fill: #31B76A;
}
}
}

79
css/_settings-button.scss Normal file
View File

@@ -0,0 +1,79 @@
.settings-button {
&-container {
position: relative;
.toolbox-icon {
align-items: center;
cursor: pointer;
display: flex;
background-color: #fff;
border-radius: 50%;
border: 1px solid #d1dbe8;
justify-content: center;
width: 38px;
height: 38px;
&:hover {
background-color: #daebfa;
border: 1px solid #daebfa;
}
&.toggled {
background: #2a3a4b;
border: 1px solid #5e6d7a;
svg {
fill: #fff;
}
&:hover {
background-color: #5e6d7a;
}
}
&.disabled, .disabled & {
cursor: initial;
color: #fff;
background-color: #a4b8d1;
}
svg {
fill: #5e6d7a;
}
}
}
&-small-icon {
background: #FFF;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
bottom: 0;
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.25);
cursor: pointer;
height: 16px;
position: absolute;
text-align: center;
right: 4px;
width: 16px;
&> svg {
margin-top: 5px;
}
&--disabled {
background-color: #a4b8d1;
cursor: default;
}
&--hovered {
bottom: -1px;
height: 20px;
right: 2px;
width: 20px;
&> svg {
margin-top: 6px;
}
}
}
}

65
css/_video-preview.css Normal file
View File

@@ -0,0 +1,65 @@
.video-preview {
max-height: 290px;
overflow: auto;
&-entry {
cursor: pointer;
height: 135px;
margin-bottom: 16px;
position: relative;
width: 240px;
&:last-child {
margin-bottom: 0;
}
&--selected {
border: 3px solid #31B76A;
cursor: default;
height: 129px;
width: 234px;
}
}
&-video {
height: 100%;
object-fit: cover;
width: 100%;
}
&-overlay {
background: rgba(42, 58, 75, 0.6);
height: 100%;
position: absolute;
width: 100%;
z-index: 1;
}
&-error {
align-items: center;
display: flex;
height: 100%;
justify-content: center;
position: absolute;
width: 100%;
}
&-label {
color: #fff;
font-size: 13px;
line-height: 20px;
overflow: hidden;
padding: 8px;
position: absolute;
text-align: center;
text-overflow: ellipsis;
width: 220px;
z-index: 2;
}
// Override @atlaskit/InlineDialog container which is made with styled components
& > div > div:nth-child(2) > div > div {
outline: none;
padding: 16px;
}
}

View File

@@ -86,5 +86,9 @@ $flagsImagePath: "../images/";
@import 'avatar';
@import 'promotional-footer';
@import 'chrome-extension-banner';
@import 'settings-button';
@import 'meter';
@import 'audio-preview';
@import 'video-preview';
/* Modules END */

View File

@@ -17,6 +17,9 @@ set -e
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
function generateRandomPassword() {
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 16
}
case "$1" in
configure)
@@ -51,7 +54,7 @@ case "$1" in
db_get jicofo/jicofo-authpassword
if [ -z "$RET" ] ; then
# if password is missing generate it, and store it
JICOFO_AUTH_PASSWORD=`head -c 8 /dev/urandom | tr '\0-\377' 'a-zA-Z0-9a-zA-Z0-9a-zA-Z0-9a-zA-Z0-9@@@@####'`
JICOFO_AUTH_PASSWORD=`generateRandomPassword`
db_set jicofo/jicofo-authpassword "$JICOFO_AUTH_PASSWORD"
else
JICOFO_AUTH_PASSWORD="$RET"
@@ -60,7 +63,7 @@ case "$1" in
db_get jicofo/jicofosecret
if [ -z "$RET" ] ; then
# if secret is missing generate it, and store it
JICOFO_SECRET=`head -c 8 /dev/urandom | tr '\0-\377' 'a-zA-Z0-9a-zA-Z0-9a-zA-Z0-9a-zA-Z0-9@@@@####'`
JICOFO_SECRET=`generateRandomPassword`
db_set jicofo/jicofosecret "$JICOFO_SECRET"
else
JICOFO_SECRET="$RET"
@@ -83,7 +86,7 @@ case "$1" in
db_get jitsi-meet-prosody/turn-secret
if [ -z "$RET" ] ; then
# 8-chars random secret used for the turnserver
TURN_SECRET=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1`
TURN_SECRET=`generateRandomPassword`
db_set jitsi-meet-prosody/turn-secret "$TURN_SECRET"
else
TURN_SECRET="$RET"

View File

@@ -1 +0,0 @@
/usr/share/jitsi-meet-turnserver/jitsi-meet.conf /etc/nginx/modules-enabled/60-jitsi-meet.conf

View File

@@ -36,20 +36,60 @@ case "$1" in
NGINX_CONFIG="/etc/nginx/sites-available/$JVB_HOSTNAME.conf"
JITSI_MEET_CONFIG="/etc/jitsi/meet/$JVB_HOSTNAME-config.js"
NGINX_SITES_ENABLED="/etc/nginx/sites-enabled/"
NGINX_CONFIG_ENABLED="${NGINX_SITES_ENABLED}${JVB_HOSTNAME}.conf"
for site in ${NGINX_SITES_ENABLED}*; do
# if it is not a file continue
[ -f "${site}" ] || continue
# if it is our config skip
[ "${site}" != "${NGINX_CONFIG_ENABLED}" ] || continue
# check whether other enabled hosts has listen 443
if cat ${site} | grep -v "^[[:space:]]*#" | grep listen | grep -q "^.*[[:space:]:]443[;[:space:]].*" ; then
# nothing to do
echo "------------------------------------------------"
echo ""
echo "turnserver not configured as other nginx sites use port 443"
echo ""
echo "------------------------------------------------"
db_stop
exit 0
fi
done
# if there was a turn config backup it so we can configure
# we cannot recognize at the moment is this a user config or default config when installing coturn
if [[ -f $TURN_CONFIG ]] && ! grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
mv $TURN_CONFIG $TURN_CONFIG.bak
fi
# detect dpkg-reconfigure, just delete old links
db_get jitsi-meet-turnserver/jvb-hostname
JVB_HOSTNAME_OLD=$RET
if [ -n "$RET" ] && [ ! "$JVB_HOSTNAME_OLD" = "$JVB_HOSTNAME" ] ; then
rm -f $TURN_CONFIG
if [[ -f $TURN_CONFIG ]] && grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
rm -f $TURN_CONFIG
fi
fi
# this detect only old installations with no nginx
db_get jitsi-meet/jvb-serve || true
if [ ! -f $NGINX_CONFIG -o "$RET" = "true" ] ; then
# nothing to do
echo "------------------------------------------------"
echo ""
echo "turnserver not configured as no nginx found to multiplex traffic"
echo ""
echo "------------------------------------------------"
db_stop
exit 0
fi
if [[ -f $TURN_CONFIG ]] ; then
echo "------------------------------------------------"
echo ""
echo "turnserver is already configured on this machine, skipping."
echo ""
echo "------------------------------------------------"
db_stop
exit 0
fi
@@ -65,46 +105,53 @@ case "$1" in
fi
TURN_SECRET="$RET"
if [[ -f $TURN_CONFIG ]] && ! grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
cp /usr/share/jitsi-meet-turnserver/turnserver.conf $TURN_CONFIG
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $TURN_CONFIG
sed -i "s/__turnSecret__/$TURN_SECRET/g" $TURN_CONFIG
sed -i "s/__external_ip_address__/$JVB_HOSTNAME/g" $TURN_CONFIG
# no turn config exists, lt's copy template and fill it in
PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
cp /usr/share/jitsi-meet-turnserver/turnserver.conf $TURN_CONFIG
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $TURN_CONFIG
sed -i "s/__turnSecret__/$TURN_SECRET/g" $TURN_CONFIG
sed -i "s/__external_ip_address__/$JVB_HOSTNAME/g" $TURN_CONFIG
# SSL for nginx
db_get jitsi-meet/cert-choice
CERT_CHOICE="$RET"
# Hack Debian Buster coturn to be able to bind privileged port 443
COTURN_UNIT_FILE="/lib/systemd/system/coturn.service"
if [[ -f $COTURN_UNIT_FILE ]] && ! grep -q "CAP_NET_BIND_SERVICE" "$COTURN_UNIT_FILE" ; then
sed -i "s/\[Service\]/\[Service\]\nAmbientCapabilities=CAP_NET_BIND_SERVICE/g" $COTURN_UNIT_FILE
systemctl daemon-reload
fi
if [ "$CERT_CHOICE" = "I want to use my own certificate" ] ; then
db_get jitsi-meet/cert-path-key
CERT_KEY="$RET"
db_get jitsi-meet/cert-path-crt
CERT_CRT="$RET"
# SSL for nginx
db_get jitsi-meet/cert-choice
CERT_CHOICE="$RET"
# replace self-signed certificate paths with user provided ones
CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g')
CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g')
sed -i "s/pkey=\/etc\/jitsi\/meet\/.*key/pkey=$CERT_KEY_ESC/g" $TURN_CONFIG
CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g')
CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g')
sed -i "s/cert=\/etc\/jitsi\/meet\/.*crt/cert=$CERT_CRT_ESC/g" $TURN_CONFIG
fi
if [ "$CERT_CHOICE" = "I want to use my own certificate" ] ; then
db_get jitsi-meet/cert-path-key
CERT_KEY="$RET"
db_get jitsi-meet/cert-path-crt
CERT_CRT="$RET"
sed -i "s/#TURNSERVER_ENABLED/TURNSERVER_ENABLED/g" /etc/default/coturn
invoke-rc.d coturn restart || true
# replace self-signed certificate paths with user provided ones
CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g')
CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g')
sed -i "s/pkey=\/etc\/jitsi\/meet\/.*key/pkey=$CERT_KEY_ESC/g" $TURN_CONFIG
CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g')
CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g')
sed -i "s/cert=\/etc\/jitsi\/meet\/.*crt/cert=$CERT_CRT_ESC/g" $TURN_CONFIG
fi
NGINX_STREAM_CONFIG="/etc/nginx/modules-enabled/60-jitsi-meet.conf"
if [ -f $NGINX_STREAM_CONFIG ] && [ -f $NGINX_CONFIG ] ; then
sed -i "s/listen 443 ssl/listen 4444 ssl http2/g" $NGINX_CONFIG
sed -i "s/listen \[\:\:\]\:443 ssl/listen \[\:\:\]\:4444 ssl http2/g" $NGINX_CONFIG
invoke-rc.d nginx reload || true
fi
sed -i "s/#TURNSERVER_ENABLED/TURNSERVER_ENABLED/g" /etc/default/coturn
invoke-rc.d coturn restart || true
# Enable turn server in config.js
if [ -f $JITSI_MEET_CONFIG ] ; then
sed -i "s/\/\/ useStunTurn: true/useStunTurn: true/g" $JITSI_MEET_CONFIG
fi
NGINX_STREAM_CONFIG="/etc/nginx/modules-enabled/60-jitsi-meet.conf"
if [ ! -f $NGINX_STREAM_CONFIG ] && [ -f $NGINX_CONFIG ] ; then
ln -s /usr/share/jitsi-meet-turnserver/jitsi-meet.conf $NGINX_STREAM_CONFIG
sed -i "s/listen 443 ssl/listen 4444 ssl http2/g" $NGINX_CONFIG
sed -i "s/listen \[\:\:\]\:443 ssl/listen \[\:\:\]\:4444 ssl http2/g" $NGINX_CONFIG
invoke-rc.d nginx reload || true
fi
# Enable turn server in config.js
if [ -f $JITSI_MEET_CONFIG ] ; then
sed -i "s/\/\/ useStunTurn: true/useStunTurn: true/g" $JITSI_MEET_CONFIG
fi
# and we're done with debconf

View File

@@ -24,6 +24,7 @@ set -e
case "$1" in
remove)
rm -rf /etc/nginx/modules-enabled/60-jitsi-meet.conf
if [ -x "/etc/init.d/nginx" ]; then
invoke-rc.d nginx reload || true
fi
@@ -32,6 +33,8 @@ case "$1" in
fi
;;
purge)
rm -rf /etc/nginx/modules-enabled/60-jitsi-meet.conf
rm -rf /etc/turnserver.conf
if [ -x "/etc/init.d/nginx" ]; then
invoke-rc.d nginx reload || true
fi

43
doc/README.md Normal file
View File

@@ -0,0 +1,43 @@
# Documentation
This document is the entrypoint to different guides, divided in three groups:
* User guide: these documents are designed to help users of the service, to better
understand all the available features and how to use them.
* Developer guide: these documents are designed to help developers who want to either
integrate the Jitsi Meet API / SDK in their products or want to improve Jitsi Meet
itself by developing new features or fixing bugs.
* DevOps guide: these documents are designed for DevOps folks, system administrators
or anyone who wishes to deploy and operate their own Jitsi Meet instance.
## User guide
Work in progress.
## Developer guide
### Web
* [iframe API](https://github.com/jitsi/jitsi-meet/blob/master/doc/api.md)
* [Jitsi Meet development](https://github.com/jitsi/jitsi-meet/blob/master/doc/development.md)
### Mobile
* [Building the mobile apps](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile.md)
* [SDK usage examples](https://github.com/jitsi/jitsi-meet-sdk-samples)
* [Enabling Dropbox support](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile-dropbox.md)
* [Enabling Google authentication](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile-google-auth.md)
## DevOps guide
* [Quick install](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md)
* [Docker install](https://github.com/jitsi/docker-jitsi-meet/blob/master/README.md)
* [Google Calendar, MS Calendar, Dropbox integrations](https://github.com/jitsi/jitsi-meet/blob/master/doc/integrations.md)
* [Video tutorials on deployment and scalability](https://jitsi.org/tutorials/)
* [Configuring a video SIP gateway](https://github.com/jitsi/jitsi-meet/blob/master/doc/sipgw-config.md)
* [Enabling speaker stats](https://github.com/jitsi/jitsi-meet/blob/master/doc/speakerstats-prosody.md)
* [Enabling TURN](https://github.com/jitsi/jitsi-meet/blob/master/doc/turn.md)
* [Networking FAQ](https://github.com/jitsi/jitsi-meet/blob/master/doc/faq.md)
* [Cloud APIs](https://github.com/jitsi/jitsi-meet/blob/master/doc/cloud-api.md)

View File

@@ -11,3 +11,5 @@ no-tcp
listening-port=443
tls-listening-port=4445
external-ip=__external_ip_address__
syslog

View File

@@ -11,9 +11,8 @@ stream {
}
# since 1.13.10
map $ssl_preread_alpn_protocols $upstream {
"h2" web;
"http/1.1" web;
"h2,http/1.1" web;
~\bh2\b web;
~\bhttp/1\. web;
default turn;
}

View File

@@ -23,7 +23,7 @@ Finally on the same machine test that you can ping the FQDN with: `ping "$(hostn
### Add the Jitsi package repository
```sh
echo 'deb https://download.jitsi.org stable/' >> /etc/apt/sources.list.d/jitsi-stable.list
wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | apt-key add -
wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add -
```
### Install Jitsi Meet

View File

@@ -19,7 +19,7 @@ There are 2 ways to integrate the SDK into your project:
Follow the instructions [here](https://github.com/jitsi/jitsi-meet-ios-sdk-releases/blob/master/README.md).
### Builduing it yourself
### Building it yourself
1. Install all required [dependencies](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile.md).

34
lang/languages-is.json Normal file
View File

@@ -0,0 +1,34 @@
{
"en": "Enska",
"af": "Afríkanska",
"bg": "Búlgarska",
"ca": "Katalónska",
"cs": "Tékkneska",
"da": "Danska",
"de": "Þýska",
"el": "Gríska",
"enGB": "Enska (Bretland)",
"eo": "Esperantó",
"es": "Spænska",
"esUS": "Spænska (spænskumælandi Ameríka)",
"et": "Eistneska",
"fi": "Finnska",
"fr": "Franska",
"frCA": "Franska (kanadísk)",
"hr": "Króatíska",
"hu": "Ungverska",
"hy": "Armenska",
"it": "Ítalska",
"ja": "Japanska",
"ko": "Kóreska",
"nl": "Hollenska",
"oc": "Occitanska",
"pl": "Pólska",
"ptBR": "Portúgalska (Brasilía)",
"ru": "Rússneska",
"sv": "Sænska",
"tr": "Tyrkneska",
"vi": "Víetnamska",
"zhCN": "Kínverska (Kína)",
"zhTW": "Kínverska (Taívan)"
}

View File

@@ -1,27 +1,28 @@
{
"en": "",
"en": "Engelsk",
"af": "",
"az": "",
"bg": "",
"cs": "",
"de": "",
"el": "",
"de": "Tysk",
"el": "Gresk",
"eo": "",
"es": "",
"fr": "",
"es": "Spansk",
"fr": "Fransk",
"hy": "",
"it": "",
"ja": "",
"ko": "",
"it": "Italiensk",
"ja": "Japansk",
"ko": "Koreansk",
"nb": "",
"oc": "",
"pl": "",
"ptBR": "",
"ru": "",
"ru": "Russisk",
"sk": "",
"sl": "",
"sv": "",
"tr": "",
"vi": "",
"zhCN": ""
}
"sv": "Svensk",
"tr": "Tyrkisk",
"vi": "Vietnamesisk",
"zhCN": "",
"da": "Dansk"
}

34
lang/languages-sc.json Normal file
View File

@@ -0,0 +1,34 @@
{
"en": "Inglesu",
"af": "Afrikaans",
"bg": "Bùlgaru",
"ca": "Catalanu",
"cs": "Tzecu",
"da": "Danesu",
"de": "Tedescu",
"el": "Gregu",
"enGB": "Inglesu (Rennu Unidu)",
"eo": "Esperanto",
"es": "Castillianu",
"esUS": "Castillianu (Amèrica de su Sud)",
"fi": "Finlandesu",
"fr": "Frantzesu",
"frCA": "Frantzesu (Canadesu)",
"hr": "Croatu",
"hu": "Ungheresu",
"hy": "Armenu",
"it": "Italianu",
"ja": "Giaponesu",
"ko": "Coreanu",
"nl": "Olandesu",
"oc": "Otzitanu",
"pl": "Polacu",
"ptBR": "Portughesu (Brasile)",
"ru": "Russu",
"sc": "Sardu",
"sv": "Isvedesu",
"tr": "Turcu",
"vi": "Vietnamita",
"zhCN": "Tzinesu (Tzina)",
"zhTW": "Tzinesu (Taiwan)"
}

View File

@@ -1,18 +1,18 @@
{
"en": "İngilizce",
"af": "",
"af": "Afrikanca",
"az": "",
"bg": "Bulgarca",
"cs": "",
"cs": "Çekçe",
"de": "Almanca",
"el": "",
"el": "Yunanca",
"eo": "Esperanto",
"es": "İspanyolca",
"fr": "Fransızca",
"hy": "Ermenice",
"it": "İtalyanca",
"ja": "",
"ko": "",
"ja": "Japonca",
"ko": "Korece",
"nb": "Norveççe Bokmal",
"oc": "Oksitan dili",
"pl": "Lehçe",
@@ -22,6 +22,17 @@
"sl": "Slovence",
"sv": "Isveççe",
"tr": "Türkçe",
"vi": "",
"zhCN": "Çince (Tayvan)"
}
"vi": "Vietnamca",
"zhCN": "Çince (Tayvan)",
"zhTW": "Çince (Tayvan)",
"nl": "Flemenkçe",
"hu": "Macarca",
"hr": "Hırvatça",
"frCA": "Fransızca (Kanada)",
"fi": "Fince",
"et": "Estonca",
"esUS": "İspanyolca (Latin Amerika)",
"enGB": "İngilizce (Birleşik Krallık)",
"da": "Danca",
"ca": "Katalanca"
}

View File

@@ -6,7 +6,7 @@
"disabled": "Не можете да каните хора.",
"failedToAdd": "Неуспешно добавяне на участници",
"footerText": "Изходящите разговори не са разрешени.",
"loading": "Търсене на хора и телефонни номера.",
"loading": "Търсене на хора и телефонни номера",
"loadingNumber": "Валидиране на номера",
"loadingPeople": "Търсене на хора",
"noResults": "Няма резултати",
@@ -72,13 +72,17 @@
"DISCONNECTED": "Изключен",
"DISCONNECTING": "Прекъсване на връзката",
"ERROR": "Грешка",
"RECONNECTING": "Появи се проблем с мрежата. Връзваме се наново..."
"RECONNECTING": "Появи се проблем с мрежата. Връзваме се наново...",
"LOW_BANDWIDTH": "Виеото на {{displayName}} беше изключено поради слаба Интернет връзка",
"GOT_SESSION_ID": "Отваряне на сесията...Завърши",
"GET_SESSION_ID_ERROR": "Грешка при отваряне на сесията: {{code}}",
"FETCH_SESSION_ID": "Отваряне на сесия..."
},
"connectionindicator": {
"address": "Адрес:",
"bandwidth": "Предполагаема скорост:",
"bitrate": "Скорост:",
"bridgeCount": "Брой сървъри:",
"bridgeCount": "Брой сървъри: ",
"connectedTo": "Свързан към:",
"framerate": "Кадри в секунда:",
"less": "Скриване",
@@ -196,24 +200,24 @@
"maxUsersLimitReachedTitle": "Достигнат е лимита за максимален брой участници",
"micConstraintFailedError": "Микрофонът Ви не покрива някои от изискванията.",
"micNotFoundError": "Не е открит микрофон.",
"micNotSendingData": "Пуснете микрофона си от системните настройки на компютъра ви.",
"micNotSendingData": "Пуснете микрофона си от системните настройки на компютъра ви",
"micNotSendingDataTitle": "Микрофона ви е спрян от системните настройки",
"micPermissionDeniedError": "Не сте дали разрешение за използване на микрофона. Ще можете да се присъедините в беседата, но другите няма да Ви чуват. Използвайте бутона с камерата в адресната лента, за да оправите това.",
"micUnknownError": "Невъзможен достъп до микрофона по неясна причина.",
"muteParticipantBody": "Вие няма да можете да спрете заглушаването на участника, но той ще може да го направи по всяко време.",
"muteParticipantButton": "Изключи микрофона",
"muteParticipantDialog": "Сигурни ли сте че искате да заглушите този участник? Няма да можете да пуснете обратно звука му, но участника ще може да направи това сам.",
"muteParticipantDialog": "Сигурни ли сте че искате да заглушите този участник? Няма да можете да пуснете обратно звука му, но участникът ще може да направи това сам.",
"muteParticipantTitle": "Спиране звука на участник?",
"Ok": "Готово",
"passwordLabel": "Парола",
"passwordLabel": "Тази среща е заключена. Моля въведете $t(lockRoomPassword) за да влезнете.",
"passwordNotSupported": "Задаването на $t(lockRoomPassword) за срещата не се поддържа.",
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) не се поддържа",
"passwordRequired": "Изисква се $t(lockRoomPassword) ",
"passwordRequired": "Изисква се $t(lockRoomPassword)",
"popupError": "Браузърът Ви блокира изскачащите прозорци от този уеб сайт. Моля, разрешете изскачащите прозорци от настройките за сигурност на браузъра си и след това опитайте отново.",
"popupErrorTitle": "Блокиран изскачащ прозорец",
"recording": "Запис",
"recordingDisabledForGuestTooltip": "Гостите не могат да стартират запис",
"recordingDisabledTooltip": "Стартирането на запис е спряно",
"recordingDisabledForGuestTooltip": "Гостите не могат да стартират запис.",
"recordingDisabledTooltip": "Стартирането на запис е спряно.",
"rejoinNow": "Повторно присъединяване сега",
"remoteControlAllowedMessage": "{{user}} прие заявката Ви за отдалечено управление!",
"remoteControlDeniedMessage": "{{user}} отказа заявката Ви за отдалечено управление!",
@@ -231,7 +235,7 @@
"retry": "Повторен опит",
"screenSharingFailedToInstall": "Опа! Разширението за споделяне на екрана не успя да се инсталира.",
"screenSharingFailedToInstallTitle": "Разширението за споделяне на екрана не успя да се инсталира",
"screenSharingFirefoxPermissionDeniedError": "Нещо се обърка докато се опитвахме да споделим екрана. Моля уверете се че сте дали права за това.",
"screenSharingFirefoxPermissionDeniedError": "Нещо се обърка докато се опитвахме да споделим екрана. Моля уверете се че сте дали права за това. ",
"screenSharingFirefoxPermissionDeniedTitle": "Упс! Не успяхме да стартираме споделянето на екрана!",
"screenSharingPermissionDeniedError": "Опа! Нещо се обърка с разрешенията на разширението за споделяне на екрана. Моля, презаредете и опитайте отново.",
"sendPrivateMessage": "Наскоро получихте лично съобщение. Искате да отговорите на това съобшение или да изпратите до всички?",
@@ -266,7 +270,14 @@
"WaitForHostMsgWOk": "Конференцията <b>{{room}}</b> все още не е започнала. Ако сте домакинът тогава натиснете бутона за да се идентифицирате. В противен случай изчакайте докато домакинът пристигне.",
"WaitingForHost": "Чакаме домакина ...",
"Yes": "Да",
"yourEntireScreen": "Целия екран"
"yourEntireScreen": "Целия екран",
"screenSharingAudio": "Сподели и звука",
"muteEveryoneStartMuted": "Всички да влизат без звук",
"muteEveryoneSelf": "себе си",
"muteEveryoneTitle": "Заглуши всички?",
"muteEveryoneDialog": "Сигурни ли сте, че искате да заглушите всички? Няма да можете да пуснете звука им отново, но участниците ще могат да направят това сами.",
"muteEveryoneElseTitle": "Заглушете всички освен {{whom}}?",
"muteEveryoneElseDialog": "След като заглушите някой, няма да можете да пуснете обратно звука му, но участникът ще може да направи това сам."
},
"dialOut": {
"statusMessage": "в момента е {{status}}"
@@ -279,7 +290,7 @@
"bad": "Лошо",
"detailsLabel": "Разкажете ни повече.",
"good": "Добра",
"rateExperience": "Моля, оценете качеството на срещата.",
"rateExperience": "Моля, оценете качеството на срещата",
"veryBad": "Много лошо",
"veryGood": "Много добра"
},
@@ -298,7 +309,7 @@
"country": "Страна",
"dialANumber": "За влизане в срещата, наберете един от изброените номера и въведете кода.",
"dialInConferenceID": "Код:",
"dialInNotSupported": "Съжаляваме, обаждането в момента не се поддържа. ",
"dialInNotSupported": "Съжаляваме, обаждането в момента не се поддържа.",
"dialInNumber": "Тел:",
"dialInSummaryError": "Проблем при достъпа на информация за опциите за влизане през телефон. Моля опитайте отново по-късно.",
"dialInTollFree": "Безплатен",
@@ -353,7 +364,7 @@
},
"liveStreaming": {
"busy": "Работим върху това да освободим ресурси за излъчване. Моля, опитайте отново след няколко минути.",
"busyTitle": "Всички излъчватели в момента са заети.",
"busyTitle": "Всички излъчватели в момента са заети",
"changeSignIn": "Смяна на акаунти.",
"choose": "Изберете предаване на живо",
"chooseCTA": "Изберете опция за предаване. Влезли сте като {{email}}.",
@@ -379,7 +390,9 @@
"signOut": "Излизане",
"start": "Започни излъчване на живо",
"streamIdHelp": "Какво е това?",
"unavailableTitle": "Излъчването на живо е недостъпно"
"unavailableTitle": "Излъчването на живо е недостъпно",
"googlePrivacyPolicy": "Политика за поверителност на Google",
"youtubeTerms": "Условия за ползване на YouTube"
},
"localRecording": {
"clientState": {
@@ -437,7 +450,7 @@
"somebody": "Някой",
"startSilentTitle": "Влязохте с опция да не чувате аудио!",
"startSilentDescription": "Влезте повторно за да пуснете звука",
"suboptimalBrowserWarning": "Опасяваме се, че няма да можете да се насладите на срещата. Работим по въпроса, междувременно използвайте някой от <a href='static/recommendedBrowsers.html' target='_blank'>напълно поддържаните браузъри</a>.",
"suboptimalBrowserWarning": "Опасяваме се, че няма да можете да се насладите на срещата. Работим по въпроса, междувременно използвайте някой от <a href='static/recommendedBrowsers.html' target='_blank'>напълно поддържаните браузъри</a>.",
"suboptimalExperienceTitle": "Внимание",
"unmute": "Пускане на микрофона",
"newDeviceCameraTitle": "Засечена е нова камера",
@@ -476,7 +489,7 @@
"busyTitle": "Всички възможности за запис в момента са заети",
"error": "Грешка при опит за запис. Моля опитайте отново.",
"expandedOff": "Записът спря",
"expandedOn": "Срещата се записва в момента",
"expandedOn": "Срещата се записва в момента.",
"expandedPending": "Записът започва...",
"failedToStart": "Неуспешен опит за записване",
"fileSharingdescription": "Споделете записа с участниците в срещата",
@@ -519,7 +532,9 @@
"selectMic": "Микрофон",
"startAudioMuted": "Всички започват заглушени",
"startVideoMuted": "Всички започват скрити",
"title": "Настройки"
"title": "Настройки",
"speakers": "Говорители",
"microphones": "Микрофони"
},
"settingsView": {
"advanced": "Разширени",
@@ -598,7 +613,10 @@
"tileView": "Превключване на изглед галерия",
"toggleCamera": "Пускане/спиране на камера",
"videomute": "Пускане/спиране на видеото",
"videoblur": "Пускане/спиране на замъгляване на видеото"
"videoblur": "Пускане/спиране на замъгляване на видеото",
"toggleFilmstrip": "Превключи видео миниатюрите",
"muteEveryone": "Заглуши всички",
"moreOptions": "Покажи повече опции"
},
"addPeople": "Добавяне на участници в разговора",
"audioOnlyOff": "Спиране режима с нисък трафик",
@@ -626,7 +644,7 @@
"mute": "Спиране/пускане на микрофона",
"noAudioSignalTitle": "Няма сигнал идващ от микрофона!",
"noAudioSignalDesc": "Ако не сте спрели звука на устройството от системните настройки, сменете с друго устройство.",
"noAudioSignalDescSuggestion": "Ако не сте спрели звука на устройството от системните настройки, използвайте някое от следните устройства:",
"noAudioSignalDescSuggestion": "Ако не сте спрели звука на устройството от системните настройки, използвайте някое от предложените устройства.",
"openChat": "Отвори съобщенията",
"pip": "Пусни Картина-в-Картина",
"privateMessage": "Изпрати лично съобщение",
@@ -648,7 +666,13 @@
"toggleCamera": "Пускане/спиране на камера",
"videomute": "Пускане/спиране на камерата",
"startvideoblur": "Замъгли фона ми",
"stopvideoblur": "Спиране замъгляването на фона"
"stopvideoblur": "Спиране замъгляването на фона",
"noisyAudioInputDesc": "Изглежда доста шум идва от микрофона ви, заглушете го или сменете устройството.",
"noisyAudioInputTitle": "Изглежда е шумно около вас!",
"noAudioSignalDialInLinkDesc": "Номера за обаждане",
"noAudioSignalDialInDesc": "Може да влезнете чрез обаждане на:",
"muteEveryone": "Заглуши всички",
"moreOptions": "Повече опции"
},
"transcribing": {
"ccButtonTooltip": "Пускане / Спиране на субтитри",
@@ -714,7 +738,8 @@
"muted": "Изключен микрофон",
"remoteControl": "Отдалечено управление",
"show": "Покажи на главния екран",
"videomute": "Участник е спрял камерата си"
"videomute": "Участник е спрял камерата си",
"domuteOthers": "Заглушете всички останали"
},
"welcomepage": {
"accessibilityLabel": {
@@ -744,6 +769,19 @@
"roomnameHint": "Въведете името или връзката на стаята в която искате да влезете. Също може да си измислите име. Само го споделете с някой, за да може и той да въведе същото име за да се срещнете.",
"sendFeedback": "Изпращане на отзиви",
"terms": "Условия",
"title": "Сигурна, с много възможности, и напълно безплатна платформа за видео конференции"
"title": "Сигурна, с много възможности, и напълно безплатна платформа за видео конференции",
"getHelp": "Търсене на помощ"
},
"helpView": {
"header": "Място за помощ"
},
"lonelyMeetingExperience": {
"youAreAlone": "Вие сте сами в срещата",
"button": "Поканете участници"
},
"chromeExtensionBanner": {
"dontShowAgain": "Не показвай повече",
"buttonText": "Инсталирайте разширението за Chrome",
"installExtensionText": "Инсталирайте разширенията за Google Calendar и Office 365"
}
}
}

View File

@@ -22,7 +22,7 @@
"headphones": "Auriculars",
"phone": "Telèfon",
"speaker": "Altaveu",
"none": "No hi ha disponible cap aparell d'àudio "
"none": "No hi ha disponible cap aparell d'àudio"
},
"audioOnly": {
"audioOnly": "Poc ample de banda"
@@ -220,7 +220,7 @@
"muteParticipantDialog": "Esteu segur que voleu silenciar aquest participant? No podreu activar-li el micròfon, però sí que podrà fer-ho ell mateix en qualsevol moment.",
"muteParticipantTitle": "Voleu silenciar aquest participant?",
"Ok": "D'acord",
"passwordLabel": "$t(lockRoomPasswordUppercase)",
"passwordLabel": "Un participant ha blocat la reunió. Introduïu una $t(lockRoomPassword) per a unirvos-hi.",
"passwordNotSupported": "No és possible definir una $t(lockRoomPassword).",
"passwordNotSupportedTitle": "No se suporta la $t(lockRoomPassword)",
"passwordRequired": "Es requereix una $t(lockRoomPassword)",
@@ -246,7 +246,7 @@
"retry": "Torna a intentar-ho",
"screenSharingFailedToInstall": "Vaja! No s'ha pogut instal·lar l'extensió de compartició de pantalla.",
"screenSharingFailedToInstallTitle": "No s'ha pogut instal·lar l'extensió de compartició de pantalla",
"screenSharingFirefoxPermissionDeniedError": "Alguna cosa no ha anat bé en intentar compartir la pantalla. Assegureu-vos que heu donat el permís per a fer-ho.",
"screenSharingFirefoxPermissionDeniedError": "Alguna cosa no ha anat bé en intentar compartir la pantalla. Assegureu-vos que heu donat el permís per a fer-ho. ",
"screenSharingFirefoxPermissionDeniedTitle": "Vaja! No hem pogut iniciar la compartició de pantalla!",
"screenSharingPermissionDeniedError": "Vaja! Alguna cosa no ha anat bé amb els permisos de l'extensió de compartició de pantalla. Torneu a carregar i intenteu-ho una altra vegada.",
"sendPrivateMessage": "Fa poc que heu rebut un missatge privat. Voleu respondre'l de forma privada, o voleu enviar el missatge al grup?",
@@ -264,13 +264,13 @@
"startLiveStreaming": "Inicia la transmissió en directe",
"startRecording": "Inicia l'enregistrament",
"startRemoteControlErrorMessage": "S'ha produït un error en intentar iniciar la sessió de control remot!",
"stopLiveStreaming": "Inicia la transmissió en directe",
"stopRecording": "Inicia l'enregistrament",
"stopRecordingWarning": "Esteu segur de voler iniciar l'enregistrament?",
"stopLiveStreaming": "Atura la transmissió en directe",
"stopRecording": "Atura l'enregistrament",
"stopRecordingWarning": "Esteu segur de voler aturar l'enregistrament?",
"stopStreamingWarning": "Esteu segur de voler aturar la transmissió en directe?",
"streamKey": "Clau de transmissió en directe",
"Submit": "Tramet",
"thankYou": "Gràcies per usar {{appName}}!",
"thankYou": "Gràcies per emprar {{appName}}!",
"token": "identificador",
"tokenAuthFailed": "No esteu autoritzat a unir-vos a aquesta trucada.",
"tokenAuthFailedTitle": "L'autenticació ha fallat",
@@ -281,7 +281,8 @@
"WaitForHostMsgWOk": "La conferència <b>{{room}}</b> encara no ha començat. Si sou l'amfitrió aleshores pitgeu «D'acord» per a autenticar-vos. Altrament, espereu que arribi l'amfitrió.",
"WaitingForHost": "S'està esperant l'amfitrió...",
"Yes": "Sí",
"yourEntireScreen": "La pantalla sencera"
"yourEntireScreen": "La pantalla sencera",
"screenSharingAudio": "Comparteix l'àudio"
},
"dialOut": {
"statusMessage": "ara és {{status}}"
@@ -394,7 +395,9 @@
"signOut": "Tanca la sessió",
"start": "Inicia la transmissió en directe",
"streamIdHelp": "Què és això?",
"unavailableTitle": "La transmissió en directe no és disponible"
"unavailableTitle": "La transmissió en directe no és disponible",
"googlePrivacyPolicy": "Política de privadesa de Google",
"youtubeTerms": "Condicions de servei del Youtube"
},
"localRecording": {
"clientState": {
@@ -448,7 +451,7 @@
"mutedRemotelyDescription": "Sempre podeu activar el micròfon quan hàgiu de parlar. Torneu a silenciar-lo quan hàgiu acabat per a mantenir el soroll lluny de la reunió.",
"passwordRemovedRemotely": "Un altre participant ha suprimit $t(lockRoomPasswordUppercase)",
"passwordSetRemotely": "Un altre participant ha establert la $t(lockRoomPassword)",
"raisedHand": " {{name}} vol parlar.",
"raisedHand": "{{name}} vol parlar.",
"somebody": "Algú",
"startSilentTitle": "Us hi heu unit sense cap sortida d'àudio!",
"startSilentDescription": "Torneu a entrar per a activar l'àudio",
@@ -534,7 +537,9 @@
"selectMic": "Micròfon",
"startAudioMuted": "Tothom comença silenciat",
"startVideoMuted": "Tothom comença amagat",
"title": "Configuració"
"title": "Configuració",
"speakers": "Altaveus",
"microphones": "Micròfons"
},
"settingsView": {
"advanced": "Avançat",
@@ -569,7 +574,8 @@
"speakerTime": "Temps de l'interlocutor"
},
"startupoverlay": {
"title": "{{app}} requereix usar el micròfon i la càmera."
"title": "{{app}} requereix usar el micròfon i la càmera.",
"policyText": " "
},
"suspendedoverlay": {
"rejoinKeyTitle": "Torna a entrar",
@@ -614,7 +620,8 @@
"tileView": "Activa o desactiva el mode mosaic",
"toggleCamera": "Activa o desactiva la càmera",
"videomute": "Activa o desactiva el vídeo",
"videoblur": "Activa o desactiva el difuminat"
"videoblur": "Activa o desactiva el difuminat",
"toggleFilmstrip": "Activa o desactiva la tira"
},
"addPeople": "Afegeix persones a la trucada",
"audioOnlyOff": "Desactiva el mode de poc ample de banda",
@@ -646,7 +653,7 @@
"noAudioSignalDesc": "Si no l'heu silenciat intencionadament en la configuració del sistema o per maquinari, considereu canviar l'aparell.",
"noAudioSignalDescSuggestion": "Si no l'heu silenciat intencionadament en la configuració del sistema o per maquinari, considereu canviar a l'aparell suggerit.",
"noAudioSignalDialInDesc": "També podeu marcar usant:",
"noAudioSignalDialInLinkDesc" : "Números de marcatge",
"noAudioSignalDialInLinkDesc": "Números de marcatge",
"noisyAudioInputTitle": "Sembla que el micròfon fa soroll!",
"noisyAudioInputDesc": "Sembla que el vostre micròfon fa soroll, considereu de silenciar-lo o canviar l'aparell.",
"openChat": "Obre el xat",
@@ -719,7 +726,7 @@
"ldTooltip": "Vídeo en baixa definició",
"lowDefinition": "Baixa definició",
"onlyAudioAvailable": "Només hi ha disponible l'àudio",
"onlyAudioSupported": "Només es permet àudio en aquest navegador",
"onlyAudioSupported": "Només es permet àudio en aquest navegador.",
"p2pEnabled": "Mode d'igual a igual activat",
"p2pVideoQualityDescription": "En el mode d'igual a igual, la qualitat del vídeo rebut només es pot canviar entre alta i només àudio. La resta de configuracions no es compliran fins sortir del mode d'igual a igual.",
"recHighDefinitionOnly": "L'alta definició serà preferent.",
@@ -767,10 +774,14 @@
"roomnameHint": "Introduïu el nom o l'URL de la sala on voleu entrar. Podeu crear un nom, només cal que les persones amb qui us reuniu el coneguin i introdueixin el mateix nom.",
"sendFeedback": "Envia comentaris",
"terms": "Condicions",
"title": "Videoconferència segura, plena de funcionalitats i completament gratuïta i lliure"
"title": "Videoconferència segura, plena de funcionalitats i completament gratuïta i lliure",
"getHelp": "Ajuda"
},
"lonelyMeetingExperience": {
"button": "Convideu altres persones",
"youAreAlone": "Sou l'únic participant de la reunió"
},
"helpView": {
"header": "Centre d'ajuda"
}
}

View File

@@ -1,86 +1,99 @@
{
"addPeople": {
"add": "",
"countryNotSupported": "",
"countryReminder": "",
"disabled": "",
"failedToAdd": "",
"footerText": "",
"loading": "",
"loadingNumber": "",
"loadingPeople": "",
"noResults": "",
"noValidNumbers": "",
"searchNumbers": "",
"searchPeople": "",
"searchPeopleAndNumbers": "",
"telephone": "",
"title": ""
"add": "Pozvat",
"countryNotSupported": "Toto místo zatím nepodporujeme.",
"countryReminder": "Voláte mimo USA? Nezapomeňte začít kódem své země!",
"disabled": "Nemůžete pozvat lidi.",
"failedToAdd": "Nepodařilo se přidat účastníky",
"footerText": "Vytáčení je zakázáno.",
"loading": "Hledání lidí a telefonních čísel",
"loadingNumber": "Ověření telefonního čísla",
"loadingPeople": "Hledání lidí pro pozvání",
"noResults": "Žádné odpovídající výsledky vyhledávání",
"noValidNumbers": "Zadejte telefonní číslo",
"searchNumbers": "Přidat telefonní čísla",
"searchPeople": "Hledat lidi",
"searchPeopleAndNumbers": "Hledat lidi nebo přidat jejich telefonní čísla",
"telephone": "Telefonní číslo: {{number}}",
"title": "Pozvěte lidi na toto setkání"
},
"audioDevices": {
"bluetooth": "Bluetooth",
"headphones": "Sluchátka",
"phone": "Telefon",
"speaker": "Řečník"
"speaker": "Reproduktor",
"none": "Nejsou k dispozici žádná zvuková zařízení"
},
"audioOnly": {
"audioOnly": "Pouze zvuk"
"audioOnly": "Nízká přenosová rychlost"
},
"calendarSync": {
"addMeetingURL": "",
"confirmAddLink": "",
"addMeetingURL": "Přidejte odkaz na schůzku",
"confirmAddLink": "Chcete k této události přidat odkaz Jitsi?",
"error": {
"appConfiguration": "",
"generic": "",
"notSignedIn": ""
"appConfiguration": "Integrace kalendáře není správně nakonfigurována.",
"generic": "Došlo k chybě. Zkontrolujte nastavení kalendáře nebo zkuste aktualizovat kalendář.",
"notSignedIn": "Při ověřování k zobrazení kalendářových událostí došlo k chybě. Zkontrolujte prosím nastavení kalendáře a zkuste se znovu přihlásit."
},
"join": "",
"joinTooltip": "",
"nextMeeting": "",
"noEvents": "",
"ongoingMeeting": "",
"permissionButton": "",
"permissionMessage": "",
"refresh": "",
"today": ""
"join": "Připojit se",
"joinTooltip": "Připojit se k videohovoru",
"nextMeeting": "další videohovor",
"noEvents": "Nejsou naplánovány žádné události.",
"ongoingMeeting": "současný videohovor",
"permissionButton": "Otevřít nastavení",
"permissionMessage": "K zobrazení videohovorů v aplikaci je potřeba oprávnění Kalendář.",
"refresh": "Obnovit kalendář",
"today": "Dnes"
},
"chat": {
"error": "",
"messagebox": "Prostor pro zprávu",
"error": "Chyba: vaše zpráva nebyla odeslána. Důvod: {{error}}",
"messagebox": "Napište zprávu",
"nickname": {
"popover": "Zvolte si přezdívku",
"title": ""
"title": "K zahájení chatu vložte přezdívku"
},
"title": ""
"title": "Chat",
"fieldPlaceHolder": "Zde napište svou zprávu",
"messageTo": "Soukromá zpráva pro {{recipient}}",
"you": "vy",
"privateNotice": "Soukromá zpráva pro {{recipient}}",
"noMessagesMessage": "V tomto videohovoru ještě nejsou žádné zprávy. Začněte konverzaci!"
},
"connectingOverlay": {
"joiningRoom": ""
"joiningRoom": "Probíhá připojování k videohovoru..."
},
"connection": {
"ATTACHED": "",
"AUTHENTICATING": "Ověřit",
"AUTHFAIL": "",
"CONNECTED": "",
"CONNECTING": "Připoje:",
"CONNFAIL": "",
"DISCONNECTED": "odpojeno",
"DISCONNECTING": "odpojeno",
"ERROR": "",
"RECONNECTING": ""
"ATTACHED": "Přiložený",
"AUTHENTICATING": "Ověřování",
"AUTHFAIL": "Ověřování selhalo",
"CONNECTED": "Připojeno",
"CONNECTING": "Připojování",
"CONNFAIL": "Připojení selhalo",
"DISCONNECTED": "Odpojeno",
"DISCONNECTING": "Odpojování",
"ERROR": "Chyba",
"RECONNECTING": "",
"LOW_BANDWIDTH": "Video pro {{displayName}} bylo vypnuto pro snížení přenosové rychlosti",
"GOT_SESSION_ID": "Získávání session-id... Hotovo",
"GET_SESSION_ID_ERROR": "Chyba při získávání session-id: {{code}}",
"FETCH_SESSION_ID": "Získává se session-id..."
},
"\u0005connection": {},
"connectionindicator": {
"address": "Adresa:",
"bandwidth": "Odhadovaná šířka pásma:",
"bitrate": "Přenosová rychlost:",
"bridgeCount": "Počet serverů:",
"connectedTo": "",
"bridgeCount": "Počet serverů: ",
"connectedTo": "Připojeno k:",
"framerate": "Rychlost snímkování:",
"less": "Zobrazit méně",
"localaddress": "Místní adresa:",
"localaddress_0": "Místní adresa:",
"localaddress_1": "Místní adresy:",
"localaddress_2": "Místní adresy:",
"localaddress_plural_2": "Místní adresy:",
"localaddress_plural_5": "Místních adres:",
"localport": "Místní port:",
"localport_0": "Místní port:",
"localport_1": "Místní porty:",
"localport_2": "Místní porty:",
"localport_plural_2": "Místní porty:",
"localport_plural_5": "Místních portů:",
"more": "Zobrazit více",
@@ -92,33 +105,40 @@
"nonoptimal": "Není optimální",
"poor": "Slabý"
},
"remoteaddress": "Vzdálená adresa:",
"remoteaddress_0": "Vzdálená adresa:",
"remoteaddress_1": "Vzdálené adresy:",
"remoteaddress_2": "Vzdálené adresy:",
"remoteaddress_plural_2": "Vzdálené adresy:",
"remoteaddress_plural_5": "Vzdálených adres:",
"remoteport": "Vzdálený port:",
"remoteport_0": "Vzdálený port:",
"remoteport_1": "Vzdálené porty:",
"remoteport_2": "Vzdálené porty:",
"remoteport_plural_2": "Vzdálené porty:",
"remoteport_plural_5": "Vzdálených portů:",
"resolution": "Rozlišení:",
"status": "Připojení:",
"transport": "Přenos:",
"transport_0": "Přenos:",
"transport_1": "Přenosy:",
"transport_2": "Přenosy:",
"transport_plural_2": "Přenosy:",
"transport_plural_5": "Přenosů:",
"turn": "(otočit)"
"turn": "(otočit)",
"e2e_rtt": "E2E RTT:"
},
"dateUtils": {
"earlier": "",
"today": "",
"yesterday": ""
"earlier": "Dříve",
"today": "Dnes",
"yesterday": "Včera"
},
"deepLinking": {
"appNotInstalled": "",
"description": "",
"descriptionWithoutWeb": "",
"appNotInstalled": "Pro připojení k tomuto videohovoru potřebujete mít na svém telefonu aplikaci {{app}}.",
"description": "Nic se nestalo? Zkusili jsme spustit videohovor v desktopové aplikaci {{app}}. Zkuste to znovu nebo spusťte webovou aplikaci {{app}}.",
"descriptionWithoutWeb": "Nic se nestalo? Zkusili jsme spustit videohovor v desktopové aplikaci {{app}}.",
"downloadApp": "Stažení aplikace",
"launchWebButton": "",
"openApp": "",
"title": "",
"tryAgainButton": ""
"launchWebButton": "Spustit na webu",
"openApp": "Pokračovat do aplikace",
"title": "Spustit videohovor v {{app}}...",
"tryAgainButton": "Zkusit znovu na desktopu"
},
"defaultLink": "např. {{url}}",
"deviceError": {
@@ -135,115 +155,115 @@
},
"dialog": {
"accessibilityLabel": {
"liveStreaming": ""
"liveStreaming": "Živý stream"
},
"allow": "Povolit",
"alreadySharedVideoMsg": "",
"alreadySharedVideoTitle": "",
"applicationWindow": "",
"Back": "",
"cameraConstraintFailedError": "",
"cameraNotFoundError": "",
"cameraNotSendingData": "",
"cameraNotSendingDataTitle": "",
"cameraPermissionDeniedError": "",
"cameraUnknownError": "",
"cameraUnsupportedResolutionError": "",
"alreadySharedVideoMsg": "Video už sdílí jiný účastník. Tato konference umožňuje sdílet jen jedno video současně.",
"alreadySharedVideoTitle": "Je povoleno jen jedno sdílené video",
"applicationWindow": "Okno aplikace",
"Back": "Zpět",
"cameraConstraintFailedError": "Vaše kamera nesplňuje některé požadované parametry.",
"cameraNotFoundError": "Kamera nebyla nalezena.",
"cameraNotSendingData": "Nelze přistupovat ke kameře. Zkontrolujte prosím, zda ji už nepoužívá jiná aplikace, vyberte jiné zařízení v nabídce nastavení nebo zkuste aplikaci znovu načíst.",
"cameraNotSendingDataTitle": "Nelze přistupovat ke kameře",
"cameraPermissionDeniedError": "Neudělili jste oprávnění k použití kamery. Můžete se sice připojit ke konferenci, ale ostatní vás neuvidí. Opravíte to stiskem tlačítka kamery v adresním řádku.",
"cameraUnknownError": "Z neznámého důvodu nelze používat kameru.",
"cameraUnsupportedResolutionError": "Vaše kamera nepodporuje požadované rozlišení obrazu.",
"Cancel": "Storno",
"close": "Zavřít",
"conferenceDisconnectMsg": "Možná byste měli zkontrolovat připojení k síti. Znovu se připojíte za {{seconds}} s...",
"conferenceDisconnectTitle": "Byl jste odhlášen.",
"conferenceReloadMsg": "Pokoušíme se to opravit. Znovu se připojíte za {{seconds}} s...",
"conferenceReloadMsg": "Pokoušíme se to opravit. Znovu se připojíte za {{seconds}} s...",
"conferenceReloadTitle": "Bohužel, něco se pokazilo.",
"confirm": "",
"confirmNo": "",
"confirmYes": "",
"confirm": "Potvrdit",
"confirmNo": "Ne",
"confirmYes": "Ano",
"connectError": "Jejda! Něco se pokazilo a do konference se nepodařilo připojit.",
"connectErrorWithMsg": "Jejda! Něco se pokazilo a do konference se nepodařilo připojit: {{msg}}",
"connecting": "Připojení:",
"connecting": "Připojení",
"contactSupport": "Kontaktovat podporu",
"copy": "Kopírovat",
"dismiss": "OK",
"displayNameRequired": "",
"displayNameRequired": "Ahoj! Jak se jmenuješ?",
"done": "Hotovo",
"enterDisplayName": "",
"error": "",
"externalInstallationMsg": "",
"externalInstallationTitle": "",
"goToStore": "",
"gracefulShutdown": "",
"IamHost": "",
"incorrectRoomLockPassword": "",
"enterDisplayName": "Vložte prosím své jméno",
"error": "Chyba",
"externalInstallationMsg": "Je potřeba nainstalovat rozšíření pro sdílení plochy.",
"externalInstallationTitle": "Požadováno rozšíření",
"goToStore": "Jít do webového obchodu",
"gracefulShutdown": "Naše služba je nyní mimo provoz kvůli údržbě. Zkuste to prosím znovu později.",
"IamHost": "Jsem hostitel",
"incorrectRoomLockPassword": "Chybné heslo",
"incorrectPassword": "Uživatelské jméno nebo heslo není správně",
"inlineInstallationMsg": "",
"inlineInstallExtension": "",
"inlineInstallationMsg": "Je potřeba nainstalovat rozšíření pro sdílení plochy.",
"inlineInstallExtension": "Nainstalovat",
"internalError": "Jejda! Něco se pokazilo. Objevila se následující chyba: {{error}}",
"internalErrorTitle": "Vnitřní chyba",
"kickMessage": "",
"kickParticipantButton": "",
"kickParticipantDialog": "",
"kickParticipantTitle": "",
"kickTitle": "",
"liveStreaming": "",
"liveStreamingDisabledForGuestTooltip": "",
"kickMessage": "Pro více informací můžete kontaktovat {{participantDisplayName}}.",
"kickParticipantButton": "Vyhodit",
"kickParticipantDialog": "Opravdu chcete vyhodit tohoto účastníka?",
"kickParticipantTitle": "Vyhodit tohoto účastníka?",
"kickTitle": "Au! {{participantDisplayName}} vás vyhodil z videohovoru",
"liveStreaming": "Živý streaming",
"liveStreamingDisabledForGuestTooltip": "Hosté nemohou spustit živý streaming.",
"liveStreamingDisabledTooltip": "",
"lockMessage": "Konferenci se nepodařilo uzamknout.",
"lockRoom": "",
"lockRoom": "Přidat videohovor $t(lockRoomPasswordUppercase)",
"lockTitle": "Zamknutí selhalo",
"logoutQuestion": "Jste si jistí, že se chcete odhlásit a ukončit konferenci?",
"logoutTitle": "Odhlásit",
"maxUsersLimitReached": "",
"maxUsersLimitReachedTitle": "",
"micConstraintFailedError": "",
"micNotFoundError": "",
"micNotSendingData": "",
"micNotSendingDataTitle": "",
"micPermissionDeniedError": "",
"micUnknownError": "",
"maxUsersLimitReached": "Byl dosažen limit počtu účastníků. Konference je plná. Kontaktujte prosím vlastníka videohovoru nebo to zkuste znovu později!",
"maxUsersLimitReachedTitle": "Dosažen limit počtu účastníků",
"micConstraintFailedError": "Váš mikrofon nesplňuje některé požadované parametry.",
"micNotFoundError": "Mikrofon nebyl nalezen.",
"micNotSendingData": "Jít do nastavení počítače, zapnout mikrofon a nastavit jeho citlivost",
"micNotSendingDataTitle": "Váš mikrofon je vypnutý v nastavení systému",
"micPermissionDeniedError": "Neudělili jste oprávnění pro použití mikrofonu. Můžete se sice připojit ke konferenci, ale ostatní vás neuslyší. Opravíte to stiskem tlačítka kamery v adresním řádku.",
"micUnknownError": "Z neznámého důvodu nelze použít mikrofon.",
"muteParticipantBody": "",
"muteParticipantButton": "Ztlumený zvuk",
"muteParticipantDialog": "",
"muteParticipantTitle": "",
"muteParticipantTitle": "Umlčet tohoto účastníka?",
"Ok": "Ok",
"passwordLabel": "",
"passwordNotSupported": "Nastavení hesla pro konferenci není podporováno.",
"passwordNotSupportedTitle": "",
"passwordRequired": "",
"passwordNotSupported": "Nastavení konference $t(lockRoomPassword) není podporováno.",
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) není podporováno",
"passwordRequired": "Požadováno $t(lockRoomPasswordUppercase)",
"popupError": "Váš prohlížeč blokuje vyskakovací okna. V nastavení zabezpečení prosím povolte vyskakování oken a zkuste to znovu.",
"popupErrorTitle": "Vyskakovací okno je zablokované",
"recording": "",
"recordingDisabledForGuestTooltip": "",
"recordingDisabledTooltip": "",
"recording": "Záznam",
"recordingDisabledForGuestTooltip": "Hosté nemohou spustit záznam.",
"recordingDisabledTooltip": "Zahájení záznamu vypnuto.",
"rejoinNow": "Znovu se připojit",
"remoteControlAllowedMessage": "",
"remoteControlDeniedMessage": "",
"remoteControlErrorMessage": "",
"remoteControlRequestMessage": "",
"remoteControlShareScreenWarning": "",
"remoteControlStopMessage": "",
"remoteControlTitle": "",
"remoteControlAllowedMessage": "{{user}} přijal(a) vaši žádost o dálkové ovládání!",
"remoteControlDeniedMessage": "{{user}} odmítl(a) vaši žádost o dálkové ovládání!",
"remoteControlErrorMessage": "Při požadavku na oprávnění k dálkového ovládání od {{user}} došlo k chybě!",
"remoteControlRequestMessage": "Umožníte {{user}} dálkově ovládat váš počítač?",
"remoteControlShareScreenWarning": "Nezapomeňte, že stiskem \"Povolit\" budete sdílet svou obrazovku!",
"remoteControlStopMessage": "Relace dálkového ovládání skončila!",
"remoteControlTitle": "Dálkové ovládání počítače",
"Remove": "Odstranit",
"removePassword": "Zrušit heslo",
"removeSharedVideoMsg": "",
"removeSharedVideoTitle": "",
"reservationError": "",
"reservationErrorMsg": "",
"removePassword": "Odstranit $t(lockRoomPassword)",
"removeSharedVideoMsg": "Opravdu chcete odstranit sdílené video?",
"removeSharedVideoTitle": "Odstranit sdílené video",
"reservationError": "Systémová chyba rezervace",
"reservationErrorMsg": "Chyba: {{code}}, zpráva: {{msg}}",
"retry": "Opakovat",
"screenSharingFailedToInstall": "Doplněk pro sdílení obrazovky se nepodařilo nainstalovat",
"screenSharingFailedToInstall": "Doplněk pro sdílení obrazovky se nepodařilo nainstalovat.",
"screenSharingFailedToInstallTitle": "Doplněk pro sdílení obrazovky se nepodařilo nainstalovat",
"screenSharingFirefoxPermissionDeniedError": "",
"screenSharingFirefoxPermissionDeniedTitle": "",
"screenSharingPermissionDeniedError": "",
"serviceUnavailable": "",
"serviceUnavailable": "Služba není dostupná",
"sessTerminated": "Volání ukončeno",
"Share": "Sdílet",
"shareVideoLinkError": "Zadejte prosím správný odkaz na youtube video.",
"shareVideoTitle": "Sdílet obraz",
"shareYourScreen": "Sdílet obrazovku",
"shareYourScreenDisabled": "",
"shareYourScreenDisabledForGuest": "",
"startLiveStreaming": "",
"startRecording": "",
"shareYourScreenDisabled": "Sdílení obrazovky vypnuto.",
"shareYourScreenDisabledForGuest": "Hosté nemohou sdílet obrazovku.",
"startLiveStreaming": "Spustit živý stream",
"startRecording": "Spustit záznam",
"startRemoteControlErrorMessage": "",
"stopLiveStreaming": "",
"stopRecording": "",
@@ -254,79 +274,85 @@
"thankYou": "Děkujeme, že používáte {{appName}}!",
"token": "token",
"tokenAuthFailed": "Bohužel nemáte povoleno se k tomuto volání připojit.",
"tokenAuthFailedTitle": "",
"tokenAuthFailedTitle": "Ověření selhalo",
"transcribing": "",
"unlockRoom": "",
"unlockRoom": "Odstranit videohovor $t(lockRoomPassword)",
"userPassword": "uživatelské heslo",
"WaitForHostMsg": "",
"WaitForHostMsgWOk": "",
"WaitingForHost": "",
"Yes": "",
"yourEntireScreen": ""
"Yes": "Ano",
"yourEntireScreen": "Celá vaše obrazovka",
"sendPrivateMessageTitle": "Poslat soukromě?",
"sendPrivateMessageOk": "Poslat soukromě",
"sendPrivateMessageCancel": "Poslat do skupiny",
"sendPrivateMessage": "Nedávno vám přišla soukromá zpráva. Chcete na ni odpovědět soukromě, nebo chcete poslat zprávu do skupiny?",
"screenSharingAudio": "Sdílet zvuk",
"muteEveryoneStartMuted": "Nyní jsou všichni umlčeni",
"muteEveryoneTitle": "Umlčet všechny?",
"muteEveryoneElseTitle": "Umlčet všechny kromě {{whom}}?"
},
"\u0005dialog": {},
"dialOut": {
"statusMessage": ""
"statusMessage": "je nyní {{status}}"
},
"feedback": {
"average": "",
"bad": "",
"detailsLabel": "",
"good": "",
"rateExperience": "",
"veryBad": "",
"veryGood": ""
"average": "Průměrná",
"bad": "Špatná",
"detailsLabel": "Řekněte nám o tom víc.",
"good": "Dobrá",
"rateExperience": "Ohodnoťte svoji zkušenost s videohovorem",
"veryBad": "Velmi špatná",
"veryGood": "Velmi dobrá"
},
"incomingCall": {
"answer": "",
"audioCallTitle": "",
"answer": "Odpovědět",
"audioCallTitle": "Příchozí hovor",
"decline": "OK",
"productLabel": "",
"videoCallTitle": ""
"productLabel": "od Jitsi Meet",
"videoCallTitle": "Příchozí videohovor"
},
"info": {
"accessibilityLabel": "Více info",
"addPassword": "Nastavit heslo",
"cancelPassword": "Zrušit heslo",
"addPassword": "Přidat $t(lockRoomPassword)",
"cancelPassword": "Zrušit $t(lockRoomPassword)",
"conferenceURL": "Odkaz:",
"country": "Země",
"dialANumber": "",
"dialInConferenceID": "",
"dialInNotSupported": "",
"dialANumber": "Pro připojení k videohovoru vytočte tato čísla a vložte PIN.",
"dialInConferenceID": "PIN:",
"dialInNotSupported": "Omlouváme se, ale vytáčení není nyní podporováno.",
"dialInNumber": "",
"dialInSummaryError": "",
"dialInTollFree": "",
"dialInTollFree": "Zdarma",
"genericError": "Ups, něco se pokazilo.",
"inviteLiveStream": "K zobrazení živého vysílání tohoto meetingu, klikněte na tento odkaz: {{url}}",
"invitePhone": "One tap audio Dial In: {{number}},,{{conferenceID}}#",
"invitePhone": "Pro připojení telefonicky použijte: {{number}},,{{conferenceID}}#\n",
"invitePhoneAlternatives": "",
"inviteURLFirstPartGeneral": "",
"inviteURLFirstPartGeneral": "Připojte se k meetingu.",
"inviteURLFirstPartPersonal": "",
"inviteURLSecondPart": "",
"liveStreamURL": "Živé vysílání:",
"moreNumbers": "More numbers",
"noNumbers": "No dial-in numbers.",
"moreNumbers": "Více čísel",
"noNumbers": "Žádná čísla pro připojení po telefonu.",
"noPassword": "Bez hesla",
"noRoom": "No room was specified to dial-in into.",
"numbers": "Dial-in Numbers",
"password": "Heslo:",
"noRoom": "Nebyla vybrána místnost pro připojení po telefonu.",
"numbers": "Čísla pro připojení telefonicky",
"password": "$t(lockRoomPasswordUppercase):",
"title": "Sdílet",
"tooltip": "Sdílet odkaz k tomuto meetingu",
"label": "Informace o meetingu"
},
"\u0005info": {},
"inviteDialog": {
"alertText": "",
"header": "",
"searchCallOnlyPlaceholder": "",
"searchPeopleOnlyPlaceholder": "",
"searchPlaceholder": "",
"send": ""
"alertText": "Pozvání některých účastníků selhalo.",
"header": "Pozvat",
"searchCallOnlyPlaceholder": "Vložte telefonní číslo",
"searchPeopleOnlyPlaceholder": "Hledat účastníky",
"searchPlaceholder": "Účastník nebo telefonní číslo",
"send": "Odeslat"
},
"inlineDialogFailure": {
"msg": "",
"retry": "",
"support": "",
"retry": "Zkusit znovu",
"support": "Podpora",
"supportMsg": ""
},
"keyboardShortcuts": {
@@ -343,9 +369,9 @@
"toggleFilmstrip": "Zobrazit / Skrýt videonáhledy účastníků",
"toggleScreensharing": "Přepnutí mezi kamerou a sdílením obrazovky",
"toggleShortcuts": "Zobrazení / Skrytí klávesových zkratek",
"videoMute": "Spuštění / Vypnutí vaší kamery"
"videoMute": "Spuštění / Vypnutí vaší kamery",
"videoQuality": "Spravovat kvalitu hovoru"
},
"\u0005keyboardShortcuts": {},
"liveStreaming": {
"busy": "",
"busyTitle": "",
@@ -366,25 +392,25 @@
"on": "",
"pending": "",
"serviceName": "",
"signedInAs": "",
"signIn": "",
"signInCTA": "",
"signOut": "",
"signedInAs": "Nyní jste přihlášen(a) jako:",
"signIn": "Přihlásit se účtem Google",
"signInCTA": "Přihlaste se nebo vložte svůj klíč ze služby YouTube.",
"signOut": "Odhlásit se",
"start": "",
"streamIdHelp": "",
"streamIdHelp": "Co je tohle?",
"unavailableTitle": ""
},
"localRecording": {
"clientState": {
"off": "",
"on": "",
"unknown": ""
"off": "Vyp",
"on": "Zap",
"unknown": "Neznámý"
},
"dialogTitle": "",
"duration": "",
"durationNA": "",
"encoding": "",
"label": "",
"dialogTitle": "Ovládání místních záznamů",
"duration": "Doba trvání",
"durationNA": "N/A",
"encoding": "Kódování",
"label": "LOR",
"labelToolTip": "",
"localRecording": "",
"me": "Já",
@@ -395,13 +421,13 @@
"notModerator": ""
},
"moderator": "Moderátor",
"no": "",
"participant": "",
"no": "Ne",
"participant": "Účastník",
"participantStats": "Zobrazit statistiku účastníků",
"sessionToken": "",
"start": "",
"stop": "",
"yes": ""
"start": "Spustit záznam",
"stop": "Zastavit záznam",
"yes": "Ano"
},
"lockRoomPassword": "heslo",
"lockRoomPasswordUppercase": "Heslo",
@@ -433,13 +459,12 @@
"suboptimalExperienceDescription": "Sakra... všimli jsme si, že vaše zkušenost s {{appName}} není úplně skvělá. Hledáme cesty, jak bychom to mohli zlepšit. Než se tak stane, vyzkoušejte některý z <a href='static/recommendedBrowsers.html' target='_blank'>plně podporovaných prohlížečů</a>.",
"suboptimalExperienceTitle": "Varování prohlížeče",
"unmute": "",
"newDeviceCameraTitle": "",
"newDeviceAudioTitle": "",
"newDeviceAction": ""
"newDeviceCameraTitle": "Detekována nová kamera",
"newDeviceAudioTitle": "Detekováno nové zvukové zařízení",
"newDeviceAction": "Použít"
},
"\u0005notify": {},
"passwordSetRemotely": "",
"passwordDigitsOnly": "",
"passwordSetRemotely": "nastaveno jiným účastníkem",
"passwordDigitsOnly": "Až {{number}} číslic",
"poweredby": "Poháněno",
"presenceStatus": {
"busy": "Obsazeno",
@@ -455,7 +480,6 @@
"rejected": "Odmítnuto",
"ringing": "Zvoní..."
},
"\u0005presenceStatus": {},
"profile": {
"setDisplayNameLabel": "Nastavte si jméno",
"setEmailInput": "Zadejte e-mail",
@@ -463,9 +487,9 @@
"title": "Profil"
},
"recording": {
"authDropboxText": "",
"availableSpace": "",
"beta": "",
"authDropboxText": "Nahrát na Dropbox",
"availableSpace": "Dostupný prostor: {{spaceLeft}} MB (přibližně {{duration}} minut záznamu)",
"beta": "BETA",
"busy": "",
"busyTitle": "",
"error": "",
@@ -494,7 +518,7 @@
"calendar": {
"about": "",
"disconnect": "odpojeno",
"microsoftSignIn": "",
"microsoftSignIn": "Přihlásit se účtem Microsoft",
"signedIn": "",
"title": "Kalendář"
},
@@ -511,25 +535,26 @@
"selectMic": "Mikrofon",
"startAudioMuted": "Při připojení všem zlumit zvuk",
"startVideoMuted": "Všechny připojovat jako skrýté",
"title": "Nastavení"
},
"\u0005settings": {
"calendar": {}
"title": "Nastavení",
"speakers": "Reproduktory",
"microphones": "Mikrofony"
},
"settingsView": {
"alertOk": "",
"alertTitle": "",
"alertOk": "OK",
"alertTitle": "Varování",
"alertURLText": "",
"buildInfoSection": "",
"conferenceSection": "",
"displayName": "",
"email": "",
"header": "",
"profileSection": "",
"serverURL": "",
"displayName": "Zobrazované jméno",
"email": "E-mail",
"header": "Nastavení",
"profileSection": "Profil",
"serverURL": "URL serveru",
"startWithAudioMuted": "",
"startWithVideoMuted": "",
"version": ""
"version": "",
"showAdvanced": "Zobrazit pokročilá nastavení",
"advanced": "Pokročilé"
},
"share": {
"dialInfoText": "",
@@ -632,9 +657,6 @@
"startvideoblur": "Rozmazat pozadí",
"stopvideoblur": "Zrušit rozmazání"
},
"\u0005toolbar": {
"accessibilityLabel": {}
},
"transcribing": {
"ccButtonTooltip": "",
"error": "",
@@ -660,51 +682,51 @@
"safariGrantPermissions": "Pokud se váš prohlížeč ptá na práva, vyberte <b><i>OK</i></b> a potvrďte."
},
"videoSIPGW": {
"busy": "",
"busyTitle": "",
"errorAlreadyInvited": "",
"errorInvite": "",
"errorInviteFailed": "",
"errorInviteFailedTitle": "",
"errorInviteTitle": "",
"pending": ""
"busy": "Pracujeme na uvolnění prostředků. Zkuste to prosím znovu za několik minut.",
"busyTitle": "Služba Místnost je nyní zaneprázdněna",
"errorAlreadyInvited": "{{displayName}} byl(a) již pozván(a)",
"errorInvite": "Konference ještě nebyla založena. Zkuste to prosím později.",
"errorInviteFailed": "Na vyřešení problému pracujeme. Zkuste to prosím znovu později.",
"errorInviteFailedTitle": "Pozvání {{displayName}} selhalo",
"errorInviteTitle": "Chyba při pozvání do místnosti",
"pending": "{{displayName}} byl(a) pozván(a)"
},
"videoStatus": {
"audioOnly": "AU",
"audioOnlyExpanded": "",
"audioOnlyExpanded": "Jste v režimu nízké přenosové rychlosti. V tomto režimu je k dispozici jen zvuk a sdílení obrazovky.",
"callQuality": "Nastavení kvality hovoru",
"hd": "",
"hd": "HD",
"hdTooltip": "Sledujete obraz ve vysoké kvalitě",
"highDefinition": "Vysoká kvalita",
"labelTooiltipNoVideo": "",
"labelTooltipAudioOnly": "",
"ld": "",
"labelTooiltipNoVideo": "Žádné video",
"labelTooltipAudioOnly": "Zapnut režim nízké přenosové rychlosti",
"ld": "LD",
"ldTooltip": "Sledujete obraz v nízké kvalitě",
"lowDefinition": "Nizká kvalita",
"onlyAudioAvailable": "",
"onlyAudioSupported": "",
"p2pEnabled": "",
"p2pVideoQualityDescription": "",
"recHighDefinitionOnly": "",
"sd": "",
"onlyAudioAvailable": "Je k dispozici jen zvuk",
"onlyAudioSupported": "V tomto prohlížeči podporujeme jen zvuk.",
"p2pEnabled": "Zapnut režim peer to peer",
"p2pVideoQualityDescription": "V režimu peer to peer lze kvalitu videa přepínat jen mezi vysokou a pouhým zvukem. Ostatní nastavení se ignorují, dokud tento režim neopustíte.",
"recHighDefinitionOnly": "Bude preferována vysoká kvalita.",
"sd": "SD",
"sdTooltip": "Sledujete obraz v běžné kvalitě",
"standardDefinition": "Běžná kvalita"
},
"videothumbnail": {
"domute": "Ztlumený zvuk",
"domute": "Umlčet",
"flip": "Převrátit",
"kick": "Vyhodit",
"moderator": "Moderátor",
"mute": "",
"mute": "Účastník je umlčen",
"muted": "Ztlumený zvuk",
"remoteControl": "Vzdálené ovládání",
"show": "",
"videomute": ""
"videomute": "Účastník si vypnul kameru",
"domuteOthers": "Umlčet všechny ostatní"
},
"\u0005videothumbnail": {},
"welcomepage": {
"accessibilityLabel": {
"join": "",
"join": "Dotykem se připojíte",
"roomname": "Zadejte jméno místnosti"
},
"appDescription": "Videokonference pro celý Váš tým, zdarma, bez nároků na Vaše data. Do konference můžete pozvat kohokoliv. Veškerá komunikace přes aplikaci {{app}} je plně šifrovaná, 100% open source zajištuje, že aplikaci můžete využívat bez omezení a navíc se nemusíte ani registrovat.",
@@ -713,21 +735,41 @@
"video": "Obraz"
},
"calendar": "Kalendář",
"connectCalendarButton": "",
"connectCalendarText": "",
"connectCalendarButton": "Připojit váš kalendář",
"connectCalendarText": "Připojte si kalendář a uvidíte všechny videohovory v {{app}}. Můžete si také přidat videohovory {{provider}} do kalendáře a spouštět je jedním klikem.",
"enterRoomTitle": "Začít nový videohovor",
"go": "ZAČÍT",
"join": "PŘIPOJIT",
"info": "",
"info": "Informace",
"privacy": "Soukromí",
"recentList": "",
"recentListDelete": "",
"recentList": "Nedávné",
"recentListDelete": "Smazat",
"recentListEmpty": "Váš seznam nedávných hovorů je prázdný. Spojte se s kolegy z Vašeho týmu, poté zde naleznete seznam nedávných hovorů.",
"reducedUIText": "",
"reducedUIText": "Vítejte v {{app}}!",
"roomname": "Zadejte jméno místnosti",
"roomnameHint": "Zadejte název nebo URL odkaz místnosti ke které se chcete připojit. Pokud jste místnost vytvořili, ujistěte se, že ostatní účastníci schůzky zadají stejné jméno jako vy.",
"sendFeedback": "Poslat zpětnou vazbu",
"terms": "Podmínky používání",
"title": "Bezpečné, plnotučné videokonference, zcela zdarma a soukromě, od lidí pro lidi."
"title": "Bezpečná, plnohodnotná a zdarma dostupná videokonference",
"roomNameAllowedChars": "Název videohovoru nesmí obsahovat žádný z těchto znaků: ?, &, :, ', \", %, #.",
"getHelp": "Získat pomoc",
"goSmall": "ZAČÍT"
},
"lonelyMeetingExperience": {
"youAreAlone": "Jste jediný/á v tomto videohovoru",
"button": "Pozvat další"
},
"helpView": {
"header": "Centrum pomoci"
},
"chromeExtensionBanner": {
"dontShowAgain": "Toto už znovu neukazovat",
"buttonText": "Nainstalovat rozšíření Chrome",
"installExtensionText": "Nainstalovat rozšíření pro integraci Google Calendar a Office 365"
},
"defaultNickname": "Franta Uživatel",
"raisedHand": "Chtěl(a) bych mluvit",
"documentSharing": {
"title": "Sdílený dokument"
}
}

View File

@@ -104,8 +104,8 @@
"nonoptimal": "Ikke optimal",
"poor": "Dårlig"
},
"remoteaddress": "Fjern adresse:",
"remoteaddress_plural": "Fjern adresser:",
"remoteaddress": "Fjernadresse:",
"remoteaddress_plural": "Fjernadresser:",
"remoteport": "Fjern port:",
"remoteport_plural": "Fjern porte:",
"resolution": "Opløsning:",
@@ -769,4 +769,4 @@
"betingelser": "Betingelser",
"title": "Skærmbesøg & videomøder"
}
}
}

View File

@@ -33,7 +33,7 @@
"error": {
"appConfiguration": "Kalenderintegration ist nicht richtig konfiguriert.",
"generic": "Ein Fehler ist aufgetreten. Prüfen Sie Ihre Kalendereinstellungen oder versuchen Sie, den Kalender zu aktualisieren.",
"notSignedIn": "Ein Fehler ist während der Authentifizierung zur Anzeige von Kalenderertermine aufgetreten. Prüfen Sie Ihre Kalendereinstellungen oder versuchen Sie, sich erneut anzumelden."
"notSignedIn": "Ein Fehler ist während der Authentifizierung zur Anzeige von Kalenderterminen aufgetreten. Prüfen Sie Ihre Kalendereinstellungen oder versuchen Sie, sich erneut anzumelden."
},
"join": "Teilnehmen",
"joinTooltip": "Am Meeting teilnehmen",
@@ -191,7 +191,7 @@
"kickMessage": "Sie können sich für weitere Einzelheiten an {{participantDisplayName}}} wenden.",
"kickParticipantButton": "Entfernen",
"kickParticipantDialog": "Wollen Sie diesen Teilnehmer wirklich entfernen?",
"kickParticipantTitle": "Teilnehmer stummschalten?",
"kickParticipantTitle": "Teilnehmer entfernen?",
"kickTitle": "Autsch! {{participantDisplayName}} hat Sie aus dem Meeting geworfen.",
"liveStreaming": "Livestreaming",
"liveStreamingDisabledForGuestTooltip": "Gäste können kein Livestreaming starten.",
@@ -241,7 +241,7 @@
"removePassword": "$t(lockRoomPassword) entfernen",
"removeSharedVideoMsg": "Sind Sie sicher, dass Sie das geteilte Video entfernen möchten?",
"removeSharedVideoTitle": "Freigegebenes Video entfernen",
"reservationError": "Fehler im Reservationssystem",
"reservationError": "Fehler im Reservierungssystem",
"reservationErrorMsg": "Fehler, Nummer: {{code}}, Nachricht: {{msg}}",
"retry": "Wiederholen",
"screenSharingFailedToInstall": "Oh! Die Erweiterung für die Bildschirmfreigabe konnte nicht installiert werden.",
@@ -315,7 +315,7 @@
"dialInConferenceID": "PIN:",
"dialInNotSupported": "Entschuldigung, leider wird das Einwählen derzeit nicht unterstützt.",
"dialInNumber": "Einwählen:",
"dialInSummaryError": "Fehler beim Abrufen der Einwählinformationen. Versuchen Sie es später erneut.",
"dialInSummaryError": "Fehler beim Abrufen der Einwahlinformationen. Versuchen Sie es später erneut.",
"dialInTollFree": "Gebührenfrei",
"genericError": "Es ist leider etwas schiefgegangen.",
"inviteLiveStream": "Klicken Sie auf {{url}} um den Livestream dieser Konferenz zu öffnen",
@@ -328,11 +328,11 @@
"moreNumbers": "Weitere Telefonnummern",
"noNumbers": "Keine Telefonnummern verfügbar.",
"noPassword": "Kein",
"noRoom": "Keine Konferenz für die Einwähl-Informationen angegeben.",
"noRoom": "Keine Konferenz für die Einwahlinformationen angegeben.",
"numbers": "Einwählnummern",
"password": "$t(lockRoomPasswordUppercase):",
"title": "Teilen",
"tooltip": "Freigabe-Link und Einwählinformationen für dieses Meeting",
"tooltip": "Freigabe-Link und Einwahlinformationen für dieses Meeting",
"label": "Meeting-Informationen"
},
"inviteDialog": {
@@ -367,7 +367,7 @@
"videoQuality": "Anrufqualität verwalten"
},
"liveStreaming": {
"busy": "Es werden Resourcen zum Streamen bereitgestellt. Bitte in ein paar Minuten erneut versuchen.",
"busy": "Es werden Ressourcen zum Streamen bereitgestellt. Bitte in ein paar Minuten erneut versuchen.",
"busyTitle": "Alle Streaming-Instanzen sind in Gebrauch",
"changeSignIn": "Konten wechseln.",
"choose": "Livestream auswählen",
@@ -405,7 +405,7 @@
"dialogTitle": "Lokale Aufzeichnungssteuerelemente",
"duration": "Dauer",
"durationNA": "N. v.",
"encoding": "Codierung",
"encoding": "Kodierung",
"label": "LOR",
"labelToolTip": "Lokale Aufzeichnung ist aktiviert",
"localRecording": "Lokale Aufzeichnung",
@@ -769,5 +769,9 @@
"sendFeedback": "Feedback senden",
"terms": "AGB",
"title": "Sichere, mit umfassenden Funktionen ausgestattete und vollkommen kostenlose Videokonferenzen"
},
"lonelyMeetingExperience": {
"button": "Weitere einladen",
"youAreAlone": "Sie sind der einzige in diesem Meeting"
}
}

View File

@@ -628,6 +628,7 @@
"logout": "Cerrar sesión",
"lowerYourHand": "Bajar la mano",
"moreActions": "Más acciones",
"moreOptions": "Más opciones",
"mute": "Activar / Desactivar Silencio",
"noAudioSignalTitle": "¡No hay entrada proveniente de su micrófono!",
"noAudioSignalDesc": "Si no lo silenció a propósito desde la configuración del sistema o el dispositivo, considere cambiar el dispositivo.",
@@ -752,5 +753,9 @@
"sendFeedback": "Enviar comentarios",
"terms": "Términos",
"title": "Seguro, lleno de funcionalidades y videoconferencias completamente gratuitas"
},
"lonelyMeetingExperience": {
"button": "Invitar a otros",
"youAreAlone": "Eres el único en la reunión"
}
}

View File

@@ -1,4 +1,4 @@
{
{
"addPeople": {
"add": "Lisa",
"countryNotSupported": "Valitud riik ei ole toetatud.",

View File

@@ -628,6 +628,7 @@
"logout": "Déconnexion",
"lowerYourHand": "Baisser la main",
"moreActions": "Plus d'actions",
"moreOptions": "Plus d'options",
"mute": "Muet / Actif",
"noAudioSignalTitle": "Il n'y a pas d'entrée provenant de votre micro !",
"noAudioSignalDesc": "Si vous n'avez pas délibérément coupé le son des paramètres du système ou du matériel, envisagez de changer le périphérique.",
@@ -752,5 +753,12 @@
"sendFeedback": "Envoyer votre avis",
"terms": "Termes",
"title": "Vidéoconférence Sécurisée, entièrement en vedette et gratuite"
},
"lonelyMeetingExperience": {
"button": "Inviter d'autres personnes",
"youAreAlone": "Vous êtes le seul participant de la réunion"
},
"helpView": {
"header": "Centre d'aide"
}
}

787
lang/main-is.json Normal file
View File

@@ -0,0 +1,787 @@
{
"addPeople": {
"add": "Bjóða",
"countryNotSupported": "Við eru ekki byrjuð með sambönd á þessum stað.",
"countryReminder": "Ertu að hringja út fyrir BNA? Gakktu úr skugga um að númerið byrji með landskóða!",
"disabled": "Þú getur ekki boðið fólki.",
"failedToAdd": "Mistókst að bæta við þátttakendum",
"footerText": "Úthringing er óvirk.",
"loading": "Leita að fólki og símanúmerum",
"loadingNumber": "Sannreyni símanúmer",
"loadingPeople": "Leita að fólki til að bjóða",
"noResults": "Engar leitarniðurstöður samsvara",
"noValidNumbers": "Settu inn símanúmer",
"searchNumbers": "Bæta við símanúmerum",
"searchPeople": "Leita að fólki",
"searchPeopleAndNumbers": "Leita að fólki og bæta við símanúmerum þess",
"telephone": "Símanúmer: {{number}}",
"title": "Bjóða fólki á þennan fund"
},
"audioDevices": {
"bluetooth": "Bluetooth",
"headphones": "Heyrnartól",
"phone": "Sími",
"speaker": "Ræðumaður",
"none": "Engin hljóðtæki tiltæk"
},
"audioOnly": {
"audioOnly": "Lítil bandbreidd"
},
"calendarSync": {
"addMeetingURL": "Bæta við fundartengli",
"confirmAddLink": "Viltu bæta við Jitsi-tengli í þennan atburð?",
"error": {
"appConfiguration": "Samþætting dagatals er ekki rétt uppsett.",
"generic": "Villa kom upp. Athugaðu stillingar dagatalsins eða prófaðu að endurlesa það.",
"notSignedIn": "Villa kom upp við auðkenningu til að skoða atburði dagatals. Athugaðu stillingar dagatalsins og prófaðu að skrá þig aftur inn á það."
},
"join": "Taka þátt",
"joinTooltip": "Taka þátt í fundinum",
"nextMeeting": "næsti fundur",
"noEvents": "Það eru engir áætlaðir atburðir á næstunni.",
"ongoingMeeting": "fundur í gangi",
"permissionButton": "Opna stillingar",
"permissionMessage": "Krafist er heimilda til að nota dagatal til að geta séð fundina þína í forritinu.",
"refresh": "Uppfæra dagatal",
"today": "Í dag"
},
"chat": {
"error": "Villa: skilaboðin þín voru ekki send. Ástæða: {{error}}",
"fieldPlaceHolder": "Skrifaðu skilaboðin þín hér",
"messagebox": "Skrifaðu skilaboð",
"messageTo": "Einkaskilaboð til {{recipient}}",
"noMessagesMessage": "Það eru ennþá engin skilaboð á fundinum. Byrjaðu umræðuna hér!",
"nickname": {
"popover": "Veldu gælunafn",
"title": "Settu inn gælunafn/stuttnefni til að nota við spjall"
},
"privateNotice": "Einkaskilaboð til {{recipient}}",
"title": "Spjall",
"you": "þú"
},
"chromeExtensionBanner": {
"installExtensionText": "Settu inn viðbót fyrir Google Calendar og samþættingu við Office 365",
"buttonText": "Setja inn Chrome-viðbót",
"dontShowAgain": "Ekki sýna mér þetta aftur"
},
"connectingOverlay": {
"joiningRoom": "Tengist við fundinn þinn ..."
},
"connection": {
"ATTACHED": "Tengt",
"AUTHENTICATING": "Auðkenning",
"AUTHFAIL": "Auðkenning mistókst",
"CONNECTED": "Tengt",
"CONNECTING": "Tengist",
"CONNFAIL": "Tenging mistókst",
"DISCONNECTED": "Aftengt",
"DISCONNECTING": "Aftengist",
"ERROR": "Villa",
"FETCH_SESSION_ID": "Næ í auðkenni setu (session-ID)...",
"GET_SESSION_ID_ERROR": "Villa við að ná í auðkenni setu: {{code}}",
"GOT_SESSION_ID": "Næ í auðkenni setu... Lokið",
"LOW_BANDWIDTH": "Slökkt var á myndmerki frá {{displayName}} til að spara bandbreidd"
},
"connectionindicator": {
"address": "Vistfang:",
"bandwidth": "Áætluð bandbreidd:",
"bitrate": "Bitahraði:",
"bridgeCount": "Fjöldi netþjóna: ",
"connectedTo": "Tengt við:",
"e2e_rtt": "E2E RTT:",
"framerate": "Rammatíðni:",
"less": "Sýna minna",
"localaddress": "Staðvært vistfang:",
"localaddress_plural": "Staðvær vistföng:",
"localport": "Staðvær gátt:",
"localport_plural": "Staðværar gáttir:",
"more": "Sýna meira",
"packetloss": "Pakkatap:",
"quality": {
"good": "Góð",
"inactive": "Óvirk",
"lost": "Tapað",
"nonoptimal": "Ekki sem best",
"poor": "Léleg"
},
"remoteaddress": "Fjartengt vistfang:",
"remoteaddress_plural": "Fjartengd vistföng:",
"remoteport": "Fjartengd gátt:",
"remoteport_plural": "Fjartengdar gáttir:",
"resolution": "Upplausn:",
"status": "Tenging:",
"transport": "Flutningsleið:",
"transport_plural": "Flutningsleiðir:"
},
"dateUtils": {
"earlier": "Fyrr",
"today": "Í dag",
"yesterday": "Í gær"
},
"deepLinking": {
"appNotInstalled": "Þú þarft {{app}} farsímaforritið til að geta tekið þátt í þessum fundi á símanum þínum.",
"description": "Gerðist ekkert? Við reyndum að ræsa fundinn þinn í {{app}} skjáborðsforritinu. Prófaðu aftur eða ræstu hann í {{app}} vefútgáfunni.",
"descriptionWithoutWeb": "Gerðist ekkert? Við reyndum að ræsa fundinn þinn í {{app}} skjáborðsforritinu.",
"downloadApp": "Ná í forritið",
"launchWebButton": "Ræsa í vafra",
"openApp": "Halda áfram í forritið",
"title": "Ræsi fundinn þinn í {{app}}...",
"tryAgainButton": "Prófa aftur í vafra"
},
"defaultLink": "t.d. {{url}}",
"defaultNickname": "dæmi: Jóna Péturs",
"deviceError": {
"cameraError": "Mistókst að ná aðgangi að myndavélinni þinni",
"cameraPermission": "Villa við að fá heimild fyrir myndavél",
"microphoneError": "Mistókst að ná aðgangi að hljóðnemanum þínum",
"microphonePermission": "Villa við að fá heimild fyrir hljóðnema"
},
"deviceSelection": {
"noPermission": "Heimild ekki veitt",
"previewUnavailable": "Forskoðun ekki tiltæk",
"selectADevice": "Veldu tæki",
"testAudio": "Spila prufuhljóð"
},
"dialog": {
"accessibilityLabel": {
"liveStreaming": "Beint streymi"
},
"allow": "Leyfa",
"alreadySharedVideoMsg": "Annar þátttakandi er þegar að deila myndmerkinu sínu. Þessi fjarfundur leyfir aðeins að einu myndmerki sé deilt í einu.",
"alreadySharedVideoTitle": "Aðeins er leyft að deila einu myndmerki í einu",
"applicationWindow": "Forritsgluggi",
"Back": "Til baka",
"cameraConstraintFailedError": "Myndavélin þín uppfyllir ekki sumt af uppsettum skilyrðum.",
"cameraNotFoundError": "Myndavél fannst ekki.",
"cameraNotSendingData": "Við náum ekki að tengjast myndavélinni þinni. Athugaðu hvort eitthvað annað forrit sé að nota hana, veldu annað tæki í stillingavalmyndinni eða reyndu að endurhlaða forritið.",
"cameraNotSendingDataTitle": "Gat ekki tengst myndavél",
"cameraPermissionDeniedError": "Þú hefur ekki gefið leyfi til að nota myndavélina þína. Þú getur samt tekið þátt í fundinum, en aðrir munu ekki sjá þig. Notaðu myndavélarhnappinn í vistfangastikunni til að laga þetta.",
"cameraUnknownError": "Get ekki notað myndavélina af óþekktum ástæðum.",
"cameraUnsupportedResolutionError": "Myndavélin þín styður ekki umbeðna upplausn myndmerkis.",
"Cancel": "Hætta við",
"close": "Loka",
"conferenceDisconnectMsg": "Þú ættir kannski að athuga nettenginguna þína. Tengist aftur eftir {{seconds}} sek...",
"conferenceDisconnectTitle": "Þú hefur verið aftengd(ur).",
"conferenceReloadMsg": "Við erum að reyna að laga þetta. Tengist aftur eftir {{seconds}} sek...",
"conferenceReloadTitle": "Því miður, eitthvað hefur farið úrskeiðis.",
"confirm": "Staðfesta",
"confirmNo": "Nei",
"confirmYes": "Já",
"connectError": "Úbbs! Eitthvað fór úrskeiðis og við náðum ekki að tengjast fjarfundinum.",
"connectErrorWithMsg": "Úbbs! Eitthvað fór úrskeiðis og við náðum ekki að tengjast fjarfundinum: {{msg}}",
"connecting": "Tengist",
"contactSupport": "Hafa samband við aðstoð",
"copy": "Afrita",
"dismiss": "Hunsa",
"displayNameRequired": "Hæ, hvað heitir þú?",
"done": "Lokið",
"enterDisplayName": "Settu hér inn nafnið þitt",
"error": "Villa",
"externalInstallationMsg": "Þú þarft að setja upp skjáborðsdeilingar-viðbótina.",
"externalInstallationTitle": "Krafist er forritsviðbótar",
"goToStore": "Fara í vefsafnið",
"gracefulShutdown": "Þjónustan okkar er ekki aðgengileg í augnablikinu. Endilega reyndu aftur síðar.",
"IamHost": "Ég er gestgjafinn",
"incorrectRoomLockPassword": "Rangt lykilorð",
"incorrectPassword": "Rangt notandanafn eða lykilorð",
"inlineInstallationMsg": "Þú þarft að setja upp skjáborðsdeilingar-viðbótina.",
"inlineInstallExtension": "Setja upp núna",
"internalError": "Úbbs! Eitthvað fór úrskeiðis. Eftirfarandi villa kom upp: {{error}}",
"internalErrorTitle": "Innri villa",
"kickMessage": "Þú getur haft samband við {{participantDisplayName}} til að sjá frekari upplýsingar.",
"kickParticipantButton": "Sparka",
"kickParticipantDialog": "Ertu viss um að þú viljir henda þessum þátttakanda út?",
"kickParticipantTitle": "Henda þessum þátttakanda út?",
"kickTitle": "Æi! {{participantDisplayName}} henti þér út af fundinum",
"liveStreaming": "Beint streymi",
"liveStreamingDisabledForGuestTooltip": "Gestir geta ekki hafið bein streymi.",
"liveStreamingDisabledTooltip": "Aðhefja beint streymi er óvirkt.",
"lockMessage": "Gat ekki læst fjarfundinum.",
"lockRoom": "Bæta við $t(lockRoomPasswordUppercase)i fyrir fund",
"lockTitle": "Læsing mistókst",
"logoutQuestion": "Ertu viss um að þú viljir skrá þig út og loka fjarfundinum?",
"logoutTitle": "Útskráning",
"maxUsersLimitReached": "Takmörkum á hámarksfjölda þátttakenda hefur verið náð. Fjarfundurinn er fullskipaður. Hafðu samband við eiganda fundarins eða reyndu aftur síðar!",
"maxUsersLimitReachedTitle": "Hámarksfjölda þátttakenda hefur verið náð",
"micConstraintFailedError": "Hljóðneminn þinn uppfyllir ekki sumt af uppsettum skilyrðum.",
"micNotFoundError": "Hljóðnemi fannst ekki.",
"micNotSendingData": "Farðu í stillingar tölvunnar þinnar til að kveikja á hljóðnemanum og aðlaga styrk hans",
"micNotSendingDataTitle": "Þaggað er niður í hljóðnemanum þínum í kerfisstillingunum",
"micPermissionDeniedError": "Þú hefur ekki gefið leyfi til að nota hljóðnemann þinn. Þú getur samt tekið þátt í fundinum, en aðrir munu ekki heyra í þér. Notaðu myndavélarhnappinn í vistfangastikunni til að laga þetta.",
"micUnknownError": "Get ekki notað hljóðnemann af óþekktum ástæðum.",
"muteEveryoneElseDialog": "Ef þaggað er niður í þeim muntu ekki geta afþaggað þá, en þeir munu geta afþaggað sig hvenær sem er .",
"muteEveryoneElseTitle": "Þagga niður í öllum nema {{whom}}?",
"muteEveryoneDialog": "Ertu viss um að þú viljir þagga niður í öllum? Þú munt ekki geta afþaggað þá, en þeir munu geta afþaggað sig hvenær sem er .",
"muteEveryoneTitle": "Þagga niður í öllum?",
"muteEveryoneSelf": "þig sjálfan",
"muteEveryoneStartMuted": "Allir byrja hljóðlaust héðan í frá",
"muteParticipantBody": "Þú munt ekki geta afþaggað þá, en þeir munu geta afþaggað sig hvenær sem er .",
"muteParticipantButton": "Þagga niður",
"muteParticipantDialog": "Ertu viss um að þú viljir þagga niður í þessum þátttakanda? Þú munt ekki geta afþaggað hann, en hann munu geta afþaggað sig hvenær sem er .",
"muteParticipantTitle": "Þagga niður í þessum þátttakanda?",
"Ok": "Í lagi",
"passwordLabel": "Þátttakandi hefur læst fundinum. Settu inn $t(lockRoomPassword) til að taka þátt í honum.",
"passwordNotSupported": "Að setja $t(lockRoomPassword) fyrir fund er ekki stutt.",
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) er ekki stutt",
"passwordRequired": "$t(lockRoomPasswordUppercase) er nauðsynlegt",
"popupError": "Vafrinn þinn er að loka á sprettglugga frá þessu vefsvæði. Virkjaðu sprettglugga í öryggisstillingum vafrans þíns og prófaðu svo aftur.",
"popupErrorTitle": "Lokað á sprettglugga",
"recording": "Upptaka",
"recordingDisabledForGuestTooltip": "Gestir geta ekki hafið upptökur.",
"recordingDisabledTooltip": "Að hefja upptöku er óvirkt.",
"rejoinNow": "Taka þátt aftur",
"remoteControlAllowedMessage": "{{user}} samþykkti beiðni þína um fjarstýringu!",
"remoteControlDeniedMessage": "{{user}} hafnaði beiðni þinni um fjarstýringu!",
"remoteControlErrorMessage": "Villa kom upp þegar reynt var að biðja um heimild til fjarstýringar frá {{user}}!",
"remoteControlRequestMessage": "Viltu leyfa {{user}} að stýra skjáborðinu þínu fjartengt?",
"remoteControlShareScreenWarning": "Athugaðu að ef þú ýtir á \"Leyfa\" muntu deila skjánum þínum!",
"remoteControlStopMessage": "Fjarstýringarsetan endaði!",
"remoteControlTitle": "Fjarstýring skjáborðs",
"Remove": "Fjarlægja",
"removePassword": "Fjarlægja $t(lockRoomPassword)",
"removeSharedVideoMsg": "Ertu viss um að þú viljir fjarlægja deilda myndmerkið þitt?",
"removeSharedVideoTitle": "Fjarlægja deilt myndmerki",
"reservationError": "Villa í pöntunarkerfi",
"reservationErrorMsg": "Villukóði: {{code}}, skilaboð: {{msg}}",
"retry": "Reyna aftur",
"screenSharingAudio": "Deila hljóði",
"screenSharingFailedToInstall": "Úbbs! Það mistókst að setja inn viðbótina fyrir skjádeilingu.",
"screenSharingFailedToInstallTitle": "Mistókst að setja inn viðbót fyrir skjádeilingu",
"screenSharingFirefoxPermissionDeniedError": "Eitthvað fór úrskeiðis við að reyna að deila skjánum þinum. Gakktu úr skugga um að þú hafir gefið okkur heimild til að gera þetta. ",
"screenSharingFirefoxPermissionDeniedTitle": "Úbbs! Ekki var hægt að hefja skjádeilingu!",
"screenSharingPermissionDeniedError": "Úbbs! Eitthvað fór úrskeiðis varðandi heimildir skjádeiliviðbótarinnar. Þú ættir að hlaða henni aftur inn og prófa svo aftur.",
"sendPrivateMessage": "Þú fékkst nýlega einkaskilaboð. Hafðirðu hugsað þér að svara þeim í einkaskilaboðum eða ætlarðu að senda skilaboð til hópsins?",
"sendPrivateMessageCancel": "Senda á hópinn",
"sendPrivateMessageOk": "Senda sem einkamál",
"sendPrivateMessageTitle": "Senda sem einkamál?",
"serviceUnavailable": "Þjónustan er ekki tiltæk",
"sessTerminated": "Símtali er lokið",
"Share": "Deila",
"shareVideoLinkError": "Settu inn réttan YouTube-tengil.",
"shareVideoTitle": "Deila myndmerki",
"shareYourScreen": "Deila skjánum þínum",
"shareYourScreenDisabled": "Skjádeiling er óvirk.",
"shareYourScreenDisabledForGuest": "Gestir geta ekki notað skjádeilingu.",
"startLiveStreaming": "Hefja beint streymi",
"startRecording": "Hefja upptöku",
"startRemoteControlErrorMessage": "Villa kom upp þegar reynt var að ræsa fjarstýringarsetu!",
"stopLiveStreaming": "Stöðva beint streymi",
"stopRecording": "Stöðva upptöku",
"stopRecordingWarning": "Ertu viss um að þú viljir stöðva þessa upptöku?",
"stopStreamingWarning": "Ertu viss um að þú viljir stöðva þetta beina streymi?",
"streamKey": "Lykill fyrir beint streymi",
"Submit": "Senda inn",
"thankYou": "Takk fyrir að nota {{appName}}!",
"token": "teikn",
"tokenAuthFailed": "Því miður, þú hefur ekki heimild til að taka þátt í þessu samtali.",
"tokenAuthFailedTitle": "Auðkenning mistókst",
"transcribing": "Umrita (transcribing)",
"unlockRoom": "Fjarlægja $t(lockRoomPassword) fundar",
"userPassword": "lykilorð notandans",
"WaitForHostMsg": "Fjarfundurinn <b>{{room}}</b> er ekki byrjaður. Ef þú ert gestgjafinn skaltu auðkenna þig. Annars ættiðu að bíða eftir að gestgjafinn skrái sig inn.",
"WaitForHostMsgWOk": "Fjarfundurinn <b>{{room}}</b> er ekki byrjaður. Ef þú ert gestgjafinn skaltu ýta á 'Í lagi' til að auðkenna þig. Annars ættiðu að bíða eftir að gestgjafinn skrái sig inn.",
"WaitingForHost": "Bíð eftir að gestgjafanum ...",
"Yes": "Já",
"yourEntireScreen": "Allur skjárinn þinn"
},
"dialOut": {
"statusMessage": "er núna {{status}}"
},
"documentSharing": {
"title": "Sameiginlegt skjal"
},
"feedback": {
"average": "Meðaltal",
"bad": "Slæmt",
"detailsLabel": "Segðu okkur meira um þetta.",
"good": "Gott",
"rateExperience": "Gefðu upplifun þinni af fundinum einkunn",
"veryBad": "Mjög slæm",
"veryGood": "Mjög góð"
},
"incomingCall": {
"answer": "Svara",
"audioCallTitle": "Innhringing",
"decline": "Hunsa",
"productLabel": "frá Jitsi Meet",
"videoCallTitle": "Innhringing myndsamtals"
},
"info": {
"accessibilityLabel": "Birta upplýsingar",
"addPassword": "Bæta við $t(lockRoomPassword)i",
"cancelPassword": "Hætta við $t(lockRoomPassword)",
"conferenceURL": "Tengill:",
"country": "Land",
"dialANumber": "Til að tengjast við fundinn þinn skaltu hringja í eitt af þessum númerum og setja inn PIN-kóðann.",
"dialInConferenceID": "PIN:",
"dialInNotSupported": "Því miður, innhringing er ekki ennþá studd.",
"dialInNumber": "Innhringing:",
"dialInSummaryError": "Villa við að sækja innhringingarupplýsingar. Reyndu aftur síðar.",
"dialInTollFree": "Gjaldfrjálst",
"genericError": "Úbbs! Eitthvað fór úrskeiðis.",
"inviteLiveStream": "Til að skoða beint streymi frá þessum fundi skaltu smella á þennan tengil: {{url}}",
"invitePhone": "Til að tengjast frekar með síma skaltu ýta á þetta: {{number}},,{{conferenceID}}#\n",
"invitePhoneAlternatives": "Ertu að leita að öðru innhringinúmeri?\nSkoðaðu innhringinúmerin fyrir þennan fund: {{url}}\n\n\nEf einnig er verið að hringja inn í gegnum símanúmer fjarfundar, skaltu taka þátt án þess að tengjast með hljóði: {{silentUrl}}",
"inviteURLFirstPartGeneral": "Þér hefur verið boðið að taka þátt í fundi.",
"inviteURLFirstPartPersonal": "{{name}} er að bjóða þér á fund.\n",
"inviteURLSecondPart": "\nTaka þátt í fundinum:\n{{url}}\n",
"liveStreamURL": "Beint streymi:",
"moreNumbers": "Fleiri símanúmer",
"noNumbers": "Engin innhringinúmer.",
"noPassword": "Ekkert",
"noRoom": "Enginn fjarfundur var tilgreindur til að hringja inn í.",
"numbers": "Innhringinúmer",
"password": "$t(lockRoomPasswordUppercase):",
"title": "Deila",
"tooltip": "Deila tengli og innhringingarupplýsingum um þennan fund",
"label": "Upplýsingar um fund"
},
"inviteDialog": {
"alertText": "Mistókst að bjóða sumum þátttakendum.",
"header": "Bjóða",
"searchCallOnlyPlaceholder": "Settu inn símanúmer",
"searchPeopleOnlyPlaceholder": "Leita að þátttakendum",
"searchPlaceholder": "Þátttakandi eða símanúmer",
"send": "Senda"
},
"inlineDialogFailure": {
"msg": "Við eigum í smá erfiðleikum.",
"retry": "Reyndu aftur",
"support": "Stuðningur",
"supportMsg": "Ef þetta heldur áfram að koma upp, skaltu hafa samband við"
},
"keyboardShortcuts": {
"focusLocal": "Gera myndmerkið þitt virkt",
"focusRemote": "Gera myndmerkið einhvers annars virkt",
"fullScreen": "Skoða skjá eða fara úr skjáfylliham",
"keyboardShortcuts": "Flýtilyklar",
"localRecording": "Birta eða fela stýringar fyrir upptöku á tölvunni",
"mute": "Þagga niður eða kveikja á hljóðnema",
"pushToTalk": "Ýta til að tala",
"raiseHand": "Rétta upp eða leggja niður höndina",
"showSpeakerStats": "Birta tölfræði ræðumanns",
"toggleChat": "Opna eða loka spjallinu",
"toggleFilmstrip": "Birta eða fela smámyndir myndmerkja",
"toggleScreensharing": "Skipta á milli myndavélar og deilingar á skjá",
"toggleShortcuts": "Birta eða fela flýtivísanir á lyklaborði",
"videoMute": "Ræsa eða stöðva myndavélina þína",
"videoQuality": "Sýsla með gæði símtals"
},
"liveStreaming": {
"busy": "Við erum að reyna að losa um einhver tilföng fyrir streymi. Reyndu aftur eftir nokkrar mínútur.",
"busyTitle": "Allar streymisvélar eru uppteknar í augnablikinu",
"changeSignIn": "Skipta um notandaaðgang.",
"choose": "Veldu beint streymi",
"chooseCTA": "Veldu valkost fyrir streymi. Þú ert núna skráð/ur inn sem {{email}}.",
"enterStreamKey": "Settu hér inn lykil fyrir beint streymi frá YouTube.",
"error": "Beint streymi mistókst. Reyndu aftur.",
"errorAPI": "Villa kom upp við að fá aðgang að útsendingum þínum á YouTube. Prófaðu að skrá þig inn aftur.",
"errorLiveStreamNotEnabled": "Beint streymi er ekki virkt fyrir {{email}}. Virkjaðu beint streymi eða skráðu þig inn á notandaaðgang þar sem beint streymi er virkjað.",
"expandedOff": "Beina streymið hefur verið stöðvað",
"expandedOn": "Verið er að taka streyma fundinum á YouTube.",
"expandedPending": "Verið er að ræsa beina streymið...",
"failedToStart": "Tókst ekki að ræsa beint streymi",
"getStreamKeyManually": "Við gátum ekki nálgast nein bein streymi. Reyndu að ná þér í lykil fyrir beint streymi frá YouTube.",
"invalidStreamKey": "Lykill fyrir beint streymi gæti verið rangur.",
"off": "Beint streymi stöðvað",
"offBy": "{{name}} stöðvaði beina streymið",
"on": "Beint streymi",
"onBy": "{{name}} byrjaði beint streymi",
"pending": "Ræsi beint streymi...",
"serviceName": "Þjónusta fyrir beint streymi",
"signedInAs": "Þú ert núna skráð/ur inn sem:",
"signIn": "Skrá inn með Google",
"signInCTA": "Skráðu þig inn eða settu inn lykil fyrir beint streymi frá YouTube.",
"signOut": "Skrá út",
"start": "Hefja beint streymi",
"streamIdHelp": "Hvað er þetta?",
"unavailableTitle": "Beint streymi er ekki tiltækt",
"youtubeTerms": "Þjónustuskilmálar YouTube",
"googlePrivacyPolicy": "Meðferð persónuupplýsinga hjá Google"
},
"localRecording": {
"clientState": {
"off": "Slökkt",
"on": "Kveikt",
"unknown": "Óþekkt"
},
"dialogTitle": "Stýringar fyrir upptöku á tölvunni",
"duration": "Tímalengd",
"durationNA": "Ekki tiltækt",
"encoding": "Kóðun",
"label": "LOR",
"labelToolTip": "Upptaka á tölvunni er í gangi",
"localRecording": "Upptaka á tölvunni",
"me": "Ég",
"messages": {
"engaged": "Upptaka á tölvunni í gangi.",
"finished": "Upptökusetu {{token}} lokið. Sendu upptökuskrána til stjórnandans.",
"finishedModerator": "Upptökusetu {{token}} lokið. Upptaka hljóðrásar á þessari tölvu hefur verið vistuð. Biddu aðra þáttakendur um að senda inn upptökur þeirra.",
"notModerator": "Þú ert ekki stjórnandinn. Þú getur ekki byrjað eða stöðvað upptöku á tölvunni."
},
"moderator": "Stjórnandi",
"no": "Nei",
"participant": "Þátttakandi",
"participantStats": "Tölfræði þátttakanda",
"sessionToken": "Setuteikn",
"start": "Hefja upptöku",
"stop": "Stöðva upptöku",
"yes": "Já"
},
"lockRoomPassword": "lykilorð",
"lockRoomPasswordUppercase": "Lykilorð",
"me": "ég",
"notify": {
"connectedOneMember": "{{name}} hefur bæst við á fundinn",
"connectedThreePlusMembers": "{{name}} og {{count}} til viðbótar hafa bæst við á fundinn",
"connectedTwoMembers": "{{first}} og {{second}} hafa bæst við á fundinn",
"disconnected": "aftengt",
"focus": "Fjarfundur virkur",
"focusFail": "{{component}} er ekki tiltækt - prófa aftur eftir {{ms}} sek",
"grantedTo": "Stjórnandaréttindi veitt til {{to}}!",
"invitedOneMember": "{{name}} hefur verið boðið",
"invitedThreePlusMembers": "{{name}} og {{count}} til viðbótar hefur verið boðið",
"invitedTwoMembers": "{{first}} og {{second}} hefur verið boðið",
"kickParticipant": "{{kicked}} var hent út af {{kicker}}",
"me": "Ég",
"moderator": "Stjórnandaréttindi veitt!",
"muted": "Þú byrjaðir samtalið með þaggað niður í þér.",
"mutedTitle": "Það er þaggað niður í þér!",
"mutedRemotelyTitle": "{{participantDisplayName}} hefur þaggað niður í þér!",
"mutedRemotelyDescription": "Þú getur alltaf afþaggað þig þegar þú ert tilbúinn til að tala. Þaggaðu svo aftur niður í hljóðnemanum svo að aukahávaði sé ekki að trufla fundinn.",
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) fjarlægt af öðrum þátttakanda",
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) stillt af öðrum þátttakanda",
"raisedHand": "{{name}} myndi vilja taka til máls.",
"somebody": "Einhver",
"startSilentTitle": "Þú mættir með ekkert hljóðúttak!",
"startSilentDescription": "Tengstu fundinum aftur til að virkja hljóð",
"suboptimalBrowserWarning": "Við erum ekki viss um að upplifun þín af fundinum verði neitt sérstök. Við erum alltaf að reyna að bæta þetta, en þangað til ættirðu frekar að nota einhvern af <a href='static/recommendedBrowsers.html' target='_blank'>þeim vöfrum sem eru studdir að fullu</a>.",
"suboptimalExperienceTitle": "Aðvörun vafra",
"unmute": "Afþagga",
"newDeviceCameraTitle": "Ný myndavél fannst",
"newDeviceAudioTitle": "Nýtt hljóðtæki fannst",
"newDeviceAction": "Nota"
},
"passwordSetRemotely": "sett af öðrum þátttakanda",
"passwordDigitsOnly": "Allt að {{number}} stafir",
"poweredby": "keyrt með",
"presenceStatus": {
"busy": "Upptekinn",
"calling": "Hringi...",
"connected": "Tengt",
"connecting": "Tengist...",
"connecting2": "Tengist*...",
"disconnected": "Aftengt",
"expired": "Útrunnið",
"ignored": "Hunsað",
"initializingCall": "Ræsi símtal...",
"invited": "Boðið",
"rejected": "Hafnað",
"ringing": "Hringing..."
},
"profile": {
"setDisplayNameLabel": "Settu inn birtingarnafnið þitt",
"setEmailInput": "Settu inn tölvupóstfang",
"setEmailLabel": "Settu inn gravatar-tölvupóstfangið þitt",
"title": "Persónusnið"
},
"raisedHand": "Myndi vilja taka til máls",
"recording": {
"authDropboxText": "Senda inn á Dropbox",
"availableSpace": "Laust pláss: {{spaceLeft}} MB (um það bil {{duration}} mínútur í upptöku)",
"beta": "BETA",
"busy": "Við erum að reyna að losa um einhver tilföng fyrir upptöku. Reyndu aftur eftir nokkrar mínútur.",
"busyTitle": "Allar upptökuvélar eru uppteknar í augnablikinu",
"error": "Upptaka mistókst. Reyndu aftur.",
"expandedOff": "Upptaka hefur verið stöðvuð",
"expandedOn": "Verið er að taka upp fundinn.",
"expandedPending": "Verið er að ræsa upptöku...",
"failedToStart": "Tókst ekki að ræsa upptöku",
"fileSharingdescription": "Deila upptöku með þátttakendum á fundinum",
"live": "BEINT",
"loggedIn": "Skráð inn sem {{userName}}",
"off": "Upptaka stöðvuð",
"offBy": "{{name}} stöðvaði upptökuna",
"on": "Upptaka",
"onBy": "{{name}} byrjaði upptökuna",
"pending": "Undirbý að taka upp fundinn...",
"rec": "REC",
"serviceDescription": "Upptakan þín verður vistuð af upptökuþjónustunni",
"serviceName": "Upptökuþjónusta",
"signIn": "Skrá inn",
"signOut": "Skrá út",
"unavailable": "Úbbs! {{serviceName}} er upptekið í augnablikinu. Við erum að vinna í þessu vandamáli. Reyndu aftur síðar.",
"unavailableTitle": "Upptaka er ekki tiltæk"
},
"sectionList": {
"pullToRefresh": "Toga til að endurlesa"
},
"settings": {
"calendar": {
"about": "Samþætting dagatals við {{appName}} er notuð til að tryggja öruggan aðgang að dagatalinu þínu þannig að hægt sé að lesa fyrirliggjandi viðburði.",
"disconnect": "Aftengjast",
"microsoftSignIn": "Skrá inn með Microsoft",
"signedIn": "Er núna með aðgang að atburðum í dagatali fyrir {{email}}. Smelltu á 'Aftengjast' til að hætta að ná í atburði í dagatali.",
"title": "Dagatal"
},
"devices": "Tæki",
"followMe": "Allir fylgjast með mér",
"language": "Tungumál",
"loggedIn": "Skráð inn sem {{name}}",
"microphones": "Hljóðnemar",
"moderator": "Stjórnandi",
"more": "Meira",
"name": "Nafn",
"noDevice": "Ekkert",
"selectAudioOutput": "Hljóðúttak",
"selectCamera": "Myndavél",
"selectMic": "Hljóðnemi",
"speakers": "Ræðumenn",
"startAudioMuted": "Allir byrja hljóðlaust",
"startVideoMuted": "Allir byrja faldir",
"title": "Stillingar"
},
"settingsView": {
"advanced": "Nánar",
"alertOk": "Í lagi",
"alertTitle": "Aðvörun",
"alertURLText": "Slóðin á netþjóninn sem sett var inn er ógild",
"buildInfoSection": "Byggingarupplýsingar",
"conferenceSection": "Fjarfundur",
"disableCallIntegration": "Gera samþættingu raunverulegra símtala óvirka",
"disableP2P": "Gera jafningjaham (peer-to-peer) óvirkan",
"displayName": "Birtingarnafn",
"email": "Tölvupóstfang",
"header": "Stillingar",
"profileSection": "Persónusnið",
"serverURL": "Slóð á netþjón",
"showAdvanced": "Birta ítarlegar stillingar",
"startWithAudioMuted": "Byrja með þaggað niður í hljóði",
"startWithVideoMuted": "Byrja með myndmerki án hljóðs",
"version": "Útgáfa"
},
"share": {
"dialInfoText": "\n\n=====\n\nViltu bara hringja inn með símanum þínum?\n\n{{defaultDialInNumber}}Smelltu hér til að sjá innhringinúmerin fyrir þennan fund\n{{dialInfoPageUrl}}",
"mainText": "Smelltu á eftirfarandi tengil til að taka þátt í fundinum:\n{{roomUrl}}"
},
"speaker": "Ræðumaður",
"speakerStats": {
"hours": "{{count}}klst",
"minutes": "{{count}}mín",
"name": "Nafn",
"seconds": "{{count}}sek",
"speakerStats": "Tölfræði ræðumanns",
"speakerTime": "Tími ræðumanns"
},
"startupoverlay": {
"policyText": " ",
"title": "{{app}} þarf að nota hljóðnema og myndavél."
},
"suspendedoverlay": {
"rejoinKeyTitle": "Taka þátt aftur",
"text": "Ýttu á <i>Taka þátt aftur</i> til að tengjast aftur.",
"title": "Myndsamtalið þitt var trufla vegna þess að tölvan þín svæfðist."
},
"toolbar": {
"accessibilityLabel": {
"audioOnly": "Víxla einungis hljóð af/á",
"audioRoute": "Veldu hljóðtæki",
"callQuality": "Sýsla með gæði myndmerkis",
"cc": "Víxla skjátextum af/á",
"chat": "Víxla spjallglugga af/á",
"document": "Víxla deildu skjali af/á",
"download": "Sækja forritin okkar",
"feedback": "Senda inn umsögn",
"fullScreen": "Víxla skjáfylli af/á",
"hangup": "Hætta í símtalinu",
"help": "Hjálp",
"invite": "Bjóða fólki",
"kick": "Henda þátttakanda út",
"localRecording": "Víxla stýringum fyrir upptöku á tölvunni af/á",
"lockRoom": "Víxla lykilorði fundar af/á",
"moreActions": "Víxla af/á valmynd fyrir fleiri aðgerðir",
"moreActionsMenu": "Valmynd fyrir fleiri aðgerðir",
"moreOptions": "Birta fleiri valkosti",
"mute": "Víxla hljóði af/á",
"muteEveryone": "Þagga niður í öllum",
"pip": "Víxla mynd-í-mynd-ham af/á",
"privateMessage": "Senda einkaskilaboð",
"profile": "Breyta persónusniðinu þínu",
"raiseHand": "Víxla á milli uppréttrar og niðurlagðrar handar",
"recording": "Víxla upptöku af/á",
"remoteMute": "Þagga niður í þátttakanda",
"Settings": "Víxla stillingum af/á",
"sharedvideo": "Víxla deilingu Youtube-myndskeiðs af/á",
"shareRoom": "Bjóddu einhverjum",
"shareYourScreen": "Víxla skjádeilingu af/á",
"shortcuts": "Víxla flýtilyklum af/á",
"show": "Birta í glugga",
"speakerStats": "Víxla tölfræði ræðumanna af/á",
"tileView": "Víxla reitasýn af/á",
"toggleCamera": "Víxla myndavél",
"toggleFilmstrip": "Víxla filmubút af/á",
"videomute": "Víxla hljóði myndmerkis af/á",
"videoblur": "Víxla móðun myndmerkis af/á"
},
"addPeople": "Bæta fólki við símtalið þitt",
"audioOnlyOff": "Gera ham fyrir litla bandbreidd óvirkan",
"audioOnlyOn": "Virkja ham fyrir litla bandbreidd",
"audioRoute": "Veldu hljóðtæki",
"authenticate": "Auðkenna",
"callQuality": "Sýsla með gæði myndmerkis",
"chat": "Opna / Loka spjalli",
"closeChat": "Loka spjalli",
"documentClose": "Loka deildu skjali",
"documentOpen": "Opna deilt skjal",
"download": "Sækja forritin okkar",
"enterFullScreen": "Skoða á öllum skjánum",
"enterTileView": "Opna reitasýn",
"exitFullScreen": "Fara úr skjáfylliham",
"exitTileView": "Loka reitasýn",
"feedback": "Senda inn umsögn",
"hangup": "Leggja á",
"help": "Hjálp",
"invite": "Bjóða fólki",
"login": "Innskráning",
"logout": "Útskráning",
"lowerYourHand": "Leggja niður höndina",
"moreActions": "Fleiri aðgerðir",
"moreOptions": "Fleiri valkostir",
"mute": "Þagga/Kveikja á hljóði",
"muteEveryone": "Þagga niður í öllum",
"noAudioSignalTitle": "Það er ekkert inntak að koma frá hljóðnemanum þínum!",
"noAudioSignalDesc": "Ef þú þaggaðir ekki viljandi niður í þessu í kerfisstillingunum eða með vélbúnaðarrofa, þá ættirðu að íhuga að skipta um hljóðtæki.",
"noAudioSignalDescSuggestion": "Ef þú þaggaðir ekki viljandi niður í þessu í kerfisstillingunum eða með vélbúnaðarrofa, þá ættirðu að íhuga að skipta yfir á hljóðtækið sem stungið er upp á.",
"noAudioSignalDialInDesc": "Þú getur einnig hringt þig inn með:",
"noAudioSignalDialInLinkDesc": "Innhringinúmer",
"noisyAudioInputTitle": "Hljóðneminn þinn lítur út fyrir að gefa frá sér truflanir!",
"noisyAudioInputDesc": "Það lítur út fyrir að hljóðneminn þinn sé að gefa frá sér truflanir, íhugaðu að þagga niður í honum eða skipta um hljóðtæki.",
"openChat": "Opna spjall",
"pip": "Fara í mynd-í-mynd-ham",
"privateMessage": "Senda einkaskilaboð",
"profile": "Breyta persónusniðinu þínu",
"raiseHand": "Rétta upp / Leggja niður hönd",
"raiseYourHand": "Rétta upp höndina",
"Settings": "Stillingar",
"sharedvideo": "Deila YouTube-myndskeiði",
"shareRoom": "Bjóddu einhverjum",
"shortcuts": "Skoða flýtilykla",
"speakerStats": "Tölfræði ræðumanns",
"startScreenSharing": "Hefja skjádeilingu",
"startSubtitles": "Hefja birtingu skjátexta",
"stopScreenSharing": "Hætta skjádeilingu",
"stopSubtitles": "Hætta birtingu skjátexta",
"stopSharedVideo": "Stöðva YouTube-myndskeið",
"talkWhileMutedPopup": "Ertu að reyna að tala? Þaggað er niður í þér.",
"tileViewToggle": "Víxla reitasýn af/á",
"toggleCamera": "Víxla myndavél",
"videomute": "Ræsa / Stöðva myndavél",
"startvideoblur": "Móða bakgrunninn minn",
"stopvideoblur": "Gera móðun bakgrunns óvirka"
},
"transcribing": {
"ccButtonTooltip": "Hefja / Hætta birtingu skjátexta",
"error": "Umritun mistókst. Reyndu aftur.",
"expandedLabel": "Umritun er virk",
"failedToStart": "Tókst ekki að ræsa umritun",
"labelToolTip": "Verið er að taka umrita (transcribe) fundinn",
"off": "Umritun stöðvuð",
"pending": "Undirbý að taka umrita fundinn...",
"start": "Hefja birtingu skjátexta",
"stop": "Hætta birtingu skjátexta",
"tr": "UR"
},
"userMedia": {
"androidGrantPermissions": "Veldu <b><i>Leyfa</i></b> þegar vafrinn þinn biður um heimildir.",
"chromeGrantPermissions": "Veldu <b><i>Leyfa</i></b> þegar vafrinn þinn biður um heimildir.",
"edgeGrantPermissions": "Veldu <b><i>Já</i></b> þegar vafrinn þinn biður um heimildir.",
"electronGrantPermissions": "Gefðu heimild til að nota myndavél og hljóðnema",
"firefoxGrantPermissions": "Veldu <b><i>Deila völdu tæki</i></b> þegar vafrinn þinn biður um heimildir.",
"iexplorerGrantPermissions": "Veldu <b><i>Í lagi</i></b> þegar vafrinn þinn biður um heimildir.",
"nwjsGrantPermissions": "Gefðu heimild til að nota myndavél og hljóðnema",
"operaGrantPermissions": "Veldu <b><i>Leyfa</i></b> þegar vafrinn þinn biður um heimildir.",
"react-nativeGrantPermissions": "Veldu <b><i>Leyfa</i></b> þegar vafrinn þinn biður um heimildir.",
"safariGrantPermissions": "Veldu <b><i>Í lagi</i></b> þegar vafrinn þinn biður um heimildir."
},
"videoSIPGW": {
"busy": "Við erum að reyna að losa um einhver tilföng. Reyndu aftur eftir nokkrar mínútur.",
"busyTitle": "Fjarfundaþjónustan er upptekin í augnablikinu",
"errorAlreadyInvited": "{{displayName}} hefur þegar verið boðið",
"errorInvite": "Fjarfundi hefur ekki verið komið á. Reyndu aftur síðar.",
"errorInviteFailed": "Við erum að vinna í þessu vandamáli. Reyndu aftur síðar.",
"errorInviteFailedTitle": "Mistókst að bjóða {{displayName}}",
"errorInviteTitle": "Villa við að bjóða á fjarfund",
"pending": "{{displayName}} hefur verið boðið"
},
"videoStatus": {
"audioOnly": "HLJ",
"audioOnlyExpanded": "Þú ert í ham fyrir litla bandbreidd. Í þessum ham geturðu einungis heyrt hljóð og séð deilda skjái.",
"callQuality": "Gæði myndmerkisúttaks",
"hd": "HD",
"hdTooltip": "Skoða myndmerki í hágæðum",
"highDefinition": "Hágæði",
"labelTooiltipNoVideo": "Ekkert myndmerki",
"labelTooltipAudioOnly": "Hamur fyrir litla bandbreidd er virkur",
"ld": "LD",
"ldTooltip": "Skoða myndmerki í lággæðum",
"lowDefinition": "Lággæði",
"onlyAudioAvailable": "Aðeins hljóð er í boði",
"onlyAudioSupported": "Við styðjum aðeins við hljóð í þessum vafra.",
"p2pEnabled": "Jafningjahamur (peer-to-peer) virkur",
"p2pVideoQualityDescription": "Í jafningjaham (peer-to-peer) eru gæði myndmerkis takmörkuð við að víxla á milli hágæða og einungis hljóðs. Aðrar stillingar eru ekki virtar nema að fara út úr jafningjaham.",
"recHighDefinitionOnly": "Kýs frekar myndmerki í hágæðum.",
"sd": "SD",
"sdTooltip": "Skoða myndmerki í staðalgæðum",
"standardDefinition": "Staðalgæði"
},
"videothumbnail": {
"domute": "Þagga niður",
"domuteOthers": "Þagga niður í öllum öðrum",
"flip": "Spegla",
"kick": "Henda út",
"moderator": "Stjórnandi",
"mute": "Þaggað niður í þáttakanda",
"muted": "Þaggað",
"remoteControl": "Ræsa / Stöðva fjarstýringu",
"show": "Birta í glugga",
"videomute": "Þátttakandi hefur stöðvað myndavél"
},
"welcomepage": {
"accessibilityLabel": {
"join": "Ýttu til að taka þátt",
"roomname": "Settu inn nafn á fjarfundi"
},
"appDescription": "Leggðu í'ann, spjallaðu í mynd við allt teymið þitt. Eiginlega ættirðu að bjóða öllum sem þú þekkir. {{app}} er að fullu dulrituð fjarfundalausn, með 100% opinn grunnkóða, sem þú getur notað allan daginn, alla daga, ókeypis — án þess að þurfa skráðan aðgang.",
"audioVideoSwitch": {
"audio": "Tal",
"video": "Myndmerki"
},
"calendar": "Dagatal",
"connectCalendarButton": "Tengdu dagatalið þitt",
"connectCalendarText": "Tengdu dagatalið þitt til að geta séð alla fundina þína í {{app}}. Að auki geturðu bætt fundum {{provider}} við dagatalið og ræst þá með einum smelli.",
"enterRoomTitle": "Byrja nýjan fund",
"getHelp": "Fá aðstoð",
"roomNameAllowedChars": "Heiti fundar ætti ekki að innihalda neinn eftirfarandi stafa: ?, &, :, ', \", %, #.",
"go": "Af stað",
"goSmall": "Af stað",
"join": "BÚA TIL / TAKA ÞÁTT",
"info": "Upplýsingar",
"privacy": "Gagnaleynd",
"recentList": "Nýlegt",
"recentListDelete": "Eyða",
"recentListEmpty": "Listinn þinn yfir nýlega atburði er tómur. Spjallaðu við teymið þitt og muntu þá finna alla nýlega fundi hér.",
"reducedUIText": "Velkomin í {{app}}!",
"roomname": "Settu inn nafn á fjarfundi",
"roomnameHint": "Settu inn nafn eða slóð á fjarfundinum sem þú ætlar að taka þátt í. Þú getur skáldað eitthvað nafn, þú verður bara að láta aðra þáttakendur vita svo þeir setji inn sama nafnið.",
"sendFeedback": "Senda inn umsögn",
"terms": "Hugtök",
"title": "Öruggir og fullkomlega frjálsir myndfundir með fullt af eiginleikum"
},
"lonelyMeetingExperience": {
"button": "Bjóddu öðrum",
"youAreAlone": "Þú ert sá eini á fundinum"
},
"helpView": {
"header": "Hjálparmiðstöð"
}
}

View File

@@ -594,6 +594,7 @@
"logout": "Logout",
"lowerYourHand": "Abbassa la mano",
"moreActions": "Più azioni",
"moreOptions": "Più opzioni",
"mute": "Microfono Attiva / Disattiva",
"openChat": "Apri una chat",
"pip": "Abilita visualizzazione immagine nellimmagine",
@@ -707,5 +708,9 @@
"sendFeedback": "Invia feedback",
"terms": "Termini di utilizzo",
"title": "Il sistema di conferenza sicuro, funzionale e completamente gratuito."
},
"lonelyMeetingExperience": {
"button": "Invita gli altri",
"youAreAlone": "Sei l'unico in riunione"
}
}

View File

@@ -1,120 +1,125 @@
{
"addPeople": {
"add": "",
"add": "Inviter",
"countryNotSupported": "",
"countryReminder": "",
"disabled": "",
"failedToAdd": "",
"footerText": "",
"loading": "",
"loadingNumber": "",
"loadingPeople": "",
"disabled": "Du kan ikke invitere folk.",
"failedToAdd": "Klarte ikke å lagge til deltagere",
"footerText": "Å ringe ut er avskrudd",
"loading": "Søker etter folk og telefonnumre",
"loadingNumber": "Bekrefter telefonnummer",
"loadingPeople": "Søker etter folk å inviterte",
"noResults": "",
"noValidNumbers": "",
"searchNumbers": "",
"searchPeople": "",
"searchPeopleAndNumbers": "",
"telephone": "",
"title": ""
"noValidNumbers": "Skriv inn et telefonnummer",
"searchNumbers": "Legg til telefonnumre",
"searchPeople": "Søk etter folk",
"searchPeopleAndNumbers": "Søk etter folk eller legg til telefonnumrene deres",
"telephone": "Telefon: {{number}}",
"title": "Inviter folk til dette møtet"
},
"audioDevices": {
"bluetooth": "",
"headphones": "",
"phone": "",
"speaker": ""
"bluetooth": "Blåtann",
"headphones": "Hodetelefoner",
"phone": "Telefon",
"speaker": "Høyttaler",
"none": "Ingen lydenheter tilgjengelig"
},
"audioOnly": {
"audioOnly": ""
"audioOnly": "Lav båndbredde"
},
"calendarSync": {
"addMeetingURL": "",
"confirmAddLink": "",
"addMeetingURL": "Legg til en møtelenke",
"confirmAddLink": "Ønsker du å legge til en Jitsi-lenke til denne hendelsen?",
"error": {
"appConfiguration": "",
"generic": "",
"notSignedIn": ""
},
"join": "",
"joinTooltip": "",
"nextMeeting": "",
"join": "Ta del",
"joinTooltip": "Ta del i møtet",
"nextMeeting": "neste møte",
"noEvents": "",
"ongoingMeeting": "",
"permissionButton": "",
"ongoingMeeting": "pågående møte",
"permissionButton": "Åpne innstillinger",
"permissionMessage": "",
"refresh": "",
"today": ""
"today": "I dag"
},
"chat": {
"error": "",
"messagebox": "",
"messagebox": "Skriv en melding",
"nickname": {
"popover": "",
"popover": "Velg et kallenavn",
"title": ""
},
"title": ""
"title": "",
"messageTo": "Privat melding til {{recipient}}",
"fieldPlaceHolder": "Skriv inn din melding her"
},
"connectingOverlay": {
"joiningRoom": ""
},
"connection": {
"ATTACHED": "",
"AUTHENTICATING": "",
"ATTACHED": "Vedlagt",
"AUTHENTICATING": "Bekrefter",
"AUTHFAIL": "",
"CONNECTED": "",
"CONNECTING": "",
"CONNECTED": "Tilkoblet",
"CONNECTING": "Kobler til",
"CONNFAIL": "",
"DISCONNECTED": "",
"DISCONNECTING": "",
"ERROR": "",
"RECONNECTING": ""
"DISCONNECTED": "Frakoblet",
"DISCONNECTING": "Kobler fra",
"ERROR": "Feil",
"RECONNECTING": "",
"GOT_SESSION_ID": "Henter økt-ID… Ferdig",
"FETCH_SESSION_ID": "Henter økt-ID…"
},
"connectionindicator": {
"address": "",
"bandwidth": "",
"address": "Adresse:",
"bandwidth": "Anslått båndbredde:",
"bitrate": "",
"bridgeCount": "",
"connectedTo": "",
"connectedTo": "Ansluttet til:",
"framerate": "",
"less": "",
"localaddress": "",
"localaddress_plural": "",
"localport": "",
"localport_plural": "",
"more": "",
"packetloss": "",
"less": "Vis mindre",
"localaddress": "Lokal adresse:",
"localaddress_plural": "Lokale adresser:",
"localport": "Lokal port:",
"localport_plural": "Lokale porter:",
"more": "Vis mer",
"packetloss": "Pakketap:",
"quality": {
"good": "",
"inactive": "",
"lost": "",
"nonoptimal": "",
"poor": ""
"good": "God",
"inactive": "Inaktiv",
"lost": "Tapt",
"nonoptimal": "Suboptimal",
"poor": "Dårlig"
},
"remoteaddress": "",
"remoteaddress_plural": "",
"remoteaddress": "Fjernadresser:",
"remoteaddress_plural": "Fjernadresser:",
"remoteport": "",
"remoteport_plural": "",
"resolution": "",
"status": "",
"resolution": "Oppløsning:",
"status": "Tilknytning:",
"transport": "",
"transport_plural": "",
"turn": ""
},
"dateUtils": {
"earlier": "",
"today": "",
"yesterday": ""
"earlier": "Tidligere",
"today": "I dag",
"yesterday": "I går"
},
"deepLinking": {
"appNotInstalled": "",
"description": "",
"descriptionWithoutWeb": "",
"downloadApp": "",
"downloadApp": "Last ned programmet",
"launchWebButton": "",
"openApp": "",
"openApp": "Fortsett til programmet",
"title": "",
"tryAgainButton": ""
},
"defaultLink": "",
"defaultLink": "f.eks.",
"deviceError": {
"cameraError": "",
"cameraPermission": "",
@@ -122,20 +127,20 @@
"microphonePermission": ""
},
"deviceSelection": {
"noPermission": "",
"previewUnavailable": "",
"selectADevice": "",
"testAudio": ""
"noPermission": "Tilgang ikke innvilget",
"previewUnavailable": "Forhåndsvisning utilgjengelig",
"selectADevice": "Velg en enhet",
"testAudio": "Spill en testlyd"
},
"dialog": {
"accessibilityLabel": {
"liveStreaming": ""
},
"allow": "",
"allow": "Tillat",
"alreadySharedVideoMsg": "",
"alreadySharedVideoTitle": "",
"applicationWindow": "",
"Back": "",
"Back": "Tilbake",
"cameraConstraintFailedError": "",
"cameraNotFoundError": "",
"cameraNotSendingData": "",
@@ -143,49 +148,49 @@
"cameraPermissionDeniedError": "",
"cameraUnknownError": "",
"cameraUnsupportedResolutionError": "",
"Cancel": "",
"Cancel": "Avbryt",
"close": "",
"conferenceDisconnectMsg": "",
"conferenceDisconnectTitle": "",
"conferenceDisconnectTitle": "Du har blitt frakoblet.",
"conferenceReloadMsg": "",
"conferenceReloadTitle": "",
"confirm": "",
"confirmNo": "",
"confirmYes": "",
"confirm": "Bekreft",
"confirmNo": "Nei",
"confirmYes": "Ja",
"connectError": "",
"connectErrorWithMsg": "",
"connecting": "",
"contactSupport": "",
"copy": "",
"dismiss": "",
"displayNameRequired": "",
"done": "",
"enterDisplayName": "",
"error": "",
"connecting": "Kobler til",
"contactSupport": "Kontakt brukerstøtte",
"copy": "Kopier",
"dismiss": "Forkast",
"displayNameRequired": "Hei. Hva heter du?",
"done": "Ferdig",
"enterDisplayName": "Skriv inn navnet ditt her",
"error": "Feil",
"externalInstallationMsg": "",
"externalInstallationTitle": "",
"externalInstallationTitle": "Programtillegg kreves",
"goToStore": "",
"gracefulShutdown": "",
"IamHost": "",
"IamHost": "Jeg er vertsskap",
"incorrectRoomLockPassword": "",
"incorrectPassword": "",
"inlineInstallationMsg": "",
"inlineInstallExtension": "",
"inlineInstallExtension": "Installer nå",
"internalError": "",
"internalErrorTitle": "",
"kickMessage": "",
"kickParticipantButton": "",
"kickParticipantDialog": "",
"kickParticipantTitle": "",
"kickTitle": "",
"kickParticipantButton": "Kast ut",
"kickParticipantDialog": "Er du sikker på at du vil kaste ut denne deltageren?",
"kickParticipantTitle": "Kast ut denne deltageren?",
"kickTitle": "Oida. {{participantDisplayName}} kastet deg ut av møtet",
"liveStreaming": "",
"liveStreamingDisabledForGuestTooltip": "",
"liveStreamingDisabledTooltip": "",
"lockMessage": "",
"lockMessage": "Klarte ikke å låse konferansen.",
"lockRoom": "",
"lockTitle": "",
"logoutQuestion": "",
"logoutTitle": "",
"logoutTitle": "Logg ut",
"maxUsersLimitReached": "",
"maxUsersLimitReachedTitle": "",
"micConstraintFailedError": "",
@@ -194,17 +199,17 @@
"micNotSendingDataTitle": "",
"micPermissionDeniedError": "",
"micUnknownError": "",
"muteParticipantBody": "",
"muteParticipantButton": "",
"muteParticipantBody": "Du vil ikke kunne oppheve forstumming av dem, men de kan oppheve forstumming selv når som helst.",
"muteParticipantButton": "Forstum",
"muteParticipantDialog": "",
"muteParticipantTitle": "",
"Ok": "",
"Ok": "OK",
"passwordLabel": "",
"passwordNotSupported": "",
"passwordNotSupportedTitle": "",
"passwordRequired": "",
"popupError": "",
"popupErrorTitle": "",
"popupErrorTitle": "Oppsprett blokkert",
"recording": "",
"recordingDisabledForGuestTooltip": "",
"recordingDisabledTooltip": "",
@@ -216,73 +221,81 @@
"remoteControlShareScreenWarning": "",
"remoteControlStopMessage": "",
"remoteControlTitle": "",
"Remove": "",
"removePassword": "",
"Remove": "Fjern",
"removePassword": "Fjern",
"removeSharedVideoMsg": "",
"removeSharedVideoTitle": "",
"removeSharedVideoTitle": "Fjern delt video",
"reservationError": "",
"reservationErrorMsg": "",
"retry": "",
"retry": "Prøv igjen",
"screenSharingFailedToInstall": "",
"screenSharingFailedToInstallTitle": "",
"screenSharingFirefoxPermissionDeniedError": "",
"screenSharingFirefoxPermissionDeniedTitle": "",
"screenSharingPermissionDeniedError": "",
"serviceUnavailable": "",
"serviceUnavailable": "Tjenesten er utilgjengelig",
"sessTerminated": "",
"Share": "",
"Share": "Del",
"shareVideoLinkError": "",
"shareVideoTitle": "",
"shareYourScreen": "",
"shareYourScreenDisabled": "",
"shareVideoTitle": "Del en video",
"shareYourScreen": "Del skjermen din",
"shareYourScreenDisabled": "Skjermdeling er avskrudd.",
"shareYourScreenDisabledForGuest": "",
"startLiveStreaming": "",
"startRecording": "",
"startRecording": "Start opptak",
"startRemoteControlErrorMessage": "",
"stopLiveStreaming": "",
"stopRecording": "",
"stopRecording": "Stopp opptak",
"stopRecordingWarning": "",
"stopStreamingWarning": "",
"streamKey": "",
"Submit": "",
"thankYou": "",
"token": "",
"Submit": "Send inn",
"thankYou": "Takk for at du bruker {{appName}}.",
"token": "symbol",
"tokenAuthFailed": "",
"tokenAuthFailedTitle": "",
"transcribing": "",
"unlockRoom": "",
"userPassword": "",
"userPassword": "brukerpassord",
"WaitForHostMsg": "",
"WaitForHostMsgWOk": "",
"WaitingForHost": "",
"Yes": "",
"yourEntireScreen": ""
"Yes": "Ja",
"yourEntireScreen": "Hele skjermen din",
"sendPrivateMessageTitle": "Send privat?",
"sendPrivateMessageOk": "Send privat",
"sendPrivateMessageCancel": "Send til gruppen",
"screenSharingAudio": "Del lyd",
"muteEveryoneStartMuted": "Alle starter forstummet fra nå av",
"muteEveryoneSelf": "deg selv",
"muteEveryoneTitle": "Forstum alle?",
"muteEveryoneElseTitle": "Forstum alle unntatt {{whom}}?"
},
"dialOut": {
"statusMessage": ""
"statusMessage": "er nå {{status}}"
},
"feedback": {
"average": "",
"bad": "",
"detailsLabel": "",
"good": "",
"rateExperience": "",
"veryBad": "",
"veryGood": ""
"average": "Middels",
"bad": "Dårlig",
"detailsLabel": "Fortell oss om det.",
"good": "God",
"rateExperience": "Vurder din møteopplevelse",
"veryBad": "Veldig dårlig",
"veryGood": "Veldig god"
},
"incomingCall": {
"answer": "",
"answer": "Svar",
"audioCallTitle": "",
"decline": "",
"productLabel": "",
"videoCallTitle": ""
},
"info": {
"accessibilityLabel": "",
"addPassword": "",
"cancelPassword": "",
"conferenceURL": "",
"country": "",
"accessibilityLabel": "Vis info",
"addPassword": "Legg til $t(lockRoomPassword)",
"cancelPassword": "Avbryt $t(lockRoomPassword)",
"conferenceURL": "Lenke:",
"country": "Land",
"dialANumber": "",
"dialInConferenceID": "",
"dialInNotSupported": "",
@@ -297,35 +310,35 @@
"inviteURLFirstPartPersonal": "",
"inviteURLSecondPart": "",
"liveStreamURL": "",
"moreNumbers": "",
"moreNumbers": "Flere nummer",
"noNumbers": "",
"noPassword": "",
"noRoom": "",
"numbers": "",
"password": "",
"title": "",
"title": "Del",
"tooltip": "",
"label": ""
},
"inviteDialog": {
"alertText": "",
"header": "",
"header": "Inviter",
"searchCallOnlyPlaceholder": "",
"searchPeopleOnlyPlaceholder": "",
"searchPlaceholder": "",
"send": ""
"send": "Send"
},
"inlineDialogFailure": {
"msg": "",
"retry": "",
"support": "",
"retry": "Prøv igjen",
"support": "Brukerstøtte",
"supportMsg": ""
},
"keyboardShortcuts": {
"focusLocal": "",
"focusRemote": "",
"fullScreen": "",
"keyboardShortcuts": "",
"keyboardShortcuts": "Tastatursnarveier",
"localRecording": "",
"mute": "",
"pushToTalk": "",
@@ -357,7 +370,7 @@
"on": "",
"pending": "",
"serviceName": "",
"signedInAs": "",
"signedInAs": "©",
"signIn": "",
"signInCTA": "",
"signOut": "",
@@ -708,5 +721,11 @@
"sendFeedback": "",
"terms": "",
"title": ""
},
"documentSharing": {
"title": "Delt dokument"
},
"chromeExtensionBanner": {
"dontShowAgain": "Ikke vis meg dette igjen"
}
}
}

View File

@@ -47,10 +47,10 @@
},
"chat": {
"error": "Erro: sua mensagem não foi enviada. Motivo: {{error}}",
"fieldPlaceHolder": "",
"fieldPlaceHolder": "Digite sua mensagem aqui",
"messagebox": "Digite uma mensagem",
"messageTo": "Mensagem privada para {{recipient}}",
"noMessagesMessage": "",
"noMessagesMessage": "Não há mensagens na reunião ainda. Inicie uma conversa aqui!",
"nickname": {
"popover": "Escolha um apelido",
"title": "Digite um apelido para usar o bate-papo"
@@ -72,7 +72,11 @@
"DISCONNECTED": "Desconectado",
"DISCONNECTING": "Desconectando",
"ERROR": "Erro",
"RECONNECTING": "Ocorreu um problema de rede. Reconectando..."
"RECONNECTING": "Ocorreu um problema de rede. Reconectando...",
"LOW_BANDWIDTH": "O vídeo de {{displayName}} foi desativado para economizar largura de banda",
"GOT_SESSION_ID": "Obtendo ID da sessão... Feito",
"GET_SESSION_ID_ERROR": "Erro ao obter o ID da sessão: {{code}}",
"FETCH_SESSION_ID": "Obtendo ID da sessão..."
},
"connectionindicator": {
"address": "Endereço:",
@@ -102,7 +106,8 @@
"resolution": "Resolução:",
"status": "Conexão:",
"transport": "Transporte:",
"transport_plural": "Transportes:"
"transport_plural": "Transportes:",
"e2e_rtt": "E2E RTT:"
},
"dateUtils": {
"earlier": "Mais cedo",
@@ -205,7 +210,7 @@
"muteParticipantDialog": "Tem certeza de que deseja silenciar este participante? Você não poderá desfazer isso, mas o participante pode reabilitar o áudio a qualquer momento.",
"muteParticipantTitle": "Deixar mudo este participante?",
"Ok": "Ok",
"passwordLabel": "$t(lockRoomPasswordUppercase)",
"passwordLabel": "A reunião foi travada por um participante. Por favor, insira a $t(lockRoomPassword) para entrar.",
"passwordNotSupported": "A configuração de uma reunião $t(lockRoomPassword) não é suportada.",
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) não suportado",
"passwordRequired": "$t(lockRoomPasswordUppercase) requerido",
@@ -232,7 +237,7 @@
"screenSharingFailedToInstall": "Oops! Falhou a instalação da extensão de compartilhamento de tela.",
"screenSharingFailedToInstallTitle": "A extensão de compartilhamento de tela falhou ao instalar",
"screenSharingFirefoxPermissionDeniedError": "Algo deu errado enquanto estávamos tentando compartilhar sua tela. Por favor, certifique-se de que você nos deu permissão para fazê-lo. ",
"screenSharingFirefoxPermissionDeniedTitle": "Opa! Não foi possível iniciar o compartilhamento de tela.",
"screenSharingFirefoxPermissionDeniedTitle": "Opa! Não foi possível iniciar o compartilhamento de tela!",
"screenSharingPermissionDeniedError": "Oops! Alguma coisa está errada com suas permissões de compartilhamento de tela. Recarregue e tente de novo.",
"sendPrivateMessage": "Você enviou uma mensagem privada recentemente. Tem intenção de responder em privado, ou deseja enviar sua mensagem para o grupo?",
"sendPrivateMessageCancel": "Enviar para o grupo",
@@ -266,7 +271,14 @@
"WaitForHostMsgWOk": "A conferência <b>{{room}}</b> ainda não começou. Se você é o anfitrião, pressione Ok para autenticar. Do contrário, aguarde a chegada do anfitrião.",
"WaitingForHost": "Esperando o hospedeiro...",
"Yes": "Sim",
"yourEntireScreen": "Toda sua tela"
"yourEntireScreen": "Toda sua tela",
"screenSharingAudio": "Compartilhar áudio",
"muteEveryoneStartMuted": "Todos iniciam silenciados daqui para frente",
"muteEveryoneSelf": "a si próprio",
"muteEveryoneDialog": "Tem certeza que deseja silenciar todos? Você não poderá ativar o som deles, mas eles podem ativar o som eles mesmo a qualquer momento.",
"muteEveryoneTitle": "Silenciar todos?",
"muteEveryoneElseTitle": "Silenciar todo mundo exceto {{whom}}?",
"muteEveryoneElseDialog": "Uma vez silenciados, você não poderá reativar o som deles, mas eles poderão reativar o som a qualquer momento."
},
"dialOut": {
"statusMessage": "está agora {{status}}"
@@ -304,7 +316,7 @@
"dialInTollFree": "Chamada gratuita",
"genericError": "Oops, alguma coisa deu errado.",
"inviteLiveStream": "Para ver a transmissão ao vivo da reunião, clique no link: {{url}}",
"invitePhone": "Para participar por telefone, toque aqui: {{number}} ,, {{conferenceID}} # \\ n",
"invitePhone": "Para participar por telefone, toque aqui: {{number}},,{{conferenceID}}#\n",
"invitePhoneAlternatives": "Procurando um número de discagem diferente?\nVeja os números de discagem da reunião: {{url}} \n\n\nSe você também estiver discando através de um telefone da sala, participe sem conectar-se ao áudio: {{silentUrl}}",
"inviteURLFirstPartGeneral": "Você foi convidado para uma reunião.",
"inviteURLFirstPartPersonal": "{{name}} está convidando você para uma reunião.\n",
@@ -379,7 +391,9 @@
"signOut": "Sair",
"start": "Iniciar uma transmissão ao vivo",
"streamIdHelp": "O que é isso?",
"unavailableTitle": "Transmissão ao vivo indisponível"
"unavailableTitle": "Transmissão ao vivo indisponível",
"googlePrivacyPolicy": "Política de Privacidade do Google",
"youtubeTerms": "Termos de serviços do YouTube"
},
"localRecording": {
"clientState": {
@@ -419,9 +433,9 @@
"connectedTwoMembers": "{{first}} e {{second}} entraram na reunião",
"disconnected": "desconectado",
"focus": "Foco da conferência",
"focusFail": "{{component}} não disponĩvel - tente em {{ms}} seg.",
"focusFail": "{{component}} não disponível - tente em {{ms}} seg",
"grantedTo": "Direitos de moderador concedido para {{to}}!",
"invitedOneMember": "{{displayName}} foi convidado",
"invitedOneMember": "{{name}} foi convidado(a)",
"invitedThreePlusMembers": "{{name}} e {{count}} outros foram convidados",
"invitedTwoMembers": "{{first}} e {{second}} foram convidados",
"kickParticipant": "{{kicked}} foi chutado por {{kicker}}",
@@ -469,7 +483,7 @@
},
"raisedHand": "Gostaria de falar",
"recording": {
"authDropboxText": "Enviar para o Dropbox.",
"authDropboxText": "Enviar para o Dropbox",
"availableSpace": "Espaço disponível: {{spaceLeft}} MB (aproximadamente {{duration}} minutos de gravação)",
"beta": "BETA",
"busy": "Estamos trabalhando para liberar recursos de gravação. Tente novamente em alguns minutos.",
@@ -519,30 +533,32 @@
"selectMic": "Microfone",
"startAudioMuted": "Todos iniciam mudos",
"startVideoMuted": "Todos iniciam ocultos",
"title": "Configurações"
"title": "Configurações",
"speakers": "Alto-faltantes",
"microphones": "Microfones"
},
"settingsView": {
"advanced": "",
"advanced": "Avançado",
"alertOk": "OK",
"alertTitle": "Atenção",
"alertURLText": "A URL digitada do servidor é inválida",
"buildInfoSection": "Informações de compilação",
"conferenceSection": "Conferência",
"disableCallIntegration": "",
"disableP2P": "",
"disableCallIntegration": "Desativar integração de chamada nativa",
"disableP2P": "Desativar modo ponto a ponto",
"displayName": "Nome de exibição",
"email": "E-mail",
"header": "Configurações",
"profileSection": "Perfil",
"serverURL": "URL do servidor",
"showAdvanced": "",
"showAdvanced": "Mostrar configurações avançadas",
"startWithAudioMuted": "Iniciar sem áudio",
"startWithVideoMuted": "Iniciar sem vídeo",
"version": "Versão"
},
"share": {
"dialInfoText": "\n\n=====\n\nDeseja apenas discar no seu telefone?\n\n{{defaultDialInNumber}}Clique neste link para ver os números de telefone para esta reunião\n{{dialInfoPageUrl}}",
"mainText": "Clique no seguinte link para entrar na reunião:{{roomUrl}}\n"
"mainText": "Clique no seguinte link para entrar na reunião:\n{{roomUrl}}"
},
"speaker": "Alto-falantes",
"speakerStats": {
@@ -598,7 +614,10 @@
"tileView": "Alternar visualização em blocos",
"toggleCamera": "Alternar câmera",
"videomute": "Alternar mudo do vídeo",
"videoblur": "Alternar desfoque de vídeo"
"videoblur": "Alternar desfoque de vídeo",
"toggleFilmstrip": "Alterar tira de filme",
"muteEveryone": "Silenciar todos",
"moreOptions": "Mostrar mais opções"
},
"addPeople": "Adicionar pessoas à sua chamada",
"audioOnlyOff": "Desabilitar modo de largura de banda baixa",
@@ -624,9 +643,9 @@
"lowerYourHand": "Baixar a mão",
"moreActions": "Mais ações",
"mute": "Mudo / Não mudo",
"noAudioSignalTitle": "",
"noAudioSignalDesc": "",
"noAudioSignalDescSuggestion": "",
"noAudioSignalTitle": "Não há entrada de áudio vindo do seu microfone!",
"noAudioSignalDesc": "Se você não o desativou propositalmente das configurações do sistema ou do hardware, considere trocar o dispositivo.",
"noAudioSignalDescSuggestion": "Se você não o desativou propositalmente das configurações do sistema ou do hardware, considere trocar para o dispositivo sugerido.",
"openChat": "Abrir chat",
"pip": "Entrar em modo Quadro-a-Quadro",
"privateMessage": "Enviar mensagem privada",
@@ -648,7 +667,13 @@
"toggleCamera": "Alternar câmera",
"videomute": "Iniciar ou parar a câmera",
"startvideoblur": "Desfocar meu plano de fundo",
"stopvideoblur": "Desativar desfoque de fundo"
"stopvideoblur": "Desativar desfoque de fundo",
"noisyAudioInputDesc": "Parece que o microfone está fazendo barulho, considere silenciar ou alterar o dispositivo.",
"noisyAudioInputTitle": "O seu microfone parece estar barulhento!",
"noAudioSignalDialInLinkDesc": "Discar números",
"noAudioSignalDialInDesc": "Você também pode discar usando:",
"muteEveryone": "Silenciar todos",
"moreOptions": "Mais opções"
},
"transcribing": {
"ccButtonTooltip": "Iniciar/parar legendas",
@@ -700,7 +725,7 @@
"onlyAudioSupported": "Suportamos somente áudio neste navegador.",
"p2pEnabled": "Ponto-a-ponto habilitada",
"p2pVideoQualityDescription": "No modo ponto a ponto, a qualidade do vídeo recebido só pode ser alternada entre alta e apenas áudio. Outras configurações não serão respeitadas até que o ponto a ponto seja encerrado.",
"recHighDefinitionOnly": "Preferência para alta definição",
"recHighDefinitionOnly": "Preferência para alta definição.",
"sd": "SD",
"sdTooltip": "Ver vídeo em definição padrão",
"standardDefinition": "Definição padrão"
@@ -714,14 +739,15 @@
"muted": "Mudo",
"remoteControl": "Controle remoto",
"show": "Mostrar no palco",
"videomute": "O participante parou a câmera"
"videomute": "O participante parou a câmera",
"domuteOthers": "Silenciar todos os demais"
},
"welcomepage": {
"accessibilityLabel": {
"join": "Toque para entrar",
"roomname": "Digite o nome da sala"
},
"appDescription": "Vá em frente, converse por vídeo com toda a equipe. De fato, convide todos que você conhece. {{app}} é uma solução de videoconferência totalmente criptografada e 100% de código aberto que você pode usar todos os dias, a cada dia, gratuitamente — sem necessidade de conta.",
"appDescription": "Vá em frente, converse por vídeo com toda a equipe. De fato, convide todos que você conhece. {{app}} é uma solução de videoconferência totalmente criptografada e 100% de código aberto que você pode usar todos os dias, a cada dia, gratuitamente — sem necessidade de conta.",
"audioVideoSwitch": {
"audio": "Voz",
"video": "Vídeo"
@@ -733,7 +759,7 @@
"roomNameAllowedChars": "Nome da reunião não deve conter qualquer um destes caracteres: ?. &, :, ', \", %, #.",
"go": "IR",
"goSmall": "IR",
"join": "",
"join": "CRIAR / ENTRAR",
"info": "Informações",
"privacy": "Política de Privacidade",
"recentList": "Recente",
@@ -744,6 +770,19 @@
"roomnameHint": "Digite o nome ou a URL da sala que você deseja entrar. Você pode digitar um nome, e apenas deixe para as pessoas que você quer se reunir digitem o mesmo nome.",
"sendFeedback": "Enviar comentários",
"terms": "Termos",
"title": "Videoconferências mais seguras, flexíveis e totalmente gratuitas"
"title": "Videoconferências mais seguras, flexíveis e totalmente gratuitas",
"getHelp": "Obter ajuda"
},
"helpView": {
"header": "Centro de ajuda"
},
"lonelyMeetingExperience": {
"youAreAlone": "Você é o único na reunião",
"button": "Convidar outros"
},
"chromeExtensionBanner": {
"dontShowAgain": "Não me mostre isso de novo",
"buttonText": "Instalar extensão do Chrome",
"installExtensionText": "Instale a extensão par integração com Google Calendar e Office 365"
}
}
}

786
lang/main-sc.json Normal file
View File

@@ -0,0 +1,786 @@
{
"addPeople": {
"add": "Invita",
"countryNotSupported": "No est ancora possìbile de impreare custa destinatzione.",
"countryReminder": "Ses mutende in foras de is Istados Unidos? Verìfica chi insertas su còdighe de istadu!",
"disabled": "Non podes invitare gente.",
"failedToAdd": "Faddina in s'agiunta de partetzipantes",
"footerText": "Is mutidas in essida sunt disativadas.",
"loading": "Chirchende gente e nùmeros de telèfonu",
"loadingNumber": "Verifichende su nùmeru de telèfonu",
"loadingPeople": "Chirchende gente de invitare",
"noResults": "Non cointzidet perunu resultadu",
"noValidNumbers": "Inserta·nche unu nùmeru de telèfonu",
"searchNumbers": "Agiunghe nùmeros de telèfonu",
"searchPeople": "Chirca gente",
"searchPeopleAndNumbers": "Chirca gente o agiunghe is nùmeros de telèfonu issoro",
"telephone": "Telèfonu: {{number}}",
"title": "Invita gente a custa riunione"
},
"audioDevices": {
"bluetooth": "Bluetooth",
"headphones": "Auriculares",
"phone": "Telèfonu",
"speaker": "Altoparlante",
"none": "Perunu dispositivu de àudio a disponimentu"
},
"audioOnly": {
"audioOnly": "Àmpiu de banda bàsciu"
},
"calendarSync": {
"addMeetingURL": "Agiunghe unu ligàmene a s'addòbiu",
"confirmAddLink": "Boles agiùnghere unu ligàmene de Jitsi a custu addòbiu?",
"error": {
"appConfiguration": "S'integratzione de su calendàriu no est cunfigurada bene.",
"generic": "Faddina. Controlla sa cunfiguratzione de calendàriu o proa de atualizare su calendàriu.",
"notSignedIn": "Faddina in s'autenticatzione pro visualizare eventos de calendàriu. Controlla sa cunfiguratzione de calendàriu e proa de ti torrare a autenticare."
},
"join": "Aderi",
"joinTooltip": "Aderi a sa riunione",
"nextMeeting": "riunione imbeniente",
"noEvents": "Perunu eventu programmadu in futuru.",
"ongoingMeeting": "riunione in cursu",
"permissionButton": "Aberi sa cunfiguratzione",
"permissionMessage": "Su permissu de su calendàriu est rechèdidu pro bìdere is riuniones tuss in s'aplicatzione.",
"refresh": "Atualiza su calendàriu",
"today": "Oe"
},
"chat": {
"error": "Faddina: su messàgiu tuo no est istadu imbiadu. Resone: {{error}}",
"fieldPlaceHolder": "Iscrie su messàgiu inoghe",
"messagebox": "Iscrie unu messàgiu",
"messageTo": "Messàgiu privadu a {{recipient}}",
"noMessagesMessage": "Perunu messàgiu ancora in sa riunione. Cumintza una tzarrada inoghe!",
"nickname": {
"popover": "Sèbera unu nòmine",
"title": "Inserta su nòmine pro impreare sa tzarrada"
},
"privateNotice": "Messàgiu privadu a {{recipient}}",
"title": "Tzarrada",
"you": "tue"
},
"chromeExtensionBanner": {
"installExtensionText": "Installa s'estensione de integratzione cun Google Calendar e Office 365",
"buttonText": "Installa s'estensione de Google",
"dontShowAgain": "Non ddu torres a ammustrare"
},
"connectingOverlay": {
"joiningRoom": "Connetende a sa riunione..."
},
"connection": {
"ATTACHED": "Allegados",
"AUTHENTICATING": "Autenticatzione in cursu",
"AUTHFAIL": "Faddina in s'autenticatzione",
"CONNECTED": "Connessione istabilida",
"CONNECTING": "Connetende",
"CONNFAIL": "Faddina in sa connessione",
"DISCONNECTED": "Disconnètidu",
"DISCONNECTING": "Disconnetende",
"ERROR": "Faddina",
"FETCH_SESSION_ID": "Otenende id de sessione...",
"GET_SESSION_ID_ERROR": "Faddina in su ritzevimentu de s'ide de sessione: {{code}}",
"GOT_SESSION_ID": "Otenende id de sessione... Fatu",
"LOW_BANDWIDTH": "Vìdeu disativadu pro {{displayName}} pro istraviare àmpiu de banda"
},
"connectionindicator": {
"address": "Indiritzu:",
"bandwidth": "Àmpiu de banda istimadu:",
"bitrate": "Velotzidade de bits:",
"bridgeCount": "Nùmeru de servidores: ",
"connectedTo": "Connessione cun:",
"e2e_rtt": "E2E RTT:",
"framerate": "Velotzidade de fotogrammas:",
"less": "Prus pagu informatziones",
"localaddress": "Indiritzu locale:",
"localaddress_plural": "Indiritzos locales:",
"localport": "Portu locale:",
"localport_plural": "Portos locales:",
"more": "Àteras informatziones",
"packetloss": "Pèrdida de pachetes:",
"quality": {
"good": "Bonu",
"inactive": "Inativa",
"lost": "Pèrdida",
"nonoptimal": "No òtima",
"poor": "Pòbera"
},
"remoteaddress": "Indiritzu remotu:",
"remoteaddress_plural": "Indiritzos remotos:",
"remoteport": "Portu remotu:",
"remoteport_plural": "Portos remotos:",
"resolution": "Risolutzione:",
"status": "Connessione:",
"transport": "Trasportu:",
"transport_plural": "Trasportos:"
},
"dateUtils": {
"earlier": "Prus antigu",
"today": "Oe",
"yesterday": "Eris"
},
"deepLinking": {
"appNotInstalled": "Tenes bisòngiu de s'aplicatzione mòbile {{app}} pro aderire a custa tzarrada dae su telèfonu.",
"description": "No est sutzèdidu nudda? Amus chircadu de aviare sa riunione tua in s'aplicatzione de iscrivania {{app}}. Torra·bi a proare o avia·la dae s'aplicatzione web {{app}}.",
"descriptionWithoutWeb": "No est sutzèdidu nudda? Amus chircadu de aviare sa riunione tua in s'aplicatzione de iscrivania {{app}}.",
"downloadApp": "Iscàrriga s'aplicatzione",
"launchWebButton": "Avia in sa web",
"openApp": "Sighi in s'aplicatzione",
"title": "Aviende sa reunione in {{app}}...",
"tryAgainButton": "Torra·bi a proare in s'aplicatzione de iscrivania"
},
"defaultLink": "p. es. {{url}}",
"defaultNickname": "es. Rosa Pink",
"deviceError": {
"cameraError": "Impossìbile atzèdere a sa càmera",
"cameraPermission": "Faddina in is permissos pro sa càmera",
"microphoneError": "Impossìbile atzèdere a su micròfonu",
"microphonePermission": "Faddina in is permissos pro su micròfonu"
},
"deviceSelection": {
"noPermission": "No as cuntzèdidu permissos",
"previewUnavailable": "Sa pre-visualizatzione no est a disponimentu",
"selectADevice": "Sèbera unu dispositivu",
"testAudio": "Riprodue unu sonu de proa"
},
"dialog": {
"accessibilityLabel": {
"liveStreaming": "Trasmissione in direta"
},
"allow": "Permite",
"alreadySharedVideoMsg": "Un'àteru partetzipante est giai cumpartende unu vìdeu. Custa cunferèntzia permitit de cumpartzire isceti unu vìdeu in contemporànea.",
"alreadySharedVideoTitle": "Isceti unu vìdeu cumpartzidu in contemporànea",
"applicationWindow": "Ventana de s'aplicatzione",
"Back": "In segus",
"cameraConstraintFailedError": "La càmera no satisfà algun dels requeriments.",
"cameraNotFoundError": "Càmera no agatada.",
"cameraNotSendingData": "Impossìbile atzèdere a sa càmera tua. Controlla si un'àtera aplicatzione est impreende custu dispositivu, sèbera un'àteru dispositivu dae su menù de cunfiguratziones o torra a carrigare s'aplicatzione.",
"cameraNotSendingDataTitle": "Non si podet atzèdere a sa càmera",
"cameraPermissionDeniedError": "No as donadu permissos pro impreare sa càmera. Podes intrare in sa cunferèntzia su pròpiu, però s'àtera gente non ti at a bìdere. Imprea su butone de sa càmera in sa barra de indiritzos pro acontzare custu problema.",
"cameraUnknownError": "Non si podet impreare sa càmera (resone disconnota).",
"cameraUnsupportedResolutionError": "Sa càmera no est cumpatìbile cun sa risolutzione de vìdeu rechèdida.",
"Cancel": "Annulla",
"close": "Serra",
"conferenceDisconnectMsg": "Controlla sa cunfiguratzione de rete. Torrende a connètere in {{seconds}} segundos...",
"conferenceDisconnectTitle": "Mutida disconnètida.",
"conferenceReloadMsg": "Semus chirchende de acontzare custu problema. Torrende a connètere in {{seconds}} segundos...",
"conferenceReloadTitle": "B'est istada una faddina.",
"confirm": "Cunfirma",
"confirmNo": "Nono",
"confirmYes": "Eja",
"connectError": "B'àt àpidu una faddina e non podimus connètere cun sa cunferèntzia.",
"connectErrorWithMsg": "B'àt àpidu una faddina e non podimus connètere cun sa cunferèntzia: {{msg}}",
"connecting": "Connetende",
"contactSupport": "Cuntatu s'agiudu",
"copy": "Còpia",
"dismiss": "Iscarta",
"displayNameRequired": "Salude! Comente ti tzèrrias?",
"done": "Fatu",
"enterDisplayName": "Inserta su nòmine inoghe",
"error": "Faddina",
"externalInstallationMsg": "Installa s'estensione nostra pro sa cumpartzidura de iscrivania.",
"externalInstallationTitle": "Estensione rechèdida",
"goToStore": "Bae a sa butega",
"gracefulShutdown": "Su servìtziu nostru est in mantenimentu. Torra·bi a proare a pustis.",
"IamHost": "So mere",
"incorrectRoomLockPassword": "Sa crae no est curreta",
"incorrectPassword": "Su nòmine o sa crae no sunt curretos",
"inlineInstallationMsg": "Installa s'estensione nostra pro sa cumpartzidura de iscrivania.",
"inlineInstallExtension": "Installa immoe",
"internalError": "B'est istada una faddina: {{error}}",
"internalErrorTitle": "Faddina interna",
"kickMessage": "Podes cuntatare {{participantDisplayName}} pro àteras informatziones.",
"kickParticipantButton": "Boga",
"kickParticipantDialog": "Seguru chi boles bogare custa persone?",
"kickParticipantTitle": "Cheres bogare custa persone?",
"kickTitle": "{{participantDisplayName}} t'at bogadu de sa riunione",
"liveStreaming": "Trasmissione in direta",
"liveStreamingDisabledForGuestTooltip": "Is persones invitadas non podent aviare una trasmissione in direta.",
"liveStreamingDisabledTooltip": "Faddina in s'aviu de sa trasmissione in direta.",
"lockMessage": "Impossìbile blocare sa cunferèntzia.",
"lockRoom": "Agiunghe riunione $t(lockRoomPasswordUppercase)",
"lockTitle": "Faddina in su blocu",
"logoutQuestion": "Seguru chi boles essire e firmare sa cunferèntzia?",
"logoutTitle": "Essi",
"maxUsersLimitReached": "Lìmite de partetzipantes cròmpidu. Sa cunferèntzia est prena. Cuntata su mere de sa riunione o torra·bi a proare.",
"maxUsersLimitReachedTitle": "Lìmite de partetzipantes cròmpidu",
"micConstraintFailedError": "Su micròfonu no at soddisfatu is rechestas.",
"micNotFoundError": "Micròfonu no agatadu.",
"micNotSendingData": "Bae a sa cunfiguratzione de s'elaboradore tuo pro ativare su micròfonu tuo e acontzare su livellu",
"micNotSendingDataTitle": "Su micròfonu tuo est in silèntziu pro more de is cunfiguratziones de su sistema tuo",
"micPermissionDeniedError": "No as donadu permissos pro impreare su micròfonu. Podes intrare in sa cunferèntzia su pròpiu, però s'àtera gente non ti at a intèndere. Imprea su butone de sa càmera in sa barra de indiritzos pro acontzare custu problema.",
"micUnknownError": "Non si podet impreare su micròfonu (resone disconnota).",
"muteEveryoneElseDialog": "Una borta chi as postu calicunu a sa muda, no as a pòdere torrare a aviare s'àudio suo, però isse ddu at a pòdere fàghere in cale si siat momentu.",
"muteEveryoneElseTitle": "Boles pònnere totus a sa muda francu {{whom}}?",
"muteEveryoneDialog": "Seguru chi boles pònnere totus a sa muda? No as a pòdere torrare a ativare s'àudio issoro, però is utentes ddu ant a pòdere ativare in cale si siat momentu.",
"muteEveryoneTitle": "Boles pònnere totus a sa muda?",
"muteEveryoneSelf": "tue",
"muteEveryoneStartMuted": "Dae immoe, is tzarradas cumintzant cun is utentes a sa muda",
"muteParticipantBody": "No as a pòdere torrare a ativare s'àudio issoro, però is utentes ddu ant a pòdere ativare in cale si siat momentu.",
"muteParticipantButton": "A sa muda",
"muteParticipantDialog": "Seguru chi boles pònnere custa persone a sa muda? No as a pòdere torrare a ativare s'àudio issoro, però is utentes ddu ant a pòdere ativare in cale si siat momentu.",
"muteParticipantTitle": "Boles pònnere custa persone a sa muda?",
"Ok": "AB",
"passwordLabel": "Unu partetzipante at blocadu sa riunione. Inserta sa $t(lockRoomPassword) pro intrare.",
"passwordNotSupported": "No est possìbile istabilire una $t(lockRoomPassword).",
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) non suportadu",
"passwordRequired": "$t(lockRoomPasswordUppercase) rechèdida",
"popupError": "Su navigadore tuo est blochende is ventanas emergentes de custu situ. Ativa is ventanas emergentes dae sa cunfiguratzione de seguresa de su navigadore e torra·bi a proare.",
"popupErrorTitle": "Finestres emergents blocades",
"recording": "Registrende",
"recordingDisabledForGuestTooltip": "Is persones invitadas non podent registrare.",
"recordingDisabledTooltip": "S'aviu de registratziones est istadu disativadu.",
"rejoinNow": "Torra a intrare",
"remoteControlAllowedMessage": "{{user}} at atzetadu sa rechesta tua de controllu remotu.",
"remoteControlDeniedMessage": "{{user}} at refudadu sa rechesta tua de controllu remotu.",
"remoteControlErrorMessage": "Faddina in sa rechesta de permissos pro su controllu remotu de {{user}}.",
"remoteControlRequestMessage": "Permitis chi {{user}} controllet in remotu s'elaboradore tuo?",
"remoteControlShareScreenWarning": "Si incarcas \"Permite\" as a cumpartzire s'ischermu tuo.",
"remoteControlStopMessage": "Sessione de controllu remotu acabada.",
"remoteControlTitle": "Controllu remotu de elaboradore",
"Remove": "Boga",
"removePassword": "Boga $t(lockRoomPassword)",
"removeSharedVideoMsg": "Seguru chi boles bogare su vìdeu chi as cumpartzidu?",
"removeSharedVideoTitle": "Boga vìdeu cumpartzidu",
"reservationError": "Faddina de riserva de sistema",
"reservationErrorMsg": "Còdighe de faddina: {{code}}, messàgiu: {{msg}}",
"retry": "Torra·bi a proare",
"screenSharingFailedToInstall": "Faddina in s'installatzione de s'estensione de cumpartzidura de ischermu.",
"screenSharingFailedToInstallTitle": "Faddina installatzione estensione cumpartzidura ischermu",
"screenSharingFirefoxPermissionDeniedError": "B'àt àpidu una faddina proende de cumpartzire s'ischermu tuo. Verìfica chi si as donadu permissos pro ddu fàghere. ",
"screenSharingFirefoxPermissionDeniedTitle": "No amus pòdidu aviare sa cumpartzidura de ischermu.",
"screenSharingPermissionDeniedError": "B'àt àpidu una faddina cun is permissos de s'estensione pro sa cumpartzidura de ischermu. Torra a carrigare e torra·bi a proare.",
"sendPrivateMessage": "As retzidu de reghente unu messàgiu privadu. Boles rispòndere a custu messàgiu in privadu, o boles imbiare su messàgiu a su grupu?",
"sendPrivateMessageCancel": "Imbia a su grupu",
"sendPrivateMessageOk": "Imbia in privadu",
"sendPrivateMessageTitle": "Boles imbiare custu messàgiu in privadu?",
"serviceUnavailable": "Su servìtziu no est a disponimentu",
"sessTerminated": "Mutida acabada",
"Share": "Cumpartzi",
"shareVideoLinkError": "Fruni unu ligàmene de youtube curretu.",
"shareVideoTitle": "Cumpartzi unu vìdeu",
"shareYourScreen": "Cumpartzi s'ischermu",
"shareYourScreenDisabled": "Cumpartzidura de ischermu disativada.",
"shareYourScreenDisabledForGuest": "Is persones invitadas non podent cumpartzire s'ischermu.",
"startLiveStreaming": "Avia sa trasmissione in direta",
"startRecording": "Avia sa registratzione",
"startRemoteControlErrorMessage": "Faddina aviende sa sessione de controllu remotu.",
"stopLiveStreaming": "Firma sa trasmissione in direta",
"stopRecording": "Firma sa registratzione",
"stopRecordingWarning": "Seguru chi boles firmare sa registratzione?",
"stopStreamingWarning": "Seguru chi boles firmare sa trasmissione in direta?",
"streamKey": "Crae de sa trasmissione in direta",
"Submit": "Imbia",
"thankYou": "Gràtzias de àere impreadu {{appName}}.",
"token": "còdighe",
"tokenAuthFailed": "No tenes permissu pro intrare in custa mutida.",
"tokenAuthFailedTitle": "Faddina in s'autenticatzione",
"transcribing": "Trascritzione",
"unlockRoom": "Boga riunione $t(lockRoomPassword)",
"userPassword": "crae de utente",
"WaitForHostMsg": "Sa cunferèntzia <b>{{room}}</b> no est cumintzada. Si ses mere de custa cunferèntzia, autèntica·ti. Si nono, iseta chi arribet.",
"WaitForHostMsgWOk": "Sa cunferèntzia <b>{{room}}</b> no est cumintzada. Si ses mere, incarca AB pro ti autenticare. Si nono, iseta chi arribet.",
"WaitingForHost": "Isetende mere...",
"Yes": "Eja",
"yourEntireScreen": "S'ischermu intreu",
"screenSharingAudio": "Cumpartzi s'àudio"
},
"dialOut": {
"statusMessage": "est immoe {{status}}"
},
"documentSharing": {
"title": "Documentu cumpartzidu"
},
"feedback": {
"average": "Mèdiu",
"bad": "Malu",
"detailsLabel": "Nara·si de prus.",
"good": "Bonu",
"rateExperience": "Vota s'esperièntzia tua in custa riunione",
"veryBad": "Mala meda",
"veryGood": "Bona meda"
},
"incomingCall": {
"answer": "Risponde",
"audioCallTitle": "Mutida in intrada",
"decline": "Iscarta",
"productLabel": "dae Jitsi Meet",
"videoCallTitle": "Mutida de vìdeu in intrada"
},
"info": {
"accessibilityLabel": "Ammustra informatziones",
"addPassword": "Agiunghe $t(lockRoomPassword)",
"cancelPassword": "Annulla $t(lockRoomPassword)",
"conferenceURL": "Ligàmene:",
"country": "Paisu",
"dialANumber": "Pro intrare in sa riunione, cumpone unu de custos nùmeros e inserta su PIN.",
"dialInConferenceID": "PIN:",
"dialInNotSupported": "Sa partetzipatzione telefònica ebbia no est suportada a oe.",
"dialInNumber": "Cumpone:",
"dialInSummaryError": "Faddina in su ritzevimentu de is nùmeros de telèfonu. Torra·bi a proare a pustis.",
"dialInTollFree": "Sena pedàgios",
"genericError": "Faddina.",
"inviteLiveStream": "Pro bìdere sa trasmissione in direta de custa riunione, incarca custu ligàmene: {{url}}",
"invitePhone": "Si boles fàghere una connessione telefònica, toca custu: {{number}},,{{conferenceID}}#\n",
"invitePhoneAlternatives": "Ses chirchende unu nùmeru diferente?\nControlla is nùmeros de telèfonu de sa riunione: {{url}}\n\n\nSi ses giai mutende tràmite unu telèfonu de sa riunione, intra sena ti connètere a s'àudio: {{silentUrl}}",
"inviteURLFirstPartGeneral": "Tenes un'invitu pro intrare in una riunione.",
"inviteURLFirstPartPersonal": "{{name}} t'at invitadu a sa riunione.\n",
"inviteURLSecondPart": "\nIntra in sa riunione:\n{{url}}\n",
"liveStreamURL": "Trasmissione in direta:",
"moreNumbers": "Àteros nùmeros",
"noNumbers": "Perunu nùmeru de mutire.",
"noPassword": "Perunu",
"noRoom": "No as ispetzificadu peruna sala de mutire.",
"numbers": "Nùmeros de mutire",
"password": "$t(lockRoomPasswordUppercase):",
"title": "Cumpartzi",
"tooltip": "Imbia su ligàmene e is nùmeros de telèfonu de custa riunione",
"label": "Informatziones de sa riunione"
},
"inviteDialog": {
"alertText": "Faddina in s'invitu de àtera gente.",
"header": "Invita",
"searchCallOnlyPlaceholder": "Inserta·nche unu nùmeru de telèfonu",
"searchPeopleOnlyPlaceholder": "Chirca gente",
"searchPlaceholder": "Partetzipante o nùmeru de telèfonu",
"send": "Imbia"
},
"inlineDialogFailure": {
"msg": "Bi amus postu unu pagu.",
"retry": "Torra·bi a proare",
"support": "Agiudu",
"supportMsg": "Si custu sighit a sutzèdere, nara·si·ddu a"
},
"keyboardShortcuts": {
"focusLocal": "Ammustra su vìdeu tuo",
"focusRemote": "Ammustra su vìdeu de s'àtera persone",
"fullScreen": "Visualiza in mannària prena o essi",
"keyboardShortcuts": "Incurtzaduras de tecladu",
"localRecording": "Ammustra o cua controllos de registratzione locale",
"mute": "Pone su micròfonu a sa muda o torra·ddu a ativare",
"pushToTalk": "Incarca pro chistionare",
"raiseHand": "Àrtzia o abassa sa manu",
"showSpeakerStats": "Ammustra istatìsticas de partetzipantes",
"toggleChat": "Aberi o serra sa tzarrada",
"toggleFilmstrip": "Ammustra o cua miniaturas de vìdeu",
"toggleScreensharing": "Cuncàmbia intre càmera e cumpartzidura de ischermu",
"toggleShortcuts": "Ammustra o cua incurtzaduras de tecladu",
"videoMute": "Avia o firma sa càmera tua",
"videoQuality": "Gesti sa calidade de sa mutida"
},
"liveStreaming": {
"busy": "Semus chirchende de liberare resursas de trasmissione. Torra·bi a proare dae immoe a carchi minutu.",
"busyTitle": "Is trasmitentes sunt ocupados immoe",
"changeSignIn": "Càmbia contos.",
"choose": "Sèbera una trasmissione in direta",
"chooseCTA": "Sèbera un'optzione pro sa trasmissione. Autenticatzione che a {{email}}.",
"enterStreamKey": "Inserta inoghe sa crae tua pro sa trasmissione in direta de YouTube.",
"error": "Faddina in sa trasmissione in direta. Torra·bi a proare.",
"errorAPI": "Faddina in s'atzessu a is trasmissiones tuas de Youtube. Torra·bi a proare.",
"errorLiveStreamNotEnabled": "Sa trasmissione in direta no est ativa in {{email}}. Ativa sa trasmissione in direta o autèntica·ti in unu contu chi tèngiat ativa sa trasmissione in direta.",
"expandedOff": "Trasmissione in direta firmada",
"expandedOn": "Custa riunione est trasmìtida in direta in YouTube.",
"expandedPending": "Trasmissione in direta aviada...",
"failedToStart": "Faddina in s'aviu de sa trasmissione in direta",
"getStreamKeyManually": "No amus pòdidu retzire peruna trasmissione in direta. Chirca de otènnere sa crae de YouTube tua pro is trasmissiones in idreta.",
"invalidStreamKey": "Sa crae pro is trasmissiones in direta podet èssere iscurreta.",
"off": "Trasmissione in direta firmada",
"offBy": "{{name}} at firmadu sa trasmissione in direta",
"on": "Trasmissione in direta",
"onBy": "{{name}} at aviadu sa trasmissione in direta",
"pending": "Aviende sa trasmissione in direta...",
"serviceName": "Servìtziu de trasmissione in direta",
"signedInAs": "Autenticatzione cun:",
"signIn": "Autèntica·ti cun Google",
"signInCTA": "Autèntica·ti o inserta sa crae tua pro sa trasmissione in direta de YouTube.",
"signOut": "Essi",
"start": "Avia sa trasmissione in direta",
"streamIdHelp": "It'est custu?",
"unavailableTitle": "Sa trasmissione in direta no est a disponimentu",
"googlePrivacyPolicy": "Polìtica de riservadesa de Google",
"youtubeTerms": "Cunditziones de servìtziu de YouTube"
},
"localRecording": {
"clientState": {
"off": "Disativada",
"on": "Ativa",
"unknown": "Disconnota"
},
"dialogTitle": "Controllos de registratzione locale",
"duration": "Durada",
"durationNA": "Non a disponimentu",
"encoding": "Codìfica",
"label": "Registr. locale",
"labelToolTip": "Sa registratzione in locale est funtzionende",
"localRecording": "Registratzione in locale",
"me": "Deo",
"messages": {
"engaged": "Sa registratzione in locale est funtzionende.",
"finished": "Acabada sa registratzione de sessione {{token}}. Imbia s'archìviu registradu a sa persone chi mòderat.",
"finishedModerator": "Acabada sa registratzione de sessione {{token}}. Registratzione locale sarvada. Dimanda a su restu de su grupu de imbiare is registratziones.",
"notModerator": "No ses moderadore. Non podes aviare o firmare registratziones in locale."
},
"moderator": "Moderadore",
"no": "Nono",
"participant": "Partetzipante",
"participantStats": "Istatìsticas de partetzipantes",
"sessionToken": "Còdighe de sessione",
"start": "Avia sa registratzione",
"stop": "Firma sa registratzione",
"yes": "Eja"
},
"lockRoomPassword": "crae",
"lockRoomPasswordUppercase": "Crae",
"me": "deo",
"notify": {
"connectedOneMember": "{{name}} at aderidu a sa riunione",
"connectedThreePlusMembers": "{{name}} è ateras {{count}} persones ant aderidu a sa riunione",
"connectedTwoMembers": "{{first}} e {{second}} ant aderidu a sa riunione",
"disconnected": "disconnètidu",
"focus": "Focus de sa cunferèntzia",
"focusFail": "{{component}} no est a disponimentu - torra·bi a proare in {{ms}} seg",
"grantedTo": "Permissos pro sa moderatzione cuntzèdidos a {{to}}.",
"invitedOneMember": "Invitu imbiadu a {{name}}",
"invitedThreePlusMembers": "Invitu imbiadu a {{name}} e àteras {{count}} persones",
"invitedTwoMembers": "Invitu imbiadu a {{first}} e {{second}}",
"kickParticipant": "{{kicker}} at bogadu a {{kicked}}",
"me": "Deo",
"moderator": "As donadu permissos pro sa moderatzione.",
"muted": "As cumintzadu una tzarrada a sa muda.",
"mutedTitle": "Ses a sa muda.",
"mutedRemotelyTitle": "{{participantDisplayName}} t'at postu a sa muda.",
"mutedRemotelyDescription": "Podes torrare a aviare s'àudio cando depas chistionare. Torra a sa muda cando as acabadu pro evitare remore in sa riunione.",
"passwordRemovedRemotely": "Un'utente at bogadu $t(lockRoomPasswordUppercase)",
"passwordSetRemotely": "Un'utente at cunfiguradu $t(lockRoomPasswordUppercase)",
"raisedHand": "{{name}} bolet chistionare.",
"somebody": "Calicunu",
"startSilentTitle": "Ses intradu sena àudio.",
"startSilentDescription": "Torra a intrare pro ativare s'àudio",
"suboptimalBrowserWarning": "Timimus chi s'esperièntzia tua de custa riunione no at a èssere bona meda. Semus chirchende de megiorare custu, però in su mentras proa de impreare unu de is <a href='static/recommendedBrowsers.html' target='_blank'>navigadores cumpatìbiles</a>.",
"suboptimalExperienceTitle": "Avisu subra de su navigadore",
"unmute": "Ativa su sonu",
"newDeviceCameraTitle": "Càmera noa rilevada",
"newDeviceAudioTitle": "Dispositivu de àudio nou rilevadu",
"newDeviceAction": "Imprea"
},
"passwordSetRemotely": "cunfiguradu dae un'àtera persone",
"passwordDigitsOnly": "Finas a {{number}} tzifras",
"poweredby": "de",
"presenceStatus": {
"busy": "No a disponimentu",
"calling": "Mutende...",
"connected": "Connessione istabilida",
"connecting": "Connetende...",
"connecting2": "Connetende*...",
"disconnected": "Disconnètidu",
"expired": "Iscadidu",
"ignored": "Ignoradu",
"initializingCall": "Aviende sa mutida...",
"invited": "Invitadu",
"rejected": "Refudadu",
"ringing": "Sonende..."
},
"profile": {
"setDisplayNameLabel": "Cunfigura su nòmine visìbile tuo",
"setEmailInput": "Inserta posta eletrònica",
"setEmailLabel": "Cunfigura indiritzu eletrònicu de gravatar",
"title": "Profilu"
},
"raisedHand": "Bògio chistionare",
"recording": {
"authDropboxText": "Càrriga a Dropbox",
"availableSpace": "Ispàtziu a disponimentu: {{spaceLeft}} MB (prus o mancu {{duration}} minutos de registratzione)",
"beta": "BETA",
"busy": "Semus traballende pro liberare resursas de registratzione. Torra·bi a proare dae immoe a carchi minutu.",
"busyTitle": "Totu is registradores sunt ocupados",
"error": "Faddina in sa registratzione. Torra·bi a proare.",
"expandedOff": "Registratzione firmada",
"expandedOn": "Registrende sa riunione.",
"expandedPending": "Aviende sa registratzione...",
"failedToStart": "Faddina in s'aviu de sa registratzione",
"fileSharingdescription": "Cumpartzi sa registratzione cun is partetzipantes de sa riunione",
"live": "IN DIRETA",
"loggedIn": "Autenticatzione: {{userName}}",
"off": "Registratzione firmada",
"offBy": "{{name}} at firmadu sa registratzione",
"on": "Registrende",
"onBy": "{{name}} at aviadu sa registratzione",
"pending": "Preparende pro registrare sa riunione...",
"rec": "REG",
"serviceDescription": "Sa registratzione at a èssere sarvada dae su servìtziu de registratzione",
"serviceName": "Servìtziu de registratzione",
"signIn": "Identìfica·ti",
"signOut": "Essi",
"unavailable": "{{serviceName}} no est a disponimentu. Semus traballende pro acontzare su problema. Torra·bi a proare a pustis.",
"unavailableTitle": "Sa registratzione no est a disponimentu"
},
"sectionList": {
"pullToRefresh": "Ispinghe pro atualizare"
},
"settings": {
"calendar": {
"about": "S'integratzione cun su calendàriu {{appName}} est impreada pro atzèdere in manera segura a su calendàriu tuo pro chi potzat lèghere is eventos imbenientes.",
"disconnect": "Disconnete",
"microsoftSignIn": "Autèntica·ti cun Microsoft",
"signedIn": "Ses atzedende a is eventos de calendàriu pro {{email}}. Incarca su butone Disconnete in bàsciu pro firmare s'atzessu a eventos de calendàriu.",
"title": "Calendàriu"
},
"devices": "Dispositivos",
"followMe": "Totus mi sighint",
"language": "Limba",
"loggedIn": "Autenticatzione: {{name}}",
"moderator": "Moderadore",
"more": "Àteru",
"name": "Nòmine",
"noDevice": "Perunu",
"selectAudioOutput": "Essida de àudio",
"selectCamera": "Càmera",
"selectMic": "Micròfonu",
"startAudioMuted": "Totus cumintzant a sa muda",
"startVideoMuted": "Totus cumintzant a sa cua",
"title": "Cunfiguratzione",
"speakers": "Altoparlantes",
"microphones": "Micròfonos"
},
"settingsView": {
"advanced": "Avantzadas",
"alertOk": "AB",
"alertTitle": "Atentzione",
"alertURLText": "Custu URL no est vàlidu",
"buildInfoSection": "Informatzione de sa versione",
"conferenceSection": "Cunferèntzia",
"disableCallIntegration": "Disativa s'integratzione de mutidas nativas",
"disableP2P": "Disativa sa modalidade a nodu terminale (p2p)",
"displayName": "Nòmine visìbile",
"email": "Indiritzu eletrònicu",
"header": "Cunfiguratzione",
"profileSection": "Profilu",
"serverURL": "URL de su servidore",
"showAdvanced": "Ammustra cunfiguratziones avantzadas",
"startWithAudioMuted": "Cumintza cun s'àudio a sa muda",
"startWithVideoMuted": "Cumintza cun su vìdeu disativadu",
"version": "Versione"
},
"share": {
"dialInfoText": "\n\n=====\n\nBoles isceti ascurtare sa cunferèntzia dae su telèfonu?\n\n{{defaultDialInNumber}}Incarca custu ligàmene pro bìdere is nùmeros de telèfonu de custa riunione\n{{dialInfoPageUrl}}\"",
"mainText": "Incarca custu ligàmene pro intrare a sa riunione:\n{{roomUrl}}"
},
"speaker": "Altoparlante",
"speakerStats": {
"hours": "{{count}} h",
"minutes": "{{count}} min",
"name": "Nòmine",
"seconds": "{{count}} seg",
"speakerStats": "Istatìsticas de partetzipante",
"speakerTime": "Tempus de partetzipante"
},
"startupoverlay": {
"title": "{{app}} tenet bisòngiu de impreare sa càmera e su micròfonu tuos.",
"policyText": " "
},
"suspendedoverlay": {
"rejoinKeyTitle": "Torra a intrare",
"text": "Incarca su butone <i>Torra a intrare</i> pro torrare a connètere.",
"title": "S'elaboradore est andadu a riposu e custu at firmadu sa mutida de vìdeu."
},
"toolbar": {
"accessibilityLabel": {
"audioOnly": "Càmbia àudio isceti",
"audioRoute": "Sèbera su dispositivu de àudio",
"callQuality": "Gesti sa calidade de su vìdeu",
"cc": "Càmbia s'istadu de is sutatìtulos",
"chat": "Càmbia ventana de tzarrada",
"document": "Càmbia documentu cumpartzidu",
"download": "Iscàrriga is aplicatziones nostras",
"feedback": "Lassa cummentos",
"fullScreen": "Ativa o disativa ischermu in mannària prena",
"hangup": "Lassa sa mutida",
"help": "Agiudu",
"invite": "Invita gente",
"kick": "Boga partetzipante",
"localRecording": "Ativa o disativa is controllos de registratzione in locale",
"lockRoom": "Ativa o disativa crae de riunione",
"moreActions": "Càmbia su menù de atziones additzionales",
"moreActionsMenu": "Menù de atziones additzionales",
"moreOptions": "Ammustra àteras optziones",
"mute": "Ativa o disativa su silèntziu de s'àudio",
"muteEveryone": "Pone totus a sa muda",
"pip": "Ativa o disativa sa modalidade immàgine in immàgine",
"privateMessage": "Imbia messàgiu de testu privadu",
"profile": "Modìfica su profilu",
"raiseHand": "Àrtzia o abassa sa manu",
"recording": "Ativa o disativa sa registratzione",
"remoteMute": "Pone partetzipante a sa muda",
"Settings": "Càmbia sa cunfiguratzione",
"sharedvideo": "Ativa o disativa sa cumpartzidura de vìdeos de Youtube",
"shareRoom": "Invita una persone",
"shareYourScreen": "Ativa o disativa sa cumpartzidura de ischermu",
"shortcuts": "Ativa o disativa incurtzaduras",
"show": "Ammustra in s'iscena",
"speakerStats": "Càmbia istatìsticas de partetzipante",
"tileView": "Càmbia a visualizatzione in mosàicu",
"toggleCamera": "Càmbia càmera",
"videomute": "Ativa o disativa su vìdeu",
"videoblur": "Ativa o disativa isfocadu"
},
"addPeople": "Agiunghe gente a sa mutida",
"audioOnlyOff": "Disativa modalidade de àmpiu de banda bàsciu",
"audioOnlyOn": "Ativa modalidade de àmpiu de banda bàsciu",
"audioRoute": "Sèbera su dispositivu de àudio",
"authenticate": "Autentica·ti",
"callQuality": "Gesti sa calidade de su vìdeu",
"chat": "Aberi o serra sa tzarrada",
"closeChat": "Serra sa tzarrada",
"documentClose": "Serra su documentu cumpartzidu",
"documentOpen": "Aberi su documentu cumpartzidu",
"download": "Iscàrriga is aplicatziones nostras",
"enterFullScreen": "Ammustra in mannària prena",
"enterTileView": "Intra in visualizatzione in mosàicu",
"exitFullScreen": "Essi de ischermu in mannària prena",
"exitTileView": "Essi de sa visualizatzione in mosàicu",
"feedback": "Lassa cummentos",
"hangup": "Essi",
"help": "Agiudu",
"invite": "Invita gente",
"login": "Intra",
"logout": "Essi",
"lowerYourHand": "Abassa sa manu",
"moreActions": "Àteras atziones",
"moreOptions": "Àteras optziones",
"mute": "Ativa o disativa s'àudio",
"muteEveryone": "Pone totus a sa muda",
"noAudioSignalTitle": "Perunu sinnale dae su micròfonu tuo.",
"noAudioSignalDesc": "Si no dd'as postu a sa muda dae sa cunfiguratzione de sistema o dae su dispositivu, forsis depes cambiare dispositivu.",
"noAudioSignalDescSuggestion": "Si no dd'as postu a sa muda dae sa cunfiguratzione de sistema o dae su dispositivu, forsis depes cambiare a su dispositivu cussigiadu.",
"noAudioSignalDialInDesc": "Podes fintzas intrare cun una mutida:",
"noAudioSignalDialInLinkDesc": "Nùmeros de mutida",
"noisyAudioInputTitle": "Su micròfonu tuo faghet remore.",
"noisyAudioInputDesc": "Su micròfonu tuo faghet remore, forsis ti depes pònnere a sa muda o depes cambiare dispositivu.",
"openChat": "Aberi sa tzarrada",
"pip": "Intra in modalidade immàgine in immàgine",
"privateMessage": "Imbia messàgiu de testu privadu",
"profile": "Modìfica su profilu",
"raiseHand": "Àrtzia o abassa sa manu",
"raiseYourHand": "Àrtzia sa manu",
"Settings": "Cunfiguratzione",
"sharedvideo": "Cumpartzi unu vìdeu de YouTube",
"shareRoom": "Invita una persone",
"shortcuts": "Ammustra incurtzaduras",
"speakerStats": "Istatìsticas de partetzipante",
"startScreenSharing": "Avia sa cumpartzidura de s'ischermu",
"startSubtitles": "Avia sutatìtulos",
"stopScreenSharing": "Firma sa cumpartzidura de s'ischermu",
"stopSubtitles": "Firma sutatìtulos",
"stopSharedVideo": "Firma vìdeu de YouTube",
"talkWhileMutedPopup": "Ses chirchende de chistionare? Ses a sa muda.",
"tileViewToggle": "Càmbia a visualizatzione in mosàicu",
"toggleCamera": "Càmbia càmera",
"videomute": "Avia o firma sa càmera",
"startvideoblur": "Isfoca s'isfundu meu",
"stopvideoblur": "Disativa s'isfocadu de s'isfundu"
},
"transcribing": {
"ccButtonTooltip": "Avia o firma sutatìtulos",
"error": "Faddina in sa trascritzione. Torra·bi a proare.",
"expandedLabel": "Trascritzione ativada",
"failedToStart": "Faddina in s'aviu de sa trascritzione",
"labelToolTip": "Trascriende sa riunione",
"off": "Trascritzione firmada",
"pending": "Preparende pro trascrìere sa riunione...",
"start": "Cumintza a ammustrare sutatìtulos",
"stop": "No ammustres prus sutatìtluos",
"tr": "TR"
},
"userMedia": {
"androidGrantPermissions": "Sèbera <b><i>Permite</i></b> cando su navigadore ti dimandet permissos.",
"chromeGrantPermissions": "Sèbera <b><i>Permite</i></b> cando su navigadore ti dimandet permissos.",
"edgeGrantPermissions": "Sèbera <b><i>Eja</i></b> cando su navigadore ti dimandet permissos.",
"electronGrantPermissions": "Cuntzede permissos pro atzèdere a sa càmera e a su micròfonu tuos",
"firefoxGrantPermissions": "Sèbera <b><i>Cumpartzi dispositivos seletzionados</i></b> cando su navigadore ti dimandet permissos.",
"iexplorerGrantPermissions": "Sèbera <b><i>AB</i></b> cando su navigadore ti dimandet permissos.",
"nwjsGrantPermissions": "Cuntzede permissos pro atzèdere a sa càmera e a su micròfonu tuos",
"operaGrantPermissions": "Sèbera <b><i>Permite</i></b> cando su navigadore ti dimandet permissos.",
"react-nativeGrantPermissions": "Sèbera <b><i>Permite</i></b> cando su navigadore ti dimandet permissos.",
"safariGrantPermissions": "Sèbera <b><i>AB</i></b> cando su navigadore ti dimandet permissos."
},
"videoSIPGW": {
"busy": "Semus traballende pro liberare resursas. Torra·bi a proare dae immoe a carchi minutu.",
"busyTitle": "Su servìtziu Room est ocupadu",
"errorAlreadyInvited": "Invitu a {{displayName}} giai imbiadu",
"errorInvite": "Sa connessione no est istada istabilida. Torra·bi a proare a pustis.",
"errorInviteFailed": "Semus traballende pro acontzare su problema. Torra·bi a proare a pustis.",
"errorInviteFailedTitle": "Faddina in s'invitu de {{displayName}}",
"errorInviteTitle": "Faddina in s'aposentu de invitos",
"pending": "Invitu a {{displayName}} imbiadu"
},
"videoStatus": {
"audioOnly": "AUD",
"audioOnlyExpanded": "Ses in modalidade de àmpiu de banda bàsciu. In custa modalidade isceti su ritzevimentu de àudio e de cumpartzidura de ischermu sunt a disponimentu.",
"callQuality": "Calidade de su vìdeu",
"hd": "HD",
"hdTooltip": "Vìdeu in arta definitzione (HD)",
"highDefinition": "Arta definitzione (HD)",
"labelTooiltipNoVideo": "Sena vìdeu",
"labelTooltipAudioOnly": "Modalidade de àmpiu de banda bàsciu ativada",
"ld": "LD",
"ldTooltip": "Vìdeu in definitzione bàscia (LD)",
"lowDefinition": "Definitzione bàscia (LD)",
"onlyAudioAvailable": "Isceti àudio a disponimentu",
"onlyAudioSupported": "Custu navigadore est isceti cumpatìbile cun s'àudio.",
"p2pEnabled": "Rete a nodu terminale (p2p) ativada",
"p2pVideoQualityDescription": "In sa modalidade a nodu terminale (p2p), sa calidade de vìdeu retzida podet èssere cambiada intre arta calidade e isceti àudio. Depes essire de sa modalidade a nodu terminale pro pòdere cunfigurare àteras optziones.",
"recHighDefinitionOnly": "S'arta definitzione (HD) at a èssere preferida.",
"sd": "SD",
"sdTooltip": "Vìdeu in definitzione istandard (SD)",
"standardDefinition": "Definitzione istàndard (SD)"
},
"videothumbnail": {
"domute": "A sa muda",
"domuteOthers": "Pone totus a sa muda",
"flip": "Fùrria",
"kick": "Boga",
"moderator": "Moderadore",
"mute": "Partetzipante a sa muda",
"muted": "A sa muda",
"remoteControl": "Avia o firma su controllu remotu",
"show": "Ammustra in s'iscena",
"videomute": "Custa persone at firmadu sa càmera"
},
"welcomepage": {
"accessibilityLabel": {
"join": "Toca pro intrare",
"roomname": "Inserta su nòmine de s'aposentu"
},
"appDescription": "Bae, tzarrada de vìdeu cun totu s'iscuadra. Difatis, podes invitare totu sa gente chi connosches. {{app}} est un'aplicatzione de vìdeu-cunferèntzia de còdighe abertu 100% cun critografia cumpleta chi podes impreare cada die, totu sa die, de badas — sena perunu contu creadu.",
"audioVideoSwitch": {
"audio": "Boghe",
"video": "Vìdeu"
},
"calendar": "Calendàriu",
"connectCalendarButton": "Connete a su calendàriu tuo",
"connectCalendarText": "Connete a su calendàriu tuo pro bìdere totu is riuniones tuas in {{app}}. In prus, agiunghe riuniones de {{provider}} a su calendàriu tuo e avia·ddas cun unu clic.",
"enterRoomTitle": "Cumintza una riunione noa",
"roomNameAllowedChars": "Su nòmine de sa riunione non podet inclùdere custos caràteres: ?, &, :, ', \", %, #.",
"go": "BAE",
"goSmall": "BAE",
"join": "CREA / INTRA",
"info": "Informatziones",
"privacy": "Riservadesa",
"recentList": "Reghentes",
"recentListDelete": "Cantzella",
"recentListEmpty": "Sa lista de reghentes est bòida. Tzarra cun s'iscuadra tua e as a agatare totu is riuniones reghentes tuas inoghe.",
"reducedUIText": "Ti donamus su benebènnidu a {{app}}!",
"roomname": "Inserta su nòmine de s'aposentu",
"roomnameHint": "Inserta su nòmine o s'URL de s'aposentu a su chi boles intrare. Ti podes imbentare unu nòmine, bastat chi ddu fatzas ischire a sa gente chi ses addobiende pro chi ddu potzant insertare su pròpiu.",
"sendFeedback": "Imbia cummentos",
"terms": "Cunditziones",
"title": "Vìdeu-cunferèntzia segura, prena de funtzionalidades, lìbera e de badas",
"getHelp": "Agiudu"
},
"lonelyMeetingExperience": {
"button": "Invita gente",
"youAreAlone": "Ses a sa sola in custa riunione"
},
"helpView": {
"header": "Tzentru de agiudu"
}
}

View File

@@ -569,9 +569,9 @@
"shareYourScreen": "Slå av eller på skärmdelning",
"shortcuts": "Stäng eller öppna genvägar",
"show": "",
"speakerStats": "Stäng eller öppna högstalarstatistik",
"speakerStats": "Stäng eller öppna talarstatistik",
"tileView": "Öppna eller stäng panelvyn",
"toggleCamera": "Byta kamera",
"toggleCamera": "Växla kamera",
"videomute": "Sätt på eller stäng av mikrofonen",
"videoblur": ""
},
@@ -606,7 +606,7 @@
"sharedvideo": "Dela en Youtube-video",
"shareRoom": "Bjud in någon",
"shortcuts": "Visa genvägar",
"speakerStats": "Högtalarspecifikationer",
"speakerStats": "Talarstatistik",
"startScreenSharing": "Starta skärmdelning",
"startSubtitles": "Starta undertextning",
"stopScreenSharing": "Avsluta skämdelning",

View File

@@ -61,14 +61,13 @@
"AUTHENTICATING": "Kimlik doğrula",
"AUTHFAIL": "",
"CONNECTED": "bağlandı",
"CONNECTING": "Bağlantı:",
"CONNECTING": "Bağlanıyor",
"CONNFAIL": "",
"DISCONNECTED": "bağlantı kesildi",
"DISCONNECTING": "bağlantı kesildi",
"ERROR": "Hata",
"RECONNECTING": ""
},
"\u0005connection": {},
"connectionindicator": {
"address": "Adres:",
"bandwidth": "Tahmini bant genişliği:",
@@ -77,8 +76,10 @@
"connectedTo": "",
"framerate": "Çerçeve hızı:",
"less": "Daha az göster",
"localaddress": "Yerel adres:Yerel adresler:",
"localport": "Yerel port:Yerel portlar:",
"localaddress": "Yerel adres:",
"localaddress_plural": "Yerel adresler:",
"localport": "Yerel port:",
"localport_plural": "Yerel portlar:",
"more": "Daha fazla göster",
"packetloss": "Paket kaybı:",
"quality": {
@@ -88,16 +89,16 @@
"nonoptimal": "",
"poor": ""
},
"remoteaddress": "Uzak adres:Uzak adresler:",
"remoteport": "Uzak port:Uzak portlar:",
"remoteaddress": "Uzak adres:",
"remoteaddress_plural": "Uzak adresler:",
"remoteport": "Uzak port:",
"remoteport_plural": "Uzak portlar:",
"resolution": "Çözünürlük:",
"status": "Bağlantı:",
"transport": "Transport:",
"transport_plural": "Transportlar:",
"turn": ""
},
"\u0005connectionindicator": {
"quality": {}
},
"dateUtils": {
"earlier": "",
"today": "",
@@ -153,7 +154,7 @@
"confirmYes": "Evet",
"connectError": "Amanin boo! Birşeyler ters gitti ve görüşmeye bağlanamadık.",
"connectErrorWithMsg": "Amanin boo! Birşeyler ters gitti ve görüşmeye bağlanamadık: {{msg}}",
"connecting": "Bağlantı:",
"connecting": "Bağlanıyor",
"contactSupport": "Destek hattına bağlan",
"copy": "Kopyala",
"dismiss": "",
@@ -161,14 +162,14 @@
"done": "",
"enterDisplayName": "",
"error": "Hata",
"externalInstallationMsg": "Masaüstü paylaşım eklentisi yüklenemedi",
"externalInstallationMsg": "Masaüstü paylaşım uzantımızı yüklemeniz gerekmektedir.",
"externalInstallationTitle": "",
"goToStore": "",
"gracefulShutdown": "Hizmetimiz bakıp için durduruldu. Daha sonra tekrar deneyiniz.",
"IamHost": "",
"incorrectRoomLockPassword": "",
"incorrectPassword": "Kullanıcı adı veya parola hatalı",
"inlineInstallationMsg": "Masaüstü paylaşım eklentisi yüklenemedi",
"inlineInstallationMsg": "Masaüstü paylaşım uzantımızı yüklemeniz gerekmektedir.",
"inlineInstallExtension": "",
"internalError": "",
"internalErrorTitle": "",
@@ -257,7 +258,6 @@
"Yes": "Evet",
"yourEntireScreen": ""
},
"\u0005dialog": {},
"dialOut": {
"statusMessage": ""
},
@@ -337,7 +337,6 @@
"toggleShortcuts": "",
"videoMute": "Kamerayı aç veya kapat"
},
"\u0005keyboardShortcuts": {},
"liveStreaming": {
"busy": "",
"busyTitle": "",
@@ -429,7 +428,6 @@
"newDeviceAudioTitle": "",
"newDeviceAction": ""
},
"\u0005notify": {},
"passwordSetRemotely": "Diğer katılımcı tarafından ayarlandı",
"passwordDigitsOnly": "",
"poweredby": "Gücünün kaynağı",
@@ -437,8 +435,8 @@
"busy": "",
"calling": "",
"connected": "bağlandı",
"connecting": "Bağlantı:",
"connecting2": "Bağlantı:",
"connecting": "Bağlanıyor...",
"connecting2": "Bağlanıyor*...",
"disconnected": "bağlantı kesildi",
"expired": "",
"ignored": "",
@@ -447,14 +445,12 @@
"rejected": "",
"ringing": ""
},
"\u0005presenceStatus": {},
"profile": {
"setDisplayNameLabel": "Teşhir adınızı ayarlayın",
"setEmailInput": "E-posta adresinizi girin",
"setEmailLabel": "Gravatar e-postanızı belirleyin",
"title": ""
},
"\u0005profile": {},
"recording": {
"authDropboxText": "",
"availableSpace": "",
@@ -506,9 +502,6 @@
"startVideoMuted": "Herkes gizli başlasın",
"title": "Ayarlar"
},
"\u0005settings": {
"calendar": {}
},
"settingsView": {
"alertOk": "",
"alertTitle": "Uyarı",
@@ -546,7 +539,6 @@
"text": "Tekrar bağlanmak için <i>Geri katıl</i>'a basın.",
"title": "Görüntülü konuşmanız kesildi, çünkü bilgisayar uyku moduna girdi."
},
"\u0005suspendedoverlay": {},
"toolbar": {
"accessibilityLabel": {
"audioOnly": "",
@@ -626,7 +618,6 @@
"startvideoblur": "",
"stopvideoblur": ""
},
"\u0005toolbar": {},
"transcribing": {
"ccButtonTooltip": "",
"error": "",
@@ -643,10 +634,10 @@
"androidGrantPermissions": "Tarayıcınız izin istediğinde <b><i>İzin Ver</i></b> seçeneğini seçin.",
"chromeGrantPermissions": "Tarayıcınız izin istediğinde <b><i>İzin Ver</i></b> seçeneğini seçin.",
"edgeGrantPermissions": "Tarayıcınız izin istediğinde <b><i>Evet</i></b> seçeneğini seçin.",
"electronGrantPermissions": "Lütfen kameranızı ve mikrofonunuzu kullanmak için gereken izni sağlayın.",
"electronGrantPermissions": "Lütfen kameranızı ve mikrofonunuzu kullanmak için izin verin",
"firefoxGrantPermissions": "Tarayıcınız izin istediğinde <b><i>Seçilen Aygıtı Paylaş</i></b> seçeneğini seçin.",
"iexplorerGrantPermissions": "Tarayıcınız izin istediğinde <b><i>Tamam</i></b> seçeneğini seçin.",
"nwjsGrantPermissions": "Lütfen kameranızı ve mikrofonunuzu kullanmak için gereken izni sağlayın.",
"nwjsGrantPermissions": "Lütfen kameranızı ve mikrofonunuzu kullanmak için izin verin",
"operaGrantPermissions": "Tarayıcınız izin istediğinde <b><i>İzin Ver</i></b> seçeneğini seçin.",
"react-nativeGrantPermissions": "Tarayıcınız izin istediğinde <b><i>İzin Ver</i></b> seçeneğini seçin.",
"safariGrantPermissions": "Tarayıcınız izin istediğinde <b><i>Tamam</i></b> seçeneğini seçin."
@@ -690,7 +681,6 @@
"show": "",
"videomute": ""
},
"\u0005videothumbnail": {},
"welcomepage": {
"accessibilityLabel": {
"join": "",
@@ -718,6 +708,5 @@
"sendFeedback": "Geribildirimde bulun",
"terms": "Kurallar",
"title": ""
},
"\u0005welcomepage": {}
}
}
}

View File

@@ -220,7 +220,7 @@
"muteParticipantDialog": "Are you sure you want to mute this participant? You won't be able to unmute them, but they can unmute themselves at any time.",
"muteParticipantTitle": "Mute this participant?",
"Ok": "Ok",
"passwordLabel": "$t(lockRoomPasswordUppercase)",
"passwordLabel": "The meeting has been locked by a participant. Please enter the $t(lockRoomPassword) to join.",
"passwordNotSupported": "Setting a meeting $t(lockRoomPassword) is not supported.",
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) not supported",
"passwordRequired": "$t(lockRoomPasswordUppercase) required",
@@ -244,6 +244,7 @@
"reservationError": "Reservation system error",
"reservationErrorMsg": "Error code: {{code}}, message: {{msg}}",
"retry": "Retry",
"screenSharingAudio": "Share audio",
"screenSharingFailedToInstall": "Oops! Your screen sharing extension failed to install.",
"screenSharingFailedToInstallTitle": "Screen sharing extension failed to install",
"screenSharingFirefoxPermissionDeniedError": "Something went wrong while we were trying to share your screen. Please make sure that you have given us permission to do so. ",
@@ -394,7 +395,9 @@
"signOut": "Sign out",
"start": "Start a live stream",
"streamIdHelp": "What's this?",
"unavailableTitle": "Live Streaming unavailable"
"unavailableTitle": "Live Streaming unavailable",
"youtubeTerms": "YouTube terms of services",
"googlePrivacyPolicy": "Google Privacy Policy"
},
"localRecording": {
"clientState": {
@@ -525,6 +528,7 @@
"followMe": "Everyone follows me",
"language": "Language",
"loggedIn": "Logged in as {{name}}",
"microphones": "Microphones",
"moderator": "Moderator",
"more": "More",
"name": "Name",
@@ -532,6 +536,7 @@
"selectAudioOutput": "Audio output",
"selectCamera": "Camera",
"selectMic": "Microphone",
"speakers": "Speakers",
"startAudioMuted": "Everyone starts muted",
"startVideoMuted": "Everyone starts hidden",
"title": "Settings"
@@ -648,7 +653,7 @@
"noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider switching the device.",
"noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider switching to the suggested device.",
"noAudioSignalDialInDesc": "You can also dial-in using:",
"noAudioSignalDialInLinkDesc" : "Dial-in numbers",
"noAudioSignalDialInLinkDesc": "Dial-in numbers",
"noisyAudioInputTitle": "Your microphone appears to be noisy!",
"noisyAudioInputDesc": "It sounds like your microphone is making noise, please consider muting or changing the device.",
"openChat": "Open chat",
@@ -755,6 +760,7 @@
"connectCalendarButton": "Connect your calendar",
"connectCalendarText": "Connect your calendar to view all your meetings in {{app}}. Plus, add {{provider}} meetings to your calendar and start them with one click.",
"enterRoomTitle": "Start a new meeting",
"getHelp": "Get help",
"roomNameAllowedChars": "Meeting name should not contain any of these characters: ?, &, :, ', \", %, #.",
"go": "GO",
"goSmall": "GO",
@@ -774,5 +780,8 @@
"lonelyMeetingExperience": {
"button": "Invite others",
"youAreAlone": "You are the only one in the meeting"
},
"helpView": {
"header": "Help centre"
}
}

View File

@@ -184,7 +184,7 @@ export default class LargeVideoManager {
this.newStreamData = null;
logger.info('hover in %s', id);
logger.info(`hover in ${id}`);
this.state = videoType;
// eslint-disable-next-line no-shadow
const container = this.getCurrentContainer();

19
package-lock.json generated
View File

@@ -10653,8 +10653,8 @@
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
},
"js-utils": {
"version": "github:jitsi/js-utils#91c5e53ca5fa42907c88d56bc78254e6e56e058d",
"from": "github:jitsi/js-utils#91c5e53ca5fa42907c88d56bc78254e6e56e058d",
"version": "github:jitsi/js-utils#0b2cef90613a74777fefd98d4ee3eda3879809ab",
"from": "github:jitsi/js-utils#0b2cef90613a74777fefd98d4ee3eda3879809ab",
"requires": {
"bowser": "2.7.0",
"js-md5": "0.7.3",
@@ -10883,8 +10883,8 @@
}
},
"lib-jitsi-meet": {
"version": "github:jitsi/lib-jitsi-meet#a7950f8ebb489225c2e8bf41fe65f330b3de0874",
"from": "github:jitsi/lib-jitsi-meet#a7950f8ebb489225c2e8bf41fe65f330b3de0874",
"version": "github:jitsi/lib-jitsi-meet#960eea3c5087ce07e9135fad70268c7d338e0de5",
"from": "github:jitsi/lib-jitsi-meet#960eea3c5087ce07e9135fad70268c7d338e0de5",
"requires": {
"@jitsi/sdp-interop": "0.1.14",
"@jitsi/sdp-simulcast": "0.2.2",
@@ -10897,7 +10897,7 @@
"strophe.js": "1.3.4",
"strophejs-plugin-disco": "0.0.2",
"strophejs-plugin-stream-management": "github:jitsi/strophejs-plugin-stream-management#cec7608601c1bc098543823fc658e3ddf758c009",
"webrtc-adapter": "github:webrtc/adapter#1eec19782b4058d186341263e7d049cea3e3290a"
"webrtc-adapter": "7.5.0"
},
"dependencies": {
"js-md5": {
@@ -18999,11 +18999,12 @@
}
},
"webrtc-adapter": {
"version": "github:webrtc/adapter#1eec19782b4058d186341263e7d049cea3e3290a",
"from": "github:webrtc/adapter#1eec19782b4058d186341263e7d049cea3e3290a",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.5.0.tgz",
"integrity": "sha512-cUqlw310uLLSYvO8FTNCVmGWSMlMt6vuSDkcYL1nW+RUvAILJ3jEIvAUgFQU5EFGnU+mf9/No14BFv3U+hoxBQ==",
"requires": {
"rtcpeerconnection-shim": "^1.1.13",
"sdp": "^2.3.0"
"rtcpeerconnection-shim": "^1.2.15",
"sdp": "^2.12.0"
}
},
"websocket-driver": {

View File

@@ -53,10 +53,10 @@
"jquery-contextmenu": "2.4.5",
"jquery-i18next": "1.2.1",
"js-md5": "0.6.1",
"js-utils": "github:jitsi/js-utils#91c5e53ca5fa42907c88d56bc78254e6e56e058d",
"js-utils": "github:jitsi/js-utils#0b2cef90613a74777fefd98d4ee3eda3879809ab",
"jsrsasign": "8.0.12",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#a7950f8ebb489225c2e8bf41fe65f330b3de0874",
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#960eea3c5087ce07e9135fad70268c7d338e0de5",
"libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
"lodash": "4.17.13",
"moment": "2.19.4",

View File

@@ -89,10 +89,22 @@ export class AbstractApp extends BaseApp<Props, *> {
return (
<Fragment>
<OverlayContainer />
{ this._createExtraPlatformSpecificElement() }
</Fragment>
);
}
/**
* Renders platform specific extra elements to be added alongside with the main element, if need be.
*
* NOTE: Overridden by child components.
*
* @returns {React$Element}
*/
_createExtraPlatformSpecificElement() {
return null;
}
_createMainElement: (React$Element<*>, Object) => ?React$Element<*>;
/**

View File

@@ -12,6 +12,7 @@ import { Platform } from '../../base/react';
import '../../base/responsive-ui';
import { updateSettings } from '../../base/settings';
import '../../google-api';
import { HelpView } from '../../help';
import '../../mobile/audio-mode';
import '../../mobile/back-button';
import '../../mobile/background';
@@ -107,6 +108,17 @@ export class App extends AbstractApp {
});
}
/**
* Renders platform specific extra elements to be added alongside with the main element, if need be.
*
* @inheritdoc
*/
_createExtraPlatformSpecificElement() {
return (
<HelpView />
);
}
/**
* Attempts to disable the use of React Native
* {@link ExceptionsManager#handleException} on platforms and in

View File

@@ -39,6 +39,7 @@ export default {
statusBarContent: ColorPalette.white,
text: ColorPalette.white
},
'Modal': {},
'LargeVideo': {
background: 'rgb(42, 58, 75)'
},

View File

@@ -1,3 +1,5 @@
import extraConfigWhitelist from './extraConfigWhitelist';
/**
* The config keys to whitelist, the keys that can be overridden.
* Currently we can only whitelist the first part of the properties, like
@@ -145,4 +147,4 @@ export default [
'useStunTurn',
'webrtcIceTcpDisable',
'webrtcIceUdpDisable'
];
].concat(extraConfigWhitelist);

View File

@@ -0,0 +1,4 @@
/**
* Deploy-specific configuration whitelists
*/
export default [];

View File

@@ -216,6 +216,18 @@ export function setAudioInputDevice(deviceId) {
};
}
/**
* Updates the output device id.
*
* @param {string} deviceId - The id of the new output device.
* @returns {Function}
*/
export function setAudioOutputDevice(deviceId) {
return function(dispatch) {
return setAudioOutputDeviceId(deviceId, dispatch);
};
}
/**
* Signals to update the currently used video input device.
*

View File

@@ -174,6 +174,60 @@ export function formatDeviceLabel(label: string) {
return formattedLabel;
}
/**
* Returns a list of objects containing all the microphone device ids and labels.
*
* @param {Object} state - The state of the application.
* @returns {Object[]}
*/
export function getAudioInputDeviceData(state: Object) {
return state['features/base/devices'].availableDevices.audioInput.map(
({ deviceId, label }) => {
return {
deviceId,
label
};
});
}
/**
* Returns a list of objectes containing all the output device ids and labels.
*
* @param {Object} state - The state of the application.
* @returns {Object[]}
*/
export function getAudioOutputDeviceData(state: Object) {
return state['features/base/devices'].availableDevices.audioOutput.map(
({ deviceId, label }) => {
return {
deviceId,
label
};
});
}
/**
* Returns a list of all the camera device ids.
*
* @param {Object} state - The state of the application.
* @returns {string[]}
*/
export function getVideoDeviceIds(state: Object) {
return state['features/base/devices'].availableDevices.videoInput.map(({ deviceId }) => deviceId);
}
/**
* Returns true if there are devices of a specific type.
*
* @param {Object} state - The state of the application.
* @param {string} type - The type of device: VideoOutput | audioOutput | audioInput.
*
* @returns {boolean}
*/
export function hasAvailableDevices(state: Object, type: string) {
return state['features/base/devices'].availableDevices[type].length > 0;
}
/**
* Set device id of the audio output device which is currently in use.
* Empty string stands for default device.

View File

@@ -0,0 +1,3 @@
<svg width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.07001 0.248238C8.3471 -0.0596449 8.82132 -0.0846038 9.1292 0.192491C9.43709 0.469585 9.46205 0.943802 9.18495 1.25168L5.65622 5.19348C5.35829 5.52451 4.83922 5.52451 4.54128 5.19348L1.06752 1.25168C0.79043 0.943802 0.81539 0.469585 1.12327 0.192491C1.43115 -0.0846038 1.90537 -0.0596449 2.18247 0.248238L5.09875 3.57062L8.07001 0.248238Z" fill="#5E6D7A"/>
</svg>

After

Width:  |  Height:  |  Size: 509 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 14.6667C4.3181 14.6667 1.33333 11.682 1.33333 8.00007C1.33333 4.31817 4.3181 1.3334 8 1.3334C11.6819 1.3334 14.6667 4.31817 14.6667 8.00007C14.6667 11.682 11.6819 14.6667 8 14.6667ZM7.33333 4.66676C7.33333 4.29857 7.6318 4.00009 8 4.00009C8.36819 4.00009 8.66666 4.29857 8.66666 4.66676V8.00009C8.66666 8.36828 8.36819 8.66676 8 8.66676C7.6318 8.66676 7.33333 8.36828 7.33333 8.00009V4.66676ZM8 10.0001C7.63181 10.0001 7.33333 10.2985 7.33333 10.6667C7.33333 11.0349 7.63181 11.3334 8 11.3334C8.36818 11.3334 8.66666 11.0349 8.66666 10.6667C8.66666 10.2985 8.36818 10.0001 8 10.0001Z" />
</svg>

After

Width:  |  Height:  |  Size: 731 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.33331 8.00004C1.33331 11.6819 4.31808 14.6667 7.99998 14.6667C11.6819 14.6667 14.6666 11.6819 14.6666 8.00004C14.6666 4.31814 11.6819 1.33337 7.99998 1.33337C4.31808 1.33337 1.33331 4.31814 1.33331 8.00004ZM13.3333 8.00005C13.3333 10.9456 10.9455 13.3334 7.99998 13.3334C5.05446 13.3334 2.66665 10.9456 2.66665 8.00005C2.66665 5.05453 5.05446 2.66672 7.99998 2.66672C10.9455 2.66672 13.3333 5.05453 13.3333 8.00005ZM7.33331 4.66673C7.33331 4.29854 7.63179 4.00006 7.99998 4.00006C8.36817 4.00006 8.66665 4.29854 8.66665 4.66673V8.00006C8.66665 8.36825 8.36817 8.66673 7.99998 8.66673C7.63179 8.66673 7.33331 8.36825 7.33331 8.00006V4.66673ZM7.99998 10C7.63179 10 7.33331 10.2985 7.33331 10.6667C7.33331 11.0349 7.63179 11.3334 7.99998 11.3334C8.36817 11.3334 8.66665 11.0349 8.66665 10.6667C8.66665 10.2985 8.36817 10 7.99998 10Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1001 B

View File

@@ -3,6 +3,7 @@
export { default as IconAdd } from './add.svg';
export { default as IconAddPeople } from './link.svg';
export { default as IconArrowBack } from './arrow_back.svg';
export { default as IconArrowDown } from './arrow_down.svg';
export { default as IconAudioOnly } from './visibility.svg';
export { default as IconAudioOnlyOff } from './visibility-off.svg';
export { default as IconAudioRoute } from './volume.svg';
@@ -27,6 +28,8 @@ export { default as IconDominantSpeaker } from './dominant-speaker.svg';
export { default as IconDownload } from './download.svg';
export { default as IconDragHandle } from './drag-handle.svg';
export { default as IconEventNote } from './event_note.svg';
export { default as IconExclamation } from './exclamation.svg';
export { default as IconExclamationSolid } from './exclamation-solid.svg';
export { default as IconExitFullScreen } from './exit-full-screen.svg';
export { default as IconFeedback } from './feedback.svg';
export { default as IconFullScreen } from './full-screen.svg';
@@ -41,8 +44,10 @@ export { default as IconMenuDown } from './menu-down.svg';
export { default as IconMenuThumb } from './thumb-menu.svg';
export { default as IconMenuUp } from './menu-up.svg';
export { default as IconMessage } from './message.svg';
export { default as IconMeter } from './meter.svg';
export { default as IconMicDisabled } from './mic-disabled.svg';
export { default as IconMicrophone } from './microphone.svg';
export { default as IconMicrophoneEmpty } from './microphone-empty.svg';
export { default as IconModerator } from './star.svg';
export { default as IconMuteEveryone } from './mute-everyone.svg';
export { default as IconMuteEveryoneElse } from './mute-everyone-else.svg';
@@ -76,3 +81,4 @@ export { default as IconVideoQualityHD } from './HD.svg';
export { default as IconVideoQualityLD } from './LD.svg';
export { default as IconVideoQualitySD } from './SD.svg';
export { default as IconVolume } from './volume.svg';
export { default as IconVolumeEmpty } from './volume-empty.svg';

View File

@@ -0,0 +1,10 @@
<svg width="38" height="12" viewBox="0 0 38 12" fill="#5E6D7A" xmlns="http://www.w3.org/2000/svg">
<rect width="3" height="12" rx="1"/>
<rect x="5" width="3" height="12" rx="1" />
<rect x="10" width="3" height="12" rx="1" />
<rect x="15" width="3" height="12" rx="1" />
<rect x="20" width="3" height="12" rx="1" />
<rect x="25" width="3" height="12" rx="1" />
<rect x="30" width="3" height="12" rx="1" />
<rect x="35" width="3" height="12" rx="1" />
</svg>

After

Width:  |  Height:  |  Size: 457 B

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 6C16 3.79086 14.2091 2 12 2C9.79086 2 8 3.79086 8 6V12C8 13.8666 9.27853 15.4346 11.0076 15.8759C11.0026 15.9166 11 15.958 11 16V17.917C8.16229 17.441 6 14.973 6 12C6 11.4477 5.55228 11 5 11C4.44772 11 4 11.4477 4 12C4 16.0796 7.05369 19.446 11 19.9381V21C11 21.5523 11.4477 22 12 22C12.5523 22 13 21.5523 13 21V19.9381C16.9463 19.446 20 16.0796 20 12C20 11.4477 19.5523 11 19 11C18.4477 11 18 11.4477 18 12C18 14.973 15.8377 17.441 13 17.917V16C13 15.958 12.9974 15.9166 12.9924 15.8759C14.7215 15.4346 16 13.8666 16 12V6ZM12 4C10.8954 4 10 4.89543 10 6V12C10 13.1046 10.8954 14 12 14C13.1046 14 14 13.1046 14 12V6C14 4.89543 13.1046 4 12 4Z" fill="#A4B8D1"/>
</svg>

After

Width:  |  Height:  |  Size: 817 B

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.1799 3.68341L6 8H3C2.44772 8 2 8.44771 2 9V15C2 15.5523 2.44772 16 3 16H6L11.1799 20.3166C11.2698 20.3915 11.383 20.4325 11.5 20.4325C11.7761 20.4325 12 20.2086 12 19.9325V4.06752C12 3.95055 11.959 3.83728 11.8841 3.74743C11.7073 3.53529 11.392 3.50662 11.1799 3.68341ZM4 10H6.7241L10 7.27008V16.7299L6.7241 14H4V10ZM14 8C16.2091 8 18 9.79086 18 12C18 14.2091 16.2091 16 14 16V14C15.1046 14 16 13.1046 16 12C16 10.8954 15.1046 10 14 10V8ZM14 4C18.4183 4 22 7.58172 22 12C22 16.4183 18.4183 20 14 20V18C17.3137 18 20 15.3137 20 12C20 8.68629 17.3137 6 14 6V4Z" fill="#A4B8D1"/>
</svg>

After

Width:  |  Height:  |  Size: 733 B

View File

@@ -0,0 +1,6 @@
// @flow
/**
* Action type to set the ID of the active modal (or undefined if needs to be hidden).
*/
export const SET_ACTIVE_MODAL_ID = 'SET_ACTIVE_MODAL_ID';

View File

@@ -0,0 +1,19 @@
// @flow
import { SET_ACTIVE_MODAL_ID } from './actionTypes';
/**
* Action to set the ID of the active modal (or undefined if needs to be hidden).
*
* @param {string} activeModalId - The new modal ID or undefined.
* @returns {{
* activeModalId: string,
* type: SET_ACTIVE_MODAL_ID
* }}
*/
export function setActiveModalId(activeModalId: ?string) {
return {
activeModalId,
type: SET_ACTIVE_MODAL_ID
};
}

View File

@@ -0,0 +1,151 @@
// @flow
import React, { PureComponent } from 'react';
import { SafeAreaView, View } from 'react-native';
import { ColorSchemeRegistry } from '../../color-scheme';
import { HeaderWithNavigation, SlidingView } from '../../react';
import { connect } from '../../redux';
import { StyleType } from '../../styles';
import { setActiveModalId } from '../actions';
import styles from './styles';
type Props = {
/**
* The color schemed style of the common header component.
*/
_headerStyles: StyleType,
/**
* True if the modal should be shown, false otherwise.
*/
_show: boolean,
/**
* The color schemed style of the modal.
*/
_styles: StyleType,
/**
* The children component(s) of the Modal, to be rendered.
*/
children: React$Node,
/**
* The Redux Dispatch function.
*/
dispatch: Function,
/**
* The i18n label key of the header title.
*/
headerLabelKey: string,
/**
* The ID of the modal that is being rendered. This is used to show/hide the modal.
*/
modalId: string,
/**
* Callback to be invoked when the modal closes.
*/
onClose?: Function,
/**
* The position from where the modal should be opened. This is derived from the
* props of the {@code SlidingView} with the same name.
*/
position?: string
};
/**
* Implements a custom Jitsi Modal that doesn't use the built in native
* Modal component of React Native.
*/
class JitsiModal extends PureComponent<Props> {
static defaultProps = {
position: 'bottom'
};
/**
* Instantiates a new component.
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this._onRequestClose = this._onRequestClose.bind(this);
}
/**
* Implements {@code PureComponent#render}.
*
* @inheritdoc
*/
render() {
const { _headerStyles, _show, _styles, children, headerLabelKey, position } = this.props;
return (
<SlidingView
onHide = { this._onRequestClose }
position = { position }
show = { _show }>
<View
style = { [
_headerStyles.page,
_styles.page
] }>
<HeaderWithNavigation
headerLabelKey = { headerLabelKey }
onPressBack = { this._onRequestClose } />
<SafeAreaView style = { styles.safeArea }>
{ children }
</SafeAreaView>
</View>
</SlidingView>
);
}
_onRequestClose: () => boolean;
/**
* Callback to be invoked when the SlidingView requests closing.
*
* @returns {boolean}
*/
_onRequestClose() {
const { _show, dispatch, onClose } = this.props;
if (_show) {
if (typeof onClose === 'function') {
onClose();
}
dispatch(setActiveModalId());
return true;
}
return false;
}
}
/**
* Maps part of the Redix state to the props of this component.
*
* @param {Object} state - The Redux state.
* @param {Props} ownProps - The own props of the component.
* @returns {Props}
*/
function _mapStateToProps(state, ownProps): $Shape<Props> {
return {
_headerStyles: ColorSchemeRegistry.get(state, 'Header'),
_show: state['features/base/modal'].activeModalId === ownProps.modalId,
_styles: ColorSchemeRegistry.get(state, 'Modal')
};
}
export default connect(_mapStateToProps)(JitsiModal);

View File

@@ -0,0 +1,3 @@
// @flow
export { default as JitsiModal } from './JitsiModal';

View File

@@ -0,0 +1,6 @@
// @flow
import { Component } from 'react';
export const JitsiModal = Component;

View File

@@ -0,0 +1,15 @@
// @flow
import { ColorSchemeRegistry, schemeColor } from '../../color-scheme';
export default {
safeArea: {
flex: 1
}
};
ColorSchemeRegistry.register('Modal', {
page: {
backgroundColor: schemeColor('background')
}
});

View File

@@ -0,0 +1,7 @@
// @flow
import './reducer';
export * from './actions';
export * from './actionTypes';
export * from './components';

View File

@@ -0,0 +1,17 @@
// @flow
import { ReducerRegistry } from '../redux';
import { SET_ACTIVE_MODAL_ID } from './actionTypes';
ReducerRegistry.register('features/base/modal', (state = {}, action) => {
switch (action.type) {
case SET_ACTIVE_MODAL_ID:
return {
...state,
activeModalId: action.activeModalId
};
}
return state;
});

View File

@@ -2,6 +2,36 @@
export * from './functions.any';
/**
* Returns the deviceId for the currently used camera.
*
* @param {Object} state - The state of the application.
* @returns {void}
*/
export function getCurrentCameraDeviceId(state: Object) {
return state['features/base/settings'].cameraDeviceId;
}
/**
* Returns the deviceId for the currently used microphone.
*
* @param {Object} state - The state of the application.
* @returns {void}
*/
export function getCurrentMicDeviceId(state: Object) {
return state['features/base/settings'].micDeviceId;
}
/**
* Returns the deviceId for the currently used speaker.
*
* @param {Object} state - The state of the application.
* @returns {void}
*/
export function getCurrentOutputDeviceId(state: Object) {
return state['features/base/settings'].audioOutputDeviceId;
}
/**
* Handles changes to the `disableCallIntegration` setting.
* Noop on web.

View File

@@ -230,13 +230,14 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
/**
* Helper function to be implemented by subclasses, which must return a
* {@code boolean} value indicating if this button is toggled or not.
* {@code boolean} value indicating if this button is toggled or not or
* undefined if the button is not toggleable.
*
* @protected
* @returns {boolean}
* @returns {?boolean}
*/
_isToggled() {
return false;
return undefined;
}
_onClick: (*) => void;

View File

@@ -0,0 +1,137 @@
// @flow
import React, { Component } from 'react';
import { Icon } from '../../icons';
type Props = {
/**
* The decorated component (ToolboxButton).
*/
children: React$Node,
/**
* Icon of the button.
*/
icon: Function,
/**
* Flag used for disabling the small icon.
*/
iconDisabled: boolean,
/**
* Click handler for the small icon.
*/
onIconClick: Function,
/**
* Additional styles.
*/
styles?: Object,
};
type State = {
/**
* Whether the button is hovered or not.
*/
isHovered: boolean,
};
/**
* Displayes the `ToolboxButtonWithIcon` component.
*
* @returns {ReactElement}
*/
export default class ToolboxButtonWithIcon extends Component<Props, State> {
/**
* Initializes a new {@code ToolboxButtonWithIcon} instance.
*
* @param {Props} props - The props of the component.
*/
constructor(props: Props) {
super(props);
this.state = {
isHovered: false
};
this._onMouseEnter = this._onMouseEnter.bind(this);
this._onMouseLeave = this._onMouseLeave.bind(this);
}
_onMouseEnter: () => void;
/**
* Handler for when the small button has the mouse over.
*
* @returns {void}.
*/
_onMouseEnter() {
this.setState({
isHovered: true
});
}
_onMouseLeave: () => void;
/**
* Handler for when the mouse leaves the small button.
*
* @returns {void}
*/
_onMouseLeave() {
this.setState({
isHovered: false
});
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {React$Node}
*/
render() {
const {
children,
icon,
iconDisabled,
onIconClick,
styles
} = this.props;
const iconProps = {};
let size = 9;
if (iconDisabled) {
iconProps.className
= 'settings-button-small-icon settings-button-small-icon--disabled';
} else {
iconProps.className = 'settings-button-small-icon';
iconProps.onClick = onIconClick;
if (this.state.isHovered) {
iconProps.className = `${iconProps.className} settings-button-small-icon--hovered`;
size = 11;
}
}
return (
<div
className = 'settings-button-container'
styles = { styles }>
{children}
<div
onMouseEnter = { this._onMouseEnter }
onMouseLeave = { this._onMouseLeave }>
<Icon
{ ...iconProps }
size = { size }
src = { icon } />
</div>
</div>
);
}
}

View File

@@ -12,6 +12,69 @@ import type { Props } from './AbstractToolboxItem';
* Web implementation of {@code AbstractToolboxItem}.
*/
export default class ToolboxItem extends AbstractToolboxItem<Props> {
/**
* Initializes a new {@code ToolboxItem} instance.
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this._onKeyDown = this._onKeyDown.bind(this);
this._onKeyUp = this._onKeyUp.bind(this);
}
_onKeyDown: (Object) => void;
/**
* Handles 'Enter' key on the button to trigger onClick for accessibility.
*
* @param {Object} event - The key event.
* @private
* @returns {void}
*/
_onKeyDown(event) {
// If the event coming to the dialog has been subject to preventDefault
// we don't handle it here.
if (event.defaultPrevented) {
return;
}
if (event.key === 'Enter') {
event.preventDefault();
event.stopPropagation();
this.props.onClick();
} else if (event.key === ' ') {
// Space triggers button onKeyUp but we need to prevent PTT here
event.preventDefault();
event.stopPropagation();
}
}
_onKeyUp: (Object) => void;
/**
* Handles ' ' (Space) key on the button to trigger onClick for
* accessibility.
*
* @param {Object} event - The key event.
* @private
* @returns {void}
*/
_onKeyUp(event) {
// If the event coming to the dialog has been subject to preventDefault
// we don't handle it here.
if (event.defaultPrevented) {
return;
}
if (event.key === ' ') {
event.preventDefault();
event.stopPropagation();
this.props.onClick();
}
}
/**
* Handles rendering of the actual item. If the label is being shown, which
* is controlled with the `showLabel` prop, the item is rendered for its
@@ -27,14 +90,22 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
elementAfter,
onClick,
showLabel,
tooltipPosition
tooltipPosition,
toggled
} = this.props;
const className = showLabel ? 'overflow-menu-item' : 'toolbox-button';
const props = {
'aria-pressed': toggled,
'aria-disabled': disabled,
'aria-label': this.accessibilityLabel,
className: className + (disabled ? ' disabled' : ''),
onClick: disabled ? undefined : onClick
onClick: disabled ? undefined : onClick,
onKeyDown: this._onKeyDown,
onKeyUp: this._onKeyUp,
tabIndex: 0,
role: 'button'
};
const elementType = showLabel ? 'li' : 'div';
const useTooltip = this.tooltip && this.tooltip.length > 0;
let children = (

View File

@@ -7,3 +7,4 @@ export { default as AbstractHangupButton } from './AbstractHangupButton';
export { default as AbstractVideoMuteButton } from './AbstractVideoMuteButton';
export { default as BetaTag } from './BetaTag';
export { default as OverflowMenuItem } from './OverflowMenuItem';
export { default as ToolboxButtonWithIcon } from './ToolboxButtonWithIcon';

View File

@@ -1,18 +1,18 @@
// @flow
import React from 'react';
import { KeyboardAvoidingView, SafeAreaView } from 'react-native';
import { KeyboardAvoidingView } from 'react-native';
import { ColorSchemeRegistry } from '../../../base/color-scheme';
import { translate } from '../../../base/i18n';
import { HeaderWithNavigation, SlidingView } from '../../../base/react';
import { JitsiModal } from '../../../base/modal';
import { connect } from '../../../base/redux';
import { StyleType } from '../../../base/styles';
import { CHAT_VIEW_MODAL_ID } from '../../constants';
import AbstractChat, {
_mapDispatchToProps,
_mapStateToProps as _abstractMapStateToProps,
type Props as AbstractProps
_mapStateToProps,
type Props
} from '../AbstractChat';
import ChatInputBar from './ChatInputBar';
@@ -20,88 +20,31 @@ import MessageContainer from './MessageContainer';
import MessageRecipient from './MessageRecipient';
import styles from './styles';
type Props = AbstractProps & {
/**
* The color-schemed stylesheet of the feature.
*/
_styles: StyleType
};
/**
* Implements a React native component that renders the chat window (modal) of
* the mobile client.
*/
class Chat extends AbstractChat<Props> {
/**
* Instantiates a new instance.
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this._onClose = this._onClose.bind(this);
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
*/
render() {
const { _styles } = this.props;
return (
<SlidingView
onHide = { this._onClose }
position = 'bottom'
show = { this.props._isOpen } >
<JitsiModal
headerLabelKey = 'chat.title'
modalId = { CHAT_VIEW_MODAL_ID }>
<KeyboardAvoidingView
behavior = 'padding'
style = { styles.chatContainer }>
<HeaderWithNavigation
headerLabelKey = 'chat.title'
onPressBack = { this._onClose } />
<SafeAreaView style = { _styles.backdrop }>
<MessageContainer messages = { this.props._messages } />
<MessageRecipient />
<ChatInputBar onSend = { this.props._onSendMessage } />
</SafeAreaView>
<MessageContainer messages = { this.props._messages } />
<MessageRecipient />
<ChatInputBar onSend = { this.props._onSendMessage } />
</KeyboardAvoidingView>
</SlidingView>
</JitsiModal>
);
}
_onClose: () => boolean
/**
* Closes the chat window.
*
* @returns {boolean}
*/
_onClose() {
if (this.props._isOpen) {
this.props._onToggleChat();
return true;
}
return false;
}
}
/**
* Maps part of the redux state to the props of this component.
*
* @param {Object} state - The Redux state.
* @returns {Props}
*/
function _mapStateToProps(state) {
return {
..._abstractMapStateToProps(state),
_styles: ColorSchemeRegistry.get(state, 'Chat')
};
}
export default translate(connect(_mapStateToProps, _mapDispatchToProps)(Chat));

View File

@@ -1,6 +1,7 @@
// @flow
import { IconChat, IconChatUnread } from '../../../base/icons';
import { setActiveModalId } from '../../../base/modal';
import { getLocalParticipant } from '../../../base/participants';
import { connect } from '../../../base/redux';
import {
@@ -9,7 +10,7 @@ import {
} from '../../../base/toolbox';
import { openDisplayNamePrompt } from '../../../display-name';
import { toggleChat } from '../../actions';
import { CHAT_VIEW_MODAL_ID } from '../../constants';
import { getUnreadCount } from '../../functions';
type Props = AbstractButtonProps & {
@@ -93,7 +94,7 @@ function _mapDispatchToProps(dispatch: Function) {
* @returns {void}
*/
_displayChat() {
dispatch(toggleChat());
dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
},
/**

View File

@@ -5,7 +5,6 @@ import { TextInput, TouchableOpacity, View } from 'react-native';
import { translate } from '../../../base/i18n';
import { Icon, IconChatSend } from '../../../base/icons';
import { Platform } from '../../../base/react';
import styles from './styles';
@@ -136,7 +135,7 @@ class ChatInputBar extends Component<Props, State> {
*/
_onFocused(focused) {
return () => {
Platform.OS === 'android' && this.setState({
this.setState({
addPadding: focused
});
};

View File

@@ -1,5 +1,7 @@
// @flow
export const CHAT_VIEW_MODAL_ID = 'chatView';
/**
* The audio ID of the audio element for which the {@link playAudio} action is
* triggered when new chat message is received.

View File

@@ -1,5 +1,6 @@
// @flow
import { SET_ACTIVE_MODAL_ID } from '../base/modal';
import { ReducerRegistry } from '../base/redux';
import {
@@ -8,6 +9,7 @@ import {
SET_PRIVATE_MESSAGE_RECIPIENT,
TOGGLE_CHAT
} from './actionTypes';
import { CHAT_VIEW_MODAL_ID } from './constants';
const DEFAULT_STATE = {
isOpen: false,
@@ -56,6 +58,12 @@ ReducerRegistry.register('features/chat', (state = DEFAULT_STATE, action) => {
messages: []
};
case SET_ACTIVE_MODAL_ID:
if (action.activeModalId === CHAT_VIEW_MODAL_ID) {
return updateChatState(state);
}
break;
case SET_PRIVATE_MESSAGE_RECIPIENT:
return {
...state,
@@ -64,14 +72,24 @@ ReducerRegistry.register('features/chat', (state = DEFAULT_STATE, action) => {
};
case TOGGLE_CHAT:
return {
...state,
isOpen: !state.isOpen,
lastReadMessage: state.messages[
navigator.product === 'ReactNative' ? 0 : state.messages.length - 1],
privateMessageRecipient: state.isOpen ? undefined : state.privateMessageRecipient
};
return updateChatState(state);
}
return state;
});
/**
* Updates the chat status on opening the chat view.
*
* @param {Object} state - The Redux state of the feature.
* @returns {Object}
*/
function updateChatState(state) {
return {
...state,
isOpen: !state.isOpen,
lastReadMessage: state.messages[
navigator.product === 'ReactNative' ? 0 : state.messages.length - 1],
privateMessageRecipient: state.isOpen ? undefined : state.privateMessageRecipient
};
}

View File

@@ -8,6 +8,7 @@ import VideoLayout from '../../../../../modules/UI/videolayout/VideoLayout';
import { connect, disconnect } from '../../../base/connection';
import { translate } from '../../../base/i18n';
import { connect as reactReduxConnect } from '../../../base/redux';
import { getBackendSafeRoomName } from '../../../base/util';
import { Chat } from '../../../chat';
import { Filmstrip } from '../../../filmstrip';
import { CalleeInfoContainer } from '../../../invite';
@@ -78,6 +79,11 @@ type Props = AbstractProps & {
*/
_layoutClassName: string,
/**
* Name for this conference room.
*/
_roomName: string,
dispatch: Function,
t: Function
}
@@ -120,7 +126,7 @@ class Conference extends AbstractConference<Props, *> {
* @inheritdoc
*/
componentDidMount() {
document.title = interfaceConfig.APP_NAME;
document.title = `${this.props._roomName} | ${interfaceConfig.APP_NAME}`;
this._start();
}
@@ -259,11 +265,13 @@ class Conference extends AbstractConference<Props, *> {
*/
function _mapStateToProps(state) {
const currentLayout = getCurrentLayout(state);
const roomName = getBackendSafeRoomName(state['features/base/conference'].room);
return {
...abstractMapStateToProps(state),
_iAmRecorder: state['features/base/config'].iAmRecorder,
_layoutClassName: LAYOUT_CLASSNAMES[currentLayout]
_layoutClassName: LAYOUT_CLASSNAMES[currentLayout],
_roomName: roomName
};
}

View File

@@ -74,6 +74,11 @@ type Props = {
*/
type State = {
/**
* The state of the audio screen share checkbox.
*/
screenShareAudio: boolean,
/**
* The currently higlighted DesktopCapturerSource.
*/
@@ -128,6 +133,7 @@ class DesktopPicker extends PureComponent<Props, State> {
_poller = null;
state = {
screenShareAudio: false,
selectedSource: {},
selectedTab: 0,
sources: {},
@@ -153,6 +159,7 @@ class DesktopPicker extends PureComponent<Props, State> {
// Bind event handlers so they are only bound once per instance.
this._onCloseModal = this._onCloseModal.bind(this);
this._onPreviewClick = this._onPreviewClick.bind(this);
this._onShareAudioChecked = this._onShareAudioChecked.bind(this);
this._onSubmit = this._onSubmit.bind(this);
this._onTabSelected = this._onTabSelected.bind(this);
this._updateSources = this._updateSources.bind(this);
@@ -241,7 +248,7 @@ class DesktopPicker extends PureComponent<Props, State> {
return selectedSource;
}
_onCloseModal: (?string, string) => void;
_onCloseModal: (?string, string, ?boolean) => void;
/**
* Dispatches an action to hide the DesktopPicker and invokes the passed in
@@ -251,10 +258,12 @@ class DesktopPicker extends PureComponent<Props, State> {
* the onSourceChoose callback.
* @param {string} type - The type of the DesktopCapturerSource to pass into
* the onSourceChoose callback.
* @param {boolean} screenShareAudio - Whether or not to add system audio to
* screen sharing session.
* @returns {void}
*/
_onCloseModal(id = '', type) {
this.props.onSourceChoose(id, type);
_onCloseModal(id = '', type, screenShareAudio = false) {
this.props.onSourceChoose(id, type, screenShareAudio);
this.props.dispatch(hideDialog());
}
@@ -285,9 +294,9 @@ class DesktopPicker extends PureComponent<Props, State> {
* @returns {void}
*/
_onSubmit() {
const { id, type } = this.state.selectedSource;
const { selectedSource: { id, type }, screenShareAudio } = this.state;
this._onCloseModal(id, type);
this._onCloseModal(id, type, screenShareAudio);
}
_onTabSelected: () => void;
@@ -306,12 +315,29 @@ class DesktopPicker extends PureComponent<Props, State> {
const { types, sources } = this.state;
this._selectedTabType = types[tabIndex];
// When we change tabs also reset the screenShareAudio state so we don't
// use the option from one tab when sharing from another.
this.setState({
screenShareAudio: false,
selectedSource: this._getSelectedSource(sources),
selectedTab: tabIndex
});
}
_onShareAudioChecked: (boolean) => void;
/**
* Set the screenSharingAudio state indicating whether or not to also share
* system audio.
*
* @param {boolean} checked - Share audio or not.
* @returns {void}
*/
_onShareAudioChecked(checked) {
this.setState({ screenShareAudio: checked });
}
/**
* Configures and renders the tabs for display.
*
@@ -328,7 +354,8 @@ class DesktopPicker extends PureComponent<Props, State> {
content: <DesktopPickerPane
key = { type }
onClick = { this._onPreviewClick }
onDoubleClick = { this._onCloseModal }
onDoubleClick = { this._onSubmit }
onShareAudioChecked = { this._onShareAudioChecked }
selectedSourceId = { selectedSource.id }
sources = { sources[type] }
type = { type } />,

View File

@@ -1,8 +1,12 @@
/* @flow */
import { Checkbox } from '@atlaskit/checkbox';
import Spinner from '@atlaskit/spinner';
import React, { Component } from 'react';
import { Platform } from '../../base/react';
import { translate } from '../../base/i18n';
import DesktopSourcePreview from './DesktopSourcePreview';
/**
@@ -20,6 +24,11 @@ type Props = {
*/
onDoubleClick: Function,
/**
* The handler to be invoked if the users checks the audio screen sharing checkbox.
*/
onShareAudioChecked: Function,
/**
* The id of the DesktopCapturerSource that is currently selected.
*/
@@ -33,7 +42,12 @@ type Props = {
/**
* The source type of the DesktopCapturerSources to display.
*/
type: string
type: string,
/**
* Used to obtain translations.
*/
t: Function
};
/**
@@ -42,6 +56,31 @@ type Props = {
* @extends Component
*/
class DesktopPickerPane extends Component<Props> {
/**
* Initializes a new DesktopPickerPane instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
super(props);
this._onShareAudioCheck = this._onShareAudioCheck.bind(this);
}
_onShareAudioCheck: (Object) => void;
/**
* Function to be called when the Checkbox is used.
*
* @param {boolean} checked - Checkbox status (checked or not).
* @returns {void}
*/
_onShareAudioCheck({ target: { checked } }) {
this.props.onShareAudioChecked(checked);
}
/**
* Implements React's {@link Component#render()}.
*
@@ -54,7 +93,8 @@ class DesktopPickerPane extends Component<Props> {
onDoubleClick,
selectedSourceId,
sources,
type
type,
t
} = this.props;
const classNames
@@ -77,12 +117,25 @@ class DesktopPickerPane extends Component<Props> {
</div>
);
let checkBox;
// Only display the share audio checkbox if we're on windows and on
// desktop sharing tab.
// App window and Mac OS screen sharing doesn't work with system audio.
if (type === 'screen' && Platform.OS === 'windows') {
checkBox = (<Checkbox
label = { t('dialog.screenSharingAudio') }
name = 'share-system-audio'
onChange = { this._onShareAudioCheck } />);
}
return (
<div className = { classNames }>
{ previews }
{ checkBox }
</div>
);
}
}
export default DesktopPickerPane;
export default translate(DesktopPickerPane);

View File

@@ -0,0 +1,54 @@
// @flow
import React, { PureComponent } from 'react';
import WebView from 'react-native-webview';
import { JitsiModal } from '../../base/modal';
import { connect } from '../../base/redux';
import { HELP_VIEW_MODAL_ID } from '../constants';
const DEFAULT_HELP_CENTRE_URL = 'https://web-cdn.jitsi.net/faq/meet-faq.html';
type Props = {
/**
* The URL to display in the Help Centre.
*/
_url: string
}
/**
* Implements a page that renders the help content for the app.
*/
class HelpView extends PureComponent<Props> {
/**
* Implements {@code PureComponent#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
return (
<JitsiModal
headerLabelKey = 'helpView.header'
modalId = { HELP_VIEW_MODAL_ID }>
<WebView source = {{ uri: this.props._url }} />
</JitsiModal>
);
}
}
/**
* Maps part of the Redux state to the props of this component.
*
* @param {Object} state - The Redux state.
* @returns {Props}
*/
function _mapStateToProps(state) {
return {
_url: state['features/base/config'].helpCentreURL || DEFAULT_HELP_CENTRE_URL
};
}
export default connect(_mapStateToProps)(HelpView);

View File

@@ -0,0 +1,3 @@
// @flow
export { default as HelpView } from './HelpView';

View File

@@ -0,0 +1,3 @@
// @flow
export const HELP_VIEW_MODAL_ID = 'helpView';

View File

@@ -0,0 +1,4 @@
// @flow
export * from './components';
export * from './constants';

View File

@@ -67,6 +67,11 @@ type Props = AbstractProps & {
type State = AbstractState & {
/**
* Boolean to show if an extra padding needs to be added to the bottom bar.
*/
bottomPadding: boolean,
/**
* State variable to keep track of the search field value.
*/
@@ -94,6 +99,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
defaultState = {
addToCallError: false,
addToCallInProgress: false,
bottomPadding: false,
fieldValue: '',
inviteItems: [],
searchInprogress: false,
@@ -194,16 +200,17 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
</View>
<TextInput
autoCorrect = { false }
autoFocus = { true }
clearButtonMode = 'always' // iOS only
autoFocus = { false }
onBlur = { this._onFocused(false) }
onChangeText = { this._onTypeQuery }
onFocus = { this._onFocused(true) }
placeholder = {
this.props.t(`inviteDialog.${placeholderKey}`)
}
ref = { this._setFieldRef }
style = { styles.searchField }
value = { this.state.fieldValue } />
{ this._renderAndroidClearButton() }
{ this._renderClearButton() }
</View>
{ Boolean(inviteItems.length) && <View style = { styles.invitedList }>
<FlatList
@@ -223,7 +230,11 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
renderItem = { this._renderItem } />
</View>
</SafeAreaView>
<SafeAreaView style = { [ styles.bottomBar, _headerStyles.headerOverlay ] }>
<SafeAreaView
style = { [
styles.bottomBar,
_headerStyles.headerOverlay,
this.state.bottomPadding ? styles.extraBarPadding : null ] }>
{ this._renderShareMeetingButton() }
</SafeAreaView>
</KeyboardAvoidingView>
@@ -317,6 +328,22 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
return false;
}
_onFocused: boolean => Function;
/**
* Constructs a callback to be used to update the padding of the field if necessary.
*
* @param {boolean} focused - True of the field is focused.
* @returns {Function}
*/
_onFocused(focused) {
return () => {
Platform.OS === 'android' && this.setState({
bottomPadding: focused
});
};
}
_onInvite: () => void
/**
@@ -433,14 +460,12 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
_query: (string) => Promise<Array<Object>>;
/**
* Renders a button to clear the text field on Android.
*
* NOTE: For the best platform experience we use the native solution on iOS.
* Renders a button to clear the text field.
*
* @returns {React#Element<*>}
*/
_renderAndroidClearButton() {
if (Platform.OS !== 'android' || !this.state.fieldValue.length) {
_renderClearButton() {
if (!this.state.fieldValue.length) {
return null;
}

View File

@@ -58,6 +58,13 @@ export default {
justifyContent: 'flex-start'
},
/**
* A special padding to avoid issues on some devices (such as Android devices with custom suggestions bar).
*/
extraBarPadding: {
paddingBottom: 30
},
invitedList: {
padding: 3
},

View File

@@ -1,6 +1,15 @@
/**
* The URL for Google Privacy Policy.
*/
export const GOOGLE_PRIVACY_POLICY = 'https://policies.google.com/privacy';
/**
* The URL that is the main landing page for YouTube live streaming and should
* have a user's live stream key.
*/
export const YOUTUBE_LIVE_DASHBOARD_URL
= 'https://www.youtube.com/live_dashboard';
export const YOUTUBE_LIVE_DASHBOARD_URL = 'https://www.youtube.com/live_dashboard';
/**
* The URL for YouTube terms and conditions.
*/
export const YOUTUBE_TERMS_URL = 'https://www.youtube.com/t/terms';

View File

@@ -11,6 +11,7 @@ import { StyleType } from '../../../../base/styles';
import AbstractStreamKeyForm, {
type Props as AbstractProps
} from '../AbstractStreamKeyForm';
import { GOOGLE_PRIVACY_POLICY, YOUTUBE_TERMS_URL } from '../constants';
type Props = AbstractProps & {
@@ -38,7 +39,10 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
super(props);
// Bind event handlers so they are only bound once per instance.
this._onOpenGooglePrivacyPolicy = this._onOpenGooglePrivacyPolicy.bind(this);
this._onOpenHelp = this._onOpenHelp.bind(this);
this._onOpenYoutubeTerms = this._onOpenYoutubeTerms.bind(this);
}
/**
@@ -101,12 +105,52 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
</TouchableOpacity>
</View>
</View>
<View>
<TouchableOpacity onPress = { this._onOpenYoutubeTerms }>
<Text
style = { [
_dialogStyles.text,
styles.text,
styles.tcText
] }>
{
t('liveStreaming.youtubeTerms')
}
</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress = { this._onOpenGooglePrivacyPolicy }>
<Text
style = { [
_dialogStyles.text,
styles.text,
styles.tcText
] }>
{
t('liveStreaming.googlePrivacyPolicy')
}
</Text>
</TouchableOpacity>
</View>
</View>
);
}
_onInputChange: Object => void
_onOpenGooglePrivacyPolicy: () => void;
/**
* Opens the Google Privacy Policy web page.
*
* @private
* @returns {void}
*/
_onOpenGooglePrivacyPolicy() {
Linking.openURL(GOOGLE_PRIVACY_POLICY);
}
_onOpenHelp: () => void
/**
@@ -123,6 +167,18 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
Linking.openURL(helpURL);
}
}
_onOpenYoutubeTerms: () => void;
/**
* Opens the YouTube terms and conditions web page.
*
* @private
* @returns {void}
*/
_onOpenYoutubeTerms() {
Linking.openURL(YOUTUBE_TERMS_URL);
}
}
export default translate(connect(_abstractMapStateToProps)(StreamKeyForm));

View File

@@ -145,6 +145,13 @@ export default createStyleSheet({
flexDirection: 'column'
},
/**
* Terms and Conditions texts.
*/
tcText: {
textAlign: 'right'
},
text: {
fontSize: 14,
textAlign: 'left'

View File

@@ -8,6 +8,7 @@ import { translate } from '../../../../base/i18n';
import AbstractStreamKeyForm, {
type Props
} from '../AbstractStreamKeyForm';
import { GOOGLE_PRIVACY_POLICY, YOUTUBE_TERMS_URL } from '../constants';
/**
* A React Component for entering a key for starting a YouTube live stream.
@@ -53,21 +54,37 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
type = 'text'
value = { this.props.value } />
<div className = 'form-footer'>
{
this.state.showValidationError
? <span className = 'warning-text'>
{ t('liveStreaming.invalidStreamKey') }
</span>
<div className = 'help-container'>
{
this.state.showValidationError
? <span className = 'warning-text'>
{ t('liveStreaming.invalidStreamKey') }
</span>
: null
}
{ this.helpURL
? <a
className = 'helper-link'
onClick = { this._onOpenHelp }>
{ t('liveStreaming.streamIdHelp') }
</a>
: null
}
{ this.helpURL
? <a
className = 'helper-link'
onClick = { this._onOpenHelp }>
{ t('liveStreaming.streamIdHelp') }
</a>
: null
}
}
</div>
<a
className = 'helper-link'
href = { YOUTUBE_TERMS_URL }
rel = 'noopener noreferrer'
target = '_blank'>
{ t('liveStreaming.youtubeTerms') }
</a>
<a
className = 'helper-link'
href = { GOOGLE_PRIVACY_POLICY }
rel = 'noopener noreferrer'
target = '_blank'>
{ t('liveStreaming.googlePrivacyPolicy') }
</a>
</div>
</div>
);
@@ -85,7 +102,7 @@ class StreamKeyForm extends AbstractStreamKeyForm<Props> {
* @returns {void}
*/
_onOpenHelp() {
window.open(this.helpURL, 'noopener');
window.open(this.helpURL, '_blank', 'noopener');
}
}

View File

@@ -130,7 +130,8 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
// but we want to indicate those in case of sip gateway
const {
iAmRecorder,
iAmSipGateway
iAmSipGateway,
disableRecordAudioNotification
} = getState()['features/base/config'];
if (iAmRecorder && !iAmSipGateway) {
@@ -153,6 +154,11 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
const initiatorName = initiator && getParticipantDisplayName(getState, initiator.getId());
initiatorName && dispatch(showStartedRecordingNotification(mode, initiatorName));
sendAnalytics(createRecordingEvent('start', mode));
if (disableRecordAudioNotification) {
break;
}
let soundID;
@@ -163,7 +169,6 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
}
if (soundID) {
sendAnalytics(createRecordingEvent('start', mode));
dispatch(playSound(soundID));
}
} else if (updatedSessionData.status === OFF
@@ -176,6 +181,11 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
duration
= (Date.now() / 1000) - oldSessionData.timestamp;
}
sendAnalytics(createRecordingEvent('stop', mode, duration));
if (disableRecordAudioNotification) {
break;
}
if (mode === JitsiRecordingConstants.mode.FILE) {
soundOff = RECORDING_OFF_SOUND_ID;
@@ -186,7 +196,6 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
}
if (soundOff && soundOn) {
sendAnalytics(createRecordingEvent('stop', mode, duration));
dispatch(stopSound(soundOn));
dispatch(playSound(soundOff));
}

View File

@@ -1,3 +1,6 @@
// The type of (redux) action which sets the visibility of the audio settings popup.
export const SET_AUDIO_SETTINGS_VISIBILITY = 'SET_AUDIO_SETTINGS_VISIBILITY';
/**
* The type of (redux) action which sets the visibility of the view/UI rendering
* the app's settings.
@@ -8,3 +11,6 @@
* }
*/
export const SET_SETTINGS_VIEW_VISIBLE = 'SET_SETTINGS_VIEW_VISIBLE';
// The type of (redux) action which sets the visibility of the video settings popup.
export const SET_VIDEO_SETTINGS_VISIBILITY = 'SET_VIDEO_SETTINGS_VISIBILITY';

View File

@@ -4,7 +4,11 @@ import { setFollowMe, setStartMutedPolicy } from '../base/conference';
import { openDialog } from '../base/dialog';
import { i18next } from '../base/i18n';
import { SET_SETTINGS_VIEW_VISIBLE } from './actionTypes';
import {
SET_AUDIO_SETTINGS_VISIBILITY,
SET_SETTINGS_VIEW_VISIBLE,
SET_VIDEO_SETTINGS_VISIBILITY
} from './actionTypes';
import { SettingsDialog } from './components';
import { getMoreTabProps, getProfileTabProps } from './functions';
@@ -38,6 +42,31 @@ export function openSettingsDialog(defaultTab: string) {
return openDialog(SettingsDialog, { defaultTab });
}
/**
* Sets the visiblity of the audio settings.
*
* @param {boolean} value - The new value.
* @returns {Function}
*/
function setAudioSettingsVisibility(value: boolean) {
return {
type: SET_AUDIO_SETTINGS_VISIBILITY,
value
};
}
/**
* Sets the visiblity of the video settings.
*
* @param {boolean} value - The new value.
* @returns {Function}
*/
function setVideoSettingsVisibility(value: boolean) {
return {
type: SET_VIDEO_SETTINGS_VISIBILITY,
value
};
}
/**
* Submits the settings from the "More" tab of the settings dialog.
@@ -84,3 +113,29 @@ export function submitProfileTab(newState: Object): Function {
}
};
}
/**
* Toggles the visiblity of the audio settings.
*
* @returns {void}
*/
export function toggleAudioSettings() {
return (dispatch: Function, getState: Function) => {
const value = getState()['features/settings'].audioSettingsVisible;
dispatch(setAudioSettingsVisibility(!value));
};
}
/**
* Toggles the visiblity of the video settings.
*
* @returns {void}
*/
export function toggleVideoSettings() {
return (dispatch: Function, getState: Function) => {
const value = getState()['features/settings'].videoSettingsVisible;
dispatch(setVideoSettingsVisibility(!value));
};
}

View File

@@ -0,0 +1,262 @@
// @flow
import React, { Component } from 'react';
import AudioSettingsHeader from './AudioSettingsHeader';
import { translate } from '../../../../base/i18n';
import { IconMicrophoneEmpty, IconVolumeEmpty } from '../../../../base/icons';
import { createLocalAudioTrack } from '../../../functions';
import MicrophoneEntry from './MicrophoneEntry';
import SpeakerEntry from './SpeakerEntry';
export type Props = {
/**
* The deviceId of the microphone in use.
*/
currentMicDeviceId: string,
/**
* The deviceId of the output device in use.
*/
currentOutputDeviceId: string,
/**
* Used to set a new microphone as the current one.
*/
setAudioInputDevice: Function,
/**
* Used to set a new output device as the current one.
*/
setAudioOutputDevice: Function,
/**
* A list of objects containing the labels and deviceIds
* of all the output devices.
*/
outputDevices: Object[],
/**
* A list with objects containing the labels and deviceIds
* of all the input devices.
*/
microphoneDevices: Object[],
/**
* Invoked to obtain translated strings.
*/
t: Function
};
type State = {
/**
* An object containing the jitsiTrack and the error (if the case)
* for the microphone that is in use.
*/
currentMicData: Object
}
/**
* Implements a React {@link Component} which displayes a list of all
* the audio input & output devices to choose from.
*
* @extends Component
*/
class AudioSettingsContent extends Component<Props, State> {
_componentWasUnmounted: boolean;
/**
* Initializes a new {@code AudioSettingsContent} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
this._onMicrophoneEntryClick = this._onMicrophoneEntryClick.bind(this);
this._onSpeakerEntryClick = this._onSpeakerEntryClick.bind(this);
this.state = {
currentMicData: {
error: false,
jitsiTrack: null
}
};
}
_onMicrophoneEntryClick: (string) => void;
/**
* Click handler for the microphone entries.
*
* @param {string} deviceId - The deviceId for the clicked microphone.
* @returns {void}
*/
_onMicrophoneEntryClick(deviceId) {
this.props.setAudioInputDevice(deviceId);
}
_onSpeakerEntryClick: (string) => void;
/**
* Click handler for the speaker entries.
*
* @param {string} deviceId - The deviceId for the clicked speaker.
* @returns {void}
*/
_onSpeakerEntryClick(deviceId) {
this.props.setAudioOutputDevice(deviceId);
}
/**
* Renders a single microphone entry.
*
* @param {Object} data - An object with the deviceId and label of the microphone.
* @param {number} index - The index of the element, used for creating a key.
* @returns {React$Node}
*/
_renderMicrophoneEntry(data, index) {
const { deviceId, label } = data;
const key = `me-${index}`;
const isSelected = deviceId === this.props.currentMicDeviceId;
let jitsiTrack = null;
let hasError = false;
if (isSelected) {
({ jitsiTrack, hasError } = this.state.currentMicData);
}
return (
<MicrophoneEntry
deviceId = { deviceId }
hasError = { hasError }
isSelected = { isSelected }
jitsiTrack = { jitsiTrack }
key = { key }
onClick = { this._onMicrophoneEntryClick }>
{label}
</MicrophoneEntry>
);
}
/**
* Renders a single speaker entry.
*
* @param {Object} data - An object with the deviceId and label of the speaker.
* @param {number} index - The index of the element, used for creating a key.
* @returns {React$Node}
*/
_renderSpeakerEntry(data, index) {
const { deviceId, label } = data;
const key = `se-${index}`;
return (
<SpeakerEntry
deviceId = { deviceId }
isSelected = { deviceId === this.props.currentOutputDeviceId }
key = { key }
onClick = { this._onSpeakerEntryClick }>
{label}
</SpeakerEntry>
);
}
/**
* Disposes the audio track for a given micData object.
*
* @param {Object} micData - The object holding the track.
* @returns {Promise<void>}
*/
_disposeTrack(micData) {
const { jitsiTrack } = micData;
return jitsiTrack ? jitsiTrack.dispose() : Promise.resolve();
}
/**
* Updates the current microphone data.
* Disposes previously created track and creates a new one.
*
* @returns {void}
*/
async _updateCurrentMicData() {
await this._disposeTrack(this.state.currentMicData);
const currentMicData = await createLocalAudioTrack(
this.props.currentMicDeviceId,
);
// In case the component gets unmounted before the track is created
// avoid a leak by not setting the state
if (this._componentWasUnmounted) {
this._disposeTrack(currentMicData);
} else {
this.setState({
currentMicData
});
}
}
/**
* Implements React's {@link Component#componentDidUpdate}.
*
* @inheritdoc
*/
componentDidUpdate(prevProps) {
if (prevProps.currentMicDeviceId !== this.props.currentMicDeviceId) {
this._updateCurrentMicData();
}
}
/**
* Implements React's {@link Component#componentDidMount}.
*
* @inheritdoc
*/
componentDidMount() {
this._updateCurrentMicData();
}
/**
* Implements React's {@link Component#componentWillUnmount}.
*
* @inheritdoc
*/
componentWillUnmount() {
this._componentWasUnmounted = true;
this._disposeTrack(this.state.currentMicData);
}
/**
* Implements React's {@link Component#render}.
*
* @inheritdoc
*/
render() {
const { microphoneDevices, outputDevices, t } = this.props;
return (
<div>
<div className = 'audio-preview-content'>
<AudioSettingsHeader
IconComponent = { IconMicrophoneEmpty }
text = { t('settings.microphones') } />
{microphoneDevices.map((data, i) =>
this._renderMicrophoneEntry(data, i),
)}
<AudioSettingsHeader
IconComponent = { IconVolumeEmpty }
text = { t('settings.speakers') } />
{outputDevices.map((data, i) =>
this._renderSpeakerEntry(data, i),
)}
</div>
</div>
);
}
}
export default translate(AudioSettingsContent);

View File

@@ -0,0 +1,53 @@
// @flow
import React from 'react';
import { Icon, IconCheck, IconExclamationSolid } from '../../../../base/icons';
/**
* The type of the React {@code Component} props of {@link AudioSettingsEntry}.
*/
export type Props = {
/**
* The text for this component.
*/
children: React$Node,
/**
* Flag indicating an error.
*/
hasError?: boolean,
/**
* Flag indicating the selection state.
*/
isSelected: boolean,
};
/**
* React {@code Component} representing an entry for the audio settings.
*
* @returns { ReactElement}
*/
export default function AudioSettingsEntry({ children, hasError, isSelected }: Props) {
const className = `audio-preview-entry ${isSelected
? 'audio-preview-entry--selected' : ''}`;
return (
<div className = { className }>
{isSelected && (
<Icon
className = 'audio-preview-icon audio-preview-icon--check'
color = '#1C2025'
size = { 14 }
src = { IconCheck } />
)}
<span className = 'audio-preview-entry-text'>{children}</span>
{hasError && <Icon
className = 'audio-preview-icon audio-preview-icon--exclamation'
size = { 16 }
src = { IconExclamationSolid } />}
</div>
);
}

View File

@@ -0,0 +1,39 @@
// @flow
import React from 'react';
import { Icon } from '../../../../base/icons';
/**
* The type of the React {@code Component} props of {@link AudioSettingsHeader}.
*/
type Props = {
/**
* The Icon used for the Header.
*/
IconComponent: Function,
/**
* The text of the Header.
*/
text: string,
};
/**
* React {@code Component} representing the Header of an audio option group.
*
* @returns { ReactElement}
*/
export default function AudioSettingsHeader({ IconComponent, text }: Props) {
return (
<div className = 'audio-preview-header'>
<div className = 'audio-preview-header-icon'>
{ <Icon
color = '#A4B8D1'
size = { 24 }
src = { IconComponent } />}
</div>
<div className = 'audio-preview-header-text'>{text}</div>
</div>
);
}

View File

@@ -0,0 +1,97 @@
// @flow
import React from 'react';
import InlineDialog from '@atlaskit/inline-dialog';
import AudioSettingsContent, { type Props as AudioSettingsContentProps } from './AudioSettingsContent';
import { toggleAudioSettings } from '../../../actions';
import {
getAudioInputDeviceData,
getAudioOutputDeviceData,
setAudioInputDevice as setAudioInputDeviceAction,
setAudioOutputDevice as setAudioOutputDeviceAction
} from '../../../../base/devices';
import { connect } from '../../../../base/redux';
import { getAudioSettingsVisibility } from '../../../functions';
import {
getCurrentMicDeviceId,
getCurrentOutputDeviceId
} from '../../../../base/settings';
type Props = AudioSettingsContentProps & {
/**
* Component's children (the audio button).
*/
children: React$Node,
/**
* Flag controlling the visibility of the popup.
*/
isOpen: boolean,
/**
* Callback executed when the popup closes.
*/
onClose: Function,
}
/**
* Popup with audio settings.
*
* @returns {ReactElement}
*/
function AudioSettingsPopup({
children,
currentMicDeviceId,
currentOutputDeviceId,
isOpen,
microphoneDevices,
setAudioInputDevice,
setAudioOutputDevice,
onClose,
outputDevices
}: Props) {
return (
<div className = 'audio-preview'>
<InlineDialog
content = { <AudioSettingsContent
currentMicDeviceId = { currentMicDeviceId }
currentOutputDeviceId = { currentOutputDeviceId }
microphoneDevices = { microphoneDevices }
outputDevices = { outputDevices }
setAudioInputDevice = { setAudioInputDevice }
setAudioOutputDevice = { setAudioOutputDevice } /> }
isOpen = { isOpen }
onClose = { onClose }
position = 'top left'>
{children}
</InlineDialog>
</div>
);
}
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
function mapStateToProps(state) {
return {
currentMicDeviceId: getCurrentMicDeviceId(state),
currentOutputDeviceId: getCurrentOutputDeviceId(state),
isOpen: getAudioSettingsVisibility(state),
microphoneDevices: getAudioInputDeviceData(state),
outputDevices: getAudioOutputDeviceData(state)
};
}
const mapDispatchToProps = {
onClose: toggleAudioSettings,
setAudioInputDevice: setAudioInputDeviceAction,
setAudioOutputDevice: setAudioOutputDeviceAction
};
export default connect(mapStateToProps, mapDispatchToProps)(AudioSettingsPopup);

View File

@@ -0,0 +1,45 @@
// @flow
import React from 'react';
import { Icon, IconMeter } from '../../../../base/icons';
type Props = {
/**
* Own class name for the component.
*/
className: string,
/**
* Flag indicating whether the component is greyed out/disabled.
*/
isDisabled?: boolean,
/**
* The level of the meter.
* Should be between 0 and 7 as per the used SVG.
*/
level: number,
};
/**
* React {@code Component} representing an audio level meter.
*
* @returns { ReactElement}
*/
export default function({ className, isDisabled, level }: Props) {
let ownClassName;
if (level > -1) {
ownClassName = `metr metr-l-${level}`;
} else {
ownClassName = `metr ${isDisabled ? 'metr--disabled' : ''}`;
}
return (
<Icon
className = { `${ownClassName} ${className}` }
size = { 12 }
src = { IconMeter } />
);
}

View File

@@ -0,0 +1,172 @@
// @flow
import React, { Component } from 'react';
import AudioSettingsEntry, { type Props as AudioSettingsEntryProps } from './AudioSettingsEntry';
import JitsiMeetJS from '../../../../base/lib-jitsi-meet/_';
import Meter from './Meter';
const JitsiTrackEvents = JitsiMeetJS.events.track;
type Props = AudioSettingsEntryProps & {
/**
* The deviceId of the microphone.
*/
deviceId: string,
/**
* Flag indicating if there is a problem with the device.
*/
hasError?: boolean,
/**
* The audio track for the current entry.
*/
jitsiTrack: Object,
/**
* Click handler for component.
*/
onClick: Function,
}
type State = {
/**
* The audio level.
*/
level: number,
}
/**
* React {@code Component} representing an entry for the microphone audio settings.
*
* @param {Props} props - The props of the component.
* @returns { ReactElement}
*/
export default class MicrophoneEntry extends Component<Props, State> {
/**
* Initializes a new {@code MicrophoneEntry} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
super(props);
this.state = {
level: -1
};
this._onClick = this._onClick.bind(this);
this._updateLevel = this._updateLevel.bind(this);
}
_onClick: () => void;
/**
* Click handler for the entry.
*
* @returns {void}
*/
_onClick() {
this.props.onClick(this.props.deviceId);
}
_updateLevel: (number) => void;
/**
* Updates the level of the meter.
*
* @param {number} num - The audio level provided by the jitsiTrack.
* @returns {void}
*/
_updateLevel(num) {
this.setState({
level: Math.floor(num / 0.125)
});
}
/**
* Subscribes to audio level chanages comming from the jitsiTrack.
*
* @returns {void}
*/
_startListening() {
const { jitsiTrack } = this.props;
jitsiTrack && jitsiTrack.on(
JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
this._updateLevel);
}
/**
* Unsubscribes from chanages comming from the jitsiTrack.
*
* @param {Object} jitsiTrack - The jitsiTrack to unsubscribe from.
* @returns {void}
*/
_stopListening(jitsiTrack) {
jitsiTrack && jitsiTrack.off(
JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
this._updateLevel);
this.setState({
level: -1
});
}
/**
* Implements React's {@link Component#componentDidUpdate}.
*
* @inheritdoc
*/
componentDidUpdate(prevProps: Props) {
if (prevProps.jitsiTrack !== this.props.jitsiTrack) {
this._stopListening(prevProps.jitsiTrack);
this._startListening();
}
}
/**
* Implements React's {@link Component#componentDidMount}.
*
* @inheritdoc
*/
componentDidMount() {
this._startListening();
}
/**
* Implements React's {@link Component#componentWillUnmount}.
*
* @inheritdoc
*/
compmonentWillUnmount() {
this._stopListening(this.props.jitsiTrack);
}
/**
* Implements React's {@link Component#render}.
*
* @inheritdoc
*/
render() {
const { children, hasError, isSelected } = this.props;
return (
<div
className = 'audio-preview-microphone'
onClick = { this._onClick }>
<AudioSettingsEntry
hasError = { hasError }
isSelected = { isSelected }>
{children}
</AudioSettingsEntry>
<Meter
className = 'audio-preview-meter-mic'
isDisabled = { hasError }
level = { this.state.level } />
</div>
);
}
}

View File

@@ -0,0 +1,119 @@
// @flow
import React, { Component } from 'react';
import AudioSettingsEntry from './AudioSettingsEntry';
import logger from '../../../logger';
import TestButton from './TestButton';
const TEST_SOUND_PATH = 'sounds/ring.wav';
/**
* The type of the React {@code Component} props of {@link SpeakerEntry}.
*/
type Props = {
/**
* The text label for the entry.
*/
children: React$Node,
/**
* Flag controlling the selection state of the entry.
*/
isSelected: boolean,
/**
* The deviceId of the speaker.
*/
deviceId: string,
/**
* Click handler for the component.
*/
onClick: Function,
};
/**
* Implements a React {@link Component} which displays an audio
* output settings entry. The user can click and play a test sound.
*
* @extends Component
*/
export default class SpeakerEntry extends Component<Props> {
/**
* A React ref to the HTML element containing the {@code audio} instance.
*/
audioRef: Object;
/**
* Initializes a new {@code SpeakerEntry} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
super(props);
this.audioRef = React.createRef();
this._onTestButtonClick = this._onTestButtonClick.bind(this);
this._onClick = this._onClick.bind(this);
}
_onClick: () => void;
/**
* Click handler for the entry.
*
* @returns {void}
*/
_onClick() {
this.props.onClick(this.props.deviceId);
}
_onTestButtonClick: Object => void;
/**
* Click handler for Test button.
* Sets the current audio output id and plays a sound.
*
* @param {Object} e - The sythetic event.
* @returns {void}
*/
async _onTestButtonClick(e) {
e.stopPropagation();
try {
await this.audioRef.current.setSinkId(this.props.deviceId);
this.audioRef.current.play();
} catch (err) {
logger.log('Could not set sink id', err);
}
}
/**
* Implements React's {@link Component#render}.
*
* @inheritdoc
*/
render() {
const { children, isSelected, deviceId } = this.props;
return (
<div
className = 'audio-preview-speaker'
onClick = { this._onClick }>
<AudioSettingsEntry
isSelected = { isSelected }
key = { deviceId }>
{children}
</AudioSettingsEntry>
<TestButton onClick = { this._onTestButtonClick } />
<audio
preload = 'auto'
ref = { this.audioRef }
src = { TEST_SOUND_PATH } />
</div>
);
}
}

View File

@@ -0,0 +1,26 @@
// @flow
import React from 'react';
type Props = {
/**
* Click handler for the button.
*/
onClick: Function,
};
/**
* React {@code Component} representing an button used for testing output sound.
*
* @returns { ReactElement}
*/
export default function TestButton({ onClick }: Props) {
return (
<div
className = 'audio-preview-test-button'
onClick = { onClick }>
Test
</div>
);
}

View File

@@ -1,2 +1,4 @@
export { default as SettingsButton } from './SettingsButton';
export { default as SettingsDialog } from './SettingsDialog';
export { default as AudioSettingsPopup } from './audio/AudioSettingsPopup';
export { default as VideoSettingsPopup } from './video/VideoSettingsPopup';

View File

@@ -0,0 +1,222 @@
// @flow
import React, { Component } from 'react';
import { translate } from '../../../../base/i18n';
import { equals } from '../../../../base/redux';
import Video from '../../../../base/media/components/Video';
import { createLocalVideoTracks } from '../../../functions';
const videoClassName = 'video-preview-video flipVideoX';
/**
* The type of the React {@code Component} props of {@link VideoSettingsContent}.
*/
export type Props = {
/**
* The deviceId of the camera device currently being used.
*/
currentCameraDeviceId: string,
/**
* Callback invoked to change current camera.
*/
setVideoInputDevice: Function,
/**
* Invoked to obtain translated strings.
*/
t: Function,
/**
* Callback invoked to toggle the settings popup visibility.
*/
toggleVideoSettings: Function,
/**
* All the camera device ids currently connected.
*/
videoDeviceIds: string[],
};
/**
* The type of the React {@code Component} state of {@link VideoSettingsContent}.
*/
type State = {
/**
* An array of all the jitsiTracks and eventual errors.
*/
trackData: Object[],
};
/**
* Implements a React {@link Component} which displays a list of video
* previews to choose from.
*
* @extends Component
*/
class VideoSettingsContent extends Component<Props, State> {
_componentWasUnmounted: boolean;
/**
* Initializes a new {@code VideoSettingsContent} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
this.state = {
trackData: new Array(props.videoDeviceIds.length).fill({
jitsiTrack: null
})
};
}
/**
* Creates and updates the track data.
*
* @returns {void}
*/
async _setTracks() {
this._disposeTracks(this.state.trackData);
const trackData = await createLocalVideoTracks(
this.props.videoDeviceIds,
);
// In case the component gets unmounted before the tracks are created
// avoid a leak by not setting the state
if (this._componentWasUnmounted) {
this._disposeTracks(trackData);
} else {
this.setState({
trackData
});
}
}
/**
* Destroys all the tracks from trackData object.
*
* @param {Object[]} trackData - An array of tracks that are to be disposed.
* @returns {Promise<void>}
*/
_disposeTracks(trackData) {
trackData.forEach(({ jitsiTrack }) => {
jitsiTrack && jitsiTrack.dispose();
});
}
/**
* Returns the click handler used when selecting the video preview.
*
* @param {string} deviceId - The id of the camera device.
* @returns {Function}
*/
_onEntryClick(deviceId) {
return () => {
this.props.setVideoInputDevice(deviceId);
this.props.toggleVideoSettings();
};
}
/**
* Renders a preview entry.
*
* @param {Object} data - The track data.
* @param {number} index - The index of the entry.
* @returns {React$Node}
*/
_renderPreviewEntry(data, index) {
const { error, jitsiTrack, deviceId } = data;
const { currentCameraDeviceId, t } = this.props;
const isSelected = deviceId === currentCameraDeviceId;
const key = `vp-${index}`;
const className = 'video-preview-entry';
if (error) {
return (
<div
className = { className }
key = { key }>
<div className = 'video-preview-error'>{t(error)}</div>
</div>
);
}
const props: Object = {
className,
key
};
const label = jitsiTrack && jitsiTrack.getTrackLabel();
if (isSelected) {
props.className = `${className} video-preview-entry--selected`;
} else {
props.onClick = this._onEntryClick(deviceId);
}
return (
<div { ...props }>
<div className = 'video-preview-label'>{label}</div>
<div className = 'video-preview-overlay' />
<Video
className = { videoClassName }
videoTrack = {{ jitsiTrack }} />
</div>
);
}
/**
* Implements React's {@link Component#componentDidMount}.
*
* @inheritdoc
*/
componentDidMount() {
this._setTracks();
}
/**
* Implements React's {@link Component#componentWillUnmount}.
*
* @inheritdoc
*/
componentWillUnmount() {
this._componentWasUnmounted = true;
this._disposeTracks(this.state.trackData);
}
/**
* Implements React's {@link Component#componentDidUpdate}.
*
* @inheritdoc
*/
componentDidUpdate(prevProps) {
if (!equals(this.props.videoDeviceIds, prevProps.videoDeviceIds)) {
this._setTracks();
}
}
/**
* Implements React's {@link Component#render}.
*
* @inheritdoc
*/
render() {
const { trackData } = this.state;
return (
<div className = 'video-preview'>
{trackData.map((data, i) => this._renderPreviewEntry(data, i))}
</div>
);
}
}
export default translate(VideoSettingsContent);

View File

@@ -0,0 +1,85 @@
// @flow
import React from 'react';
import InlineDialog from '@atlaskit/inline-dialog';
import { toggleVideoSettings } from '../../../actions';
import {
getVideoDeviceIds,
setVideoInputDevice as setVideoInputDeviceAction
} from '../../../../base/devices';
import { getVideoSettingsVisibility } from '../../../functions';
import { connect } from '../../../../base/redux';
import { getCurrentCameraDeviceId } from '../../../../base/settings';
import VideoSettingsContent, { type Props as VideoSettingsProps } from './VideoSettingsContent';
type Props = VideoSettingsProps & {
/**
* Component children (the Video button).
*/
children: React$Node,
/**
* Flag controlling the visibility of the popup.
*/
isOpen: boolean,
/**
* Callback executed when the popup closes.
*/
onClose: Function,
}
/**
* Popup with a preview of all the video devices.
*
* @returns {ReactElement}
*/
function VideoSettingsPopup({
currentCameraDeviceId,
children,
isOpen,
onClose,
setVideoInputDevice,
videoDeviceIds
}: Props) {
return (
<div className = 'video-preview'>
<InlineDialog
content = { <VideoSettingsContent
currentCameraDeviceId = { currentCameraDeviceId }
setVideoInputDevice = { setVideoInputDevice }
toggleVideoSettings = { onClose }
videoDeviceIds = { videoDeviceIds } /> }
isOpen = { isOpen }
onClose = { onClose }
position = 'top right'>
{ children }
</InlineDialog>
</div>
);
}
/**
* Maps (parts of) the redux state to the associated {@code VideoSettingsPopup}'s
* props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
function mapStateToProps(state) {
return {
currentCameraDeviceId: getCurrentCameraDeviceId(state),
isOpen: getVideoSettingsVisibility(state),
videoDeviceIds: getVideoDeviceIds(state)
};
}
const mapDispatchToProps = {
onClose: toggleVideoSettings,
setVideoInputDevice: setVideoInputDeviceAction
};
export default connect(mapStateToProps, mapDispatchToProps)(VideoSettingsPopup);

View File

@@ -2,6 +2,7 @@
import { toState } from '../base/redux';
import { parseStandardURIString } from '../base/util';
import { i18next, DEFAULT_LANGUAGE, LANGUAGES } from '../base/i18n';
import { createLocalTrack } from '../base/lib-jitsi-meet/functions';
import {
getLocalParticipant,
isLocalParticipantModerator
@@ -130,3 +131,73 @@ export function getProfileTabProps(stateful: Object | Function) {
email: localParticipant.email
};
}
/**
* Returns a promise which resolves with a list of objects containing
* all the video jitsiTracks and appropriate errors for the given device ids.
*
* @param {string[]} ids - The list of the camera ids for wich to create tracks.
*
* @returns {Promise<Object[]>}
*/
export function createLocalVideoTracks(ids: string[]) {
return Promise.all(ids.map(deviceId => createLocalTrack('video', deviceId)
.then(jitsiTrack => {
return {
jitsiTrack,
deviceId
};
})
.catch(() => {
return {
jitsiTrack: null,
deviceId,
error: 'deviceSelection.previewUnavailable'
};
})));
}
/**
* Returns a promise which resolves with an object containing the corresponding
* the audio jitsiTrack/error.
*
* @param {string} deviceId - The deviceId for the current microphone.
*
* @returns {Promise<Object>}
*/
export function createLocalAudioTrack(deviceId: string) {
return createLocalTrack('audio', deviceId)
.then(jitsiTrack => {
return {
hasError: false,
jitsiTrack
};
})
.catch(() => {
return {
hasError: true,
jitsiTrack: null
};
});
}
/**
* Returns the visibility state of the audio settings.
*
* @param {Object} state - The state of the application.
* @returns {boolean}
*/
export function getAudioSettingsVisibility(state: Object) {
return state['features/settings'].audioSettingsVisible;
}
/**
* Returns the visibility state of the video settings.
*
* @param {Object} state - The state of the application.
* @returns {boolean}
*/
export function getVideoSettingsVisibility(state: Object) {
return state['features/settings'].videoSettingsVisible;
}

View File

@@ -2,7 +2,11 @@
import { ReducerRegistry } from '../base/redux';
import { SET_SETTINGS_VIEW_VISIBLE } from './actionTypes';
import {
SET_AUDIO_SETTINGS_VISIBILITY,
SET_SETTINGS_VIEW_VISIBLE,
SET_VIDEO_SETTINGS_VISIBILITY
} from './actionTypes';
ReducerRegistry.register('features/settings', (state = {}, action) => {
switch (action.type) {
@@ -11,6 +15,16 @@ ReducerRegistry.register('features/settings', (state = {}, action) => {
...state,
visible: action.visible
};
case SET_AUDIO_SETTINGS_VISIBILITY:
return {
...state,
audioSettingsVisible: action.value
};
case SET_VIDEO_SETTINGS_VISIBILITY:
return {
...state,
videoSettingsVisible: action.value
};
}
return state;

View File

@@ -0,0 +1,127 @@
// @flow
import React, { Component } from 'react';
import AudioMuteButton from '../AudioMuteButton';
import { hasAvailableDevices } from '../../../base/devices';
import { IconArrowDown } from '../../../base/icons';
import JitsiMeetJS from '../../../base/lib-jitsi-meet/_';
import { ToolboxButtonWithIcon } from '../../../base/toolbox';
import { connect } from '../../../base/redux';
import { AudioSettingsPopup, toggleAudioSettings } from '../../../settings';
type Props = {
/**
* Click handler for the small icon. Opens audio options.
*/
onAudioOptionsClick: Function,
/**
* If the user has audio input or audio output devices.
*/
hasDevices: boolean,
/**
* Flag controlling the visibility of the button.
*/
visible: boolean,
};
type State = {
/**
* If there are permissions for audio devices.
*/
hasPermissions: boolean,
}
/**
* Button used for audio & audio settings.
*
* @returns {ReactElement}
*/
class AudioSettingsButton extends Component<Props, State> {
/**
* Initializes a new {@code AudioSettingsButton} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
this.state = {
hasPermissions: false
};
}
/**
* Updates device permissions.
*
* @returns {Promise<void>}
*/
async _updatePermissions() {
const hasPermissions = await JitsiMeetJS.mediaDevices.isDevicePermissionGranted(
'audio',
);
this.setState({
hasPermissions
});
}
/**
* Implements React's {@link Component#componentDidMount}.
*
* @inheritdoc
*/
componentDidMount() {
this._updatePermissions();
}
/**
* Implements React's {@link Component#render}.
*
* @inheritdoc
*/
render() {
const { hasDevices, onAudioOptionsClick, visible } = this.props;
const settingsDisabled = !this.state.hasPermissions || !hasDevices;
return visible ? (
<AudioSettingsPopup>
<ToolboxButtonWithIcon
icon = { IconArrowDown }
iconDisabled = { settingsDisabled }
onIconClick = { onAudioOptionsClick }>
<AudioMuteButton />
</ToolboxButtonWithIcon>
</AudioSettingsPopup>
) : null;
}
}
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
function mapStateToProps(state) {
return {
hasDevices:
hasAvailableDevices(state, 'audioInput')
|| hasAvailableDevices(state, 'audioOutput')
};
}
const mapDispatchToProps = {
onAudioOptionsClick: toggleAudioSettings
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(AudioSettingsButton);

Some files were not shown because too many files have changed in this diff Show More