Bläddra i källkod

Adds dial-out UI.

j8
yanas 8 år sedan
förälder
incheckning
2855ea1500

+ 6
- 7
conference.js Visa fil

@@ -1295,6 +1295,12 @@ export default {
1295 1295
             APP.UI.onSharedVideoStop(id);
1296 1296
         });
1297 1297
 
1298
+        room.on(ConferenceEvents.USER_STATUS_CHANGED, (id, status) => {
1299
+            let user = room.getParticipantById(id);
1300
+            if (user) {
1301
+                APP.UI.updateUserStatus(user, status);
1302
+            }
1303
+        });
1298 1304
 
1299 1305
         room.on(ConferenceEvents.USER_ROLE_CHANGED, (id, role) => {
1300 1306
             if (this.isLocalId(id)) {
@@ -1651,13 +1657,6 @@ export default {
1651 1657
             });
1652 1658
         });
1653 1659
 
1654
-        APP.UI.addListener(UIEvents.SIP_DIAL, (sipNumber) => {
1655
-            room.dial(sipNumber)
1656
-                .catch((err) => {
1657
-                    logger.error("Error dialing out", err);
1658
-                });
1659
-        });
1660
-
1661 1660
         APP.UI.addListener(UIEvents.RESOLUTION_CHANGED,
1662 1661
             (id, oldResolution, newResolution, delay) => {
1663 1662
             var logObject = {

+ 64
- 0
css/_dial-out.scss Visa fil

@@ -0,0 +1,64 @@
1
+/**
2
+ * The dialog content element.
3
+ */
4
+.dial-out-content {
5
+    margin-top: 5px;
6
+
7
+   /**
8
+    * The style of the flag icon.
9
+    */
10
+    .dial-out-flag-icon {
11
+        position: absolute;
12
+        left: 5px;
13
+        top: 10px;
14
+    }
15
+
16
+    /**
17
+     * The style of the dial code element.
18
+     */
19
+    .dial-out-code {
20
+        padding-left: 25px !important;
21
+    }
22
+
23
+    /**
24
+     * The dial-out dialog error element.
25
+     */
26
+    .dial-out-error {
27
+        color: $errorColor;
28
+    }
29
+
30
+    /**
31
+     * The style of the dial input element.
32
+     */
33
+    .dial-out-input {
34
+        padding-left: 70px;
35
+    }
36
+
37
+    /**
38
+     * Re-styling the default dropdown inside the dial-out-content.
39
+     */
40
+    .dropdown {
41
+        left: $formPadding;
42
+        position: absolute !important;
43
+        width: 65px
44
+    }
45
+
46
+    /**
47
+     * Re-styling the default form-control inside the dial-out-content.
48
+     */
49
+    .form-control {
50
+        padding-bottom: 8px !important;
51
+    }
52
+
53
+    .dropdown {
54
+        display: inline-block;
55
+        position: relative;
56
+        overflow: hidden;
57
+    }
58
+
59
+    .dropdown-trigger-icon {
60
+        position: absolute;
61
+        right: 0;
62
+        top: 4px;
63
+    }
64
+}

+ 35
- 0
css/_flag-icon.scss Visa fil

@@ -0,0 +1,35 @@
1
+.flag-icon-background {
2
+  background-size: contain;
3
+  background-position: 50%;
4
+  background-repeat: no-repeat;
5
+}
6
+.flag-icon {
7
+  background-size: contain;
8
+  background-position: 50%;
9
+  background-repeat: no-repeat;
10
+  position: relative;
11
+  display: inline-block;
12
+  width: 1.33333333em;
13
+  line-height: 1em;
14
+}
15
+.flag-icon:before {
16
+  content: "\00a0";
17
+}
18
+.flag-icon-au {
19
+    background-image: url(../images/countries/au.svg);
20
+}
21
+.flag-icon-ca {
22
+    background-image: url(../images/countries/ca.svg);
23
+}
24
+.flag-icon-de {
25
+    background-image: url(../images/countries/de.svg);
26
+}
27
+.flag-icon-gb {
28
+    background-image: url(../images/countries/gb.svg);
29
+}
30
+.flag-icon-fr {
31
+    background-image: url(../images/countries/fr.svg);
32
+}
33
+.flag-icon-us {
34
+    background-image: url(../images/countries/us.svg);
35
+}

+ 1
- 0
css/_variables.scss Visa fil

@@ -149,6 +149,7 @@ $inputControlEmColor: #f29424;
149 149
 //buttons
150 150
 $linkFontColor: #489afe;
151 151
 $linkHoverFontColor: #287ade;
152
+$formPadding: 16px;
152 153
 
153 154
 /**
154 155
  * Unsupported browser

+ 1
- 1
css/components/_form-control.scss Visa fil

@@ -1,5 +1,5 @@
1 1
 .form-control {
2
-    padding: 16px 0;
2
+    padding: $formPadding 0;
3 3
 
4 4
     &:first-child {
5 5
         padding-top: 0;

+ 3
- 1
css/main.scss Visa fil

@@ -26,11 +26,13 @@
26 26
 
27 27
 @import 'font';
28 28
 @import 'font-awesome';
29
-
30 29
 /* Fonts END */
31 30
 
31
+@import 'flag-icon';
32
+
32 33
 /* Modules BEGIN */
33 34
 
35
+@import 'dial-out';
34 36
 @import 'toastr';
35 37
 @import 'base';
36 38
 @import 'utils';

+ 9
- 0
images/countries/au.svg Visa fil

@@ -0,0 +1,9 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
2
+  <g stroke-width="1pt">
3
+    <path fill="#006" d="M0 0h640v480H0z"/>
4
+    <path d="M0 0v27.95L307.037 250h38.647v-27.95L38.647 0H0zm345.684 0v27.95L38.647 250H0v-27.95L307.037 0h38.647z" fill="#fff"/>
5
+    <path d="M144.035 0v250h57.614V0h-57.615zM0 83.333v83.333h345.684V83.333H0z" fill="#fff"/>
6
+    <path d="M0 100v50h345.684v-50H0zM155.558 0v250h34.568V0h-34.568zM0 250l115.228-83.334h25.765L25.765 250H0zM0 0l115.228 83.333H89.463L0 18.633V0zm204.69 83.333L319.92 0h25.764L230.456 83.333H204.69zM345.685 250l-115.228-83.334h25.765l89.464 64.7V250z" fill="#c00"/>
7
+    <path d="M299.762 392.523l-43.653 3.795 6.013 43.406-30.187-31.764-30.186 31.764 6.014-43.406-43.653-3.795 37.68-22.364-24.244-36.495 40.97 15.514 13.42-41.713 13.42 41.712 40.97-15.515-24.242 36.494m224.444 62.372l-10.537-15.854 17.81 6.742 5.824-18.125 5.825 18.126 17.807-6.742-10.537 15.854 16.37 9.718-18.965 1.65 2.616 18.85-13.116-13.793-13.117 13.794 2.616-18.85-18.964-1.65m16.368-291.815l-10.537-15.856 17.81 6.742 5.824-18.122 5.825 18.12 17.807-6.74-10.537 15.855 16.37 9.717-18.965 1.65 2.616 18.85-13.116-13.793-13.117 13.794 2.616-18.85-18.964-1.65m-89.418 104.883l-10.537-15.853 17.808 6.742 5.825-18.125 5.825 18.125 17.808-6.742-10.536 15.853 16.37 9.72-18.965 1.65 2.615 18.85-13.117-13.795-13.117 13.795 2.617-18.85-18.964-1.65m216.212-37.929l-10.558-15.854 17.822 6.742 5.782-18.125 5.854 18.125 17.772-6.742-10.508 15.854 16.362 9.718-18.97 1.65 2.608 18.85-13.118-13.793-13.117 13.793 2.61-18.85-18.936-1.65m-22.251 73.394l-10.367 6.425 2.914-11.84-9.316-7.863 12.165-.896 4.605-11.29 4.606 11.29 12.165.897-9.317 7.863 2.912 11.84" fill-rule="evenodd" fill="#fff"/>
8
+  </g>
9
+</svg>

+ 6
- 0
images/countries/ca.svg Visa fil

@@ -0,0 +1,6 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
2
+  <g transform="translate(74.118) scale(.9375)">
3
+    <path fill="#fff" d="M81.137 0h362.276v512H81.137z"/>
4
+    <path fill="#bf0a30" d="M-100 0H81.138v512H-100zm543.413 0H624.55v512H443.414zM135.31 247.41l-14.067 4.808 65.456 57.446c4.95 14.764-1.72 19.116-5.97 26.86l71.06-9.02-1.85 71.512 14.718-.423-3.21-70.918 71.13 8.432c-4.402-9.297-8.32-14.233-4.247-29.098l65.414-54.426-11.447-4.144c-9.36-7.222 4.044-34.784 6.066-52.178 0 0-38.195 13.135-40.698 6.262l-9.727-18.685-34.747 38.17c-3.796.91-5.413-.6-6.304-3.808l16.053-79.766-25.42 14.297c-2.128.91-4.256.125-5.658-2.355l-24.45-49.06-25.21 50.95c-1.9 1.826-3.803 2.037-5.382.796l-24.204-13.578 14.53 79.143c-1.156 3.14-3.924 4.025-7.18 2.324l-33.216-37.737c-4.345 6.962-7.29 18.336-13.033 20.885-5.744 2.387-24.98-4.823-37.873-7.637 4.404 15.895 18.176 42.302 9.46 50.957z"/>
5
+  </g>
6
+</svg>

+ 5
- 0
images/countries/de.svg Visa fil

@@ -0,0 +1,5 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
2
+  <path fill="#ffce00" d="M0 320h640v160.002H0z"/>
3
+  <path d="M0 0h640v160H0z"/>
4
+  <path fill="#d00" d="M0 160h640v160H0z"/>
5
+</svg>

+ 7
- 0
images/countries/fr.svg Visa fil

@@ -0,0 +1,7 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
2
+  <g fill-rule="evenodd" stroke-width="1pt">
3
+    <path fill="#fff" d="M0 0h640v480H0z"/>
4
+    <path fill="#00267f" d="M0 0h213.337v480H0z"/>
5
+    <path fill="#f31830" d="M426.662 0H640v480H426.662z"/>
6
+  </g>
7
+</svg>

+ 15
- 0
images/countries/gb.svg Visa fil

@@ -0,0 +1,15 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
2
+  <defs>
3
+    <clipPath id="a">
4
+      <path fill-opacity=".67" d="M-85.333 0h682.67v512h-682.67z"/>
5
+    </clipPath>
6
+  </defs>
7
+  <g clip-path="url(#a)" transform="translate(80) scale(.94)">
8
+    <g stroke-width="1pt">
9
+      <path fill="#006" d="M-256 0H768.02v512.01H-256z"/>
10
+      <path d="M-256 0v57.244l909.535 454.768H768.02V454.77L-141.515 0H-256zM768.02 0v57.243L-141.515 512.01H-256v-57.243L653.535 0H768.02z" fill="#fff"/>
11
+      <path d="M170.675 0v512.01h170.67V0h-170.67zM-256 170.67v170.67H768.02V170.67H-256z" fill="#fff"/>
12
+      <path d="M-256 204.804v102.402H768.02V204.804H-256zM204.81 0v512.01h102.4V0h-102.4zM-256 512.01L85.34 341.34h76.324l-341.34 170.67H-256zM-256 0L85.34 170.67H9.016L-256 38.164V0zm606.356 170.67L691.696 0h76.324L426.68 170.67h-76.324zM768.02 512.01L426.68 341.34h76.324L768.02 473.848v38.162z" fill="#c00"/>
13
+    </g>
14
+  </g>
15
+</svg>

+ 18
- 0
images/countries/us.svg Visa fil

@@ -0,0 +1,18 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
2
+  <g fill-rule="evenodd" transform="scale(.9375)">
3
+    <g stroke-width="1pt">
4
+      <path d="M0 0h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0z" fill="#bd3d44"/>
5
+      <path d="M0 39.385h972.81V78.77H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0z" fill="#fff"/>
6
+    </g>
7
+    <path fill="#192f5d" d="M0 0h389.12v275.69H0z"/>
8
+    <g fill="#fff">
9
+      <path d="M32.427 11.8l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 39.37l3.54 10.896h11.458L70.583 57l3.542 10.897-9.27-6.734-9.269 6.734L59.126 57l-9.269-6.734h11.458zm64.852 0l3.54 10.896h11.457L135.435 57l3.54 10.897-9.268-6.734-9.27 6.734L123.978 57l-9.27-6.734h11.458zm64.855 0l3.54 10.896h11.458L200.29 57l3.541 10.897-9.27-6.734-9.268 6.734L188.833 57l-9.269-6.734h11.457zm64.855 0l3.54 10.896h11.458L265.145 57l3.541 10.897-9.269-6.734-9.27 6.734L253.69 57l-9.27-6.734h11.458zm64.852 0l3.54 10.896h11.457L329.997 57l3.54 10.897-9.268-6.734-9.27 6.734L318.54 57l-9.27-6.734h11.458zM32.427 66.939l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 94.508l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zM32.427 122.078l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 149.647l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458z"/>
10
+      <g>
11
+        <path d="M32.427 177.217l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 204.786l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458z"/>
12
+      </g>
13
+      <g>
14
+        <path d="M32.427 232.356l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458z"/>
15
+      </g>
16
+    </g>
17
+  </g>
18
+</svg>

+ 1
- 1
interface_config.js Visa fil

@@ -38,7 +38,7 @@ var interfaceConfig = { // eslint-disable-line no-unused-vars
38 38
         //main toolbar
39 39
         'microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'hangup',
40 40
         //extended toolbar
41
-        'profile', 'contacts', 'chat', 'recording', 'etherpad', 'sharedvideo', 'sip', 'settings', 'raisehand', 'filmstrip'], // jshint ignore:line
41
+        'profile', 'contacts', 'chat', 'recording', 'etherpad', 'sharedvideo', 'dialout', 'settings', 'raisehand', 'filmstrip'], // jshint ignore:line
42 42
     /**
43 43
      * Main Toolbar Buttons
44 44
      * All of them should be in TOOLBAR_BUTTONS

+ 11
- 6
lang/main.json Visa fil

@@ -277,8 +277,6 @@
277 277
         "Save": "Save",
278 278
         "recording": "Recording",
279 279
         "recordingToken": "Enter recording token",
280
-        "Dial": "Dial",
281
-        "sipMsg": "Enter SIP number",
282 280
         "passwordCheck": "Are you sure you would like to remove your password?",
283 281
         "passwordMsg": "Set a password to lock your room",
284 282
         "shareLink": "Share the link to the call",
@@ -447,9 +445,16 @@
447 445
         "unlocked": "This call is unlocked. Any new caller with the link may join the call."
448 446
     },
449 447
     "videoStatus": {
450
-        "hd": "HD",
451
-        "hdVideo": "HD video",
452
-        "sd": "SD",
453
-        "sdVideo": "SD video"
448
+      "hd": "HD",
449
+      "hdVideo": "HD video",
450
+      "sd": "SD",
451
+      "sdVideo": "SD video"
452
+    },
453
+    "dialOut": {
454
+        "dial": "Dial",
455
+        "dialOut": "Call a phone number",
456
+        "statusMessage": "is now __status__",
457
+        "enterPhone": "Enter phone number",
458
+        "phoneNotAllowed": "Oh, we don't support that destination yet! Sorry!"
454 459
     }
455 460
 }

+ 17
- 2
modules/UI/UI.js Visa fil

@@ -43,7 +43,7 @@ import {
43 43
     showDialPadButton,
44 44
     showEtherpadButton,
45 45
     showSharedVideoButton,
46
-    showSIPCallButton,
46
+    showDialOutButton,
47 47
     showToolbox
48 48
 } from '../../react/features/toolbox';
49 49
 
@@ -544,7 +544,7 @@ UI.onPeerVideoTypeChanged
544 544
 UI.updateLocalRole = isModerator => {
545 545
     VideoLayout.showModeratorIndicator();
546 546
 
547
-    APP.store.dispatch(showSIPCallButton(isModerator));
547
+    APP.store.dispatch(showDialOutButton(isModerator));
548 548
     APP.store.dispatch(showSharedVideoButton());
549 549
 
550 550
     Recording.showRecordingButton(isModerator);
@@ -589,6 +589,21 @@ UI.updateUserRole = user => {
589 589
     }
590 590
 };
591 591
 
592
+/**
593
+ * Updates the user status.
594
+ *
595
+ * @param {JitsiParticipant} user - The user which status we need to update.
596
+ * @param {string} status - The new status.
597
+ */
598
+UI.updateUserStatus = (user, status) => {
599
+    let displayName = user.getDisplayName();
600
+    messageHandler.notify(
601
+        displayName, '', 'connected', "dialOut.statusMessage",
602
+        {
603
+            status: UIUtil.escapeHtml(status)
604
+        });
605
+};
606
+
592 607
 /**
593 608
  * Toggles smileys in the chat.
594 609
  */

+ 48
- 0
react/features/dial-out/actionTypes.js Visa fil

@@ -0,0 +1,48 @@
1
+import { Symbol } from '../base/react';
2
+
3
+/**
4
+ * The type of the action which signals a check for a dial-out phone number has
5
+ * succeeded.
6
+ *
7
+ * {
8
+ *     type: PHONE_NUMBER_CHECKED,
9
+ *     response: Object
10
+ * }
11
+ */
12
+export const PHONE_NUMBER_CHECKED
13
+    = Symbol('PHONE_NUMBER_CHECKED');
14
+
15
+/**
16
+ * The type of the action which signals a cancel of the dial-out operation.
17
+ *
18
+ * {
19
+ *     type: DIAL_OUT_CANCELED,
20
+ *     response: Object
21
+ * }
22
+ */
23
+export const DIAL_OUT_CANCELED
24
+    = Symbol('DIAL_OUT_CANCELED');
25
+
26
+/**
27
+ * The type of the action which signals a request for dial-out country codes has
28
+ * succeeded.
29
+ *
30
+ * {
31
+ *     type: DIAL_OUT_CODES_UPDATED,
32
+ *     response: Object
33
+ * }
34
+ */
35
+export const DIAL_OUT_CODES_UPDATED
36
+    = Symbol('DIAL_OUT_CODES_UPDATED');
37
+
38
+/**
39
+ * The type of the action which signals a failure in some of dial-out service
40
+ * requests.
41
+ *
42
+ * {
43
+ *     type: DIAL_OUT_SERVICE_FAILED,
44
+ *     response: Object
45
+ * }
46
+ */
47
+export const DIAL_OUT_SERVICE_FAILED
48
+    = Symbol('DIAL_OUT_SERVICE_FAILED');

+ 97
- 0
react/features/dial-out/actions.js Visa fil

@@ -0,0 +1,97 @@
1
+import { openDialog } from '../../features/base/dialog';
2
+
3
+import {
4
+    DIAL_OUT_CANCELED,
5
+    DIAL_OUT_CODES_UPDATED,
6
+    DIAL_OUT_SERVICE_FAILED,
7
+    PHONE_NUMBER_CHECKED
8
+} from './actionTypes';
9
+
10
+import { DialOutDialog } from './components';
11
+
12
+declare var $: Function;
13
+declare var config: Object;
14
+
15
+/**
16
+ * Dials the given number.
17
+ *
18
+ * @returns {Function}
19
+ */
20
+export function cancel() {
21
+    return {
22
+        type: DIAL_OUT_CANCELED
23
+    };
24
+}
25
+
26
+/**
27
+ * Dials the given number.
28
+ *
29
+ * @param {string} dialNumber - The number to dial.
30
+ * @returns {Function}
31
+ */
32
+export function dial(dialNumber) {
33
+    return (dispatch, getState) => {
34
+        const { conference } = getState()['features/base/conference'];
35
+
36
+        conference.dial(dialNumber);
37
+    };
38
+}
39
+
40
+/**
41
+ * Sends an ajax request for dial-out country codes.
42
+ *
43
+ * @param {string} dialNumber - The dial number to check for validity.
44
+ * @returns {Function}
45
+ */
46
+export function checkDialNumber(dialNumber) {
47
+    return (dispatch, getState) => {
48
+        const { dialOutAuthUrl } = getState()['features/base/config'];
49
+
50
+        const fullUrl = `${dialOutAuthUrl}?phone=${dialNumber}`;
51
+
52
+        $.getJSON(fullUrl)
53
+            .success(response =>
54
+                dispatch({
55
+                    type: PHONE_NUMBER_CHECKED,
56
+                    response
57
+                }))
58
+            .error(error =>
59
+                dispatch({
60
+                    type: DIAL_OUT_SERVICE_FAILED,
61
+                    error
62
+                }));
63
+    };
64
+}
65
+
66
+
67
+/**
68
+ * Opens the dial-out dialog.
69
+ *
70
+ * @returns {Function}
71
+ */
72
+export function openDialOutDialog() {
73
+    return openDialog(DialOutDialog);
74
+}
75
+
76
+/**
77
+ * Sends an ajax request for dial-out country codes.
78
+ *
79
+ * @returns {Function}
80
+ */
81
+export function updateDialOutCodes() {
82
+    return (dispatch, getState) => {
83
+        const { dialOutCodesUrl } = getState()['features/base/config'];
84
+
85
+        $.getJSON(dialOutCodesUrl)
86
+            .success(response =>
87
+                dispatch({
88
+                    type: DIAL_OUT_CODES_UPDATED,
89
+                    response
90
+                }))
91
+            .error(error =>
92
+                dispatch({
93
+                    type: DIAL_OUT_SERVICE_FAILED,
94
+                    error
95
+                }));
96
+    };
97
+}

+ 40
- 0
react/features/dial-out/components/CountryIcon.js Visa fil

@@ -0,0 +1,40 @@
1
+import React, { Component } from 'react';
2
+
3
+/**
4
+ * Implements a React Component to render a country flag icon.
5
+ */
6
+class CountryIcon extends Component {
7
+    /**
8
+     * {@code CountryIcon}'s property types.
9
+     *
10
+     * @static
11
+     */
12
+    static propTypes = {
13
+        /**
14
+         * The css style class name.
15
+         */
16
+        className: React.PropTypes.string,
17
+
18
+        /**
19
+         * The 2-letter country code.
20
+         */
21
+        countryCode: React.PropTypes.string
22
+    }
23
+
24
+    /**
25
+     * Implements React's {@link Component#render()}.
26
+     *
27
+     * @inheritdoc
28
+     * @returns {ReactElement}
29
+     */
30
+    render() {
31
+        const iconClassName
32
+            = `flag-icon flag-icon-${this.props.countryCode}
33
+             flag-icon-squared ${this.props.className}`;
34
+
35
+        return <span className = { iconClassName } />;
36
+
37
+    }
38
+}
39
+
40
+export default CountryIcon;

+ 226
- 0
react/features/dial-out/components/DialOutDialog.web.js Visa fil

@@ -0,0 +1,226 @@
1
+import React, { Component } from 'react';
2
+import { connect } from 'react-redux';
3
+
4
+import { translate } from '../../base/i18n';
5
+import { Dialog } from '../../base/dialog';
6
+
7
+import { cancel, checkDialNumber, dial } from '../actions';
8
+import DialOutNumbersForm from './DialOutNumbersForm';
9
+
10
+/**
11
+ * Implements a React Component which allows the user to dial out from the
12
+ * conference.
13
+ */
14
+class DialOutDialog extends Component {
15
+
16
+    /**
17
+     * {@code DialOutDialog} component's property types.
18
+     *
19
+     * @static
20
+     */
21
+    static propTypes = {
22
+        /**
23
+         * Property indicating if a dial number is allowed.
24
+         */
25
+        _isDialNumberAllowed: React.PropTypes.bool,
26
+
27
+        /**
28
+         * The function performing the cancel action.
29
+         */
30
+        cancel: React.PropTypes.func,
31
+
32
+        /**
33
+         * The function performing the phone number validity check.
34
+         */
35
+        checkDialNumber: React.PropTypes.func,
36
+
37
+        /**
38
+         * The function performing the dial action.
39
+         */
40
+        dial: React.PropTypes.func,
41
+
42
+        /**
43
+         * Invoked to obtain translated strings.
44
+         */
45
+        t: React.PropTypes.func
46
+    }
47
+
48
+    /**
49
+     * Initializes a new {@code DialOutNumbersForm} instance.
50
+     *
51
+     * @param {Object} props - The read-only properties with which the new
52
+     * instance is to be initialized.
53
+     */
54
+    constructor(props) {
55
+        super(props);
56
+
57
+        this.state = {
58
+            /**
59
+             * The number to dial.
60
+             */
61
+            dialNumber: '',
62
+
63
+            /**
64
+             * Indicates if the dial input is currently empty.
65
+             */
66
+            isDialInputEmpty: true
67
+        };
68
+
69
+        // Bind event handlers so they are only bound once for every instance.
70
+        this._onDialNumberChange = this._onDialNumberChange.bind(this);
71
+        this._onCancel = this._onCancel.bind(this);
72
+        this._onSubmit = this._onSubmit.bind(this);
73
+    }
74
+
75
+    /**
76
+     * Implements React's {@link Component#render()}.
77
+     *
78
+     * @inheritdoc
79
+     * @returns {ReactElement}
80
+     */
81
+    render() {
82
+        const { _isDialNumberAllowed } = this.props;
83
+
84
+        return (
85
+            <Dialog
86
+                okDisabled = { this.state.isDialInputEmpty
87
+                    || !_isDialNumberAllowed }
88
+                okTitleKey = 'dialOut.dial'
89
+                onCancel = { this._onCancel }
90
+                onSubmit = { this._onSubmit }
91
+                titleKey = 'dialOut.dialOut'
92
+                width = 'small'>
93
+                { this._renderContent() }
94
+            </Dialog>);
95
+    }
96
+
97
+    /**
98
+     * Formats the dial number in a way to remove all non digital characters
99
+     * from it (including spaces, brackets, dash, dot, etc.).
100
+     *
101
+     * @param {string} dialNumber - The phone number to format.
102
+     * @private
103
+     * @returns {string} - The formatted phone number.
104
+     */
105
+    _formatDialNumber(dialNumber) {
106
+        return dialNumber.replace(/\D/g, '');
107
+    }
108
+
109
+    /**
110
+     * Renders the dialog content.
111
+     *
112
+     * @returns {XML}
113
+     * @private
114
+     */
115
+    _renderContent() {
116
+        const { _isDialNumberAllowed } = this.props;
117
+
118
+        return (
119
+            <div className = 'dial-out-content'>
120
+                { _isDialNumberAllowed ? '' : this._renderErrorMessage() }
121
+                <DialOutNumbersForm
122
+                    onChange = { this._onDialNumberChange } />
123
+            </div>);
124
+    }
125
+
126
+    /**
127
+     * Renders the error message to display if the dial phone number is not
128
+     * allowed.
129
+     *
130
+     * @returns {XML}
131
+     * @private
132
+     */
133
+    _renderErrorMessage() {
134
+        const { t } = this.props;
135
+
136
+        return (
137
+            <div className = 'dial-out-error'>
138
+                { t('dialOut.phoneNotAllowed') }
139
+            </div>);
140
+    }
141
+
142
+    /**
143
+     * Cancel the dial out.
144
+     *
145
+     * @private
146
+     * @returns {boolean} - Returns true to indicate that the dialog should be
147
+     * closed.
148
+     */
149
+    _onCancel() {
150
+        this.props.cancel();
151
+
152
+        return true;
153
+    }
154
+
155
+    /**
156
+     * Dials the number.
157
+     *
158
+     * @private
159
+     * @returns {boolean} - Returns true to indicate that the dialog should be
160
+     * closed.
161
+     */
162
+    _onSubmit() {
163
+        if (this.props._isDialNumberAllowed) {
164
+            this.props.dial(this.state.dialNumber);
165
+        }
166
+
167
+        return true;
168
+    }
169
+
170
+    /**
171
+     * Updates the dialNumber and check for validity.
172
+     *
173
+     * @param {string} dialCode - The dial code value.
174
+     * @param {string} dialInput - The dial input value.
175
+     * @private
176
+     * @returns {void}
177
+     */
178
+    _onDialNumberChange(dialCode, dialInput) {
179
+        // We remove all starting zeros from the dial input before attaching it
180
+        // to the country code.
181
+        const formattedDialInput = dialInput.replace(/^(0+)/, '');
182
+
183
+        const dialNumber = `${dialCode}${formattedDialInput}`;
184
+
185
+        const formattedNumber = this._formatDialNumber(dialNumber);
186
+
187
+        this.props.checkDialNumber(formattedNumber);
188
+
189
+        this.setState({
190
+            dialNumber: formattedNumber,
191
+            isDialInputEmpty: !formattedDialInput
192
+            || formattedDialInput.length === 0
193
+        });
194
+    }
195
+}
196
+
197
+/**
198
+ * Maps (parts of) the Redux state to the associated
199
+ * {@code DialOutDialog}'s props.
200
+ *
201
+ * @param {Object} state - The Redux state.
202
+ * @private
203
+ * @returns {{
204
+ *     _isDialNumberAllowed: React.PropTypes.bool
205
+ * }}
206
+ */
207
+function _mapStateToProps(state) {
208
+    const { isDialNumberAllowed } = state['features/dial-out'];
209
+
210
+    return {
211
+        /**
212
+         * Property indicating if a dial number is allowed.
213
+         *
214
+         * @private
215
+         * @type {boolean}
216
+         */
217
+        _isDialNumberAllowed: isDialNumberAllowed
218
+    };
219
+}
220
+
221
+export default translate(
222
+    connect(_mapStateToProps, {
223
+        cancel,
224
+        dial,
225
+        checkDialNumber
226
+    })(DialOutDialog));

+ 346
- 0
react/features/dial-out/components/DialOutNumbersForm.web.js Visa fil

@@ -0,0 +1,346 @@
1
+import React, { Component } from 'react';
2
+import { connect } from 'react-redux';
3
+import ExpandIcon from '@atlaskit/icon/glyph/expand';
4
+import { StatelessDropdownMenu } from '@atlaskit/dropdown-menu';
5
+
6
+import { translate } from '../../base/i18n';
7
+import CountryIcon from './CountryIcon';
8
+import { updateDialOutCodes } from '../actions';
9
+
10
+/**
11
+ * The expand icon of the dropdown menu.
12
+ *
13
+ * @type {XML}
14
+ */
15
+const EXPAND_ICON = <ExpandIcon label = 'expand' />;
16
+
17
+/**
18
+ * The default value of the country if the fetch service is unavailable.
19
+ *
20
+ * @type {{name: string, dialCode: string, code: string}}
21
+ */
22
+const DEFAULT_COUNTRY = {
23
+    name: 'United States',
24
+    dialCode: '+1',
25
+    code: 'US'
26
+};
27
+
28
+/**
29
+ * React {@code Component} responsible for fetching and displaying dial-out
30
+ * country codes, as well as dialing a phone number.
31
+ *
32
+ * @extends Component
33
+ */
34
+class DialOutNumbersForm extends Component {
35
+    /**
36
+     * {@code DialOutNumbersForm}'s property types.
37
+     *
38
+     * @static
39
+     */
40
+    static propTypes = {
41
+        /**
42
+         * The redux state representing the list of dial-out codes.
43
+         */
44
+        _dialOutCodes: React.PropTypes.array,
45
+
46
+        /**
47
+         * The function called on every dial input change.
48
+         */
49
+        onChange: React.PropTypes.func,
50
+
51
+        /**
52
+         * Invoked to obtain translated strings.
53
+         */
54
+        t: React.PropTypes.func,
55
+
56
+        /**
57
+         * Invoked to send an ajax request for dial-out codes.
58
+         */
59
+        updateDialOutCodes: React.PropTypes.func
60
+    }
61
+
62
+    /**
63
+     * Initializes a new {@code DialOutNumbersForm} instance.
64
+     *
65
+     * @param {Object} props - The read-only properties with which the new
66
+     * instance is to be initialized.
67
+     */
68
+    constructor(props) {
69
+        super(props);
70
+
71
+        this.state = {
72
+            dialInput: '',
73
+
74
+            /**
75
+             * Whether or not the dropdown should be open.
76
+             *
77
+             * @type {boolean}
78
+             */
79
+            isDropdownOpen: false,
80
+
81
+            /**
82
+             * The selected country.
83
+             *
84
+             * @type {Object}
85
+             */
86
+            selectedCountry: DEFAULT_COUNTRY
87
+        };
88
+
89
+        /**
90
+         * The internal reference to the DOM/HTML element backing the React
91
+         * {@code Component} text input.
92
+         *
93
+         * @private
94
+         * @type {HTMLInputElement}
95
+         */
96
+        this._dialInputElem = null;
97
+
98
+        // Bind event handlers so they are only bound once for every instance.
99
+        this._onInputChange = this._onInputChange.bind(this);
100
+        this._onOpenChange = this._onOpenChange.bind(this);
101
+        this._onSelect = this._onSelect.bind(this);
102
+        this._setDialInputElement = this._setDialInputElement.bind(this);
103
+    }
104
+
105
+    /**
106
+     * Dispatches a request for dial out codes if not already present in the
107
+     * redux store. If dial out codes are present, sets a default code to
108
+     * display in the dropdown trigger.
109
+     *
110
+     * @inheritdoc
111
+     * returns {void}
112
+     */
113
+    componentDidMount() {
114
+        const dialOutCodes = this.props._dialOutCodes;
115
+
116
+        if (dialOutCodes) {
117
+            this._setDefaultCode(dialOutCodes);
118
+        } else {
119
+            this.props.updateDialOutCodes();
120
+        }
121
+    }
122
+
123
+    /**
124
+     * Monitors for dial out code updates and sets a default code to display in
125
+     * the dropdown trigger if not already set.
126
+     *
127
+     * @inheritdoc
128
+     * returns {void}
129
+     */
130
+    componentWillReceiveProps(nextProps) {
131
+        if (!this.state.selectedCountry && nextProps._dialOutCodes) {
132
+            this._setDefaultCode(nextProps._dialOutCodes);
133
+        }
134
+    }
135
+
136
+    /**
137
+     * Implements React's {@link Component#render()}.
138
+     *
139
+     * @inheritdoc
140
+     * @returns {ReactElement}
141
+     */
142
+    render() {
143
+        const { t, _dialOutCodes } = this.props;
144
+
145
+        const items
146
+            = _dialOutCodes ? this._formatCountryCodes(_dialOutCodes) : [];
147
+
148
+        return (
149
+            <div className = 'form-control'>
150
+                { this._createDropdownMenu(items) }
151
+                <div className = 'dial-out-input'>
152
+                    <input
153
+                        autoFocus = { true }
154
+                        className = 'input-control'
155
+                        onChange = { this._onInputChange }
156
+                        placeholder = { t('dialOut.enterPhone') }
157
+                        ref = { this._setDialInputElement }
158
+                        type = 'text' />
159
+                </div>
160
+            </div>
161
+        );
162
+    }
163
+
164
+    /**
165
+     * Creates a {@code StatelessDropdownMenu} instance.
166
+     *
167
+     * @param {Array} items - The content to display within the dropdown.
168
+     * @returns {ReactElement}
169
+     */
170
+    _createDropdownMenu(items) {
171
+        const { code, dialCode } = this.state.selectedCountry;
172
+
173
+        return (
174
+            <StatelessDropdownMenu
175
+                isOpen = { this.state.isDropdownOpen }
176
+                items = { [ { items } ] }
177
+                onItemActivated = { this._onSelect }
178
+                onOpenChange = { this._onOpenChange }
179
+                shouldFitContainer = { true }>
180
+                { this._createDropdownTrigger(dialCode, code) }
181
+            </StatelessDropdownMenu>
182
+        );
183
+    }
184
+
185
+    /**
186
+     * Creates a React {@code Component} with a readonly HTMLInputElement as a
187
+     * trigger for displaying the dropdown menu. The {@code Component} will also
188
+     * display the currently selected number.
189
+     *
190
+     * @param {string} dialCode - The +xx dial code.
191
+     * @param {string} countryCode - The country 2 letter code.
192
+     * @private
193
+     * @returns {ReactElement}
194
+     */
195
+    _createDropdownTrigger(dialCode, countryCode) {
196
+        return (
197
+            <div className = 'dropdown'>
198
+                <CountryIcon
199
+                    className = 'dial-out-flag-icon'
200
+                    countryCode = { `${countryCode}` } />
201
+                <input
202
+                    className = 'input-control dial-out-code'
203
+                    readOnly = { true }
204
+                    type = 'text'
205
+                    value = { dialCode || '' } />
206
+                <span className = 'dropdown-trigger-icon'>
207
+                    { EXPAND_ICON }
208
+                </span>
209
+            </div>
210
+        );
211
+    }
212
+
213
+    /**
214
+     * Transforms the passed in numbers object into an array of objects that can
215
+     * be parsed by {@code StatelessDropdownMenu}.
216
+     *
217
+     * @param {Object} countryCodes - The list of country codes.
218
+     * @private
219
+     * @returns {Array<Object>}
220
+     */
221
+    _formatCountryCodes(countryCodes) {
222
+
223
+        return countryCodes.map(country => {
224
+            const countryIcon
225
+                = <CountryIcon countryCode = { `${country.code}` } />;
226
+
227
+            const countryElement
228
+                = <span>{countryIcon} { country.name }</span>;
229
+
230
+            return {
231
+                content: `${country.dialCode}`,
232
+                elemBefore: countryElement,
233
+                country
234
+            };
235
+        });
236
+    }
237
+
238
+    /**
239
+     * Updates the dialNumber when changes to the dial text or code happen.
240
+     *
241
+     * @private
242
+     * @returns {void}
243
+     */
244
+    _onDialNumberChange() {
245
+        const { dialCode } = this.state.selectedCountry;
246
+
247
+        this.props.onChange(dialCode, this.state.dialInput);
248
+    }
249
+
250
+    /**
251
+     * Updates the dialInput state when the input changes.
252
+     *
253
+     * @param {Object} e - The event notifying us of the change.
254
+     * @private
255
+     * @returns {void}
256
+     */
257
+    _onInputChange(e) {
258
+        this.setState({
259
+            dialInput: e.target.value
260
+        }, () => {
261
+            this._onDialNumberChange();
262
+        });
263
+    }
264
+
265
+    /**
266
+     * Sets the internal state to either open or close the dropdown. If the
267
+     * dropdown is disabled, the state will always be set to false.
268
+     *
269
+     * @param {Object} dropdownEvent - The even returned from clicking on the
270
+     * dropdown trigger.
271
+     * @private
272
+     * @returns {void}
273
+     */
274
+    _onOpenChange(dropdownEvent) {
275
+        this.setState({
276
+            isDropdownOpen: dropdownEvent.isOpen
277
+        });
278
+    }
279
+
280
+    /**
281
+     * Updates the internal state of the currently selected country code.
282
+     *
283
+     * @param {Object} selection - Event from choosing an dropdown option.
284
+     * @private
285
+     * @returns {void}
286
+     */
287
+    _onSelect(selection) {
288
+        this.setState({
289
+            isDropdownOpen: false,
290
+            selectedCountry: selection.item.country
291
+        }, () => {
292
+            this._onDialNumberChange();
293
+
294
+            this._dialInputElem.focus();
295
+        });
296
+    }
297
+
298
+    /**
299
+     * Updates the internal state of the currently selected number by defaulting
300
+     * to the first available number.
301
+     *
302
+     * @param {Object} countryCodes - The list of country codes to choose from
303
+     * for setting a default code.
304
+     * @private
305
+     * @returns {void}
306
+     */
307
+    _setDefaultCode(countryCodes) {
308
+        this.setState({
309
+            selectedCountry: countryCodes[0]
310
+        });
311
+    }
312
+
313
+    /**
314
+     * Sets the internal reference to the DOM/HTML element backing the React
315
+     * {@code Component} dial input.
316
+     *
317
+     * @param {HTMLInputElement} input - The DOM/HTML element for this
318
+     * {@code Component}'s text input.
319
+     * @private
320
+     * @returns {void}
321
+     */
322
+    _setDialInputElement(input) {
323
+        this._dialInputElem = input;
324
+    }
325
+}
326
+
327
+/**
328
+ * Maps (parts of) the Redux state to the associated
329
+ * {@code DialOutNumbersForm}'s props.
330
+ *
331
+ * @param {Object} state - The Redux state.
332
+ * @private
333
+ * @returns {{
334
+ *     _dialOutCodes: React.PropTypes.object
335
+ * }}
336
+ */
337
+function _mapStateToProps(state) {
338
+    const { dialOutCodes } = state['features/dial-out'];
339
+
340
+    return {
341
+        _dialOutCodes: dialOutCodes
342
+    };
343
+}
344
+
345
+export default translate(connect(_mapStateToProps,
346
+    { updateDialOutCodes })(DialOutNumbersForm));

+ 1
- 0
react/features/dial-out/components/index.js Visa fil

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

+ 4
- 0
react/features/dial-out/index.js Visa fil

@@ -0,0 +1,4 @@
1
+export * from './actions';
2
+export * from './components';
3
+
4
+import './reducer';

+ 48
- 0
react/features/dial-out/reducer.js Visa fil

@@ -0,0 +1,48 @@
1
+import {
2
+    ReducerRegistry
3
+} from '../base/redux';
4
+
5
+import {
6
+    DIAL_OUT_CANCELED,
7
+    DIAL_OUT_CODES_UPDATED,
8
+    DIAL_OUT_SERVICE_FAILED,
9
+    PHONE_NUMBER_CHECKED
10
+} from './actionTypes';
11
+
12
+const DEFAULT_STATE = {
13
+    dialOutCodes: null,
14
+    error: null,
15
+    isDialNumberAllowed: true
16
+};
17
+
18
+ReducerRegistry.register(
19
+    'features/dial-out',
20
+    (state = DEFAULT_STATE, action) => {
21
+        switch (action.type) {
22
+        case DIAL_OUT_CANCELED: {
23
+            return DEFAULT_STATE;
24
+        }
25
+        case DIAL_OUT_CODES_UPDATED: {
26
+            return {
27
+                ...state,
28
+                error: null,
29
+                dialOutCodes: action.response
30
+            };
31
+        }
32
+        case DIAL_OUT_SERVICE_FAILED: {
33
+            return {
34
+                ...state,
35
+                error: action.error
36
+            };
37
+        }
38
+        case PHONE_NUMBER_CHECKED: {
39
+            return {
40
+                ...state,
41
+                error: null,
42
+                isDialNumberAllowed: action.response.allow
43
+            };
44
+        }
45
+        }
46
+
47
+        return state;
48
+    });

+ 3
- 3
react/features/invite/components/DialInNumbersForm.js Visa fil

@@ -192,7 +192,7 @@ class DialInNumbersForm extends Component {
192 192
     }
193 193
 
194 194
     /**
195
-     * Creates a React {@code Component} with a redonly HTMLInputElement as a
195
+     * Creates a React {@code Component} with a readonly HTMLInputElement as a
196 196
      * trigger for displaying the dropdown menu. The {@code Component} will also
197 197
      * display the currently selected number.
198 198
      *
@@ -269,7 +269,7 @@ class DialInNumbersForm extends Component {
269 269
             return [];
270 270
         }
271 271
 
272
-        const formattedNumbeers = phoneRegions.map(region => {
272
+        const formattedNumbers = phoneRegions.map(region => {
273 273
             const numbers = dialInNumbers[region];
274 274
 
275 275
             return numbers.map(number => {
@@ -280,7 +280,7 @@ class DialInNumbersForm extends Component {
280 280
             });
281 281
         });
282 282
 
283
-        return Array.prototype.concat(...formattedNumbeers);
283
+        return Array.prototype.concat(...formattedNumbers);
284 284
     }
285 285
 
286 286
     /**

+ 4
- 3
react/features/toolbox/actions.web.js Visa fil

@@ -215,14 +215,15 @@ export function showSharedVideoButton(): Function {
215 215
 }
216 216
 
217 217
 /**
218
- * Shows SIP call button if it's required and appropriate flag is passed.
218
+ * Shows the dial out button if it's required and appropriate
219
+ * flag is passed.
219 220
  *
220 221
  * @param {boolean} show - Flag showing whether to show button or not.
221 222
  * @returns {Function}
222 223
  */
223
-export function showSIPCallButton(show: boolean): Function {
224
+export function showDialOutButton(show: boolean): Function {
224 225
     return (dispatch: Dispatch<*>, getState: Function) => {
225
-        const buttonName = 'sip';
226
+        const buttonName = 'dialout';
226 227
 
227 228
         if (show
228 229
                 && APP.conference.sipGatewayEnabled()

+ 18
- 46
react/features/toolbox/defaultToolbarButtons.js Visa fil

@@ -5,39 +5,11 @@ import React from 'react';
5 5
 import UIEvents from '../../../service/UI/UIEvents';
6 6
 
7 7
 import { openInviteDialog } from '../invite';
8
+import { openDialOutDialog } from '../dial-out';
8 9
 
9 10
 declare var APP: Object;
10
-declare var config: Object;
11 11
 declare var JitsiMeetJS: Object;
12 12
 
13
-/**
14
- * Shows SIP number dialog.
15
- *
16
- * @returns {void}
17
- */
18
-function _showSIPNumberInput() {
19
-    const defaultNumber = config.defaultSipNumber || '';
20
-    const msgString
21
-        = `<input class="input-control" name="sipNumber" type="text" value="${
22
-            defaultNumber}" autofocus>`;
23
-
24
-    APP.UI.messageHandler.openTwoButtonDialog({
25
-        focus: ':input:first',
26
-        leftButtonKey: 'dialog.Dial',
27
-        msgString,
28
-        titleKey: 'dialog.sipMsg',
29
-
30
-        // eslint-disable-next-line max-params
31
-        submitFunction(event, value, message, formValues) {
32
-            const { sipNumber } = formValues;
33
-
34
-            if (value && sipNumber) {
35
-                APP.UI.emitEvent(UIEvents.SIP_DIAL, sipNumber);
36
-            }
37
-        }
38
-    });
39
-}
40
-
41 13
 /**
42 14
  * All toolbar buttons' descriptors.
43 15
  */
@@ -169,6 +141,23 @@ export default {
169 141
         tooltipKey: 'toolbar.sharescreen'
170 142
     },
171 143
 
144
+    /**
145
+     * The descriptor of the dial out toolbar button.
146
+     */
147
+    dialout: {
148
+        classNames: [ 'button', 'icon-telephone' ],
149
+        enabled: true,
150
+
151
+        // Will be displayed once the SIP calls functionality is detected.
152
+        hidden: true,
153
+        id: 'toolbar_button_dial_out',
154
+        onClick() {
155
+            JitsiMeetJS.analytics.sendEvent('toolbar.sip.clicked');
156
+            APP.store.dispatch(openDialOutDialog());
157
+        },
158
+        tooltipKey: 'dialOut.dialOut'
159
+    },
160
+
172 161
     /**
173 162
      * The descriptor of the dialpad toolbar button.
174 163
      */
@@ -395,22 +384,5 @@ export default {
395 384
             }
396 385
         ],
397 386
         tooltipKey: 'toolbar.sharedvideo'
398
-    },
399
-
400
-    /**
401
-     * The descriptor of the SIP call toolbar button.
402
-     */
403
-    sip: {
404
-        classNames: [ 'button', 'icon-telephone' ],
405
-        enabled: true,
406
-
407
-        // Will be displayed once the SIP calls functionality is detected.
408
-        hidden: true,
409
-        id: 'toolbar_button_sip',
410
-        onClick() {
411
-            JitsiMeetJS.analytics.sendEvent('toolbar.sip.clicked');
412
-            _showSIPNumberInput();
413
-        },
414
-        tooltipKey: 'toolbar.sip'
415 387
     }
416 388
 };

+ 0
- 1
service/UI/UIEvents.js Visa fil

@@ -71,7 +71,6 @@ export default {
71 71
     HANGUP: "UI.hangup",
72 72
     LOGOUT: "UI.logout",
73 73
     RECORDING_TOGGLED: "UI.recording_toggled",
74
-    SIP_DIAL: "UI.sip_dial",
75 74
     SUBJECT_CHANGED: "UI.subject_changed",
76 75
     VIDEO_DEVICE_CHANGED: "UI.video_device_changed",
77 76
     AUDIO_DEVICE_CHANGED: "UI.audio_device_changed",

Laddar…
Avbryt
Spara