Compare commits

...

11 Commits

Author SHA1 Message Date
Aaron van Meerten
e48ddc28eb updated node-sass version for npm 10 2018-11-20 16:39:41 -06:00
Bettenbuk Zoltan
71edea8aac Rearrange recording feature files 2018-11-20 14:42:33 +01:00
Bettenbuk Zoltan
2b1cb75e40 [RN] Update react-native-calendar-events lib
This is required to get rid of a warning after react native update. See related commit in lib.
2018-11-19 14:35:22 +01:00
damencho
216782d606 Commit from translate.jitsi.org by user damencho.: 583 of 583 strings translated (0 fuzzy). 2018-11-14 03:33:01 +00:00
Emil Ivov
c707b82419 Replacing Atlassian with 8x8 2018-11-11 08:43:34 -06:00
Bettenbuk Zoltan
3fdf944763 Fix eslint/jsdoc warnings (doc change only!) 2018-11-08 15:52:34 +01:00
virtuacoplenny
56100d0d5c Merge pull request #3594 from mmoanis/update-docs
Update docs for AbstractRecordButton _mapStateToProps
2018-11-07 09:20:05 -08:00
Leonard Kim
486e8e35d9 ref: move all prop type declaration to flow
For the most part the changes are taking the "static propTypes" declaration off
of components and declaring them as Flow types. Sometimes to support flow some
method signatures had to be added. There are some exceptions in which more had
to be done to tame the beast:
- AbstractVideoTrack: put in additional truthy checks for videoTrack.
- Video: add truthy checks for the _videoElement ref.
- shouldRenderVideoTrack function: Some component could pass null for the
  videoTrack argument and Flow wanted that called out explicitly.
- DisplayName: Add a truthy check for the input ref before acting on it.
- NumbersList: Move array checks inline for Flow to comprehend array methods
  could be called. Add type checks in the Object.entries loop as the value is
  assumed to be a mixed type by Flow.
- AbstractToolbarButton: add additional truthy check for passed in type.
2018-11-07 17:38:10 +01:00
Bettenbuk Zoltan
554974a36d [RN] Fix YouTube channel name list 2018-11-07 16:48:56 +01:00
mmoanis
cd943319d6 Update docs for AbstractRecordButton _mapStateToProps 2018-11-06 11:36:00 +01:00
Дамян Минков
837f496e8f Moves muc definition to be last.
Fixes common problem where people following https://github.com/jitsi/jicofo#secure-domain have a syntax error, forgetting the comma after muc definition.
2018-11-06 09:55:32 +01:00
157 changed files with 3533 additions and 3117 deletions

View File

@@ -130,7 +130,7 @@ equivalent to these of a direct one-to-one WebRTC call. This is what's unique to
Jitsi Meet in terms of security.
The [meet.jit.si](https://meet.jit.si) service is maintained by the Jitsi team
at [Atlassian](https://atlassian.com).
at [8x8](https://8x8.com).
## Mobile app
Jitsi Meet is also available as a React Native app for Android and iOS.

View File

@@ -18,9 +18,6 @@ var config = {
// XMPP domain.
domain: 'jitsi-meet.example.com',
// XMPP MUC domain. FIXME: use XEP-0030 to discover it.
muc: 'conference.jitsi-meet.example.com'
// When using authentication, domain for guest users.
// anonymousdomain: 'guest.example.com',
@@ -35,6 +32,9 @@ var config = {
// Focus component domain. Defaults to focus.<domain>.
// focus: 'focus.jitsi-meet.example.com',
// XMPP MUC domain. FIXME: use XEP-0030 to discover it.
muc: 'conference.jitsi-meet.example.com'
},
// BOSH URL. FIXME: use XEP-0156 to discover it.

View File

@@ -1,11 +1,18 @@
{
"en": "Anglais",
"az": "Azerbaïdjanais",
"bg": "Bulgare",
"cs": "Tchèque",
"de": "Allemand",
"el": "Grec",
"eo": "Espéranto",
"es": "Espagnol",
"fr": "Français",
"hy": "Arménien",
"it": "Italien",
"ja": "Japonais",
"ko": "Coréen",
"nb": "Norvégien Bokmal",
"oc": "Occitan",
"pl": "Polonais",
"ptBR": "Portugais (Brésil)",
@@ -14,7 +21,6 @@
"sl": "Slovène",
"sv": "Suédois",
"tr": "Turc",
"zhCN": "Chinois (Chine)",
"nb": "Norvégien Bokmal",
"eo": "Espéranto"
"vi": "Vietnamien",
"zhCN": "Chinois (Chine)"
}

View File

@@ -1,6 +1,5 @@
{
"contactlist": "__count__ Membres",
"contactlist_plural": "",
"contactlist_plural": "__count__ Membres",
"passwordSetRemotely": "défini par un autre membre",
"poweredby": "Produit par",
"inviteUrlDefaultMsg": "Votre conférence est en cours de création...",
@@ -23,6 +22,7 @@
"react-nativeGrantPermissions": "Sélectionnez <b><i>Autoriser</i></b> lorsque votre navigateur demande des autorisations.",
"chromeGrantPermissions": "Sélectionnez <b><i>Autoriser</i></b> lorsque votre navigateur demande des autorisations.",
"androidGrantPermissions": "Sélectionnez <b><i>Autoriser</i></b> lorsque votre navigateur demande des autorisations.",
"electronGrantPermissions": "Merci d'autoriser le partage de votre camera et microphone",
"firefoxGrantPermissions": "Sélectionnez <b><i>Partager le périphérique sélectionné</i></b> lorsque votre navigateur demande des autorisations.",
"operaGrantPermissions": "Sélectionnez <b><i>Autoriser</i></b> lorsque votre navigateur demande des autorisations.",
"iexplorerGrantPermissions": "Sélectionnez <b><i>OK</i></b> quand le navigateur demande les permissions.",
@@ -35,57 +35,42 @@
"raiseHand": "Lever ou baisser la main",
"pushToTalk": "Appuyer pour parler",
"toggleScreensharing": "Basculer entre la caméra et le partage d'écran",
"toggleFilmstrip": "Afficher ou cacher la vidéo",
"toggleShortcuts": "Afficher ou masquer ce menu d'aide",
"toggleFilmstrip": "Afficher ou masquer les vignettes vidéos",
"toggleShortcuts": "Afficher ou masquer les raccourcis clavier",
"focusLocal": "Épingler ma vidéo",
"focusRemote": "Épingler la vidéo des autres",
"focusRemote": "Épingler la vidéo de quelqu'un d'autre",
"toggleChat": "Ouvrir ou fermer le panneau de conversation",
"mute": "Activer ou désactiver le microphone",
"fullScreen": "Activer ou Désactiver le plein écran",
"fullScreen": "Activer / Désactiver le mode plein écran",
"videoMute": "Démarrer ou arrêter votre caméra",
"showSpeakerStats": "Afficher les statistiques de l'interlocuteur"
"showSpeakerStats": "Afficher les statistiques de l'interlocuteur",
"localRecording": "Afficher ou masquer les commandes de l'enregistrement local"
},
"welcomepage": {
"disable": "Ne plus afficher cette page",
"feature1": {
"content": "Aucun téléchargement requis. __app__ s'utilise directement depuis votre navigateur. Partager simplement l'URL de votre conférence avec les autres pour commencer.",
"title": "Simple à utiliser"
"accessibilityLabel": {
"join": "Touchez pour rejoindre",
"roomname": "Saisissez un nom de salle"
},
"feature2": {
"content": "Les vidéo conférences à plusieurs participants nécessitent moins de 128 kbps. Le partage d'écran et les conférences avec seulement de l'audio sont possibles avec beaucoup moins de débit.",
"title": "Bande passante faible"
},
"feature3": {
"content": "__app__ est sous licence Apache. Vous êtes libre de télécharger, d'utiliser, de modifier et de partager __app__ selon cette licence libre.",
"title": "Open source"
},
"feature4": {
"content": "Il n'y a pas de limitation sur le nombre d'utilisateurs ou de conférences. Seules la puissance et la bande passante du serveur sont des facteurs limitants.",
"title": "Nombre d'utilisateurs illimité"
},
"feature5": {
"content": "C'est facile de partager votre écran avec d'autres personnes. __app__ est idéal pour les présentations en ligne, les cours, et les sessions de support technique.",
"title": "Partage d'écran"
},
"feature6": {
"content": "Besoin de confidentialité ? Les salles de conférence __app__ peuvent être sécurisées par un mot de passe pour exclure les invités non désirées, et prévenir des interruptions.",
"title": "Salles sécurisées"
},
"feature7": {
"content": "__app__ propose Etherpad, un éditeur de texte collaboratif en temps réel qui est parfait pour les procès-verbaux, l'édition d'articles et plus encore.",
"title": "Notes partagées"
},
"feature8": {
"content": "Apprenez plus au sujet de vos utilisateurs avec une intégration facile de Piwik, Google Analytics et d'autres systèmes de statistiques et supervision d'utilisation.",
"title": "Statistiques d'utilisation"
"appDescription": "Allez-y, chat vidéo avec toute l'équipe. En fait, invitez tout le monde que vous connaissez. __app__ est une solution de visioconférence entièrement cryptée et 100% open source que vous pouvez utiliser toute la journée, tous les jours, gratuitement— aucun compte requis.",
"audioVideoSwitch": {
"audio": "Voix",
"video": "Vidéo"
},
"calendar": "Calendrier",
"connectCalendarText": "Connectez votre calendrier pour voir toutes vos réunion dans __app__. Ajoutez les réunions __app__ dans votre calendrier pour les lancer en un seul clic.",
"connectCalendarButton": "Connecter votre calendrier",
"enterRoomTitle": "Démarrer une nouvelle réunion",
"go": "Créer",
"join": "REJOINDRE",
"privacy": "Confidentialité",
"recentList": "Récent",
"recentListDelete": "Supprimer",
"recentListEmpty": "Votre liste récente est actuellement vide. Discuter avec votre équipe et vous trouverez toutes vos réunions récentes ici.",
"roomname": "Saisissez un nom de salle",
"roomnamePlaceHolder": "nom de la conférence",
"roomnameHint": "Entrez le nom ou l'URL de la salle que vous souhaitez rejoindre. Vous pouvez faire un nom, laissez les gens que vous rencontrerez le savoir afin qu'ils entrent le même nom.",
"sendFeedback": "Envoyer votre avis",
"terms": "Termes"
"terms": "Termes",
"title": "Vidéoconférence Sécurisée, entièrement en vedette et gratuite"
},
"startupoverlay": {
"policyText": " ",
@@ -97,52 +82,95 @@
"rejoinKeyTitle": "Rejoindre"
},
"toolbar": {
"accessibilityLabel": {
"audioOnly": "Activer/désactiver le mode voix uniquement",
"audioRoute": "",
"callQuality": "Accorder la qualité des appels",
"chat": "Afficher/masquer la discussion instantanée",
"cc": "Activer/désactiver les sous-titres",
"document": "Activer/désactiver le document partagé",
"feedback": "Laisser des commentaires",
"fullScreen": "Activer/désactiver le plein écran",
"hangup": "Quitter la conversation",
"invite": "Inviter des participants",
"localRecording": "Activer/désactiver les contrôles d'enregistrement local",
"lockRoom": "Activer/Désactiver le verrouillage de la session",
"moreActions": "Activer/désactiver le menu d'actions supplémentaires",
"moreActionsMenu": "Menu d'actions supplémentaires",
"mute": "Activer/désactiver l'audio",
"pip": "Activer/désactiver le mode Picture in Picture",
"profile": "Éditer votre profil",
"raiseHand": "Lever/baisser la main",
"recording": "Activer/désactiver l'enregistrement",
"Settings": "Afficher/masquer le menu des paramètres",
"sharedvideo": "Démarrer/arrêter le partage de vidéo Youtube",
"shareRoom": "Inviter quelqu'un",
"shareYourScreen": "Activer/désactiver le partage décran",
"shortcuts": "Afficher/masquer les raccourcis",
"speakerStats": "Afficher/cacher les statistiques de parole",
"toggleCamera": "Activer/désactiver la caméra",
"tileView": "Activer/désactiver la vue mosaïque",
"videomute": "Activer/désactiver la vidéo"
},
"addPeople": "Ajouter des personnes à votre appel",
"audioonly": "Activer / Désactiver le mode audio uniquement (économiser de la bande passante)",
"audioOnlyOn": "Activer/désactiver le mode audio uniquement (économiser de la bande passante)",
"audioOnlyOff": "Désactiver le mode audio uniquement",
"audioRoute": "Sélectionner le périphérique audio",
"callQuality": "Accorder la qualité des appels",
"enterFullScreen": "Afficher en plein écran",
"exitFullScreen": "Quitter le mode plein écran",
"feedback": "Laisser des commentaires",
"moreActions": "Plus d'actions",
"mute": "Muet / Actif",
"videomute": "Démarrer / Arrêter la caméra",
"authenticate": "Authentifiez-vous",
"lock": "Verrouiller / déverrouiller la conférence",
"invite": "Partager le lien",
"chat": "Ouvrir / Fermer le chat",
"etherpad": "Ouvrir / Fermer le document partagé",
"documentOpen": "Ouvrir le document partagé",
"documentClose": "Fermer le document partagé",
"shareRoom": "Partager le salon",
"sharedvideo": "Partager une vidéo YouTube",
"sharescreen": "Démarrer / Arrêter le partage d'écran",
"stopSharedVideo": "Arrêter la vidéo YouTube",
"fullscreen": "Activer / Désactiver le plein écran",
"sip": "Appeler un numéro SIP",
"Settings": "Paramètres",
"hangup": "Quitter",
"login": "Connexion",
"logout": "Déconnexion",
"dialpad": "Ouvrir / Fermer le pavé numérique",
"sharedVideoMutedPopup": "Votre vidéo a été coupée pour que vous puissiez parler aux autres participants.",
"toggleCamera": "Activer/désactiver la caméra",
"micMutedPopup": "Votre microphone a été coupé afin que vous puissiez profiter de la vidéo partagée",
"talkWhileMutedPopup": "Vous voulez parler? Vous êtes en muet.",
"unableToUnmutePopup": "Vous ne pouvez pas réactiver votre microphone pendant que la vidéo partagée est activée.",
"cameraDisabled": "La camera n'est pas disponible",
"micDisabled": "Le microphone n'est pas disponible",
"filmstrip": "Afficher / Masquer les vidéos",
"pip": "Entrer en mode Picture-in-Picture",
"profile": "Éditer votre profil",
"raiseHand": "Lever / Baisser la main"
},
"unsupportedBrowser": {
"appNotInstalled": "Rejoignez cette réunion avec __app__ sur votre téléphone.",
"downloadApp": "Télécharger l'application",
"openApp": "Continuer sur __app__"
},
"bottomtoolbar": {
"chat": "Ouvrir / fermer le chat",
"filmstrip": "Afficher / cacher les vidéos",
"contactlist": "Voir et inviter des participants"
"raiseHand": "Lever / Baisser la main",
"shortcuts": "Afficher les raccourcis",
"speakerStats": "Statistiques de l'interlocuteur",
"tileViewToggle": "Activer/désactiver la vue mosaïque",
"invite": "Inviter des participants"
},
"chat": {
"nickname": {
"title": "Saisissez un pseudonyme dans le champ ci-dessous",
"popover": "Choisissez un pseudonyme"
},
"error": "Erreur : votre message \"__originalText__\" n'a pas été envoyé. Raison : __error__",
"messagebox": "Saisissez votre texte..."
},
"settings": {
"calendar": {
"about": "L'intégration de __appName__ avec votre calendrier permet daccéder de manière sécurisée aux événement à venir.",
"disconnect": "Se déconnecter",
"microsoftSignIn": "Se connecter avec Microsoft",
"signedIn": "Accès aux événements du calendrier __email__. Cliquez sur le bouton se déconnecter ci-dessous pour arrêter l'accès aux événements du calendrier.",
"title": "Calendrier"
},
"title": "Paramètres",
"update": "Mise à jour",
"name": "Nom",
@@ -152,11 +180,15 @@
"selectMic": "Microphone",
"selectAudioOutput": "Sortie audio",
"followMe": "Tout le monde me suit",
"language": "Langue",
"loggedIn": "Connecté en tant que __name__",
"noDevice": "Aucun",
"cameraAndMic": "Caméra et microphone",
"moderator": "MODÉRATEUR",
"moderator": "Moderateur",
"more": "Plus",
"password": "DÉFINIR UN MOT DE PASSE",
"audioVideo": "AUDIO ET VIDÉO"
"audioVideo": "AUDIO ET VIDÉO",
"devices": "Périphériques"
},
"profile": {
"title": "Profil",
@@ -176,7 +208,9 @@
},
"connectionindicator": {
"header": "État de la connexion",
"connectedTo": "Connecté à :",
"bitrate": "Débit :",
"bridgeCount": "Nombre de serveurs :",
"packetloss": "Perte de paquets :",
"resolution": "Résolution :",
"framerate": "Images par seconde",
@@ -216,15 +250,20 @@
"focus": "Focus de conférence",
"focusFail": "__component__ n'est pas disponible - réessayez dans __ms__ sec",
"grantedTo": "Droits modérateur accordés à __to__ !",
"grantedToUnknown": "Droits modérateur accordés à $t(notify.somebody)!",
"muted": "Vous avez commencé la conversation en muet.",
"mutedTitle": "Vous êtes en muet !",
"raisedHand": "Aimerait prendre la parole."
"raisedHand": "Aimerait prendre la parole.",
"suboptimalExperienceTitle": "Avertissement du navigateur",
"suboptimalExperienceDescription": "Eer ... nous craignons que votre expérience avec __appName__ ne sera pas aussi excellente que nous le pensions. Nous cherchons des moyens d'améliorer cela, mais jusque là, essayez d'utiliser l'un des <a href='static/recommendedBrowsers.html' target='_blank'>navigateurs entièrement pris en charge</a>."
},
"dialog": {
"add": "Ajouter",
"accessibilityLabel": {
"liveStreaming": "Diffusion en direct"
},
"allow": "Autoriser",
"confirm": "Confirmer",
"kickMessage": "Oups! Vous avez été renvoyé de la réunion !",
"kickTitle": "Viré de la conférence",
"popupErrorTitle": "Pop-up bloquée",
"popupError": "Votre navigateur bloque les fenêtres pop-up. Veuillez autoriser les fenêtres pop-up dans les paramètres de votre navigateur.",
"passwordErrorTitle": "Problème avec le mot de passe",
@@ -237,7 +276,6 @@
"copy": "Copier",
"contactSupport": "Contacter le support",
"error": "Erreur",
"createPassword": "Créer un mot de passe",
"detectext": "Une erreur est survenue pendant la détection de l'extension de partage d'écran.",
"failedpermissions": "Échec d'obtention des permissions pour utiliser le micro et/ou la caméra.",
"conferenceReloadTitle": "Malheureusement, un problème est survenu",
@@ -248,6 +286,7 @@
"rejoinNow": "Rejoindre maintenant",
"maxUsersLimitReachedTitle": "Le nombre maximal de participants est atteint",
"maxUsersLimitReached": "Le nombre maximal de participants est atteint. La conférence est complète. Merci de contacter le propriétaire du salon ou réessayer plus tard.",
"lockRoom": "Verrouiller la réunion",
"lockTitle": "Échec du verrouillage",
"lockMessage": "Impossible de verrouiller la conférence.",
"warning": "Avertissement",
@@ -288,10 +327,6 @@
"Save": "Sauvegarder",
"recording": "Enregistrement",
"recordingToken": "Saisissez un jeton d'enregistrement",
"passwordCheck": "Voulez-vous vraiment supprimer votre mot de passe ?",
"passwordMsg": "Saisissez un mot de passe pour verrouiller la conférence",
"shareLink": "Partager le lien de la conférence",
"yourPassword": "Saisissez un nouveau mot de passe",
"Back": "Retour",
"serviceUnavailable": "Service indisponible",
"gracefulShutdown": "Le service est actuellement en maintenance. Réessayez plus tard.",
@@ -299,29 +334,31 @@
"reservationError": "Erreur du système de réservation",
"reservationErrorMsg": "Code d'erreur: __code__, message: __msg__",
"password": "Saisir le mot de passe",
"unlockRoom": "Déverrouiller la réunion",
"userPassword": "mot de passe utilisateur",
"token": "jeton",
"tokenAuthFailedTitle": "Échec de l'authentification",
"tokenAuthFailed": "Désolé, vous n'êtes pas autorisé à rejoindre cette conversation.",
"displayNameRequired": "Un nom d'utilisateur est requis",
"enterDisplayName": "Veuillez saisir votre nom",
"extensionRequired": "Extension requise :",
"firefoxExtensionPrompt": "Vous devez installer une extension Firefox pour utiliser le partage d'écran. Merci d'essayer de nouveau après l'installation <a href='__url__'>depuis ce lien</a> !",
"feedbackHelp": "Vos retours nous permettrons d'améliorer notre expérience vidéo.",
"feedbackQuestion": "Informez-nous à propos de votre appel !",
"thankYou": "Merci d'avoir utilisé __appName__ !",
"sorryFeedback": "Nous sommes désolés d'apprendre cela. Voulez-vous nous en dire plus ?",
"liveStreaming": "Direct",
"streamKey": "Stream name/key",
"startLiveStreaming": "Commencer le direct",
"streamKey": "Clé Live stream",
"startLiveStreaming": "Démarrer la diffusion en direct",
"startRecording": "Commencer l'enregistrement",
"stopStreamingWarning": "Désirez-vous vraiment arrêter le direct?",
"stopRecordingWarning": "Désirez-vous vraiment arrêter l'enregistrement?",
"stopLiveStreaming": "Arrêter le direct",
"stopLiveStreaming": "Arrêter la diffusion en direct",
"stopRecording": "Arrêter l'enregistrement",
"doNotShowMessageAgain": "Ne plus afficher ce message",
"permissionDenied": "Permission refusée",
"screenSharingFailedToInstall": "Oups! Votre extension de partage d'écran n'a pas pu être installée.",
"screenSharingFailedToInstallTitle": "L'extension de partage d'écran n'a pas pu être installée",
"screenSharingFirefoxPermissionDeniedError": "Quelque chose s'est mal passé pendant que nous essayions de partager votre écran. S'il vous plaît assurez-vous que vous nous avez donné la permission de le faire.",
"screenSharingFirefoxPermissionDeniedTitle": "Oups! Nous ne pouvions pas démarrer le partage d'écran!",
"screenSharingPermissionDeniedError": "Oups! Une erreur s'est produite avec vos autorisations d'extension de partage d'écran. Veuillez rafraîchir et réessayer.",
"cameraUnsupportedResolutionError": "Votre appareil ne prend pas en charge la résolution vidéo requise.",
"cameraUnknownError": "Vous ne pouvez pas utiliser la caméra pour une raison inconnue.",
@@ -344,6 +381,10 @@
"muteParticipantTitle": "Couper le micro de ce participant?",
"muteParticipantBody": "Vous ne pourrez plus réactiver leurs micros, mais ils peuvent l'activer par eux-même à tout moment.",
"muteParticipantButton": "Couper le micro",
"liveStreamingDisabledTooltip": "La diffusion en direct est désactivé",
"liveStreamingDisabledForGuestTooltip": "Les invités ne peuvent démarrer la diffusion en direct.",
"recordingDisabledTooltip": "L'enregistrement est désactivé.",
"recordingDisabledForGuestTooltip": "Les invités ne peuvent enregistrer.",
"remoteControlTitle": "Contrôle de bureau à distance",
"remoteControlRequestMessage": "Voulez-vous autoriser __user__ à contrôler votre bureau?",
"remoteControlShareScreenWarning": "Si vous appuyez sur \"Autoriser\" vous allez partager votre écran!",
@@ -354,8 +395,11 @@
"remoteControlStopMessage": "La prise en main à distance est terminée!",
"close": "Fermer",
"shareYourScreen": "Partagez votre écran",
"shareYourScreenDisabled": "Le partage décran est désactivé.",
"shareYourScreenDisabledForGuest": "Les invités ne peuvent partager l'écran",
"yourEntireScreen": "Votre écran entier",
"applicationWindow": "Fenêtre d'application"
"applicationWindow": "Fenêtre d'application",
"transcribing": "Transcription"
},
"email": {
"sharedKey": [
@@ -385,6 +429,22 @@
],
"and": "et"
},
"share": {
"mainText": [
"Cliquez sur le lien suivant pour rejoindre une conférence :",
"__roomUrl__"
],
"dialInfoText": [
"",
"",
"=====",
"",
"Voulez-vous appeler depuis votre téléphone?",
"",
"__defaultDialInNumber__Cliquez sur ce lien pour voir les numéros de téléphone pour cette conférence",
"__dialInfoPageUrl__"
]
},
"connection": {
"ERROR": "Erreur",
"CONNECTING": "Connexion en cours",
@@ -398,30 +458,67 @@
"ATTACHED": "Attachée"
},
"recording": {
"beta": "BETA",
"busy": "Nous sommes en train de libérer les ressources d'enregistrement. Réessayez dans quelques minutes.",
"busyTitle": "Tous les enregistreurs sont actuellement occupés",
"buttonTooltip": "Démarrer / Arrêter l'enregistrement",
"error": "Échec de l'enregistrement. Veuillez réessayer.",
"expandedOff": "L'enregistrement a été arrêté",
"expandedOn": "Cette conférence est actuellement en cours d'enregistrement.",
"expandedPending": "Démarrage de l'enregistrement...",
"failedToStart": "L'enregistrement n'as pas réussi à démarrer",
"live": "DIRECT",
"off": "Enregistrement arrêté",
"on": "Enregistrement",
"pending": "Enregistrement en attente de participant...",
"pending": "Préparation de l'enregistrement de la réunion...",
"rec": "REC",
"authDropboxText": "Téléchargement vers Dropbox",
"serviceName": "Service d'enregistrement",
"signOut": "Se déconnecter",
"signIn": "s'identifier",
"loggedIn": "Connecté en tant que __userName__",
"availableSpace": "Espace disponible: __spaceLeft_ Mo (approximativement __duration__ minutes d'enregistrement)",
"startRecordingBody": "Voulez-vous vraiment démarrer l'enregistrement?",
"unavailable": "Oups! Le __serviceName__ est actuellement indisponible. Nous travaillons sur la résolution du problème. Veuillez réessayer plus tard.",
"unavailableTitle": "Enregistrement indisponible"
},
"transcribing": {
"pending": "Préparation de la transcription de la réunion...",
"off": "La transcription désactivée",
"error": "Échec de la transcription. Veuillez réessayer.",
"expandedLabel": "La transcription est actuellement activée",
"failedToStart": "Échec de démarrage de la transcription",
"tr": "TR",
"labelToolTip": "La transcription de la réunion est en cours",
"ccButtonTooltip": "Afficher/masquer les sous-titres",
"start": "Afficher/masquer les sous-titres",
"stop": "Désactiver le sous-titrage"
},
"liveStreaming": {
"busy": "Nous travaillons sur la libération des ressources de Streaming. Veuillez réessayez dans quelques minutes.",
"busyTitle": "Tous les streamers sont actuellement occupés",
"buttonTooltip": "Démarrer / Arrêter le Stream",
"changeSignIn": "Changer de compte.",
"choose": "Choisir un flux live",
"chooseCTA": "Choisissez une option de diffusion. Vous êtes actuellement connecté comme __email__.",
"enterStreamKey": "Entrez votre clé de flux live Youtube ici",
"error": "Le Streaming a échoué. Veuillez réessayer.",
"errorAPI": "Une erreur s'est produite lors de l'accès à vos diffusions YouTube. Veuillez réessayer de vous connecter.",
"errorLiveStreamNotEnabled": "La diffusion en direct n'est pas activée pour __email__. Merci de l'activer ou de vous connecter avec un compte où elle est déjà activée.",
"expandedOff": "La diffusion en direct a été arrêtée",
"expandedOn": "La conférence est en cours de diffusion sur YouTube.",
"expandedPending": "La diffusion en direct a commencé...",
"failedToStart": "Le Streaming n'as pas réussi à démarrer",
"off": "Le Streaming a été arrêter",
"off": "Le Streaming a été arrêté",
"on": "Direct",
"pending": "Commencer le direct...",
"serviceName": "Service de diffusion en direct",
"streamIdRequired": "Merci de renseigner le stream id pour lancer le streaming.",
"streamIdHelp": "Où puis-je trouver ceci?",
"signedInAs": "Vous êtes connecté en tant que :",
"signIn": "Se connecter avec Google",
"signOut": "Se déconnecter",
"signInCTA": "Connectez vous ou entrez votre clé de flux live provenant de Youtube.",
"start": "Démarrer la diffusion en direct",
"streamIdHelp": "Qu'est-ce que c'est?",
"unavailableTitle": "Le Streaming est indisponible"
},
"videoSIPGW": {
@@ -449,28 +546,20 @@
"noPermission": "Permission non accordée",
"previewUnavailable": "Aperçu non disponible",
"selectADevice": "Sélectionner un périphérique",
"testAudio": "Son de test"
},
"invite": {
"addPassword": "Ajouter un mot de passe",
"callNumber": "Appeler le __number__",
"enterID": "Saisissez l'identifiant: __conferenceID__ suivi de # pour rejoindre avec un téléphone",
"howToDialIn": "Pour rejoindre avec un téléphone, utilisez un des des numéros suivants et l'identifiant de la conférence",
"hidePassword": "Cacher le mot de passe",
"inviteTo": "inviter des participants à __conferenceName__",
"invitedYouTo": "__userName__ vous a invité(e) à la conférence __inviteURL__",
"invitePeople": "Inviter",
"locked": "Cet appel est verrouillé. les nouveaux interlocuteurs devraient avoir le lien et saisir le mot de passe pour rejoindre.",
"showPassword": "Afficher le mot de passe",
"unlocked": "Cet appel est verrouillé. Tout nouveau participant avec un lien peut rejoindre l'appel."
"testAudio": "Lire un audio de test"
},
"videoStatus": {
"audioOnly": "VOIX",
"audioOnlyExpanded": "Vous êtes en mode audio uniquement. Ce mode économise de la bande passant mais vous ne pourrez pas voir la vidéo des autres participants.",
"callQuality": "Qualité de l'appel",
"hd": "HD",
"hdTooltip": "Regardez la vidéo en haute définition",
"highDefinition": "Haute définition",
"labelTooltipVideo": "Qualité vidéo actuelle",
"labelTooltipAudioOnly": "Mode audio uniquement activé",
"labelTooiltipNoVideo": "Aucune vidéo",
"labelTooltipVideo": "Qualité vidéo actuelle",
"ld": "BD",
"ldTooltip": "Regardez la vidéo en basse définition",
"lowDefinition": "Basse définition",
"onlyAudioAvailable": "Seul l'audio est disponible",
"onlyAudioSupported": "Nous ne supportons que l'audio sur ce navigateur.",
@@ -478,21 +567,31 @@
"p2pVideoQualityDescription": "En mode peer to peer, la qualité d'appel reçue ne peut être basculée qu'entre haut et audio. Les autres paramètres ne seront pas respectés tant que l'on n'aura pas quitté peer to peer.",
"recHighDefinitionOnly": "Va préférer la haute définition",
"sd": "MD",
"sdTooltip": "Regardez la vidéo en définition standard",
"standardDefinition": "Moyenne Définition",
"qualityButtonTip": "Changer la qualité de vidéo reçue"
},
"dialOut": {
"dial": "Composer",
"dialOut": "Appeler #",
"statusMessage": "est maintenant __status__",
"enterPhone": "Saisissez un numéro de téléphone",
"phoneNotAllowed": "Désolé, nous ne supportons pas encore cette destination!"
"statusMessage": "est maintenant __status__"
},
"addPeople": {
"add": "Ajouter",
"add": "Inviter",
"countryNotSupported": "Nous ne supportons pas encore cette destination.",
"countryReminder": "Appel hors États-Unis? Veuillez commencer avec le code du pays!",
"disabled": "Vous ne pouvez pas inviter quelqu'un.",
"footerText": "Appels sortants désactivés",
"invite": "Inviter",
"loading": "Rechercher des personnes et des numéros de téléphone",
"loadingNumber": "Validation du numéro de téléphone",
"loadingPeople": "Recherche de personnes à inviter",
"noResults": "Aucun résultat de recherche correspondant",
"searchPlaceholder": "Rechercher des personnes et des salons à ajouter",
"title": "Ajouter des personnes à votre appel",
"noValidNumbers": "Veuillez entrer un numéro de téléphone",
"notAvailable": "Vous ne pouvez pas inviter quelqu'un.",
"searchNumbers": "Ajouter des numéros de téléphone",
"searchPeople": "Rechercher une personne",
"searchPeopleAndNumbers": "Rechercher des personnes ou ajouter leurs numéros de téléphone",
"telephone": "Téléphone: __number__",
"title": "Inviter une personne à cette réunion",
"failedToAdd": "Échec de l'ajout de membres"
},
"inlineDialogFailure": {
@@ -511,14 +610,131 @@
"average": "Moyen",
"bad": "Mauvais",
"good": "Bien",
"rateExperience": "Veuillez évaluer votre réunion.",
"detailsLabel": "Dites nous en plus à ce sujet.",
"rateExperience": "Veuillez évaluer votre expérience.",
"veryBad": "Très mauvais",
"veryGood": "Très bon"
},
"info": {
"copy": "Copier le lien",
"invite": "Inviter à __app__",
"title": "Informations sur la conférence",
"tooltip": "Obtenir des informations d'accès"
"accessibilityLabel": "Afficher les informations",
"addPassword": "Ajouter un mot de passe",
"cancelPassword": "Annuler mot de passe",
"conferenceURL": "Lien:",
"country": "Pays",
"dialANumber": "Pour rejoindre votre réunion, composez l'un de ces numéros, puis entrez ce code PIN: __conferenceID __ #",
"dialInNumber": "Composer:",
"dialInConferenceID": "PIN:",
"dialInNotSupported": "Désolé, les appels entrants ne sont pas supportés.",
"genericError": "Oups, quelque chose a mal tourné.",
"inviteLiveStream": "Pour voir la diffusion en direct de cette réunion, cliquez sur ce lien : __url__",
"invitePhone": "Pour joindre par téléphone, composez __number__ et saisissez ce code PIN : __conferenceID__ #",
"invitePhoneAlternatives": "Pour voir plus de numéros de téléphone, suivez ce lien : __url__",
"inviteURL": "Pour rejoindre la vidéoconférence, cliquez sur ce lien : __url__",
"liveStreamURL": "Diffusion en direct :",
"moreNumbers": "Plus de numéros ",
"noNumbers": "Numéros à composer non trouvés",
"noPassword": "Aucun",
"noRoom": "Aucune réunion n'a été spécifiée pour l'appel entrant.",
"numbers": "Numéros d'appel",
"password": "Mot de passe:",
"title": "Partager",
"tooltip": "Partager le lien et les informations de connexion pour cette conférence"
},
"settingsView": {
"alertOk": "D'accord",
"alertTitle": "Avertissement",
"alertURLText": "L'URL du serveur est invalide",
"conferenceSection": "Conférence",
"displayName": "Pseudo",
"email": "Email",
"header": "Paramètres",
"profileSection": "Profil",
"serverURL": "URL du serveur",
"startWithAudioMuted": "Commencez avec la vidéo en sourdine",
"startWithVideoMuted": "Commencez avec la vidéo en sourdine"
},
"calendarSync": {
"addMeetingURL": "Ajouter un lien de conférence",
"confirmAddLink": "Voulez-vous ajouter un lien Jitsi à cet événement?",
"confirmAddLinkTitle": "Calendrier",
"join": "Joindre",
"joinTooltip": "Rejoindre la réunion",
"nextMeeting": "prochaine réunion",
"noEvents": "Il n'y a pas dévénement à venir.",
"ongoingMeeting": "La réunion en cours",
"permissionButton": "Afficher les réglages",
"permissionMessage": "La permission du calendrier est requise pour afficher vos réunions dans l'application.",
"refresh": "Rafraîchir le calendrier",
"today": "Aujourd'hui"
},
"recentList": {
"joinPastMeeting": "Rejoindre une réunion précédente"
},
"sectionList": {
"pullToRefresh": "Tirer pour recharger"
},
"deepLinking": {
"title": "Lancement de votre réunion dans __app __ en cours...",
"description": "Rien ne s'est passé? Nous avons essayé de lancer votre réunion dans l'application de bureau __app__. Essayez à nouveau ou lancez-la dans l'application web __app__.",
"tryAgainButton": "Réessayez sur le bureau",
"launchWebButton": "Lancer dans le navigateur",
"appNotInstalled": "Vous avez besoin de l'application mobile __app__ pour participer à cette réunion avec votre téléphone.",
"downloadApp": "Télécharger l'application",
"openApp": "Continuer vers l'application"
},
"presenceStatus": {
"invited": "Invité(e)",
"ringing": "Appel en cours...",
"calling": "Appel...",
"initializingCall": "Lancement de l'appel...",
"connected": "Connecté",
"connecting": "Connexion en cours...",
"connecting2": "Connexion en cours*...",
"disconnected": "Déconnecté",
"busy": "Occupé",
"rejected": "Rejeté",
"ignored": "Ignoré",
"expired": "Expiré"
},
"dateUtils": {
"today": "Aujourd'hui",
"yesterday": "Hier",
"earlier": "Plus tôt"
},
"incomingCall": {
"answer": "Répondre",
"audioCallTitle": "Appel entrant",
"decline": "Rejeter",
"productLabel": "de Jitsi Meet",
"videoCallTitle": "Appel vidéo entrant"
},
"localRecording": {
"localRecording": "Enregistrement local",
"dialogTitle": "Commandes de l'enregistrement local",
"start": "Démarrer l'enregistrement",
"stop": "Arrêter l'enregistrement",
"moderator": "Moderateur",
"me": "Moi",
"duration": "Durée",
"durationNA": "N/A",
"encoding": "Encodage",
"participantStats": "Statistiques du participant",
"participant": "Participant",
"sessionToken": "Token de la session",
"clientState": {
"on": "Actif",
"off": "Inactif",
"unknown": "Inconnu"
},
"messages": {
"engaged": "Enregistrement local engagé.",
"finished": "L'enregistrement de la session __token__ s'est terminé. Merci d'envoyer le fichier au modérateur.",
"finishedModerator": "L'enregistrement de la session __token__ s'est terminé. La piste a bien été sauvegardée. Merci de demander aux autres participants de soumettre leurs enregistrements.",
"notModerator": "Vous n'êtes pas le modérateur. Vous ne pouvez pas démarrer ou arrêter un enregistrement local."
},
"yes": "Oui",
"no": "Non",
"label": "ENR-LOC",
"labelToolTip": "L'enregistrement local est engagé"
}
}

View File

@@ -462,55 +462,57 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
* the event and value - the listener.
* Currently we support the following
* events:
* incomingMessage - receives event notifications about incoming
* {@code incomingMessage} - receives event notifications about incoming
* messages. The listener will receive object with the following structure:
* {{
* 'from': from,//JID of the user that sent the message
* 'nick': nick,//the nickname of the user that sent the message
* 'message': txt//the text of the message
* }}
* outgoingMessage - receives event notifications about outgoing
* {@code outgoingMessage} - receives event notifications about outgoing
* messages. The listener will receive object with the following structure:
* {{
* 'message': txt//the text of the message
* }}
* displayNameChanged - receives event notifications about display name
* change. The listener will receive object with the following structure:
* {@code displayNameChanged} - receives event notifications about display
* name change. The listener will receive object with the following
* structure:
* {{
* jid: jid,//the JID of the participant that changed his display name
* displayname: displayName //the new display name
* }}
* participantJoined - receives event notifications about new participant.
* {@code participantJoined} - receives event notifications about new
* participant.
* The listener will receive object with the following structure:
* {{
* jid: jid //the jid of the participant
* }}
* participantLeft - receives event notifications about the participant that
* left the room.
* {@code participantLeft} - receives event notifications about the
* participant that left the room.
* The listener will receive object with the following structure:
* {{
* jid: jid //the jid of the participant
* }}
* video-conference-joined - receives event notifications about the local
* user has successfully joined the video conference.
* {@code video-conference-joined} - receives event notifications about the
* local user has successfully joined the video conference.
* The listener will receive object with the following structure:
* {{
* roomName: room //the room name of the conference
* }}
* video-conference-left - receives event notifications about the local user
* has left the video conference.
* {@code video-conference-left} - receives event notifications about the
* local user has left the video conference.
* The listener will receive object with the following structure:
* {{
* roomName: room //the room name of the conference
* }}
* screenSharingStatusChanged - receives event notifications about
* {@code screenSharingStatusChanged} - receives event notifications about
* turning on/off the local user screen sharing.
* The listener will receive object with the following structure:
* {{
* on: on //whether screen sharing is on
* }}
* readyToClose - all hangup operations are completed and Jitsi Meet is
* ready to be disposed.
* {@code readyToClose} - all hangup operations are completed and Jitsi Meet
* is ready to be disposed.
* @returns {void}
*
* @deprecated
@@ -537,11 +539,12 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
/**
* Executes command. The available commands are:
* displayName - sets the display name of the local participant to the value
* passed in the arguments array.
* toggleAudio - mutes / unmutes audio with no arguments.
* toggleVideo - mutes / unmutes video with no arguments.
* toggleFilmStrip - hides / shows the filmstrip with no arguments.
* {@code displayName} - Sets the display name of the local participant to
* the value passed in the arguments array.
* {@code toggleAudio} - Mutes / unmutes audio with no arguments.
* {@code toggleVideo} - Mutes / unmutes video with no arguments.
* {@code toggleFilmStrip} - Hides / shows the filmstrip with no arguments.
*
* If the command doesn't require any arguments the parameter should be set
* to empty array or it may be omitted.
*
@@ -562,13 +565,13 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
/**
* Executes commands. The available commands are:
* displayName - sets the display name of the local participant to the value
* passed in the arguments array.
* toggleAudio - mutes / unmutes audio. no arguments
* toggleVideo - mutes / unmutes video. no arguments
* toggleFilmStrip - hides / shows the filmstrip. no arguments
* toggleChat - hides / shows chat. no arguments.
* toggleShareScreen - starts / stops screen sharing. no arguments.
* {@code displayName} - Sets the display name of the local participant to
* the value passed in the arguments array.
* {@code toggleAudio} - Mutes / unmutes audio. No arguments.
* {@code toggleVideo} - Mutes / unmutes video. No arguments.
* {@code toggleFilmStrip} - Hides / shows the filmstrip. No arguments.
* {@code toggleChat} - Hides / shows chat. No arguments.
* {@code toggleShareScreen} - Starts / stops screen sharing. No arguments.
*
* @param {Object} commandList - The object with commands to be executed.
* The keys of the object are the commands that will be executed and the

552
package-lock.json generated
View File

@@ -2318,10 +2318,13 @@
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
"dev": true
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"dev": true,
"requires": {
"safer-buffer": "~2.1.0"
}
},
"asn1.js": {
"version": "4.10.1",
@@ -2428,9 +2431,9 @@
"dev": true
},
"aws4": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true
},
"babel-code-frame": {
@@ -3055,11 +3058,10 @@
"dev": true
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"dev": true,
"optional": true,
"requires": {
"tweetnacl": "^0.14.3"
}
@@ -3116,15 +3118,6 @@
"multicast-dns-service-types": "^1.1.0"
}
},
"boom": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
"integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
"dev": true,
"requires": {
"hoek": "4.x.x"
}
},
"bowser": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.2.tgz",
@@ -3718,9 +3711,9 @@
"integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q="
},
"combined-stream": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
"integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
"dev": true,
"requires": {
"delayed-stream": "~1.0.0"
@@ -4070,26 +4063,6 @@
"which": "^1.2.9"
}
},
"cryptiles": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
"integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
"dev": true,
"requires": {
"boom": "5.x.x"
},
"dependencies": {
"boom": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
"integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
"dev": true,
"requires": {
"hoek": "4.x.x"
}
}
}
},
"crypto-browserify": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
@@ -4620,13 +4593,13 @@
}
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"dev": true,
"optional": true,
"requires": {
"jsbn": "~0.1.0"
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"ee-first": {
@@ -5679,9 +5652,9 @@
}
},
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true
},
"extend-shallow": {
@@ -6013,13 +5986,13 @@
"dev": true
},
"form-data": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "1.0.6",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
@@ -7166,29 +7139,14 @@
}
},
"gaze": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
"integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
"integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
"dev": true,
"requires": {
"globule": "^1.0.0"
}
},
"generate-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
"integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
"dev": true
},
"generate-object-property": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
"integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
"dev": true,
"requires": {
"is-property": "^1.0.0"
}
},
"get-caller-file": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
@@ -7284,14 +7242,22 @@
}
},
"globule": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz",
"integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
"integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
"dev": true,
"requires": {
"glob": "~7.1.1",
"lodash": "~4.17.4",
"lodash": "~4.17.10",
"minimatch": "~3.0.2"
},
"dependencies": {
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"graceful-fs": {
@@ -7328,13 +7294,39 @@
"dev": true
},
"har-validator": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"dev": true,
"requires": {
"ajv": "^5.1.0",
"ajv": "^6.5.5",
"har-schema": "^2.0.0"
},
"dependencies": {
"ajv": {
"version": "6.5.5",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz",
"integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
}
}
},
"has": {
@@ -7430,18 +7422,6 @@
"minimalistic-assert": "^1.0.0"
}
},
"hawk": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
"integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
"dev": true,
"requires": {
"boom": "4.x.x",
"cryptiles": "3.x.x",
"hoek": "4.x.x",
"sntp": "2.x.x"
}
},
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -7453,12 +7433,6 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
"hoek": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
"integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
"dev": true
},
"hoist-non-react-statics": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
@@ -8063,25 +8037,6 @@
"is-extglob": "^1.0.0"
}
},
"is-my-ip-valid": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
"integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
"dev": true
},
"is-my-json-valid": {
"version": "2.17.2",
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz",
"integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==",
"dev": true,
"requires": {
"generate-function": "^2.0.0",
"generate-object-property": "^1.1.0",
"is-my-ip-valid": "^1.0.0",
"jsonpointer": "^4.0.0",
"xtend": "^4.0.0"
}
},
"is-number": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
@@ -8143,12 +8098,6 @@
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
},
"is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
"dev": true
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
@@ -8363,8 +8312,7 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"dev": true,
"optional": true
"dev": true
},
"jsc-android": {
"version": "224109.1.0",
@@ -8479,12 +8427,6 @@
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
},
"jsonpointer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
"dev": true
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -9631,20 +9573,19 @@
"dev": true
},
"node-gyp": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
"integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=",
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
"integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
"dev": true,
"requires": {
"fstream": "^1.0.0",
"glob": "^7.0.3",
"graceful-fs": "^4.1.2",
"minimatch": "^3.0.2",
"mkdirp": "^0.5.0",
"nopt": "2 || 3",
"npmlog": "0 || 1 || 2 || 3 || 4",
"osenv": "0",
"request": "2",
"request": "^2.87.0",
"rimraf": "2",
"semver": "~5.3.0",
"tar": "^2.0.0",
@@ -9653,7 +9594,7 @@
"dependencies": {
"semver": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
"dev": true
}
@@ -9770,9 +9711,9 @@
}
},
"node-sass": {
"version": "4.8.3",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.8.3.tgz",
"integrity": "sha512-tfFWhUsCk/Y19zarDcPo5xpj+IW3qCfOjVdHtYeG6S1CKbQOh1zqylnQK6cV3z9k80yxAnFX9Y+a9+XysDhhfg==",
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.10.0.tgz",
"integrity": "sha512-fDQJfXszw6vek63Fe/ldkYXmRYK/QS6NbvM3i5oEo9ntPDy4XX7BcKZyTKv+/kSSxRtXXc7l+MSwEmYc0CSy6Q==",
"dev": true,
"requires": {
"async-foreach": "^0.1.3",
@@ -9788,41 +9729,14 @@
"meow": "^3.7.0",
"mkdirp": "^0.5.1",
"nan": "^2.10.0",
"node-gyp": "^3.3.1",
"node-gyp": "^3.8.0",
"npmlog": "^4.0.0",
"request": "~2.79.0",
"request": "^2.88.0",
"sass-graph": "^2.2.4",
"stdout-stream": "^1.4.0",
"true-case-path": "^1.0.2"
},
"dependencies": {
"assert-plus": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
"dev": true
},
"aws-sign2": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
"integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
"dev": true
},
"boom": {
"version": "2.10.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
"dev": true,
"requires": {
"hoek": "2.x.x"
}
},
"caseless": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
"integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
"dev": true
},
"cross-spawn": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
@@ -9833,26 +9747,6 @@
"which": "^1.2.9"
}
},
"cryptiles": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
"dev": true,
"requires": {
"boom": "2.x.x"
}
},
"form-data": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.5",
"mime-types": "^2.1.12"
}
},
"gauge": {
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
@@ -9869,47 +9763,6 @@
"wide-align": "^1.1.0"
}
},
"har-validator": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
"integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
"dev": true,
"requires": {
"chalk": "^1.1.1",
"commander": "^2.9.0",
"is-my-json-valid": "^2.12.4",
"pinkie-promise": "^2.0.0"
}
},
"hawk": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
"dev": true,
"requires": {
"boom": "2.x.x",
"cryptiles": "2.x.x",
"hoek": "2.x.x",
"sntp": "1.x.x"
}
},
"hoek": {
"version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
"dev": true
},
"http-signature": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
"dev": true,
"requires": {
"assert-plus": "^0.2.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
@@ -9920,9 +9773,9 @@
}
},
"nan": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
"integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==",
"dev": true
},
"npmlog": {
@@ -9937,49 +9790,6 @@
"set-blocking": "~2.0.0"
}
},
"qs": {
"version": "6.3.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
"integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
"dev": true
},
"request": {
"version": "2.79.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
"integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
"dev": true,
"requires": {
"aws-sign2": "~0.6.0",
"aws4": "^1.2.1",
"caseless": "~0.11.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.0",
"forever-agent": "~0.6.1",
"form-data": "~2.1.1",
"har-validator": "~2.0.6",
"hawk": "~3.1.3",
"http-signature": "~1.1.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.7",
"oauth-sign": "~0.8.1",
"qs": "~6.3.0",
"stringstream": "~0.0.4",
"tough-cookie": "~2.3.0",
"tunnel-agent": "~0.4.1",
"uuid": "^3.0.0"
}
},
"sntp": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
"integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
"dev": true,
"requires": {
"hoek": "2.x.x"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@@ -9990,12 +9800,6 @@
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"tunnel-agent": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
"integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
"dev": true
}
}
},
@@ -10089,9 +9893,9 @@
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true
},
"object-assign": {
@@ -11277,6 +11081,12 @@
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"psl": {
"version": "1.1.29",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
"integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==",
"dev": true
},
"public-encrypt": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
@@ -11323,6 +11133,12 @@
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
"dev": true
},
"query-string": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
@@ -11730,8 +11546,8 @@
"integrity": "sha512-vLNJIedXQZN4p3ChFsAgVHacnJqQMnLl+wBsnZuliRkmsjEHo8kQOA9fnLih/OoiDi1O3eHQvXC5L8f+RYiKgw=="
},
"react-native-calendar-events": {
"version": "github:wmcmahan/react-native-calendar-events#cb2731db6684a49b4343e09de7f9c2fcc68bcd9b",
"from": "github:wmcmahan/react-native-calendar-events#cb2731db6684a49b4343e09de7f9c2fcc68bcd9b"
"version": "github:wmcmahan/react-native-calendar-events#056807286da610d884fb6b4c8ca187a767b261f7",
"from": "github:wmcmahan/react-native-calendar-events#056807286da610d884fb6b4c8ca187a767b261f7"
},
"react-native-callstats": {
"version": "3.53.4",
@@ -12258,39 +12074,58 @@
}
},
"request": {
"version": "2.83.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
"integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
"version": "2.88.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.6.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.1",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.1",
"har-validator": "~5.0.3",
"hawk": "~6.0.2",
"form-data": "~2.3.2",
"har-validator": "~5.1.0",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.17",
"oauth-sign": "~0.8.2",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.1",
"safe-buffer": "^5.1.1",
"stringstream": "~0.0.5",
"tough-cookie": "~2.3.3",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.1.0"
"uuid": "^3.3.2"
},
"dependencies": {
"qs": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
"mime-db": {
"version": "1.37.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
"integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
"dev": true
},
"mime-types": {
"version": "2.1.21",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
"integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
"dev": true,
"requires": {
"mime-db": "~1.37.0"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
"dev": true
}
}
@@ -13259,7 +13094,7 @@
},
"load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true,
"requires": {
@@ -13272,7 +13107,7 @@
},
"os-locale": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
"dev": true,
"requires": {
@@ -13412,7 +13247,7 @@
"dependencies": {
"source-map": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true,
"requires": {
@@ -13788,15 +13623,6 @@
"kind-of": "^3.2.0"
}
},
"sntp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
"integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
"dev": true,
"requires": {
"hoek": "4.x.x"
}
},
"sockjs": {
"version": "0.3.18",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz",
@@ -13997,9 +13823,9 @@
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"sshpk": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
"integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz",
"integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==",
"dev": true,
"requires": {
"asn1": "~0.2.3",
@@ -14009,6 +13835,7 @@
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
@@ -14051,9 +13878,9 @@
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
},
"stdout-stream": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
"integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=",
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
"integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
"dev": true,
"requires": {
"readable-stream": "^2.0.1"
@@ -14067,7 +13894,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -14245,12 +14072,6 @@
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
"dev": true
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -14478,7 +14299,7 @@
},
"tar": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
"resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
"integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
"dev": true,
"requires": {
@@ -14664,11 +14485,12 @@
}
},
"tough-cookie": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
"integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"dev": true,
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
}
},
@@ -14684,27 +14506,12 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
},
"true-case-path": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz",
"integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
"integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
"dev": true,
"requires": {
"glob": "^6.0.4"
},
"dependencies": {
"glob": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
"integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
"dev": true,
"requires": {
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "2 || 3",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
}
"glob": "^7.1.2"
}
},
"tslib": {
@@ -14737,8 +14544,7 @@
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"dev": true,
"optional": true
"dev": true
},
"type-check": {
"version": "0.3.2",
@@ -15752,34 +15558,12 @@
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"wide-align": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"dev": true,
"requires": {
"string-width": "^1.0.2"
},
"dependencies": {
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
}
"string-width": "^1.0.2 || 2"
}
},
"window-size": {

View File

@@ -63,7 +63,7 @@
"react-i18next": "7.13.0",
"react-native": "0.57.1",
"react-native-background-timer": "2.0.0",
"react-native-calendar-events": "github:wmcmahan/react-native-calendar-events#cb2731db6684a49b4343e09de7f9c2fcc68bcd9b",
"react-native-calendar-events": "github:wmcmahan/react-native-calendar-events#056807286da610d884fb6b4c8ca187a767b261f7",
"react-native-callstats": "3.53.4",
"react-native-fast-image": "github:jitsi/react-native-fast-image#1f8c93a5584869848d75cc9b946beb9688efe285",
"react-native-google-signin": "1.0.0-rc6",
@@ -110,7 +110,7 @@
"flow-bin": "0.78.0",
"imports-loader": "0.7.1",
"metro-react-native-babel-preset": "0.47.0",
"node-sass": "4.8.3",
"node-sass": "4.10.0",
"precommit-hook": "3.0.0",
"string-replace-loader": "1.3.0",
"style-loader": "0.19.0",

View File

@@ -413,7 +413,7 @@ export function createRemoteVideoMenuButtonEvent(buttonName, attributes) {
/**
* Creates an event indicating that an action related to screen sharing
* occurred (e.g. it was started or stopped).
* occurred (e.g. It was started or stopped).
*
* @param {string} action - The action which occurred.
* @returns {Object} The event in a format suitable for sending via
@@ -466,7 +466,7 @@ export function createSharedVideoEvent(action, attributes = {}) {
* Creates an event associated with a shortcut being pressed, released or
* triggered. By convention, where appropriate an attribute named 'enable'
* should be used to indicate the action which resulted by the shortcut being
* pressed (e.g. whether screen sharing was enabled or disabled).
* pressed (e.g. Whether screen sharing was enabled or disabled).
*
* @param {string} shortcut - The identifier of the shortcut which produced
* an action.
@@ -512,7 +512,7 @@ export function createStartAudioOnlyEvent(audioOnly) {
*
* @param {string} source - The source of the configuration, 'local' or
* 'remote' depending on whether it comes from the static configuration (i.e.
* config.js) or comes dynamically from Jicofo.
* {@code config.js}) or comes dynamically from Jicofo.
* @param {boolean} audioMute - Whether the configuration requests that audio
* is muted.
* @param {boolean} videoMute - Whether the configuration requests that video
@@ -573,7 +573,7 @@ export function createSyncTrackStateEvent(mediaType, muted) {
* Creates an event associated with a toolbar button being clicked/pressed. By
* convention, where appropriate an attribute named 'enable' should be used to
* indicate the action which resulted by the shortcut being pressed (e.g.
* whether screen sharing was enabled or disabled).
* Whether screen sharing was enabled or disabled).
*
* @param {string} buttonName - The identifier of the toolbar button which was
* clicked/pressed.
@@ -595,9 +595,9 @@ export function createToolbarEvent(buttonName, attributes = {}) {
* Creates an event which indicates that a local track was muted.
*
* @param {string} mediaType - The track's media type ('audio' or 'video').
* @param {string} reason - The reason the track was muted (e.g. it was
* @param {string} reason - The reason the track was muted (e.g. It was
* triggered by the "initial mute" option, or a previously muted track was
* replaced (e.g. when a new device was used)).
* replaced (e.g. When a new device was used)).
* @param {boolean} muted - Whether the track was muted or unmuted.
* @returns {Object} The event in a format suitable for sending via
* sendAnalytics.

View File

@@ -128,10 +128,10 @@ export class AbstractApp extends BaseApp<Props, *> {
}
/**
* Navigates this {@code AbstractApp} to (i.e. opens) a specific URL.
* Navigates this {@code AbstractApp} to (i.e. Opens) a specific URL.
*
* @param {Object|string} url - The URL to navigate this {@code AbstractApp}
* to (i.e. the URL to open).
* to (i.e. The URL to open).
* @protected
* @returns {void}
*/

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
/**
@@ -13,27 +14,24 @@ const AUDIO_LEVEL_DOTS = 5;
*/
const CENTER_DOT_INDEX = Math.floor(AUDIO_LEVEL_DOTS / 2);
/**
* The type of the React {@code Component} props of {@link AudioLevelIndicator}.
*/
type Props = {
/**
* The current audio level to display. The value should be a number between
* 0 and 1.
*/
audioLevel: number
};
/**
* Creates a ReactElement responsible for drawing audio levels.
*
* @extends {Component}
*/
class AudioLevelIndicator extends Component {
/**
* {@code AudioLevelIndicator}'s property types.
*
* @static
*/
static propTypes = {
/**
* The current audio level to display. The value should be a number
* between 0 and 1.
*
* @type {number}
*/
audioLevel: PropTypes.number
};
class AudioLevelIndicator extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -23,7 +23,7 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
* password + guest access configuration. Refer to {@link LoginDialog} for more
* info.
*
* @param {string} id - The XMPP user's ID (e.g. user@domain.com).
* @param {string} id - The XMPP user's ID (e.g. {@code user@domain.com}).
* @param {string} password - The XMPP user's password.
* @param {JitsiConference} conference - The conference for which the local
* participant's role will be upgraded.

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { Text, TextInput, View } from 'react-native';
import { connect as reduxConnect } from 'react-redux';
@@ -11,6 +12,65 @@ import { JitsiConnectionErrors } from '../../base/lib-jitsi-meet';
import { authenticateAndUpgradeRole, cancelLogin } from '../actions';
import styles from './styles';
/**
* The type of the React {@link Component} props of {@link LoginDialog}.
*/
type Props = {
/**
* {@link JitsiConference} that needs authentication - will hold a valid
* value in XMPP login + guest access mode.
*/
_conference: Object,
/**
* The server hosts specified in the global config.
*/
_configHosts: Object,
/**
* Indicates if the dialog should display "connecting" status message.
*/
_connecting: boolean,
/**
* The error which occurred during login/authentication.
*/
_error: Object,
/**
* The progress in the floating range between 0 and 1 of the authenticating
* and upgrading the role of the local participant/user.
*/
_progress: number,
/**
* Redux store dispatch method.
*/
dispatch: Dispatch<*>,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@link Component} state of {@link LoginDialog}.
*/
type State = {
/**
* The user entered password for the conference.
*/
password: string,
/**
* The user entered local participant name.
*/
username: string
};
/**
* Dialog asks user for username and password.
*
@@ -38,58 +98,14 @@ import styles from './styles';
* See {@link https://github.com/jitsi/jicofo#secure-domain} for a description
* of the configuration parameters.
*/
class LoginDialog extends Component {
/**
* LoginDialog component's property types.
*
* @static
*/
static propTypes = {
/**
* {@link JitsiConference} that needs authentication - will hold a valid
* value in XMPP login + guest access mode.
*/
_conference: PropTypes.object,
/**
*
*/
_configHosts: PropTypes.object,
/**
* Indicates if the dialog should display "connecting" status message.
*/
_connecting: PropTypes.bool,
/**
* The error which occurred during login/authentication.
*/
_error: PropTypes.object,
/**
* The progress in the floating range between 0 and 1 of the
* authenticating and upgrading the role of the local participant/user.
*/
_progress: PropTypes.number,
/**
* Redux store dispatch method.
*/
dispatch: PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class LoginDialog extends Component<Props, State> {
/**
* Initializes a new LoginDialog instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
this.state = {
@@ -119,7 +135,7 @@ class LoginDialog extends Component {
} = this.props;
let messageKey;
let messageOptions;
const messageOptions = {};
if (progress && progress < 1) {
messageKey = 'connection.FETCH_SESSION_ID';
@@ -142,7 +158,6 @@ class LoginDialog extends Component {
}
} else if (name) {
messageKey = 'dialog.connectErrorWithMsg';
messageOptions || (messageOptions = {});
messageOptions.msg = `${name} ${error.message}`;
}
}
@@ -170,7 +185,7 @@ class LoginDialog extends Component {
<Text style = { styles.dialogText }>
{
messageKey
? t(messageKey, messageOptions || {})
? t(messageKey, messageOptions)
: connecting
? t('connection.CONNECTING')
: ''
@@ -181,6 +196,8 @@ class LoginDialog extends Component {
);
}
_onUsernameChange: (string) => void;
/**
* Called when user edits the username.
*
@@ -194,6 +211,8 @@ class LoginDialog extends Component {
});
}
_onPasswordChange: (string) => void;
/**
* Called when user edits the password.
*
@@ -207,6 +226,8 @@ class LoginDialog extends Component {
});
}
_onCancel: () => void;
/**
* Notifies this LoginDialog that it has been dismissed by cancel.
*
@@ -217,6 +238,8 @@ class LoginDialog extends Component {
this.props.dispatch(cancelLogin());
}
_onLogin: () => void;
/**
* Notifies this LoginDialog that the login button (OK) has been pressed by
* the user.

View File

@@ -198,8 +198,8 @@ export function getNearestReceiverVideoQualityLevel(availableHeight: number) {
}
/**
* Handle an error thrown by the backend (i.e. lib-jitsi-meet) while
* manipulating a conference participant (e.g. pin or select participant).
* Handle an error thrown by the backend (i.e. {@code lib-jitsi-meet}) while
* manipulating a conference participant (e.g. Pin or select participant).
*
* @param {Error} err - The Error which was thrown by the backend while
* manipulating a conference participant and which is to be handled.

View File

@@ -71,7 +71,7 @@ export type ConnectionFailedError = {
/**
* Opens new connection.
*
* @param {string} [id] - The XMPP user's ID (e.g. user@server.com).
* @param {string} [id] - The XMPP user's ID (e.g. {@code user@server.com}).
* @param {string} [password] - The XMPP user's password.
* @returns {Function}
*/

View File

@@ -4,7 +4,7 @@ import { toState } from '../redux';
/**
* Retrieves a simplified version of the conference/location URL stripped of URL
* params (i.e. query/search and hash) which should be used for sending invites.
* params (i.e. Query/search and hash) which should be used for sending invites.
*
* @param {Function|Object} stateOrGetState - The redux state or redux's
* {@code getState} function.

View File

@@ -1,35 +1,35 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { connect } from 'react-redux';
/**
* The type of the React {@code Component} props of {@link DialogContainer}.
*/
type Props = {
/**
* The component to render.
*/
_component: Function,
/**
* The props to pass to the component that will be rendered.
*/
_componentProps: Object,
/**
* True if the UI is in a compact state where we don't show dialogs.
*/
_reducedUI: boolean
};
/**
* Implements a DialogContainer responsible for showing all dialogs. We will
* need a separate container so we can handle multiple dialogs by showing them
* simultaneously or queuing them.
*/
export class DialogContainer extends Component {
/**
* DialogContainer component's property types.
*
* @static
*/
static propTypes = {
/**
* The component to render.
*/
_component: PropTypes.func,
/**
* The props to pass to the component that will be rendered.
*/
_componentProps: PropTypes.object,
/**
* True if the UI is in a compact state where we don't show dialogs.
*/
_reducedUI: PropTypes.bool
};
export class DialogContainer extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -32,7 +32,7 @@ const SOCK_STREAM = 1; /* stream socket */
* The RTCPeerConnection provided by react-native-webrtc fires onaddstream
* before it remembers remotedescription (and thus makes it available to API
* clients). Because that appears to be a problem for lib-jitsi-meet which has
* been successfully running on Chrome, Firefox, etc. for a very long
* been successfully running on Chrome, Firefox and others for a very long
* time, attempt to meet its expectations (by extending RTCPPeerConnection).
*
* @class

View File

@@ -39,9 +39,10 @@ function _getCommonPrototype(a, b) {
}
/**
* Implements an absolute minimum of the common logic of Document.querySelector
* and Element.querySelector. Implements the most simple of selectors necessary
* to satisfy the call sites at the time of this writing i.e. select by tagName.
* Implements an absolute minimum of the common logic of
* {@code Document.querySelector} and {@code Element.querySelector}. Implements
* the most simple of selectors necessary to satisfy the call sites at the time
* of this writing (i.e. Select by tagName).
*
* @param {Node} node - The Node which is the root of the tree to query.
* @param {string} selectors - The group of CSS selectors to match on.

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { trackVideoStarted } from '../../tracks';
@@ -6,51 +7,71 @@ import { trackVideoStarted } from '../../tracks';
import { shouldRenderVideoTrack } from '../functions';
import { Video } from './_';
/**
* The type of the React {@code Component} props of {@link AbstractVideoTrack}.
*/
export type Props = {
/**
* The Redux dispatch function.
*/
dispatch: Dispatch<*>,
/**
* Callback to invoke when the {@link Video} of {@code AbstractVideoTrack}
* is clicked/pressed.
*/
onPress?: Function,
/**
* The Redux representation of the participant's video track.
*/
videoTrack?: Object,
/**
* Whether or not video should be rendered after knowing video playback has
* started.
*/
waitForVideoStarted?: boolean,
/**
* The z-order of the Video of AbstractVideoTrack in the stacking space of
* all Videos. For more details, refer to the zOrder property of the Video
* class for React Native.
*/
zOrder?: number,
/**
* Indicates whether zooming (pinch to zoom and/or drag) is enabled.
*/
zoomEnabled?: boolean
};
/**
* The type of the React {@code Component} state of {@link AbstractVideoTrack}.
*/
type State = {
/**
* The Redux representation of the participant's video track.
*/
videoTrack: Object | null
};
/**
* Implements a React {@link Component} that renders video element for a
* specific video track.
*
* @abstract
*/
export default class AbstractVideoTrack extends Component {
/**
* AbstractVideoTrack component's property types.
*
* @static
*/
static propTypes = {
dispatch: PropTypes.func,
/**
* Callback to invoke when the {@link Video} of
* {@code AbstractVideoTrack} is clicked/pressed.
*/
onPress: PropTypes.func,
videoTrack: PropTypes.object,
waitForVideoStarted: PropTypes.bool,
/**
* The z-order of the Video of AbstractVideoTrack in the stacking space
* of all Videos. For more details, refer to the zOrder property of the
* Video class for React Native.
*/
zOrder: PropTypes.number,
/**
* Indicates whether zooming (pinch to zoom and/or drag) is enabled.
*/
zoomEnabled: PropTypes.bool
};
export default class AbstractVideoTrack<P: Props> extends Component<P, State> {
/**
* Initializes a new AbstractVideoTrack instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: P) {
super(props);
this.state = {
@@ -69,7 +90,7 @@ export default class AbstractVideoTrack extends Component {
* receive.
* @returns {void}
*/
componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps: P) {
const oldValue = this.state.videoTrack;
const newValue = _falsy2null(nextProps.videoTrack);
@@ -88,7 +109,7 @@ export default class AbstractVideoTrack extends Component {
const { videoTrack } = this.state;
let render;
if (this.props.waitForVideoStarted) {
if (this.props.waitForVideoStarted && videoTrack) {
// That's the complex case: we have to wait for onPlaying before we
// render videoTrack. The complexity comes from the fact that
// onPlaying will come after we render videoTrack.
@@ -110,14 +131,15 @@ export default class AbstractVideoTrack extends Component {
render = shouldRenderVideoTrack(videoTrack, false);
}
const stream
= render ? videoTrack.jitsiTrack.getOriginalStream() : null;
const stream = render && videoTrack
? videoTrack.jitsiTrack.getOriginalStream() : null;
// Actual zoom is currently only enabled if the stream is a desktop
// stream.
const zoomEnabled
= this.props.zoomEnabled
&& stream
&& videoTrack
&& videoTrack.videoType === 'desktop';
return (
@@ -131,6 +153,8 @@ export default class AbstractVideoTrack extends Component {
);
}
_onVideoPlaying: () => void;
/**
* Handler for case when video starts to play.
*

View File

@@ -1,6 +1,5 @@
// @flow
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { RTCView } from 'react-native-webrtc';
@@ -9,60 +8,58 @@ import { Pressable } from '../../../react';
import styles from './styles';
import VideoTransform from './VideoTransform';
/**
* The type of the React {@code Component} props of {@link Video}.
*/
type Props = {
mirror: boolean,
onPlaying: Function,
/**
* Callback to invoke when the {@code Video} is clicked/pressed.
*/
onPress: Function,
stream: Object,
/**
* Similarly to the CSS property z-index, specifies the z-order of this
* Video in the stacking space of all Videos. When Videos overlap,
* zOrder determines which one covers the other. A Video with a larger
* zOrder generally covers a Video with a lower one.
*
* Non-overlapping Videos may safely share a z-order (because one does
* not have to cover the other).
*
* The support for zOrder is platform-dependent and/or
* implementation-specific. Thus, specifying a value for zOrder is to be
* thought of as giving a hint rather than as imposing a requirement.
* For example, video renderers such as Video are commonly implemented
* using OpenGL and OpenGL views may have different numbers of layers in
* their stacking space. Android has three: a layer bellow the window
* (aka default), a layer bellow the window again but above the previous
* layer (aka media overlay), and above the window. Consequently, it is
* advisable to limit the number of utilized layers in the stacking
* space to the minimum sufficient for the desired display. For example,
* a video call application usually needs a maximum of two zOrder
* values: 0 for the remote video(s) which appear in the background, and
* 1 for the local video(s) which appear above the remote video(s).
*/
zOrder: number,
/**
* Indicates whether zooming (pinch to zoom and/or drag) is enabled.
*/
zoomEnabled: boolean
};
/**
* The React Native {@link Component} which is similar to Web's
* {@code HTMLVideoElement} and wraps around react-native-webrtc's
* {@link RTCView}.
*/
export default class Video extends Component<*> {
/**
* {@code Video} component's property types.
*
* @static
*/
static propTypes = {
mirror: PropTypes.bool,
onPlaying: PropTypes.func,
/**
* Callback to invoke when the {@code Video} is clicked/pressed.
*/
onPress: PropTypes.func,
stream: PropTypes.object,
/**
* Similarly to the CSS property z-index, specifies the z-order of this
* Video in the stacking space of all Videos. When Videos overlap,
* zOrder determines which one covers the other. A Video with a larger
* zOrder generally covers a Video with a lower one.
*
* Non-overlapping Videos may safely share a z-order (because one does
* not have to cover the other).
*
* The support for zOrder is platform-dependent and/or
* implementation-specific. Thus, specifying a value for zOrder is to be
* thought of as giving a hint rather than as imposing a requirement.
* For example, video renderers such as Video are commonly implemented
* using OpenGL and OpenGL views may have different numbers of layers in
* their stacking space. Android has three: a layer bellow the window
* (aka default), a layer bellow the window again but above the previous
* layer (aka media overlay), and above the window. Consequently, it is
* advisable to limit the number of utilized layers in the stacking
* space to the minimum sufficient for the desired display. For example,
* a video call application usually needs a maximum of two zOrder
* values: 0 for the remote video(s) which appear in the background, and
* 1 for the local video(s) which appear above the remote video(s).
*/
zOrder: PropTypes.number,
/**
* Indicates whether zooming (pinch to zoom and/or drag) is enabled.
*/
zoomEnabled: PropTypes.bool
};
export default class Video extends Component<Props> {
/**
* React Component method that executes once component is mounted.
*

View File

@@ -1,8 +1,11 @@
/* @flow */
import React from 'react';
import { View } from 'react-native';
import { connect } from 'react-redux';
import AbstractVideoTrack from '../AbstractVideoTrack';
import type { Props } from '../AbstractVideoTrack';
import styles from './styles';
/**
@@ -10,14 +13,7 @@ import styles from './styles';
*
* @extends AbstractVideoTrack
*/
class VideoTrack extends AbstractVideoTrack {
/**
* VideoTrack component's property types.
*
* @static
*/
static propTypes = AbstractVideoTrack.propTypes
class VideoTrack extends AbstractVideoTrack<Props> {
/**
* Renders the video element for the associated video track.
*

View File

@@ -1,12 +1,42 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
/**
* The type of the React {@code Component} props of {@link Video}.
*/
type Props = {
/**
* CSS classes to add to the video element.
*/
className: string,
/**
* The value of the id attribute of the video. Used by the torture tests to
* locate video elements.
*/
id: string,
/**
* Optional callback to invoke once the video starts playing.
*/
onVideoPlaying: Function,
/**
* The JitsiLocalTrack to display.
*/
videoTrack: ?Object
};
/**
* Component that renders a video element for a passed in video track.
*
* @extends Component
*/
class Video extends Component {
class Video extends Component<Props> {
_videoElement: ?Object;
/**
* Default values for {@code Video} component's properties.
*
@@ -18,41 +48,13 @@ class Video extends Component {
id: ''
};
/**
* {@code Video} component's property types.
*
* @static
*/
static propTypes = {
/**
* CSS classes to add to the video element.
*/
className: PropTypes.string,
/**
* The value of the id attribute of the video. Used by the torture tests
* to locate video elements.
*/
id: PropTypes.string,
/**
* Optional callback to invoke once the video starts playing.
*/
onVideoPlaying: PropTypes.func,
/**
* The JitsiLocalTrack to display.
*/
videoTrack: PropTypes.object
};
/**
* Initializes a new {@code Video} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
/**
@@ -78,8 +80,10 @@ class Video extends Component {
* @returns {void}
*/
componentDidMount() {
this._videoElement.volume = 0;
this._videoElement.onplaying = this._onVideoPlaying;
if (this._videoElement) {
this._videoElement.volume = 0;
this._videoElement.onplaying = this._onVideoPlaying;
}
this._attachTrack(this.props.videoTrack);
}
@@ -98,13 +102,13 @@ class Video extends Component {
/**
* Updates the video display only if a new track is added. This component's
* updating is blackboxed from React to prevent re-rendering of video
* element, as the lib uses track.attach(videoElement) instead.
* element, as the lib uses {@code track.attach(videoElement)} instead.
*
* @inheritdoc
* @returns {boolean} - False is always returned to blackbox this component.
* @returns {boolean} - False is always returned to blackbox this component
* from React.
*/
shouldComponentUpdate(nextProps) {
shouldComponentUpdate(nextProps: Props) {
const currentJitsiTrack = this.props.videoTrack
&& this.props.videoTrack.jitsiTrack;
const nextJitsiTrack = nextProps.videoTrack
@@ -167,6 +171,8 @@ class Video extends Component {
}
}
_onVideoPlaying: () => void;
/**
* Invokes the onvideoplaying callback if defined.
*
@@ -179,6 +185,8 @@ class Video extends Component {
}
}
_setVideoElement: () => void;
/**
* Sets an instance variable for the component's video element so it can be
* referenced later for attaching and detaching a JitsiLocalTrack.

View File

@@ -1,51 +1,49 @@
import PropTypes from 'prop-types';
/* @flow */
import React from 'react';
import { connect } from 'react-redux';
import AbstractVideoTrack from '../AbstractVideoTrack';
import type { Props as AbstractVideoTrackProps } from '../AbstractVideoTrack';
import Video from './Video';
/**
* The type of the React {@code Component} props of {@link VideoTrack}.
*/
type Props = {
...AbstractVideoTrackProps,
/**
* CSS classes to add to the video element.
*/
className: string,
/**
* The value of the id attribute of the video. Used by the torture tests
* to locate video elements.
*/
id: string
};
/**
* Component that renders a video element for a passed in video track and
* notifies the store when the video has started playing.
*
* @extends AbstractVideoTrack
*/
class VideoTrack extends AbstractVideoTrack {
class VideoTrack extends AbstractVideoTrack<Props> {
/**
* Default values for {@code VideoTrack} component's properties.
*
* @static
*/
static defaultProps = {
...AbstractVideoTrack.defaultProps,
className: '',
id: ''
};
/**
* {@code VideoTrack} component's property types.
*
* @static
*/
static propTypes = {
...AbstractVideoTrack.propTypes,
/**
* CSS classes to add to the video element.
*/
className: PropTypes.string,
/**
* The value of the id attribute of the video. Used by the torture tests
* to locate video elements.
*/
id: PropTypes.string
};
/**
* Renders the video element.
*
@@ -62,6 +60,8 @@ class VideoTrack extends AbstractVideoTrack {
videoTrack = { this.props.videoTrack } />
);
}
_onVideoPlaying: () => void;
}
export default connect()(VideoTrack);

View File

@@ -58,7 +58,7 @@ export function isVideoMutedByUser(stateful: Function | Object) {
* otherwise, false.
*/
export function shouldRenderVideoTrack(
videoTrack: { muted: boolean, videoStarted: boolean },
videoTrack: ?{ muted: boolean, videoStarted: boolean },
waitForVideoStarted: boolean) {
return (
videoTrack

View File

@@ -146,11 +146,11 @@ export default class Avatar extends Component<Props, State> {
}
/**
* Notifies this {@code Component} that it will be unmounted and destroyed
* and, most importantly, that it should no longer call
* {@link #setState(Object)}. {@code Avatar} needs it because it downloads
* images via {@link ImageCache} which will asynchronously notify about
* success.
* Notifies this {@code Component} that it will be unmounted and destroyed,
* and most importantly, that it should no longer call
* {@link #setState(Object)}. The {@code Avatar} needs it because it
* downloads images via {@link ImageCache} which will asynchronously notify
* about success.
*
* @inheritdoc
* @returns {void}

View File

@@ -127,8 +127,9 @@ export function getParticipantCount(stateful: Object | Function) {
/**
* Returns participant's display name.
* FIXME: remove the hardcoded strings once interfaceConfig is stored in redux
* and merge with a similarly named method in conference.js.
*
* FIXME: Remove the hardcoded strings once interfaceConfig is stored in redux
* and merge with a similarly named method in {@code conference.js}.
*
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's
* {@code getState} function to be used to retrieve the state.

View File

@@ -1,5 +1,6 @@
/* @flow */
import InlineDialog from '@atlaskit/inline-dialog';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
/**
@@ -28,13 +29,68 @@ function _mapPositionToPaddingClass(position = 'left') {
return DIALOG_TO_PADDING_POSITION[position.split(' ')[0]];
}
/**
* The type of the React {@code Component} props of {@link Popover}.
*/
type Props = {
/**
* A child React Element to use as the trigger for showing the dialog.
*/
children: React$Node,
/**
* Additional CSS classnames to apply to the root of the {@code Popover}
* component.
*/
className: string,
/**
* The ReactElement to display within the dialog.
*/
content: Object,
/**
* Whether displaying of the popover should be prevented.
*/
disablePopover: boolean,
/**
* An id attribute to apply to the root of the {@code Popover}
* component.
*/
id: string,
/**
* Callback to invoke when the popover has opened.
*/
onPopoverOpen: Function,
/**
* From which side of the dialog trigger the dialog should display. The
* value will be passed to {@code InlineDialog}.
*/
position: string
};
/**
* The type of the React {@code Component} state of {@link Popover}.
*/
type State = {
/**
* Whether or not the {@code InlineDialog} should be displayed.
*/
showDialog: boolean
};
/**
* Implements a React {@code Component} for showing an {@code InlineDialog} on
* mouseenter of the trigger and contents, and hiding the dialog on mouseleave.
*
* @extends Component
*/
class Popover extends Component {
class Popover extends Component<Props, State> {
/**
* Default values for {@code Popover} component's properties.
*
@@ -45,66 +101,16 @@ class Popover extends Component {
id: ''
};
/**
* {@code Popover} component's property types.
*
* @static
*/
static propTypes = {
/**
* A child React Element to use as the trigger for showing the dialog.
*/
children: PropTypes.object,
/**
* Additional CSS classnames to apply to the root of the {@code Popover}
* component.
*/
className: PropTypes.string,
/**
* The ReactElement to display within the dialog.
*/
content: PropTypes.object,
/**
* Whether displaying of the popover should be prevented.
*/
disablePopover: PropTypes.bool,
/**
* An id attribute to apply to the root of the {@code Popover}
* component.
*/
id: PropTypes.string,
/**
* Callback to invoke when the popover has opened.
*/
onPopoverOpen: PropTypes.func,
/**
* From which side of the dialog trigger the dialog should display. The
* value will be passed to {@code InlineDialog}.
*/
position: PropTypes.string
};
/**
* Initializes a new {@code Popover} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
this.state = {
/**
* Whether or not the {@code InlineDialog} should be displayed.
*
* @type {boolean}
*/
showDialog: false
};
@@ -136,6 +142,8 @@ class Popover extends Component {
);
}
_onHideDialog: () => void;
/**
* Stops displaying the {@code InlineDialog}.
*
@@ -146,6 +154,8 @@ class Popover extends Component {
this.setState({ showDialog: false });
}
_onShowDialog: () => void;
/**
* Displays the {@code InlineDialog} and calls any registered onPopoverOpen
* callbacks.

View File

@@ -58,7 +58,6 @@ export type Props = {
visible?: ?boolean
};
/**
* Abstract (base) class for container of React {@link Component} children with
* a style.

View File

@@ -12,7 +12,7 @@ export default class AbstractPage<P> extends Component<P> {
* content of the component.
*
* Note: It is a static method as the {@code Component} may not be
* initialized yet when the UI invokes refresh (e.g. tab change).
* initialized yet when the UI invokes refresh (e.g. Tab change).
*
* @returns {void}
*/

View File

@@ -91,8 +91,8 @@ class NavigateSectionList extends Component<Props> {
}
/**
* Implements React's Component.render.
* Note: we don't use the refreshing value yet, because refreshing of these
* Implements React's {@code Component.render}.
* Note: We don't use the refreshing value yet, because refreshing of these
* lists is super quick, no need to complicate the code - yet.
*
* @inheritdoc

View File

@@ -1,47 +1,47 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { Linking } from 'react-native';
import Text from './Text';
/**
* The type of the React {@code Component} props of {@link Link}.
*/
type Props = {
/**
* The children to be displayed within this Link.
*/
children: React$Node,
/**
* Notifies that this Link failed to open the URL associated with it.
*/
onLinkingOpenURLRejected: Function,
/**
* The CSS style to be applied to this Link for the purposes of display.
*/
style: Object,
/**
* The URL to be opened when this Link is clicked/pressed.
*/
url: string
};
/**
* Implements a (hyper)link to a URL in the fashion of the HTML anchor element
* and its href attribute.
*/
export default class Link extends Component {
/**
* {@code Link} component's property types.
*
* @static
*/
static propTypes = {
/**
* The children to be displayed within this Link.
*/
children: PropTypes.node,
/**
* Notifies that this Link failed to open the URL associated with it.
*/
onLinkingOpenURLRejected: PropTypes.func,
/**
* The CSS style to be applied to this Link for the purposes of display.
*/
style: PropTypes.object,
/**
* The URL to be opened when this Link is clicked/pressed.
*/
url: PropTypes.string
};
export default class Link extends Component<Props> {
/**
* Initializes a new Link instance.
*
* @param {Object} props - Component properties.
*/
constructor(props) {
constructor(props: Props) {
super(props);
// Bind event handlers so they are only bound once for every instance.
@@ -77,6 +77,8 @@ export default class Link extends Component {
onRejected && onRejected(reason);
}
_onPress: () => void;
/**
* Handles press on this Link. Opens the URL associated with this Link.
*

View File

@@ -9,13 +9,6 @@ import type { Props } from '../AbstractContainer';
* @extends AbstractContainer
*/
export default class Container<P: Props> extends AbstractContainer<P> {
/**
* {@code Container} component's property types.
*
* @static
*/
static propTypes = AbstractContainer.propTypes;
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,34 +1,32 @@
/* @flow */
import Button from '@atlaskit/button';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { translate } from '../../../i18n';
declare var interfaceConfig: Object;
/**
* The type of the React {@code Component} props of {@link InlineDialogFailure}.
*/
type Props = {
/**
* Allows to retry the call that previously didn't succeed.
*/
onRetry: Function,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* Inline dialog that represents a failure and allows a retry.
*/
class InlineDialogFailure extends Component<*> {
/**
* {@code InlineDialogFailure}'s property types.
*
* @static
*/
static propTypes = {
/**
* Allows to retry the call that previously didn't succeed.
*/
onRetry: PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class InlineDialogFailure extends Component<Props> {
/**
* Renders the content of this component.
*

View File

@@ -1,7 +1,8 @@
// @flow
import { MultiSelectStateless } from '@atlaskit/multi-select';
import AKInlineDialog from '@atlaskit/inline-dialog';
import _debounce from 'lodash/debounce';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import InlineDialogFailure from './InlineDialogFailure';
@@ -9,118 +10,127 @@ import InlineDialogFailure from './InlineDialogFailure';
const logger = require('jitsi-meet-logger').getLogger(__filename);
/**
* A MultiSelect that is also auto-completing.
* The type of the React {@code Component} props of
* {@link MultiSelectAutocomplete}.
*/
class MultiSelectAutocomplete extends Component {
type Props = {
/**
* {@code MultiSelectAutocomplete} component's property types.
*
* @static
* The default value of the selected item.
*/
static propTypes = {
/**
* The default value of the selected item.
*/
defaultValue: PropTypes.array,
defaultValue: Array<Object>,
/**
* Optional footer to show as a last element in the results.
* Should be of type {content: <some content>}
*/
footer: PropTypes.object,
/**
* Optional footer to show as a last element in the results.
* Should be of type {content: <some content>}
*/
footer: Object,
/**
* Indicates if the component is disabled.
*/
isDisabled: PropTypes.bool,
/**
* Indicates if the component is disabled.
*/
isDisabled: boolean,
/**
* Text to display while a query is executing.
*/
loadingMessage: PropTypes.string,
/**
* Text to display while a query is executing.
*/
loadingMessage: string,
/**
* The text to show when no matches are found.
*/
noMatchesFound: PropTypes.string,
/**
* The text to show when no matches are found.
*/
noMatchesFound: string,
/**
* The function called immediately before a selection has been actually
* selected. Provides an opportunity to do any formatting.
*/
onItemSelected: PropTypes.func,
/**
* The function called immediately before a selection has been actually
* selected. Provides an opportunity to do any formatting.
*/
onItemSelected: Function,
/**
* The function called when the selection changes.
*/
onSelectionChange: PropTypes.func,
/**
* The function called when the selection changes.
*/
onSelectionChange: Function,
/**
* The placeholder text of the input component.
*/
placeholder: PropTypes.string,
/**
* The placeholder text of the input component.
*/
placeholder: string,
/**
* The service providing the search.
*/
resourceClient: PropTypes.shape({
makeQuery: PropTypes.func,
parseResults: PropTypes.func
}).isRequired,
/**
* The service providing the search.
*/
resourceClient: { makeQuery: Function, parseResults: Function },
/**
* Indicates if the component should fit the container.
*/
shouldFitContainer: PropTypes.bool,
/**
* Indicates if the component should fit the container.
*/
shouldFitContainer: boolean,
/**
* Indicates if we should focus.
*/
shouldFocus: PropTypes.bool
};
/**
* Indicates if we should focus.
*/
shouldFocus: boolean
};
/**
* The type of the React {@code Component} state of
* {@link MultiSelectAutocomplete}.
*/
type State = {
/**
* Indicates if the dropdown is open.
*/
isOpen: boolean,
/**
* The text that filters the query result of the search.
*/
filterValue: string,
/**
* Indicates if the component is currently loading results.
*/
loading: boolean,
/**
* Indicates if there was an error.
*/
error: boolean,
/**
* The list of result items.
*/
items: Array<Object>,
/**
* The list of selected items.
*/
selectedItems: Array<Object>
};
/**
* A MultiSelect that is also auto-completing.
*/
class MultiSelectAutocomplete extends Component<Props, State> {
/**
* Initializes a new {@code MultiSelectAutocomplete} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
const defaultValue = this.props.defaultValue || [];
this.state = {
/**
* Indicates if the dropdown is open.
*/
isOpen: false,
/**
* The text that filters the query result of the search.
*/
filterValue: '',
/**
* Indicates if the component is currently loading results.
*/
loading: false,
/**
* Indicates if there was an error.
*/
error: false,
/**
* The list of result items.
*/
items: [],
/**
* The list of selected items.
*/
selectedItems: [ ...defaultValue ]
};
@@ -137,7 +147,7 @@ class MultiSelectAutocomplete extends Component {
* having been selected.
* @returns {void}
*/
setSelectedItems(selectedItems = []) {
setSelectedItems(selectedItems: Array<Object> = []) {
this.setState({ selectedItems });
}
@@ -177,6 +187,8 @@ class MultiSelectAutocomplete extends Component {
);
}
_onFilterChange: (string) => void;
/**
* Sets the state and sends a query on filter change.
*
@@ -198,6 +210,8 @@ class MultiSelectAutocomplete extends Component {
}
}
_onRetry: () => void;
/**
* Retries the query on retry.
*
@@ -208,6 +222,8 @@ class MultiSelectAutocomplete extends Component {
this._sendQuery(this.state.filterValue);
}
_onSelectionChange: (Object) => void;
/**
* Updates the selected items when a selection event occurs.
*
@@ -258,6 +274,8 @@ class MultiSelectAutocomplete extends Component {
);
}
_sendQuery: (string) => void;
/**
* Sends a query to the resourceClient.
*

View File

@@ -1,6 +1,5 @@
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -17,32 +16,71 @@ const _RIGHT_WATERMARK_STYLE = {
backgroundImage: 'url(images/rightwatermark.png)'
};
/**
* The type of the React {@code Component} props of {@link Watermarks}.
*/
type Props = {
/**
* Whether or not the current user is logged in through a JWT.
*/
_isGuest: boolean,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@code Component} state of {@link Watermarks}.
*/
type State = {
/**
* The url to open when clicking the brand watermark.
*/
brandWatermarkLink: string,
/**
* The url to open when clicking the Jitsi watermark.
*/
jitsiWatermarkLink: string,
/**
* Whether or not the brand watermark should be displayed.
*/
showBrandWatermark: boolean,
/**
* Whether or not the Jitsi watermark should be displayed.
*/
showJitsiWatermark: boolean,
/**
* Whether or not the Jitsi watermark should be displayed for users not
* logged in through a JWT.
*/
showJitsiWatermarkForGuests: boolean,
/**
* Whether or not the show the "powered by Jitsi.org" link.
*/
showPoweredBy: boolean
};
/**
* A Web Component which renders watermarks such as Jits, brand, powered by,
* etc.
*/
class Watermarks extends Component<*, *> {
static propTypes = {
_isGuest: PropTypes.bool,
t: PropTypes.func
};
state = {
brandWatermarkLink: String,
jitsiWatermarkLink: String,
showBrandWatermark: Boolean,
showJitsiWatermark: Boolean,
showJitsiWatermarkForGuests: Boolean,
showPoweredBy: Boolean
};
class Watermarks extends Component<Props, State> {
/**
* Initializes a new Watermarks instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Object) {
constructor(props: Props) {
super(props);
let showBrandWatermark;

View File

@@ -113,7 +113,7 @@ function _set(
/**
* Returns redux state from the specified {@code stateful} which is presumed to
* be related to the redux state (e.g. the redux store, the redux
* be related to the redux state (e.g. The redux store, the redux
* {@code getState} function).
*
* @param {Function|Object} stateful - The entity such as the redux store or the

View File

@@ -1,11 +1,17 @@
// @flow
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from '../constants';
/**
* The type of the React {@code Component} props of {@link AspectRatioAware}.
*/
type Props = {
aspectRatio: ASPECT_RATIO_NARROW | ASPECT_RATIO_WIDE
};
/**
* Determines whether a specific React {@code Component} decorated into an
* {@link AspectRatioAware} has {@link ASPECT_RATIO_NARROW} as the value of its
@@ -34,20 +40,7 @@ export function makeAspectRatioAware(
/**
* Renders {@code WrappedComponent} with the React prop {@code aspectRatio}.
*/
class AspectRatioAware extends Component<*> {
/**
* Properties of the aspect ratio aware wrapper.
*/
static propTypes = {
/**
* Either {@link ASPECT_RATIO_NARROW} or {@link ASPECT_RATIO_WIDE}.
*/
aspectRatio: PropTypes.oneOf([
ASPECT_RATIO_NARROW,
ASPECT_RATIO_WIDE
])
}
class AspectRatioAware extends Component<Props> {
/**
* Implement's React render method to wrap the nested component.
*

View File

@@ -57,7 +57,7 @@ ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
* Retrieves the legacy profile values regardless of it's being in pre or
* post-flattening format.
*
* FIXME: Let's remove this after a predefined time (e.g. by July 2018) to avoid
* FIXME: Let's remove this after a predefined time (e.g. By July 2018) to avoid
* garbage in the source.
*
* @private

View File

@@ -73,7 +73,7 @@ export default class Storage {
* Returns the value associated with a specific key in this {@code Storage}
* in an async manner. The method is required for the cases where we need
* the stored data but we're not sure yet whether this {@code Storage} is
* already initialized (e.g. on app start).
* already initialized (e.g. On app start).
*
* @param {string} key - The name of the key to retrieve the value of.
* @returns {Promise}

View File

@@ -418,7 +418,7 @@ function _addTracks(tracks) {
* @returns {Promise} - A {@code Promise} resolved once all
* {@code gumProcess.cancel()} {@code Promise}s are settled because all we care
* about here is to be sure that the {@code getUserMedia} callbacks have
* completed (i.e. returned from the native side).
* completed (i.e. Returned from the native side).
*/
function _cancelGUMProcesses(getState) {
const logError

View File

@@ -115,7 +115,7 @@ class CalendarListContent extends Component<Props> {
*
* @private
* @param {string} url - The url string to navigate to.
* @param {string} analyticsEventName - Тhe name of the analytics event.
* @param {string} analyticsEventName - Тhe name of the analytics event
* associated with this action.
* @returns {void}
*/

View File

@@ -121,7 +121,7 @@ class CalendarListContent extends Component<Props> {
*
* @private
* @param {string} url - The url string to navigate to.
* @param {string} analyticsEventName - Тhe name of the analytics event.
* @param {string} analyticsEventName - Тhe name of the analytics event
* associated with this action.
* @returns {void}
*/

View File

@@ -30,7 +30,7 @@ function _isDisplayableCalendarEntry(entry) {
/**
* Updates the calendar entries in redux when new list is received. The feature
* calendar-sync doesn't display all calendar events, it displays unique
* title, URL, and start time tuples i.e. it doesn't display subsequent
* title, URL, and start time tuples, and it doesn't display subsequent
* occurrences of recurring events, and the repetitions of events coming from
* multiple calendars.
*

View File

@@ -433,9 +433,9 @@ function _mapDispatchToProps(dispatch) {
/**
* Dispatches an action changing the visibility of the {@link Toolbox}.
*
* @param {boolean} visible - {@code true} to show the {@code Toolbox}
* or {@code false} to hide it.
* @private
* @param {boolean} visible - Pass {@code true} to show the
* {@code Toolbox} or {@code false} to hide it.
* @returns {void}
*/
_setToolboxVisible(visible) {

View File

@@ -1,6 +1,5 @@
/* global interfaceConfig */
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { translate } from '../../base/i18n';
@@ -10,6 +9,8 @@ import { ConnectionStatsTable } from '../../connection-stats';
import statsEmitter from '../statsEmitter';
declare var interfaceConfig: Object;
/**
* The connection quality percentage that must be reached to be considered of
* good quality and can result in the connection indicator being hidden.
@@ -25,7 +26,7 @@ const INDICATOR_DISPLAY_THRESHOLD = 30;
*
* @type {Object[]}
*/
const QUALITY_TO_WIDTH = [
const QUALITY_TO_WIDTH: Array<Object> = [
// Full (3 bars)
{
@@ -54,108 +55,107 @@ const QUALITY_TO_WIDTH = [
// Note: we never show 0 bars as long as there is a connection.
];
/**
* The type of the React {@code Component} props of {@link ConnectionIndicator}.
*/
type Props = {
/**
* Whether or not the component should ignore setting a visibility class for
* hiding the component when the connection quality is not strong.
*/
alwaysVisible: boolean,
/**
* The current condition of the user's connection, matching one of the
* enumerated values in the library.
*/
connectionStatus: string,
/**
* Whether or not clicking the indicator should display a popover for more
* details.
*/
enableStatsDisplay: boolean,
/**
* The font-size for the icon.
*/
iconSize: number,
/**
* Whether or not the displays stats are for local video.
*/
isLocalVideo: boolean,
/**
* Relative to the icon from where the popover for more connection details
* should display.
*/
statsPopoverPosition: string,
/**
* Invoked to obtain translated strings.
*/
t: Function,
/**
* The user ID associated with the displayed connection indication and
* stats.
*/
userID: string
};
/**
* The type of the React {@code Component} state of {@link ConnectionIndicator}.
*/
type State = {
/**
* The timeout for automatically hiding the indicator.
*/
autoHideTimeout: TimeoutID | null,
/**
* Whether or not a CSS class should be applied to the root for hiding the
* connection indicator. By default the indicator should start out hidden
* because the current connection status is not known at mount.
*/
showIndicator: boolean,
/**
* Whether or not the popover content should display additional statistics.
*/
showMoreStats: boolean,
/**
* Cache of the stats received from subscribing to stats emitting. The keys
* should be the name of the stat. With each stat update, updates stats are
* mixed in with cached stats and a new stats object is set in state.
*/
stats: Object
};
/**
* Implements a React {@link Component} which displays the current connection
* quality percentage and has a popover to show more detailed connection stats.
*
* @extends {Component}
*/
class ConnectionIndicator extends Component {
/**
* {@code ConnectionIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* Whether or not the component should ignore setting a visibility class
* for hiding the component when the connection quality is not strong.
*/
alwaysVisible: PropTypes.bool,
/**
* The current condition of the user's connection, matching one of the
* enumerated values in the library.
*
* @type {JitsiParticipantConnectionStatus}
*/
connectionStatus: PropTypes.string,
/**
* Whether or not clicking the indicator should display a popover for
* more details.
*/
enableStatsDisplay: PropTypes.bool,
/**
* The font-size for the icon.
*/
iconSize: PropTypes.number,
/**
* Whether or not the displays stats are for local video.
*/
isLocalVideo: PropTypes.bool,
/**
* Relative to the icon from where the popover for more connection
* details should display.
*/
statsPopoverPosition: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func,
/**
* The user ID associated with the displayed connection indication and
* stats.
*/
userID: PropTypes.string
};
class ConnectionIndicator extends Component<Props, State> {
/**
* Initializes a new {@code ConnectionIndicator} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
this.state = {
/**
* The timeout for automatically hiding the indicator.
*
* @type {timeoutID}
*/
autoHideTimeout: null,
/**
* Whether or not a CSS class should be applied to the root for
* hiding the connection indicator. By default the indicator should
* start out hidden because the current connection status is not
* known at mount.
*
* @type {boolean}
*/
showIndicator: false,
/**
* Whether or not the popover content should display additional
* statistics.
*
* @type {boolean}
*/
showMoreStats: false,
/**
* Cache of the stats received from subscribing to stats emitting.
* The keys should be the name of the stat. With each stat update,
* updates stats are mixed in with cached stats and a new stats
* object is set in state.
*/
stats: {}
};
@@ -201,7 +201,9 @@ class ConnectionIndicator extends Component {
statsEmitter.unsubscribeToClientStats(
this.props.userID, this._onStatsUpdated);
clearTimeout(this.state.autoHideTimeout);
if (this.state.autoHideTimeout) {
clearTimeout(this.state.autoHideTimeout);
}
}
/**
@@ -257,7 +259,7 @@ class ConnectionIndicator extends Component {
return 'status-high';
}
return QUALITY_TO_WIDTH.find(x => percent >= x.percent).colorClass;
return this._getDisplayConfiguration(percent).colorClass;
}
/**
@@ -287,7 +289,7 @@ class ConnectionIndicator extends Component {
// established so far. Assume a strong connection to start.
tipKey = 'connectionindicator.quality.good';
} else {
const config = QUALITY_TO_WIDTH.find(x => percent >= x.percent);
const config = this._getDisplayConfiguration(percent);
tipKey = config.tip;
}
@@ -297,6 +299,21 @@ class ConnectionIndicator extends Component {
return this.props.t(tipKey);
}
/**
* Get the icon configuration from QUALITY_TO_WIDTH which has a percentage
* that matches or exceeds the passed in percentage. The implementation
* assumes QUALITY_TO_WIDTH is already sorted by highest to lowest
* percentage.
*
* @param {number} percent - The connection percentage, out of 100, to find
* the closest matching configuration for.
* @private
* @returns {Object}
*/
_getDisplayConfiguration(percent: number): Object {
return QUALITY_TO_WIDTH.find(x => percent >= x.percent) || {};
}
/**
* Returns additional class names to add to the root of the component. The
* class names are intended to be used for hiding or showing the indicator.
@@ -314,6 +331,8 @@ class ConnectionIndicator extends Component {
? 'show-connection-indicator' : 'hide-connection-indicator';
}
_onStatsUpdated: (Object) => void;
/**
* Callback invoked when new connection stats associated with the passed in
* user ID are available. Will update the component's display of current
@@ -341,6 +360,8 @@ class ConnectionIndicator extends Component {
this._updateIndicatorAutoHide(newStats.percent);
}
_onToggleShowMore: () => void;
/**
* Callback to invoke when the show more link in the popover content is
* clicked. Sets the state which will determine if the popover should show
@@ -383,7 +404,7 @@ class ConnectionIndicator extends Component {
} else {
const { percent } = this.state.stats;
iconWidth = QUALITY_TO_WIDTH.find(x => percent >= x.percent).width;
iconWidth = this._getDisplayConfiguration(percent).width;
}
return [
@@ -449,7 +470,10 @@ class ConnectionIndicator extends Component {
*/
_updateIndicatorAutoHide(percent) {
if (percent < INDICATOR_DISPLAY_THRESHOLD) {
clearTimeout(this.state.autoHideTimeout);
if (this.state.autoHideTimeout) {
clearTimeout(this.state.autoHideTimeout);
}
this.setState({
autoHideTimeout: null,
showIndicator: true

View File

@@ -1,119 +1,120 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { translate } from '../../base/i18n';
/**
* The type of the React {@code Component} props of
* {@link ConnectionStatsTable}.
*/
type Props = {
/**
* Statistics related to bandwidth.
* {{
* download: Number,
* upload: Number
* }}
*/
bandwidth: Object,
/**
* Statistics related to bitrate.
* {{
* download: Number,
* upload: Number
* }}
*/
bitrate: Object,
/**
* The number of bridges (aka media servers) currently used in the
* conference.
*/
bridgeCount: number,
/**
* A message describing the connection quality.
*/
connectionSummary: string,
/**
* The end-to-end round-trip-time.
*/
e2eRtt: number,
/**
* Statistics related to frame rates for each ssrc.
* {{
* [ ssrc ]: Number
* }}
*/
framerate: Object,
/**
* Whether or not the statistics are for local video.
*/
isLocalVideo: boolean,
/**
* Callback to invoke when the show additional stats link is clicked.
*/
onShowMore: Function,
/**
* Statistics related to packet loss.
* {{
* download: Number,
* upload: Number
* }}
*/
packetLoss: Object,
/**
* The region that we think the client is in.
*/
region: string,
/**
* Statistics related to display resolutions for each ssrc.
* {{
* [ ssrc ]: {
* height: Number,
* width: Number
* }
* }}
*/
resolution: Object,
/**
* The region of the media server that we are connected to.
*/
serverRegion: string,
/**
* Whether or not additional stats about bandwidth and transport should be
* displayed. Will not display even if true for remote participants.
*/
shouldShowMore: boolean,
/**
* Invoked to obtain translated strings.
*/
t: Function,
/**
* Statistics related to transports.
*/
transport: Array<Object>
};
/**
* React {@code Component} for displaying connection statistics.
*
* @extends Component
*/
class ConnectionStatsTable extends Component {
/**
* {@code ConnectionStatsTable} component's property types.
*
* @static
*/
static propTypes = {
/**
* Statistics related to bandwidth.
* {{
* download: Number,
* upload: Number
* }}
*/
bandwidth: PropTypes.object,
/**
* Statistics related to bitrate.
* {{
* download: Number,
* upload: Number
* }}
*/
bitrate: PropTypes.object,
/**
* The number of bridges (aka media servers) currently used in the
* conference.
*/
bridgeCount: PropTypes.number,
/**
* A message describing the connection quality.
*/
connectionSummary: PropTypes.string,
/**
* The end-to-end round-trip-time.
*/
e2eRtt: PropTypes.number,
/**
* Statistics related to frame rates for each ssrc.
* {{
* [ ssrc ]: Number
* }}
*/
framerate: PropTypes.object,
/**
* Whether or not the statistics are for local video.
*/
isLocalVideo: PropTypes.bool,
/**
* Callback to invoke when the show additional stats link is clicked.
*/
onShowMore: PropTypes.func,
/**
* Statistics related to packet loss.
* {{
* download: Number,
* upload: Number
* }}
*/
packetLoss: PropTypes.object,
/**
* The region that we think the client is in.
*/
region: PropTypes.string,
/**
* Statistics related to display resolutions for each ssrc.
* {{
* [ ssrc ]: {
* height: Number,
* width: Number
* }
* }}
*/
resolution: PropTypes.object,
/**
* The region of the media server that we are connected to.
*/
serverRegion: PropTypes.string,
/**
* Whether or not additional stats about bandwidth and transport should
* be displayed. Will not display even if true for remote participants.
*/
shouldShowMore: PropTypes.bool,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func,
/**
* Statistics related to transports.
*/
transport: PropTypes.array
};
class ConnectionStatsTable extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*
@@ -574,7 +575,7 @@ class ConnectionStatsTable extends Component {
* @private
* @returns {ReactElement}
*/
_renderTransportTableRow(config) {
_renderTransportTableRow(config: Object) {
const { additionalData, data, key, label } = config;
return (

View File

@@ -1,6 +1,5 @@
// @flow
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -34,32 +33,43 @@ const _URLS = {
ios: interfaceConfig.MOBILE_DOWNLOAD_LINK_IOS
};
/**
* The type of the React {@code Component} props of
* {@link DeepLinkingMobilePage}.
*/
type Props = {
/**
* The name of the conference attempting to being joined.
*/
_room: string,
/**
* The function to translate human-readable text.
*/
t: Function
};
/**
* The type of the React {@code Component} state of
* {@link DeepLinkingMobilePage}.
*/
type State = {
/**
* The URL to link to on the button for opening the mobile app.
*/
joinURL: string
};
/**
* React component representing mobile browser page.
*
* @class DeepLinkingMobilePage
*/
class DeepLinkingMobilePage extends Component<*, *> {
state: Object;
/**
* DeepLinkingMobilePage component's property types.
*
* @static
*/
static propTypes = {
/**
* The name of the conference attempting to being joined.
*/
_room: PropTypes.string,
/**
* The function to translate human-readable text.
*
* @public
* @type {Function}
*/
t: PropTypes.func
class DeepLinkingMobilePage extends Component<Props, State> {
state = {
joinURL: ''
};
/**
@@ -68,7 +78,7 @@ class DeepLinkingMobilePage extends Component<*, *> {
* @param {Object} props - The read-only React {@code Component} props with
* which the new instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
// Bind event handlers so they are only bound once per instance.

View File

@@ -1,7 +1,6 @@
// @flow
import Tabs from '@atlaskit/tabs';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -42,41 +41,65 @@ const TAB_LABELS = {
const VALID_TYPES = Object.keys(TAB_LABELS);
/**
* The type of the React {@code Component} props of {@link DesktopPicker}.
*/
type Props = {
/**
* An array with desktop sharing sources to be displayed.
*/
desktopSharingSources: Array<string>,
/**
* Used to request DesktopCapturerSources.
*/
dispatch: Dispatch<*>,
/**
* The callback to be invoked when the component is closed or when a
* DesktopCapturerSource has been chosen.
*/
onSourceChoose: Function,
/**
* Used to obtain translations.
*/
t: Function
};
/**
* The type of the React {@code Component} state of {@link DesktopPicker}.
*/
type State = {
/**
* The currently higlighted DesktopCapturerSource.
*/
selectedSource: Object,
/**
* The desktop source type currently being displayed.
*/
selectedTab: number,
/**
* An object containing all the DesktopCapturerSources.
*/
sources: Object,
/**
* The desktop source types to fetch previews for.
*/
types: Array<string>
};
/**
* React component for DesktopPicker.
*
* @extends Component
*/
class DesktopPicker extends Component<*, *> {
/**
* DesktopPicker component's property types.
*
* @static
*/
static propTypes = {
/**
* An array with desktop sharing sources to be displayed.
*/
desktopSharingSources: PropTypes.arrayOf(PropTypes.string),
/**
* Used to request DesktopCapturerSources.
*/
dispatch: PropTypes.func,
/**
* The callback to be invoked when the component is closed or when
* a DesktopCapturerSource has been chosen.
*/
onSourceChoose: PropTypes.func,
/**
* Used to obtain translations.
*/
t: PropTypes.func
};
class DesktopPicker extends Component<Props, State> {
_poller = null;
state = {
@@ -99,7 +122,7 @@ class DesktopPicker extends Component<*, *> {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
// Bind event handlers so they are only bound once per instance.
@@ -132,7 +155,7 @@ class DesktopPicker extends Component<*, *> {
* instance will receive.
* @returns {void}
*/
componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps: Props) {
const { desktopSharingSources } = nextProps;
/**

View File

@@ -1,48 +1,47 @@
/* @flow */
import Spinner from '@atlaskit/spinner';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import DesktopSourcePreview from './DesktopSourcePreview';
/**
* The type of the React {@code Component} props of {@link DesktopPickerPane}.
*/
type Props = {
/**
* The handler to be invoked when a DesktopSourcePreview is clicked.
*/
onClick: Function,
/**
* The handler to be invoked when a DesktopSourcePreview is double clicked.
*/
onDoubleClick: Function,
/**
* The id of the DesktopCapturerSource that is currently selected.
*/
selectedSourceId: string,
/**
* An array of DesktopCapturerSources.
*/
sources: Array<Object>,
/**
* The source type of the DesktopCapturerSources to display.
*/
type: string
};
/**
* React component for showing a grid of DesktopSourcePreviews.
*
* @extends Component
*/
class DesktopPickerPane extends Component {
/**
* DesktopPickerPane component's property types.
*
* @static
*/
static propTypes = {
/**
* The handler to be invoked when a DesktopSourcePreview is clicked.
*/
onClick: PropTypes.func,
/**
* The handler to be invoked when a DesktopSourcePreview is double
* clicked.
*/
onDoubleClick: PropTypes.func,
/**
* The id of the DesktopCapturerSource that is currently selected.
*/
selectedSourceId: PropTypes.string,
/**
* An array of DesktopCapturerSources.
*/
sources: PropTypes.array,
/**
* The source type of the DesktopCapturerSources to display.
*/
type: PropTypes.string
};
class DesktopPickerPane extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,55 +1,56 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
/**
* The type of the React {@code Component} props of
* {@link DesktopSourcePreview}.
*/
type Props = {
/**
* The callback to invoke when the component is clicked. The id of the
* clicked on DesktopCapturerSource will be passed in.
*/
onClick: Function,
/**
* The callback to invoke when the component is double clicked. The id of
* the DesktopCapturerSource will be passed in.
*/
onDoubleClick: Function,
/**
* The indicator which determines whether this DesktopSourcePreview is
* selected. If true, the 'is-selected' CSS class will be added to the root
* of Component.
*/
selected: boolean,
/**
* The DesktopCapturerSource to display.
*/
source: Object,
/**
* The source type of the DesktopCapturerSources to display.
*/
type: string
};
/**
* React component for displaying a preview of a DesktopCapturerSource.
*
* @extends Component
*/
class DesktopSourcePreview extends Component {
/**
* DesktopSourcePreview component's property types.
*
* @static
*/
static propTypes = {
/**
* The callback to invoke when the component is clicked. The id of
* the DesktopCapturerSource will be passed in.
*/
onClick: PropTypes.func,
/**
* The callback to invoke when the component is double clicked. The id
* of the DesktopCapturerSource will be passed in.
*/
onDoubleClick: PropTypes.func,
/**
* The indicator which determines whether this DesktopSourcePreview is
* selected. If true, the 'is-selected' CSS class will be added to the
* Component.
*/
selected: PropTypes.bool,
/**
* The DesktopCapturerSource to display.
*/
source: PropTypes.object,
/**
* The source type of the DesktopCapturerSources to display.
*/
type: PropTypes.string
};
class DesktopSourcePreview extends Component<Props> {
/**
* Initializes a new DesktopSourcePreview instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
this._onClick = this._onClick.bind(this);
@@ -83,6 +84,8 @@ class DesktopSourcePreview extends Component {
);
}
_onClick: () => void;
/**
* Invokes the passed in onClick callback.
*
@@ -94,6 +97,8 @@ class DesktopSourcePreview extends Component {
this.props.onClick(source.id, type);
}
_onDoubleClick: () => void;
/**
* Invokes the passed in onDoubleClick callback.
*

View File

@@ -1,31 +1,42 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { JitsiTrackEvents } from '../../base/lib-jitsi-meet';
/**
* The type of the React {@code Component} props of {@link AudioInputPreview}.
*/
type Props = {
/**
* The JitsiLocalTrack to show an audio level meter for.
*/
track: Object
};
/**
* The type of the React {@code Component} props of {@link AudioInputPreview}.
*/
type State = {
/**
* The current audio input level being received, from 0 to 1.
*/
audioLevel: number
};
/**
* React component for displaying a audio level meter for a JitsiLocalTrack.
*/
class AudioInputPreview extends Component {
/**
* AudioInputPreview component's property types.
*
* @static
*/
static propTypes = {
/*
* The JitsiLocalTrack to show an audio level meter for.
*/
track: PropTypes.object
};
class AudioInputPreview extends Component<Props, State> {
/**
* Initializes a new AudioInputPreview instance.
*
* @param {Object} props - The read-only React Component props with which
* the new instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
this.state = {
@@ -52,7 +63,7 @@ class AudioInputPreview extends Component {
* @inheritdoc
* @returns {void}
*/
componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps: Props) {
if (nextProps.track !== this.props.track) {
this._listenForAudioUpdates(nextProps.track);
this._updateAudioLevel(0);
@@ -117,6 +128,8 @@ class AudioInputPreview extends Component {
this._updateAudioLevel);
}
_updateAudioLevel: (number) => void;
/**
* Updates the internal state of the last know audio level. The level should
* be between 0 and 1, as the level will be used as a percentage out of 1.

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { translate } from '../../base/i18n';
@@ -6,28 +7,29 @@ import { Audio } from '../../base/media';
const TEST_SOUND_PATH = 'sounds/ring.wav';
/**
* The type of the React {@code Component} props of {@link AudioOutputPreview}.
*/
type Props = {
/**
* The device id of the audio output device to use.
*/
deviceId: string,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* React component for playing a test sound through a specified audio device.
*
* @extends Component
*/
class AudioOutputPreview extends Component {
/**
* AudioOutputPreview component's property types.
*
* @static
*/
static propTypes = {
/**
* The device id of the audio output device to use.
*/
deviceId: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class AudioOutputPreview extends Component<Props> {
_audioElement: ?Object;
/**
* Initializes a new AudioOutputPreview instance.
@@ -35,7 +37,7 @@ class AudioOutputPreview extends Component {
* @param {Object} props - The read-only React Component props with which
* the new instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
this._audioElement = null;
@@ -85,6 +87,8 @@ class AudioOutputPreview extends Component {
);
}
_onClick: () => void;
/**
* Plays a test sound.
*
@@ -96,6 +100,8 @@ class AudioOutputPreview extends Component {
&& this._audioElement.play();
}
_setAudioElement: (Object) => void;
/**
* Sets the instance variable for the component's audio element so it can be
* accessed directly.
@@ -104,7 +110,7 @@ class AudioOutputPreview extends Component {
* @private
* @returns {void}
*/
_setAudioElement(element) {
_setAudioElement(element: Object) {
this._audioElement = element;
}

View File

@@ -1,64 +1,64 @@
/* @flow */
import AKDropdownMenu from '@atlaskit/dropdown-menu';
import ChevronDownIcon from '@atlaskit/icon/glyph/chevron-down';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { translate } from '../../base/i18n';
/**
* The type of the React {@code Component} props of {@link DeviceSelector}.
*/
type Props = {
/**
* MediaDeviceInfos used for display in the select element.
*/
devices: Array<Object>,
/**
* If false, will return a selector with no selection options.
*/
hasPermission: boolean,
/**
* CSS class for the icon to the left of the dropdown trigger.
*/
icon: string,
/**
* If true, will render the selector disabled with a default selection.
*/
isDisabled: boolean,
/**
* The translation key to display as a menu label.
*/
label: string,
/**
* The callback to invoke when a selection is made.
*/
onSelect: Function,
/**
* The default device to display as selected.
*/
selectedDeviceId: string,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* React component for selecting a device from a select element. Wraps
* AKDropdownMenu with device selection specific logic.
*
* @extends Component
*/
class DeviceSelector extends Component {
/**
* DeviceSelector component's property types.
*
* @static
*/
static propTypes = {
/**
* MediaDeviceInfos used for display in the select element.
*/
devices: PropTypes.array,
/**
* If false, will return a selector with no selection options.
*/
hasPermission: PropTypes.bool,
/**
* CSS class for the icon to the left of the dropdown trigger.
*/
icon: PropTypes.string,
/**
* If true, will render the selector disabled with a default selection.
*/
isDisabled: PropTypes.bool,
/**
* The translation key to display as a menu label.
*/
label: PropTypes.string,
/**
* The callback to invoke when a selection is made.
*/
onSelect: PropTypes.func,
/**
* The default device to display as selected.
*/
selectedDeviceId: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class DeviceSelector extends Component<Props> {
/**
* Initializes a new DeviceSelector instance.
*
@@ -178,6 +178,8 @@ class DeviceSelector extends Component {
);
}
_onSelect: (Object) => void;
/**
* Invokes the passed in callback to notify of selection changes.
*

View File

@@ -1,35 +1,35 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { Video } from '../../base/media';
const VIDEO_ERROR_CLASS = 'video-preview-has-error';
/**
* The type of the React {@code Component} props of {@link VideoInputPreview}.
*/
type Props = {
/**
* An error message to display instead of a preview. Displaying an error
* will take priority over displaying a video preview.
*/
error: string,
/**
* The JitsiLocalTrack to display.
*/
track: Object
};
/**
* React component for displaying video. This component defers to lib-jitsi-meet
* logic for rendering the video.
*
* @extends Component
*/
class VideoInputPreview extends Component {
/**
* VideoInputPreview component's property types.
*
* @static
*/
static propTypes = {
/**
* An error message to display instead of a preview. Displaying an error
* will take priority over displaying a video preview.
*/
error: PropTypes.string,
/**
* The JitsiLocalTrack to display.
*/
track: PropTypes.object
};
class VideoInputPreview extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -7,54 +8,71 @@ import { appendSuffix } from '../functions';
import { translate } from '../../base/i18n';
import { participantDisplayNameChanged } from '../../base/participants';
/**
* The type of the React {@code Component} props of {@link DisplayName}.
*/
type Props = {
/**
* Whether or not the display name should be editable on click.
*/
allowEditing: boolean,
/**
* Invoked to update the participant's display name.
*/
dispatch: Dispatch<*>,
/**
* The participant's current display name.
*/
displayName: string,
/**
* A string to append to the displayName, if provided.
*/
displayNameSuffix: string,
/**
* The ID attribute to add to the component. Useful for global querying for
* the component by legacy components and torture tests.
*/
elementID: string,
/**
* The ID of the participant whose name is being displayed.
*/
participantID: string,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@code Component} state of {@link DisplayName}.
*/
type State = {
/**
* The current value of the display name in the edit field.
*/
editDisplayNameValue: string,
/**
* Whether or not the component should be displaying an editable input.
*/
isEditing: boolean
};
/**
* React {@code Component} for displaying and editing a participant's name.
*
* @extends Component
*/
class DisplayName extends Component {
/**
* {@code DisplayName}'s property types.
*
* @static
*/
static propTypes = {
/**
* Whether or not the display name should be editable on click.
*/
allowEditing: PropTypes.bool,
/**
* Invoked to update the participant's display name.
*/
dispatch: PropTypes.func,
/**
* The participant's current display name.
*/
displayName: PropTypes.string,
/**
* A string to append to the displayName, if provided.
*/
displayNameSuffix: PropTypes.string,
/**
* The ID attribute to add to the component. Useful for global querying
* for the component by legacy components and torture tests.
*/
elementID: PropTypes.string,
/**
* The ID of the participant whose name is being displayed.
*/
participantID: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class DisplayName extends Component<Props, State> {
_nameInput: ?HTMLInputElement;
/**
* Initializes a new {@code DisplayName} instance.
@@ -62,23 +80,11 @@ class DisplayName extends Component {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
this.state = {
/**
* The current value of the display name in the edit field.
*
* @type {string}
*/
editDisplayNameValue: '',
/**
* Whether or not the component should be displaying an editable
* input.
*
* @type {boolean}
*/
isEditing: false
};
@@ -109,7 +115,9 @@ class DisplayName extends Component {
* @returns {void}
*/
componentDidUpdate(previousProps, previousState) {
if (!previousState.isEditing && this.state.isEditing) {
if (!previousState.isEditing
&& this.state.isEditing
&& this._nameInput) {
this._nameInput.select();
}
}
@@ -156,6 +164,8 @@ class DisplayName extends Component {
);
}
_onChange: () => void;
/**
* Updates the internal state of the display name entered into the edit
* field.
@@ -170,6 +180,8 @@ class DisplayName extends Component {
});
}
_onKeyDown: () => void;
/**
* Submits the editted display name update if the enter key is pressed.
*
@@ -183,6 +195,8 @@ class DisplayName extends Component {
}
}
_onStartEditing: () => void;
/**
* Updates the component to display an editable input field and sets the
* initial value to the current display name.
@@ -199,6 +213,8 @@ class DisplayName extends Component {
}
}
_onSubmit: () => void;
/**
* Dispatches an action to update the display name if any change has
* occurred after editing. Clears any temporary state used to keep track
@@ -223,6 +239,8 @@ class DisplayName extends Component {
this._nameInput = null;
}
_setNameInputRef: (HTMLInputElement | null) => void;
/**
* Sets the internal reference to the HTML element backing the React
* {@code Component} input with id {@code editDisplayName}.

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { FieldTextStateless as TextField } from '@atlaskit/field-text';
@@ -10,51 +11,56 @@ import {
participantDisplayNameChanged
} from '../../base/participants';
/**
* The type of the React {@code Component} props of {@link DisplayNamePrompt}.
*/
type Props = {
/**
* The current ID for the local participant. Used for setting the display
* name on the associated participant.
*/
_localParticipantID: string,
/**
* Invoked to update the local participant's display name.
*/
dispatch: Dispatch<*>,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@code Component} props of {@link DisplayNamePrompt}.
*/
type State = {
/**
* The name to show in the display name text field.
*/
displayName: string
};
/**
* Implements a React {@code Component} for displaying a dialog with an field
* for setting the local participant's display name.
*
* @extends Component
*/
class DisplayNamePrompt extends Component {
/**
* {@code DisplayNamePrompt} component's property types.
*
* @static
*/
static propTypes = {
/**
* The current ID for the local participant. Used for setting the
* display name on the associated participant.
*/
_localParticipantID: PropTypes.string,
/**
* Invoked to update the local participant's display name.
*/
dispatch: PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class DisplayNamePrompt extends Component<Props, State> {
/**
* Initializes a new {@code DisplayNamePrompt} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
this.state = {
/**
* The name to show in the display name text field.
*
* @type {string}
*/
displayName: ''
};
@@ -88,6 +94,8 @@ class DisplayNamePrompt extends Component {
</Dialog>);
}
_onDisplayNameChange: (Object) => void;
/**
* Updates the entered display name.
*
@@ -102,12 +110,14 @@ class DisplayNamePrompt extends Component {
});
}
_onSubmit: () => boolean;
/**
* Dispatches an action to update the local participant's display name. A
* name must be entered for the action to dispatch.
*
* @private
* @returns {void}
* @returns {boolean}
*/
_onSubmit() {
const { displayName } = this.state;

View File

@@ -1,9 +1,8 @@
/* global interfaceConfig */
/* @flow */
import { FieldTextAreaStateless } from '@atlaskit/field-text-area';
import StarIcon from '@atlaskit/icon/glyph/star';
import StarFilledIcon from '@atlaskit/icon/glyph/star-filled';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -16,6 +15,8 @@ import { translate } from '../../base/i18n';
import { cancelFeedback, submitFeedback } from '../actions';
declare var interfaceConfig: Object;
const scoreAnimationClass
= interfaceConfig.ENABLE_FEEDBACK_ANIMATION ? 'shake-rotate' : '';
@@ -33,6 +34,70 @@ const SCORES = [
'feedback.veryGood'
];
/**
* The type of the React {@code Component} props of {@link FeedbackDialog}.
*/
type Props = {
/**
* The cached feedback message, if any, that was set when closing a previous
* instance of {@code FeedbackDialog}.
*/
_message: string,
/**
* The cached feedback score, if any, that was set when closing a previous
* instance of {@code FeedbackDialog}.
*/
_score: number,
/**
* The JitsiConference that is being rated. The conference is passed in
* because feedback can occur after a conference has been left, so
* references to it may no longer exist in redux.
*/
conference: Object,
/**
* Invoked to signal feedback submission or canceling.
*/
dispatch: Dispatch<*>,
/**
* Callback invoked when {@code FeedbackDialog} is unmounted.
*/
onClose: Function,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@code Component} state of {@link FeedbackDialog}.
*/
type State = {
/**
* The currently entered feedback message.
*/
message: string,
/**
* The score selection index which is currently being hovered. The value -1
* is used as a sentinel value to match store behavior of using -1 for no
* score having been selected.
*/
mousedOverScore: number,
/**
* The currently selected score selection index. The score will not be 0
* indexed so subtract one to map with SCORES.
*/
score: number
};
/**
* A React {@code Component} for displaying a dialog to rate the current
* conference quality, write a message describing the experience, and submit
@@ -40,49 +105,13 @@ const SCORES = [
*
* @extends Component
*/
class FeedbackDialog extends Component {
class FeedbackDialog extends Component<Props, State> {
/**
* {@code FeedbackDialog} component's property types.
*
* @static
* An array of objects with click handlers for each of the scores listed in
* the constant SCORES. This pattern is used for binding event handlers only
* once for each score selection icon.
*/
static propTypes = {
/**
* The cached feedback message, if any, that was set when closing a
* previous instance of {@code FeedbackDialog}.
*/
_message: PropTypes.string,
/**
* The cached feedback score, if any, that was set when closing a
* previous instance of {@code FeedbackDialog}.
*/
_score: PropTypes.number,
/**
* The JitsiConference that is being rated. The conference is passed in
* because feedback can occur after a conference has been left, so
* references to it may no longer exist in redux.
*
* @type {JitsiConference}
*/
conference: PropTypes.object,
/**
* Invoked to signal feedback submission or canceling.
*/
dispatch: PropTypes.func,
/**
* Callback invoked when {@code FeedbackDialog} is unmounted.
*/
onClose: PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
_scoreClickConfigurations: Array<Object>;
/**
* Initializes a new {@code FeedbackDialog} instance.
@@ -90,7 +119,7 @@ class FeedbackDialog extends Component {
* @param {Object} props - The read-only React {@code Component} props with
* which the new instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
const { _message, _score } = this.props;
@@ -121,13 +150,6 @@ class FeedbackDialog extends Component {
score: _score > -1 ? _score - 1 : _score
};
/**
* An array of objects with click handlers for each of the scores listed
* in SCORES. This pattern is used for binding event handlers only once
* for each score selection icon.
*
* @type {Object[]}
*/
this._scoreClickConfigurations = SCORES.map((textKey, index) => {
return {
_onClick: () => this._onScoreSelect(index),
@@ -234,6 +256,8 @@ class FeedbackDialog extends Component {
);
}
_onCancel: () => boolean;
/**
* Dispatches an action notifying feedback was not submitted. The submitted
* score will have one added as the rest of the app does not expect 0
@@ -251,6 +275,8 @@ class FeedbackDialog extends Component {
return true;
}
_onMessageChange: (Object) => void;
/**
* Updates the known entered feedback message.
*
@@ -274,6 +300,8 @@ class FeedbackDialog extends Component {
this.setState({ score });
}
_onScoreContainerMouseLeave: () => void;
/**
* Sets the currently hovered score to null to indicate no hover is
* occurring.
@@ -297,6 +325,8 @@ class FeedbackDialog extends Component {
this.setState({ mousedOverScore });
}
_onSubmit: () => void;
/**
* Dispatches the entered feedback for submission. The submitted score will
* have one added as the rest of the app does not expect 0 indexing.

View File

@@ -1,26 +1,26 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import BaseIndicator from './BaseIndicator';
/**
* The type of the React {@code Component} props of {@link AudioMutedIndicator}.
*/
type Props = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: string
};
/**
* React {@code Component} for showing an audio muted icon with a tooltip.
*
* @extends Component
*/
class AudioMutedIndicator extends Component {
/**
* {@code AudioMutedIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: PropTypes.string
};
class AudioMutedIndicator extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,15 +1,59 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import Tooltip from '@atlaskit/tooltip';
import { translate } from '../../../base/i18n';
/**
* The type of the React {@code Component} props of {@link BaseIndicator}.
*/
type Props = {
/**
* Additional CSS class names to set on the icon container.
*/
className: string,
/**
* The CSS classnames to set on the icon element of the component.
*/
iconClassName: string,
/**
* The font size for the icon.
*/
iconSize: string,
/**
* The ID attribue to set on the root element of the component.
*/
id: string,
/**
* Invoked to obtain translated strings.
*/
t: Function,
/**
* The translation key to use for displaying a tooltip when hovering over
* the component.
*/
tooltipKey: string,
/**
* From which side of the indicator the tooltip should appear from,
* defaulting to "top".
*/
tooltipPosition: string
};
/**
* React {@code Component} for showing an icon with a tooltip.
*
* @extends Component
*/
class BaseIndicator extends Component {
class BaseIndicator extends Component<Props> {
/**
* Default values for {@code BaseIndicator} component's properties.
*
@@ -23,50 +67,6 @@ class BaseIndicator extends Component {
tooltipPosition: 'top'
};
/**
* {@code BaseIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* Additional CSS class names to set on the icon container.
*/
className: PropTypes.string,
/**
* The CSS classnames to set on the icon element of the component.
*/
iconClassName: PropTypes.string,
/**
* The font size for the icon.
*/
iconSize: PropTypes.string,
/**
* The ID attribue to set on the root element of the component.
*/
id: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func,
/**
* The translation key to use for displaying a tooltip when hovering
* over the component.
*/
tooltipKey: PropTypes.string,
/**
* From which side of the indicator the tooltip should appear from.
* Defaults to "top".
*/
tooltipPosition: PropTypes.string
};
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,34 +1,33 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import BaseIndicator from './BaseIndicator';
/**
* The type of the React {@code Component} props of
* {@link DominantSpeakerIndicator}.
*/
type Props = {
/**
* The font-size for the icon.
*/
iconSize: number,
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: string
};
/**
* Thumbnail badge showing that the participant is the dominant speaker in
* the conference.
*
* @extends Component
*/
class DominantSpeakerIndicator extends Component {
/**
* {@code DominantSpeakerIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* The font-size for the icon.
*
* @type {number}
*/
iconSize: PropTypes.number,
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: PropTypes.string
};
class DominantSpeakerIndicator extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,26 +1,26 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import BaseIndicator from './BaseIndicator';
/**
* The type of the React {@code Component} props of {@link ModeratorIndicator}.
*/
type Props = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: string
};
/**
* React {@code Component} for showing a moderator icon with a tooltip.
*
* @extends Component
*/
class ModeratorIndicator extends Component {
/**
* {@code ModeratorIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: PropTypes.string
};
class ModeratorIndicator extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,33 +1,31 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import BaseIndicator from './BaseIndicator';
/**
* The type of the React {@code Component} props of {@link RaisedHandIndicator}.
*/
type Props = {
/**
* The font-size for the icon.
*/
iconSize: number,
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: string
};
/**
* Thumbnail badge showing that the participant would like to speak.
*
* @extends Component
*/
class RaisedHandIndicator extends Component {
/**
* {@code RaisedHandIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* The font-size for the icon.
*
* @type {number}
*/
iconSize: PropTypes.number,
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: PropTypes.string
};
class RaisedHandIndicator extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,26 +1,26 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import BaseIndicator from './BaseIndicator';
/**
* The type of the React {@code Component} props of {@link VideoMutedIndicator}.
*/
type Props = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: string
};
/**
* React {@code Component} for showing a video muted icon with a tooltip.
*
* @extends Component
*/
class VideoMutedIndicator extends Component {
/**
* {@code VideoMutedIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: PropTypes.string
};
class VideoMutedIndicator extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -149,11 +149,12 @@ class GoogleApi {
let title;
// Finding title from the broadcast with the same
// channelId. If not found (unknown scenario), we use
// the key as title again.
// boundStreamId. If not found (unknown scenario), we
// use the key as title again.
for (const broadcast of broadcasts) {
if (broadcast.snippet.channelId
=== stream.snippet.channelId) {
if (broadcast.contentDetails
&& broadcast.contentDetails.boundStreamId
=== stream.id) {
title = broadcast.snippet.title;
}
}

View File

@@ -37,14 +37,14 @@ export function beginAddPeople() {
/**
* Invites (i.e. sends invites to) an array of invitees (which may be a
* combination of users, rooms, phone numbers, and video rooms).
* Invites (i.e. Sends invites to) an array of invitees (which may be a
* combination of users, rooms, phone numbers, and video rooms.
*
* @param {Array<Object>} invitees - The recepients to send invites to.
* @param {Array<Object>} showCalleeInfo - Indicates whether the
* {@code CalleeInfo} should be displayed or not.
* @returns {Promise<Array<Object>>} A {@code Promise} resolving with an array
* of invitees who were not invited (i.e. invites were not sent to them).
* of invitees who were not invited (i.e. Invites were not sent to them).
*/
export function invite(
invitees: Array<Object>,

View File

@@ -2,7 +2,6 @@
import Avatar from '@atlaskit/avatar';
import InlineMessage from '@atlaskit/inline-message';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -19,88 +18,96 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
declare var interfaceConfig: Object;
/**
* The type of the React {@code Component} props of {@link AddPeopleDialog}.
*/
type Props = {
/**
* The {@link JitsiMeetConference} which will be used to invite "room"
* participants through the SIP Jibri (Video SIP gateway).
*/
_conference: Object,
/**
* The URL for validating if a phone number can be called.
*/
_dialOutAuthUrl: string,
/**
* Whether to show a footer text after the search results as a last element.
*/
_footerTextEnabled: boolean,
/**
* The JWT token.
*/
_jwt: string,
/**
* The query types used when searching people.
*/
_peopleSearchQueryTypes: Array<string>,
/**
* The URL pointing to the service allowing for people search.
*/
_peopleSearchUrl: string,
/**
* Whether or not to show Add People functionality.
*/
addPeopleEnabled: boolean,
/**
* Whether or not to show Dial Out functionality.
*/
dialOutEnabled: boolean,
/**
* The redux {@code dispatch} function.
*/
dispatch: Dispatch<*>,
/**
* Invoked to obtain translated strings.
*/
t: Function,
};
/**
* The type of the React {@code Component} state of {@link AddPeopleDialog}.
*/
type State = {
/**
* Indicating that an error occurred when adding people to the call.
*/
addToCallError: boolean,
/**
* Indicating that we're currently adding the new people to the
* call.
*/
addToCallInProgress: boolean,
/**
* The list of invite items.
*/
inviteItems: Array<Object>
};
/**
* The dialog that allows to invite people to the call.
*/
class AddPeopleDialog extends Component<*, *> {
/**
* {@code AddPeopleDialog}'s property types.
*
* @static
*/
static propTypes = {
/**
* The {@link JitsiMeetConference} which will be used to invite "room"
* participants through the SIP Jibri (Video SIP gateway).
*/
_conference: PropTypes.object,
/**
* The URL for validating if a phone number can be called.
*/
_dialOutAuthUrl: PropTypes.string,
/**
* Whether to show a footer text after the search results
* as a last element.
*/
_footerTextEnabled: PropTypes.bool,
/**
* The JWT token.
*/
_jwt: PropTypes.string,
/**
* The query types used when searching people.
*/
_peopleSearchQueryTypes: PropTypes.arrayOf(PropTypes.string),
/**
* The URL pointing to the service allowing for people search.
*/
_peopleSearchUrl: PropTypes.string,
/**
* Whether or not to show Add People functionality.
*/
addPeopleEnabled: PropTypes.bool,
/**
* Whether or not to show Dial Out functionality.
*/
dialOutEnabled: PropTypes.bool,
/**
* The redux {@code dispatch} function.
*/
dispatch: PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class AddPeopleDialog extends Component<Props, State> {
_multiselect = null;
_resourceClient: Object;
state = {
/**
* Indicating that an error occurred when adding people to the call.
*/
addToCallError: false,
/**
* Indicating that we're currently adding the new people to the
* call.
*/
addToCallInProgress: false,
/**
* The list of invite items.
*/
inviteItems: []
};
@@ -110,7 +117,7 @@ class AddPeopleDialog extends Component<*, *> {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
// Bind event handlers so they are only bound once per instance.
@@ -142,10 +149,11 @@ class AddPeopleDialog extends Component<*, *> {
/**
* React Component method that executes once component is updated.
*
* @param {Object} prevProps - The state object before the update.
* @param {Object} prevState - The state object before the update.
* @returns {void}
*/
componentDidUpdate(prevState) {
componentDidUpdate(prevProps, prevState) {
/**
* Clears selected items from the multi select component on successful
* invite.

View File

@@ -1,32 +1,32 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { translate } from '../../../base/i18n';
/**
* The type of the React {@code Component} props of {@link NoRoomError}.
*/
type Props = {
/**
* Additional CSS classnames to append to the root of the component.
*/
className: string,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* Displays an error message stating no room name was specified to fetch dial-in
* numbers for.
*
* @extends Component
*/
class NoRoomError extends Component {
/**
* {@code NoRoomError} component's property types.
*
* @static
*/
static propTypes = {
/**
* Additional CSS classnames to append to the root of the component.
*/
className: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class NoRoomError extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,31 +1,31 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { translate } from '../../../base/i18n';
/**
* Displays a conference ID used as a pin for dialing into a conferene.
* The type of the React {@code Component} props of {@link ConferenceID}.
*/
type Props = {
/**
* The conference ID for dialing in.
*/
conferenceID: number,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* Displays a conference ID used as a pin for dialing into a conference.
*
* @extends Component
*/
class ConferenceID extends Component {
/**
* {@code ConferenceID} component's property types.
*
* @static
*/
static propTypes = {
/**
* The conference ID for dialing in.
*/
conferenceID: PropTypes.number,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class ConferenceID extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,6 +1,5 @@
/* global config */
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { translate } from '../../../base/i18n';
@@ -8,53 +7,72 @@ import { translate } from '../../../base/i18n';
import ConferenceID from './ConferenceID';
import NumbersList from './NumbersList';
declare var config: Object;
/**
* The type of the React {@code Component} props of {@link DialInSummary}.
*/
type Props = {
/**
* Additional CSS classnames to append to the root of the component.
*/
className: string,
/**
* Whether or not numbers should include links with the telephone protocol.
*/
clickableNumbers: boolean,
/**
* The name of the conference to show a conferenceID for.
*/
room: string,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@code Component} state of {@link DialInSummary}.
*/
type State = {
/**
* The numeric ID of the conference, used as a pin when dialing in.
*/
conferenceID: ?string,
/**
* An error message to display.
*/
error: string,
/**
* Whether or not the app is fetching data.
*/
loading: boolean,
/**
* The dial-in numbers. entered by the local participant.
*/
numbers: ?Array<Object>,
/**
* Whether or not dial-in is allowed.
*/
numbersEnabled: ?boolean
}
/**
* Displays a page listing numbers for dialing into a conference and pin to
* the a specific conference.
*
* @extends Component
*/
class DialInSummary extends Component {
/**
* {@code DialInSummary} component's property types.
*
* @static
*/
static propTypes = {
/**
* Additional CSS classnames to append to the root of the component.
*/
className: PropTypes.string,
/**
* Whether or not numbers should include links with the telephone
* protocol.
*/
clickableNumbers: PropTypes.bool,
/**
* The name of the conference to show a conferenceID for.
*/
room: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
/**
* {@code DialInSummary} component's local state.
*
* @type {Object}
* @property {number} conferenceID - The numeric ID of the conference, used
* as a pin when dialing in.
* @property {string} error - An error message to display.
* @property {boolean} loading - Whether or not the app is fetching data.
* @property {Array|Object} numbers - The dial-in numbers.
* entered by the local participant.
* @property {boolean} numbersEnabled - Whether or not dial-in is allowed.
*/
class DialInSummary extends Component<Props, State> {
state = {
conferenceID: null,
error: '',
@@ -69,7 +87,7 @@ class DialInSummary extends Component {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
// Bind event handlers so they are only bound once for every instance.
@@ -183,6 +201,8 @@ class DialInSummary extends Component {
.catch(() => Promise.reject(this.props.t('info.genericError')));
}
_onGetConferenceIDSuccess: (Object) => void;
/**
* Callback invoked when fetching the conference ID succeeds.
*
@@ -200,6 +220,8 @@ class DialInSummary extends Component {
this.setState({ conferenceID: id });
}
_onGetNumbersSuccess: (Object) => void;
/**
* Callback invoked when fetching dial-in numbers succeeds. Sets the
* internal to show the numbers.
@@ -218,6 +240,8 @@ class DialInSummary extends Component {
});
}
_setErrorMessage: (string) => void;
/**
* Sets an error message to display on the page instead of content.
*

View File

@@ -1,47 +1,39 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { translate } from '../../../base/i18n';
type Props = {
/**
* Whether or not numbers should include links with the telephone protocol.
*/
clickableNumbers: boolean,
/**
* The conference ID for dialing in.
*/
conferenceID: number,
/**
* The phone numbers to display. Can be an array of numbers or an object
* with countries as keys and an array of numbers as values.
*/
numbers: { [string]: Array<string> } | Array<string>,
/**
* Invoked to obtain translated strings.
*/
t: Function
}
/**
* Displays a table with phone numbers to dial in to a conference.
*
* @extends Component
*/
class NumbersList extends Component {
/**
* {@code NumbersList} component's property types.
*
* @static
*/
static propTypes = {
/**
* Whether or not numbers should include links with the telephone
* protocol.
*/
clickableNumbers: PropTypes.bool,
/**
* The conference ID for dialing in.
*/
conferenceID: PropTypes.number,
/**
* The phone numbers to display. Can be an array of numbers
* or an object with countries as keys and an array of numbers
* as values.
*/
numbers: PropTypes.oneOfType([
PropTypes.array,
PropTypes.object
]),
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class NumbersList extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*
@@ -50,22 +42,21 @@ class NumbersList extends Component {
*/
render() {
const { numbers, t } = this.props;
const showWithoutCountries = Array.isArray(numbers);
return (
<table className = 'dial-in-numbers-list'>
<thead>
<tr>
{ showWithoutCountries
{ Array.isArray(numbers)
? null
: <th>{ t('info.country') }</th> }
<th>{ t('info.numbers') }</th>
</tr>
</thead>
<tbody className = 'dial-in-numbers-body'>
{ showWithoutCountries
{ Array.isArray(numbers)
? numbers.map(this._renderNumberRow)
: this._renderWithCountries() }
: this._renderWithCountries(numbers) }
</tbody>
</table>);
}
@@ -73,15 +64,25 @@ class NumbersList extends Component {
/**
* Renders rows of countries and associated phone numbers.
*
* @param {Object} numbersMapping - Things yeah.
* @private
* @returns {ReactElement[]}
*/
_renderWithCountries() {
_renderWithCountries(numbersMapping: Object) {
const rows = [];
for (const [ country, numbers ] of Object.entries(this.props.numbers)) {
const formattedNumbers = numbers.map(
number => this._renderNumberDiv(number));
for (const [ country, numbers ] of Object.entries(numbersMapping)) {
if (!Array.isArray(numbers)) {
return;
}
const formattedNumbers = numbers.map(number => {
if (typeof number === 'string') {
return this._renderNumberDiv(number);
}
return null;
});
rows.push(
<tr key = { country }>

View File

@@ -1,39 +1,39 @@
/* @flow */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from '../../../base/i18n';
/**
* The type of the React {@code Component} props of {@link DialInNumber}.
*/
type Props = {
/**
* The numberic identifier for the current conference, used after dialing a
* the number to join the conference.
*/
conferenceID: number,
/**
* The phone number to dial to begin the process of dialing into a
* conference.
*/
phoneNumber: string,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* React {@code Component} responsible for displaying a telephone number and
* conference ID for dialing into a conference.
*
* @extends Component
*/
class DialInNumber extends Component {
/**
* {@code DialInNumber} component's property types.
*
* @static
*/
static propTypes = {
/**
* The numberic identifier for the current conference, used after
* dialing a the number to join the conference.
*/
conferenceID: PropTypes.number,
/**
* The phone number to dial to begin the process of dialing into a
* conference.
*/
phoneNumber: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class DialInNumber extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -13,88 +14,103 @@ import PasswordForm from './PasswordForm';
const logger = require('jitsi-meet-logger').getLogger(__filename);
/**
* The type of the React {@code Component} props of {@link InfoDialog}.
*/
type Props = {
/**
* Whether or not the current user can modify the current password.
*/
_canEditPassword: boolean,
/**
* The JitsiConference for which to display a lock state and change the
* password.
*/
_conference: Object,
/**
* The name of the current conference. Used as part of inviting users.
*/
_conferenceName: string,
/**
* The current url of the conference to be copied onto the clipboard.
*/
_inviteURL: string,
/**
* The current location url of the conference.
*/
_locationURL: Object,
/**
* The value for how the conference is locked (or undefined if not locked)
* as defined by room-lock constants.
*/
_locked: string,
/**
* The current known password for the JitsiConference.
*/
_password: string,
/**
* The object representing the dialIn feature.
*/
dialIn: Object,
/**
* Invoked to open a dialog for adding participants to the conference.
*/
dispatch: Dispatch<*>,
/**
* The current known URL for a live stream in progress.
*/
liveStreamViewURL: string,
/**
* Callback invoked when the dialog should be closed.
*/
onClose: Function,
/**
* Callback invoked when a mouse-related event has been detected.
*/
onMouseOver: Function,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@code Component} state of {@link InfoDialog}.
*/
type State = {
/**
* Whether or not to show the password in editing mode.
*/
passwordEditEnabled: boolean,
/**
* The conference dial-in number to display.
*/
phoneNumber: ?string
};
/**
* A React Component with the contents for a dialog that shows information about
* the current conference.
*
* @extends Component
*/
class InfoDialog extends Component {
/**
* {@code InfoDialog} component's property types.
*
* @static
*/
static propTypes = {
/**
* Whether or not the current user can modify the current password.
*/
_canEditPassword: PropTypes.bool,
/**
* The JitsiConference for which to display a lock state and change the
* password.
*
* @type {JitsiConference}
*/
_conference: PropTypes.object,
/**
* The name of the current conference. Used as part of inviting users.
*/
_conferenceName: PropTypes.string,
/**
* The current url of the conference to be copied onto the clipboard.
*/
_inviteURL: PropTypes.string,
/**
* The current location url of the conference.
*/
_locationURL: PropTypes.object,
/**
* The value for how the conference is locked (or undefined if not
* locked) as defined by room-lock constants.
*/
_locked: PropTypes.string,
/**
* The current known password for the JitsiConference.
*/
_password: PropTypes.string,
/**
* The object representing the dialIn feature.
*/
dialIn: PropTypes.object,
/**
* Invoked to open a dialog for adding participants to the conference.
*/
dispatch: PropTypes.func,
/**
* The current known URL for a live stream in progress.
*/
liveStreamViewURL: PropTypes.string,
/**
* Callback invoked when the dialog should be closed.
*/
onClose: PropTypes.func,
/**
* Callback invoked when a mouse-related event has been detected.
*/
onMouseOver: PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class InfoDialog extends Component<Props, State> {
_copyElement: ?Object;
/**
* {@code InfoDialog} component's local state.
@@ -107,7 +123,7 @@ class InfoDialog extends Component {
*/
state = {
passwordEditEnabled: false,
phoneNumber: ''
phoneNumber: undefined
};
/**
@@ -116,7 +132,7 @@ class InfoDialog extends Component {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Props) {
super(props);
const { defaultCountry, numbers } = props.dialIn;
@@ -162,7 +178,8 @@ class InfoDialog extends Component {
const { defaultCountry, numbers } = nextProps.dialIn;
this.setState({
phoneNumber: _getDefaultPhoneNumber(numbers, defaultCountry)
phoneNumber:
_getDefaultPhoneNumber(numbers, defaultCountry)
});
}
}
@@ -293,6 +310,8 @@ class InfoDialog extends Component {
return this.props._inviteURL.replace(/^https?:\/\//i, '');
}
_onClickURLText: (Object) => void;
/**
* Callback invoked when a displayed URL link is clicked to prevent actual
* navigation from happening. The URL links have an href to display the
@@ -307,6 +326,8 @@ class InfoDialog extends Component {
event.preventDefault();
}
_onCopyInviteURL: () => void;
/**
* Callback invoked to copy the contents of {@code this._copyElement} to the
* clipboard.
@@ -316,14 +337,20 @@ class InfoDialog extends Component {
*/
_onCopyInviteURL() {
try {
this._copyElement.select();
if (!this._copyElement) {
throw new Error('No element to copy from.');
}
this._copyElement && this._copyElement.select();
document.execCommand('copy');
this._copyElement.blur();
this._copyElement && this._copyElement.blur();
} catch (err) {
logger.error('error when copying the text', err);
}
}
_onPasswordRemove: () => void;
/**
* Callback invoked to unlock the current JitsiConference.
*
@@ -334,6 +361,8 @@ class InfoDialog extends Component {
this._onPasswordSubmit('');
}
_onPasswordSubmit: (string) => void;
/**
* Callback invoked to set a password on the current JitsiConference.
*
@@ -352,6 +381,8 @@ class InfoDialog extends Component {
));
}
_onTogglePasswordEditState: () => void;
/**
* Toggles whether or not the password should currently be shown as being
* edited locally.
@@ -476,6 +507,8 @@ class InfoDialog extends Component {
&& phoneNumber);
}
_setCopyElement: () => void;
/**
* Sets the internal reference to the DOM/HTML element backing the React
* {@code Component} input.
@@ -485,7 +518,7 @@ class InfoDialog extends Component {
* @private
* @returns {void}
*/
_setCopyElement(element) {
_setCopyElement(element: Object) {
this._copyElement = element;
}
}

View File

@@ -1,56 +1,60 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { translate } from '../../../base/i18n';
import { LOCKED_LOCALLY } from '../../../room-lock';
/**
* The type of the React {@code Component} props of {@link PasswordForm}.
*/
type Props = {
/**
* Whether or not to show the password editing field.
*/
editEnabled: boolean,
/**
* The value for how the conference is locked (or undefined if not locked)
* as defined by room-lock constants.
*/
locked: string,
/**
* Callback to invoke when the local participant is submitting a password
* set request.
*/
onSubmit: Function,
/**
* The current known password for the JitsiConference.
*/
password: string,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@code Component} state of {@link PasswordForm}.
*/
type State = {
/**
* The value of the password being entered by the local participant.
*/
enteredPassword: string
};
/**
* React {@code Component} for displaying and editing the conference password.
*
* @extends Component
*/
class PasswordForm extends Component {
/**
* {@code PasswordForm} component's property types.
*
* @static
*/
static propTypes = {
/**
* Whether or not to show the password editing field.
*/
editEnabled: PropTypes.bool,
/**
* The value for how the conference is locked (or undefined if not
* locked) as defined by room-lock constants.
*/
locked: PropTypes.string,
/**
* Callback to invoke when the local participant is submitting a
* password set request.
*/
onSubmit: PropTypes.func,
/**
* The current known password for the JitsiConference.
*/
password: PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
/**
* {@code PasswordForm} component's local state.
*
* @type {Object}
* @property {string} enteredPassword - The value of the password being
* entered by the local participant.
*/
class PasswordForm extends Component<Props, State> {
state = {
enteredPassword: ''
};
@@ -61,7 +65,7 @@ class PasswordForm extends Component {
* @param {Props} props - The React {@code Component} props to initialize
* the new {@code PasswordForm} instance with.
*/
constructor(props) {
constructor(props: Props) {
super(props);
// Bind event handlers so they are only bound once per instance.
@@ -77,7 +81,7 @@ class PasswordForm extends Component {
* @inheritdoc
* @param {Props} nextProps - New props component will receive.
*/
componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps: Props) {
if (this.props.editEnabled && !nextProps.editEnabled) {
this.setState({ enteredPassword: '' });
}
@@ -148,6 +152,8 @@ class PasswordForm extends Component {
);
}
_onEnteredPasswordChange: (Object) => void;
/**
* Updates the internal state of entered password.
*
@@ -159,6 +165,8 @@ class PasswordForm extends Component {
this.setState({ enteredPassword: event.target.value });
}
_onPasswordSubmit: (Object) => void;
/**
* Invokes the passed in onSubmit callback to notify the parent that a
* password submission has been attempted.

View File

@@ -532,7 +532,7 @@ export function getDialInfoPageURL(
*/
export function _getDefaultPhoneNumber(
dialInNumbers: Object,
defaultCountry: string = 'US') {
defaultCountry: string = 'US'): ?string {
if (Array.isArray(dialInNumbers)) {
// Dumbly return the first number if an array.
return dialInNumbers[0];

View File

@@ -121,7 +121,7 @@ function _beginAddPeople(store, next, action) {
}
/**
* Handles the {@code invite} event of the feature invite i.e. invites specific
* Handles the {@code invite} event of the feature invite and invites specific
* invitees to the current, ongoing conference.
*
* @param {Object} event - The details of the event.
@@ -146,7 +146,7 @@ function _onInvite({ addPeopleControllerScope, externalAPIScope, invitees }) {
}
/**
* Handles the {@code performQuery} event of the feature invite i.e. queries for
* Handles the {@code performQuery} event of the feature invite and queries for
* invitees who may subsequently be invited to the current, ongoing conference.
*
* @param {Object} event - The details of the event.

View File

@@ -1,34 +1,35 @@
/* @flow */
import Lozenge from '@atlaskit/lozenge';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Dialog } from '../../base/dialog';
import { translate } from '../../base/i18n';
/**
* The type of the React {@code Component} props of
* {@link KeyboardShortcutsDialog}.
*/
type Props = {
/**
* A Map with keyboard keys as keys and translation keys as values.
*/
shortcutDescriptions: Object,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* Implements a React {@link Component} which displays a dialog describing
* registered keyboard shortcuts.
*
* @extends Component
*/
class KeyboardShortcutsDialog extends Component {
/**
* {@code KeyboardShortcutsDialog} component's property types.
*
* @static
*/
static propTypes = {
/**
* A Map with keyboard keys as keys and translation keys as values.
*/
shortcutDescriptions: PropTypes.object,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
class KeyboardShortcutsDialog extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -48,7 +48,7 @@ export function selectParticipant() {
/**
* Action to select the participant to be displayed in LargeVideo based on a
* variety of factors: if there is a dominant or pinned speaker, or if there are
* variety of factors: If there is a dominant or pinned speaker, or if there are
* remote tracks, etc.
*
* @returns {Function}
@@ -105,7 +105,7 @@ function _electLastVisibleRemoteVideo(tracks) {
}
/**
* Returns the identifier of the participant who is to be on the stage i.e.
* Returns the identifier of the participant who is to be on the stage and
* should be displayed in {@code LargeVideo}.
*
* @param {Object} state - The Redux state from which the participant to be

View File

@@ -288,7 +288,7 @@ class LocalRecordingInfoDialog extends Component<Props, State> {
}
/**
* Renders the moderator-only controls, i.e. stats of all users and the
* Renders the moderator-only controls: The stats of all users and the
* action links.
*
* @private

View File

@@ -221,7 +221,7 @@ class RecordingController {
/**
* Registers listeners for XMPP events.
*
* @param {JitsiConference} conference - {@code JitsiConference} instance.
* @param {JitsiConference} conference - A {@code JitsiConference} instance.
* @returns {void}
*/
registerEvents(conference: Object) {
@@ -633,7 +633,7 @@ class RecordingController {
}
/* eslint-disable */
return (Promise.resolve(): Promise<void>);
return (Promise.resolve(): Promise<void>);
// FIXME: better ways to satisfy flow and ESLint at the same time?
/* eslint-enable */

View File

@@ -161,7 +161,7 @@ class Encoder {
/**
* Constructor.
* Note: only create instance when Flac.isReady() returns true.
* Note: Only create instance when Flac.isReady() returns true.
*
* @param {number} sampleRate - Sample rate of the raw audio data.
* @param {number} bitDepth - Bit depth (bit per sample).

View File

@@ -1,31 +1,28 @@
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { LoadingIndicator } from '../../../base/react';
/**
* The type of the React {@code Component} props of
* {@link NetworkActivityIndicator}.
*/
type Props = {
/**
* Indicates whether there is network activity i.e. ongoing network
* requests.
*/
_networkActivity: boolean
};
/**
* The React {@code Component} which renders a progress indicator when there
* are ongoing network requests.
*/
class NetworkActivityIndicator extends Component<*> {
/**
* {@code NetworkActivityIndicator} React {@code Component}'s prop types.
*
* @static
*/
static propTypes = {
/**
* Indicates whether there is network activity i.e. ongoing network
* requests.
*
* @private
*/
_networkActivity: PropTypes.bool
};
class NetworkActivityIndicator extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -1,6 +1,5 @@
// @flow
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import {
@@ -20,54 +19,71 @@ declare var APP: Object;
const logger = require('jitsi-meet-logger').getLogger(__filename);
/**
* The type of the React {@code Component} props of
* {@link AbstractPageReloadOverlay}.
*/
type Props = {
/**
* The details is an object containing more information about the connection
* failed (shard changes, was the computer suspended, etc.)
*/
details: Object,
dispatch: Dispatch<*>,
/**
* The indicator which determines whether the reload was caused by network
* failure.
*/
isNetworkFailure: boolean,
/**
* The reason for the error that will cause the reload.
* NOTE: Used by PageReloadOverlay only.
*/
reason: string,
/**
* The function to translate human-readable text.
*/
t: Function
};
/**
* The type of the React {@code Component} state of
* {@link AbstractPageReloadOverlay}.
*/
type State = {
/**
* The translation key for the title of the overlay.
*/
message: string,
/**
* Current value(time) of the timer.
*/
timeLeft: number,
/**
* How long the overlay dialog will be displayed before the conference will
* be reloaded.
*/
timeoutSeconds: number,
/**
* The translation key for the title of the overlay.
*/
title: string
};
/**
* Implements an abstract React {@link Component} for the page reload overlays.
*/
export default class AbstractPageReloadOverlay extends Component<*, *> {
/**
* {@code AbstractPageReloadOverlay} component's property types.
*
* @static
*/
static propTypes = {
/**
* The details is an object containing more information about the
* connection failed (shard changes, was the computer suspended, etc.)
*
* @public
* @type {object}
*/
details: PropTypes.object,
dispatch: PropTypes.func,
/**
* The indicator which determines whether the reload was caused by
* network failure.
*
* @public
* @type {boolean}
*/
isNetworkFailure: PropTypes.bool,
/**
* The reason for the error that will cause the reload.
* NOTE: Used by PageReloadOverlay only.
*
* @public
* @type {string}
*/
reason: PropTypes.string,
/**
* The function to translate human-readable text.
*
* @public
* @type {Function}
*/
t: PropTypes.func
};
export default class AbstractPageReloadOverlay
extends Component<Props, State> {
/**
* Determines whether this overlay needs to be rendered (according to a
* specific redux state). Called by {@link OverlayContainer}.
@@ -109,38 +125,6 @@ export default class AbstractPageReloadOverlay extends Component<*, *> {
_interval: ?IntervalID;
state: {
/**
* The translation key for the title of the overlay.
*
* @type {string}
*/
message: string,
/**
* Current value(time) of the timer.
*
* @type {number}
*/
timeLeft: number,
/**
* How long the overlay dialog will be displayed before the
* conference will be reloaded.
*
* @type {number}
*/
timeoutSeconds: number,
/**
* The translation key for the title of the overlay.
*
* @type {string}
*/
title: string
};
/**
* Initializes a new AbstractPageReloadOverlay instance.
*

View File

@@ -1,26 +1,24 @@
import PropTypes from 'prop-types';
/* @flow */
import { Component } from 'react';
/**
* The type of the React {@code Component} props of
* {@link AbstractSuspendedOverlay}.
*/
type Props = {
/**
* The function to translate human-readable text.
*/
t: Function
};
/**
* Implements a React {@link Component} for suspended overlay. Shown when a
* suspend is detected.
*/
export default class AbstractSuspendedOverlay extends Component {
/**
* {@code AbstractSuspendedOverlay} component's property types.
*
* @static
*/
static propTypes = {
/**
* The function to translate human-readable text.
*
* @public
* @type {Function}
*/
t: PropTypes.func
};
export default class AbstractSuspendedOverlay extends Component<Props> {
/**
* Determines whether this overlay needs to be rendered (according to a
* specific redux state). Called by {@link OverlayContainer}.
@@ -29,7 +27,7 @@ export default class AbstractSuspendedOverlay extends Component {
* @returns {boolean} - If this overlay needs to be rendered, {@code true};
* {@code false}, otherwise.
*/
static needsRender(state) {
static needsRender(state: Object) {
return state['features/overlay'].suspendDetected;
}
}

View File

@@ -1,35 +1,31 @@
import PropTypes from 'prop-types';
/* @flow */
import { Component } from 'react';
/**
* The type of the React {@code Component} props of
* {@link AbstractUserMediaPermissionsOverlay}.
*/
type Props = {
/**
* The browser which is used currently. The text is different for every
* browser.
*/
browser: string,
/**
* The function to translate human-readable text.
*/
t: Function
};
/**
* Implements a React {@link Component} for overlay with guidance how to proceed
* with gUM prompt.
*/
export default class AbstractUserMediaPermissionsOverlay extends Component {
/**
* {@code AbstractUserMediaPermissionsOverlay} component's property types.
*
* @static
*/
static propTypes = {
/**
* The browser which is used currently. The text is different for every
* browser.
*
* @public
* @type {string}
*/
browser: PropTypes.string,
/**
* The function to translate human-readable text.
*
* @public
* @type {Function}
*/
t: PropTypes.func
};
export default class AbstractUserMediaPermissionsOverlay
extends Component<Props> {
/**
* Determines whether this overlay needs to be rendered (according to a
* specific redux state). Called by {@link OverlayContainer}.
@@ -38,7 +34,7 @@ export default class AbstractUserMediaPermissionsOverlay extends Component {
* @returns {boolean} - If this overlay needs to be rendered, {@code true};
* {@code false}, otherwise.
*/
static needsRender(state) {
static needsRender(state: Object) {
return state['features/overlay'].isMediaPermissionPromptVisible;
}
}
@@ -52,7 +48,7 @@ export default class AbstractUserMediaPermissionsOverlay extends Component {
* browser: string
* }}
*/
export function abstractMapStateToProps(state) {
export function abstractMapStateToProps(state: Object) {
const { browser } = state['features/overlay'];
return {

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -10,50 +11,40 @@ import {
import OverlayFrame from './OverlayFrame';
/**
* The type of the React {@code Component} props of
* {@link FilmstripOnlyOverlayFrame}.
*/
type Props = {
/**
* The source (e.g. URI, URL) of the avatar image of the local participant.
*/
_avatar: string,
/**
* The children components to be displayed into the overlay frame for
* filmstrip only mode.
*/
children: React$Node,
/**
* The css class name for the icon that will be displayed over the avatar.
*/
icon: string,
/**
* Indicates the css style of the overlay. If true, then lighter; darker,
* otherwise.
*/
isLightOverlay: boolean
};
/**
* Implements a React Component for the frame of the overlays in filmstrip only
* mode.
*/
class FilmstripOnlyOverlayFrame extends Component {
/**
* FilmstripOnlyOverlayFrame component's property types.
*
* @static
*/
static propTypes = {
/**
* The source (e.g. URI, URL) of the avatar image of the local
* participant.
*
* @private
*/
_avatar: PropTypes.string,
/**
* The children components to be displayed into the overlay frame for
* filmstrip only mode.
*
* @type {ReactElement}
*/
children: PropTypes.node.isRequired,
/**
* The css class name for the icon that will be displayed over the
* avatar.
*
* @type {string}
*/
icon: PropTypes.string,
/**
* Indicates the css style of the overlay. If true, then lighter;
* darker, otherwise.
*
* @type {boolean}
*/
isLightOverlay: PropTypes.bool
};
class FilmstripOnlyOverlayFrame extends Component<Props> {
/**
* Renders content related to the icon.
*

View File

@@ -1,32 +1,42 @@
/* global interfaceConfig */
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
declare var interfaceConfig: Object;
/**
* The type of the React {@code Component} props of {@link OverlayFrame}.
*/
type Props = {
/**
* The children components to be displayed into the overlay frame.
*/
children: React$Node,
/**
* Indicates the css style of the overlay. If true, then lighter; darker,
* otherwise.
*/
isLightOverlay: boolean
};
/**
* The type of the React {@code Component} state of {@link OverlayFrame}.
*/
type State = {
/**
* Whether or not the application is currently displaying in filmstrip only
* mode.
*/
filmstripOnly: boolean
};
/**
* Implements a React {@link Component} for the frame of the overlays.
*/
export default class OverlayFrame extends Component {
/**
* OverlayFrame component's property types.
*
* @static
*/
static propTypes = {
/**
* The children components to be displayed into the overlay frame.
*/
children: PropTypes.node.isRequired,
/**
* Indicates the css style of the overlay. If true, then lighter;
* darker, otherwise.
*
* @type {boolean}
*/
isLightOverlay: PropTypes.bool
};
export default class OverlayFrame extends Component<Props, State> {
/**
* Initializes a new AbstractOverlay instance.
*
@@ -34,7 +44,7 @@ export default class OverlayFrame extends Component {
* instance is to be initialized.
* @public
*/
constructor(props) {
constructor(props: Props) {
super(props);
this.state = {

View File

@@ -1,46 +1,37 @@
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { reloadNow } from '../../app';
import { translate } from '../../base/i18n';
/**
* The type of the React {@code Component} props of {@link ReloadButton}.
*/
type Props = {
/**
* Reloads the page.
*/
_reloadNow: Function,
/**
* The function to translate human-readable text.
*/
t: Function,
/**
* The translation key for the text in the button.
*/
textKey: string
};
/**
* Implements a React Component for button for the overlays that will reload
* the page.
*/
class ReloadButton extends Component<*> {
/**
* PageReloadOverlay component's property types.
*
* @static
*/
static propTypes = {
/**
* Reloads the page.
*
* @type {Function}
*/
_reloadNow: PropTypes.func,
/**
* The function to translate human-readable text.
*
* @public
* @type {Function}
*/
t: PropTypes.func,
/**
* The translation key for the text in the button.
*
* @type {string}
*/
textKey: PropTypes.string.isRequired
};
class ReloadButton extends Component<Props> {
/**
* Renders the button for relaod the page if necessary.
*

View File

@@ -1,4 +1,5 @@
import PropTypes from 'prop-types';
/* @flow */
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -8,13 +9,51 @@ import { Text } from '../../base/react';
import { STATUS_TO_I18N_KEY } from '../constants';
/**
* The type of the React {@code Component} props of {@link PresenceLabel}.
*/
type Props = {
/**
* The current present status associated with the passed in participantID
* prop.
*/
_presence: string,
/**
* Class name for the presence label.
*/
className: string,
/**
* Default presence status that will be displayed if user's presence status
* is not available.
*/
defaultPresence: string,
/**
* The ID of the participant whose presence status should display.
*/
participantID: string,
/**
* Styles for the presence label.
*/
style: Object,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* React {@code Component} for displaying the current presence status of a
* participant.
*
* @extends Component
*/
class PresenceLabel extends Component {
class PresenceLabel extends Component<Props> {
/**
* The default values for {@code PresenceLabel} component's property types.
*
@@ -24,45 +63,6 @@ class PresenceLabel extends Component {
_presence: ''
};
/**
* {@code PresenceLabel} component's property types.
*
* @static
*/
static propTypes = {
/**
* The current present status associated with the passed in
* participantID prop.
*/
_presence: PropTypes.string,
/**
* Class name for the presence label.
*/
className: PropTypes.string,
/**
* Default presence status that will be displayed if user's presence
* status is not available.
*/
defaultPresence: PropTypes.string,
/**
* The ID of the participant whose presence status shoul display.
*/
participantID: PropTypes.string,
/**
* Styles for the presence label.
*/
style: PropTypes.object,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -31,7 +31,8 @@ export function clearRecordingSessions() {
* Signals that the pending recording notification should be removed from the
* screen.
*
* @param {string} streamType - The type of the stream (e.g. file or stream).
* @param {string} streamType - The type of the stream ({@code 'file'} or
* {@code 'stream'}).
* @returns {Function}
*/
export function hidePendingRecordingNotification(streamType: string) {
@@ -52,7 +53,6 @@ export function hidePendingRecordingNotification(streamType: string) {
* Sets the stream key last used by the user for later reuse.
*
* @param {string} streamKey - The stream key to set.
* redux.
* @returns {{
* type: SET_STREAM_KEY,
* streamKey: string
@@ -69,7 +69,8 @@ export function setLiveStreamKey(streamKey: string) {
* Signals that the pending recording notification should be shown on the
* screen.
*
* @param {string} streamType - The type of the stream (e.g. file or stream).
* @param {string} streamType - The type of the stream ({@code file} or
* {@code stream}).
* @returns {Function}
*/
export function showPendingRecordingNotification(streamType: string) {
@@ -109,7 +110,8 @@ export function showRecordingError(props: Object) {
* Signals that the stopped recording notification should be shown on the
* screen for a given period.
*
* @param {string} streamType - The type of the stream (e.g. file or stream).
* @param {string} streamType - The type of the stream ({@code file} or
* {@code stream}).
* @returns {showNotification}
*/
export function showStoppedRecordingNotification(streamType: string) {
@@ -162,8 +164,8 @@ export function updateRecordingSessionData(session: Object) {
* passed.
*
* @param {?number} uid - The UID of the notification.
* redux.
* @param {string} streamType - The type of the stream (e.g. file or stream).
* @param {string} streamType - The type of the stream ({@code file} or
* {@code stream}).
* @returns {{
* type: SET_PENDING_RECORDING_NOTIFICATION_UID,
* streamType: string,

View File

@@ -10,8 +10,10 @@ import {
import { getActiveSession } from '../../functions';
import StartLiveStreamDialog from './StartLiveStreamDialog';
import StopLiveStreamDialog from './StopLiveStreamDialog';
import {
StartLiveStreamDialog,
StopLiveStreamDialog
} from './_';
/**
* The type of the React {@code Component} props of

View File

@@ -194,7 +194,6 @@ export default class AbstractStartLiveStreamDialog<P: Props>
* display of the entered YouTube stream key.
*
* @param {string} streamKey - The stream key entered in the field.
* changed text.
* @private
* @returns {void}
*/

View File

@@ -0,0 +1,3 @@
// @flow
export * from './native';

View File

@@ -0,0 +1,3 @@
// @flow
export * from './web';

View File

@@ -1,3 +1,3 @@
export { default as LiveStreamButton } from './LiveStreamButton';
export { default as StartLiveStreamDialog } from './StartLiveStreamDialog';
export { default as StopLiveStreamDialog } from './StopLiveStreamDialog';
// @flow
export * from './_';

View File

@@ -4,7 +4,7 @@ import React, { Component } from 'react';
import { Platform, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { translate } from '../../../base/i18n';
import { translate } from '../../../../base/i18n';
import {
GOOGLE_API_STATES,
@@ -12,7 +12,7 @@ import {
googleApi,
GoogleSignInButton,
setGoogleAPIState
} from '../../../google-api';
} from '../../../../google-api';
import styles from './styles';

View File

@@ -2,12 +2,12 @@
import { connect } from 'react-redux';
import { translate } from '../../../base/i18n';
import { translate } from '../../../../base/i18n';
import AbstractLiveStreamButton, {
_mapStateToProps,
type Props
} from './AbstractLiveStreamButton';
} from '../AbstractLiveStreamButton';
/**
* An implementation of a button for starting and stopping live streaming.

View File

@@ -4,14 +4,15 @@ import React from 'react';
import { View } from 'react-native';
import { connect } from 'react-redux';
import { translate } from '../../../base/i18n';
import { googleApi } from '../../../google-api';
import { translate } from '../../../../base/i18n';
import { googleApi } from '../../../../google-api';
import { setLiveStreamKey } from '../../actions';
import { setLiveStreamKey } from '../../../actions';
import AbstractStartLiveStreamDialog,
{ _mapStateToProps, type Props } from './AbstractStartLiveStreamDialog';
{ _mapStateToProps, type Props } from '../AbstractStartLiveStreamDialog';
import GoogleSigninForm from './GoogleSigninForm';
import StreamKeyForm from './StreamKeyForm';
import StreamKeyPicker from './StreamKeyPicker';
@@ -47,7 +48,7 @@ class StartLiveStreamDialog extends AbstractStartLiveStreamDialog<Props> {
*
* FIXME: This is a temporary method to store the streaming key on mobile
* for easier use, until the Google sign-in is implemented. We don't store
* the key on web for security reasons (e.g. we don't want to have the key
* the key on web for security reasons (e.g. We don't want to have the key
* stored if the used signed out).
*
* @private
@@ -80,7 +81,7 @@ class StartLiveStreamDialog extends AbstractStartLiveStreamDialog<Props> {
* A callback to be invoked when an authenticated user changes, so
* then we can get (or clear) the YouTube stream key.
*
* TODO: handle errors by showing some indication to the user.
* TODO: Handle errors by showing some indication to the user.
*
* @private
* @param {Object} response - The retreived signin response.

View File

@@ -3,12 +3,12 @@
import React from 'react';
import { connect } from 'react-redux';
import { DialogContent } from '../../../base/dialog';
import { translate } from '../../../base/i18n';
import { DialogContent } from '../../../../base/dialog';
import { translate } from '../../../../base/i18n';
import AbstractStopLiveStreamDialog, {
_mapStateToProps
} from './AbstractStopLiveStreamDialog';
} from '../AbstractStopLiveStreamDialog';
/**
* A React Component for confirming the participant wishes to stop the currently

View File

@@ -3,11 +3,12 @@
import React from 'react';
import { Linking, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { translate } from '../../../base/i18n';
import { translate } from '../../../../base/i18n';
import AbstractStreamKeyForm, {
type Props
} from './AbstractStreamKeyForm';
} from '../AbstractStreamKeyForm';
import styles from './styles';
/**

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