Selaa lähdekoodia

[RN] Add recent-list feature

j8
Zoltan Bettenbuk 7 vuotta sitten
vanhempi
commit
45c405de0e

+ 9
- 0
css/_font.scss Näytä tiedosto

25
     -moz-osx-font-smoothing: grayscale;
25
     -moz-osx-font-smoothing: grayscale;
26
 }
26
 }
27
 
27
 
28
+.icon-public:before {
29
+  content: "\e80b";
30
+}
31
+.icon-event_note:before {
32
+    content: "\e616";
33
+}
34
+.icon-timer:before {
35
+    content: "\e425";
36
+}
28
 .icon-thumb-menu:before {
37
 .icon-thumb-menu:before {
29
     content: "\e5d4";
38
     content: "\e5d4";
30
 }
39
 }

+ 7
- 6
doc/adding-an-icon.md Näytä tiedosto

2
 1. Go to https://icomoon.io/app/
2
 1. Go to https://icomoon.io/app/
3
 2. Go to "Manage Projects" from the menu on the top left.
3
 2. Go to "Manage Projects" from the menu on the top left.
4
 3. Use "Import project" and select <code>fonts/selection.json</code> from Jitsi Meet.
4
 3. Use "Import project" and select <code>fonts/selection.json</code> from Jitsi Meet.
5
-4. Import icons (e.g. svg files) using the "import items" button.
6
-5. Go to "generate font" and make sure the identifiers for the new icons are correct.
7
-6. Download the result in a zip file using the "download" button.
8
-7. Copy <code>selection.json</code> and <code>fonts/jitsi.*</code> from the zip file to <code>fonts/</code> in Jitsi Meet
9
-8. Copy the class for the new icon from <code>style.css</code> in the zip file to <code>css/font.css</code> in Jitsi Meet (do *not* copy the whole file)
5
+4. Click "load".
6
+5. Add the new icons using the "Add icons from library" button...
7
+6. Go to "generate font" and make sure the identifiers for the new icons are correct.
8
+7. Download the result in a zip file using the "download" button.
9
+8. Copy <code>selection.json</code> and <code>fonts/jitsi.*</code> from the zip file to <code>fonts/</code> in Jitsi Meet
10
+9. Copy the class for the new icon from <code>style.css</code> in the zip file to <code>css/_font.scss</code> in Jitsi Meet (do *not* copy the whole file)
11
+10. Copy the <code>selection.json</code> file to <code>react/features/base/font-icons</code> overwriting <code>jitsi.json</code>
10
 
12
 
11
 Sample commit: https://github.com/jitsi/jitsi-meet/commit/68bc819b89aec12364fcf07b81efa83a1900eed6
13
 Sample commit: https://github.com/jitsi/jitsi-meet/commit/68bc819b89aec12364fcf07b81efa83a1900eed6
12
-

BIN
fonts/jitsi.eot Näytä tiedosto


+ 3
- 0
fonts/jitsi.svg Näytä tiedosto

11
 <glyph unicode="&#xe145;" glyph-name="add" d="M810 470h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
11
 <glyph unicode="&#xe145;" glyph-name="add" d="M810 470h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
12
 <glyph unicode="&#xe1aa;" glyph-name="bluetooth" d="M550 328l-80 82v-162zM470 776v-162l80 82zM670 696l-184-184 184-184-244-242h-42v324l-196-196-60 60 238 238-238 238 60 60 196-196v324h42zM834 738c40-64 62-142 62-222 0-84-24-160-66-226l-50 50c26 52 42 110 42 172s-16 120-42 172zM608 512l98 98c12-30 20-64 20-98s-8-70-20-100z" />
12
 <glyph unicode="&#xe1aa;" glyph-name="bluetooth" d="M550 328l-80 82v-162zM470 776v-162l80 82zM670 696l-184-184 184-184-244-242h-42v324l-196-196-60 60 238 238-238 238 60 60 196-196v324h42zM834 738c40-64 62-142 62-222 0-84-24-160-66-226l-50 50c26 52 42 110 42 172s-16 120-42 172zM608 512l98 98c12-30 20-64 20-98s-8-70-20-100z" />
13
 <glyph unicode="&#xe310;" glyph-name="headset" d="M512 982c212 0 384-172 384-384v-300c0-70-58-128-128-128h-128v342h170v86c0 166-132 298-298 298s-298-132-298-298v-86h170v-342h-128c-70 0-128 58-128 128v300c0 212 172 384 384 384z" />
13
 <glyph unicode="&#xe310;" glyph-name="headset" d="M512 982c212 0 384-172 384-384v-300c0-70-58-128-128-128h-128v342h170v86c0 166-132 298-298 298s-298-132-298-298v-86h170v-342h-128c-70 0-128 58-128 128v300c0 212 172 384 384 384z" />
14
+<glyph unicode="&#xe425;" glyph-name="timer" d="M512 170c166 0 298 134 298 300s-132 298-298 298-298-132-298-298 132-300 298-300zM812 708c52-66 84-148 84-238 0-212-172-384-384-384s-384 172-384 384 172 384 384 384c90 0 174-34 240-86l60 62c22-18 42-38 60-60zM470 426v256h84v-256h-84zM640 982v-86h-256v86h256z" />
14
 <glyph unicode="&#xe5d4;" glyph-name="thumb-menu" d="M512 342c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 598c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 682c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
15
 <glyph unicode="&#xe5d4;" glyph-name="thumb-menu" d="M512 342c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 598c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 682c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
15
 <glyph unicode="&#xe603;" glyph-name="presentation" horiz-adv-x="1088" d="M952.495 1019.065h-818.689c-72.81 0-132.183-60.63-132.183-135.162v-750.719c0-74.473 59.372-135.101 132.183-135.101h818.686c72.936 0 132.314 60.625 132.314 135.101v750.722c0.003 74.532-59.378 135.159-132.311 135.159zM946.346 139.651h-806.14v737.822h806.015l0.126-737.822zM685.753 738.544h216.911v-566.758h-216.911v566.758zM428.672 610.002h216.911v-438.216h-216.911v438.216zM172.339 481.46h216.161v-309.677h-216.161v309.677z" />
16
 <glyph unicode="&#xe603;" glyph-name="presentation" horiz-adv-x="1088" d="M952.495 1019.065h-818.689c-72.81 0-132.183-60.63-132.183-135.162v-750.719c0-74.473 59.372-135.101 132.183-135.101h818.686c72.936 0 132.314 60.625 132.314 135.101v750.722c0.003 74.532-59.378 135.159-132.311 135.159zM946.346 139.651h-806.14v737.822h806.015l0.126-737.822zM685.753 738.544h216.911v-566.758h-216.911v566.758zM428.672 610.002h216.911v-438.216h-216.911v438.216zM172.339 481.46h216.161v-309.677h-216.161v309.677z" />
16
 <glyph unicode="&#xe613;" glyph-name="recDisable" horiz-adv-x="1140" d="M1123.444 1003.015c-23.593 26.481-64.131 28.989-90.74 5.395l-1008.269-893.436c-26.609-23.468-28.991-64.131-5.46-90.676 12.674-14.306 30.308-21.649 48.126-21.649 15.123 0 30.372 5.401 42.544 16.195l130.045 115.22c90.743-81.844 210.569-132.165 342.473-132.101 282.816 0.061 510.913 227.969 511.287 510.972 0.126 109.934-34.682 211.367-93.499 294.72l118.088 104.625c26.483 23.526 28.997 64.129 5.404 90.735zM944.422 513.818c0.128-200.922-161.896-363.201-362.509-362.952-87.56 0.123-167.573 31.151-230.061 82.569l331.277 293.509v-73.176c1.071-60.993 32.696-92.18 94.944-93.692 61.997 1.512 93.686 32.763 95.131 93.756v41.096h-72.227v-47.499c0.251-4.642-0.564-10.607-2.511-17.949-1.25-3.261-3.448-6.020-6.525-8.093-3.197-2.572-7.845-3.828-13.868-3.828-10.543 0.31-17.132 4.268-19.827 11.921-1.068 3.512-1.947 6.905-2.508 10.163-0.254 2.887-0.377 5.532-0.377 7.786v143.511l42.477 37.634c0.215-0.432 0.452-0.851 0.63-1.303 1.947-6.467 2.762-12.799 2.511-19.076v-36.772h72.227v30.121c-0.246 31.245-9.086 54.699-26.363 70.447l40.711 36.069c35.787-56.055 56.803-122.585 56.867-194.244zM239.795 395.47c-12.613 37.023-19.827 76.557-19.827 117.913-0.19 200.236 161.584 362.009 361.945 362.135 56.853 0 110.313-13.302 158.133-36.398l117.846 104.421c-79.444 50.952-173.758 80.817-275.292 80.948-283.377 0.181-511.354-227.729-511.789-511.675-0.126-79.567 18.636-154.679 51.137-221.882l117.848 104.538zM388.576 690.020h-97.514v-249.057l72.23 64.070v0.689h0.815l117.72 104.418c0 0.564 0.123 0.94 0.123 1.509 0.753 53.898-30.369 80.069-93.374 78.37zM405.959 625.517c1.942-2.767 3.074-6.469 3.323-11.112 0.312-4.452 0.438-9.6 0.438-15.246 0.251-10.916-0.689-19.83-2.949-26.985-2.952-7.594-10.983-11.357-24.159-11.357h-19.325v74.043h15.31c7.842 0 13.865-0.683 18.072-2.19 4.397-1.573 7.468-3.953 9.29-7.153z" />
17
 <glyph unicode="&#xe613;" glyph-name="recDisable" horiz-adv-x="1140" d="M1123.444 1003.015c-23.593 26.481-64.131 28.989-90.74 5.395l-1008.269-893.436c-26.609-23.468-28.991-64.131-5.46-90.676 12.674-14.306 30.308-21.649 48.126-21.649 15.123 0 30.372 5.401 42.544 16.195l130.045 115.22c90.743-81.844 210.569-132.165 342.473-132.101 282.816 0.061 510.913 227.969 511.287 510.972 0.126 109.934-34.682 211.367-93.499 294.72l118.088 104.625c26.483 23.526 28.997 64.129 5.404 90.735zM944.422 513.818c0.128-200.922-161.896-363.201-362.509-362.952-87.56 0.123-167.573 31.151-230.061 82.569l331.277 293.509v-73.176c1.071-60.993 32.696-92.18 94.944-93.692 61.997 1.512 93.686 32.763 95.131 93.756v41.096h-72.227v-47.499c0.251-4.642-0.564-10.607-2.511-17.949-1.25-3.261-3.448-6.020-6.525-8.093-3.197-2.572-7.845-3.828-13.868-3.828-10.543 0.31-17.132 4.268-19.827 11.921-1.068 3.512-1.947 6.905-2.508 10.163-0.254 2.887-0.377 5.532-0.377 7.786v143.511l42.477 37.634c0.215-0.432 0.452-0.851 0.63-1.303 1.947-6.467 2.762-12.799 2.511-19.076v-36.772h72.227v30.121c-0.246 31.245-9.086 54.699-26.363 70.447l40.711 36.069c35.787-56.055 56.803-122.585 56.867-194.244zM239.795 395.47c-12.613 37.023-19.827 76.557-19.827 117.913-0.19 200.236 161.584 362.009 361.945 362.135 56.853 0 110.313-13.302 158.133-36.398l117.846 104.421c-79.444 50.952-173.758 80.817-275.292 80.948-283.377 0.181-511.354-227.729-511.789-511.675-0.126-79.567 18.636-154.679 51.137-221.882l117.848 104.538zM388.576 690.020h-97.514v-249.057l72.23 64.070v0.689h0.815l117.72 104.418c0 0.564 0.123 0.94 0.123 1.509 0.753 53.898-30.369 80.069-93.374 78.37zM405.959 625.517c1.942-2.767 3.074-6.469 3.323-11.112 0.312-4.452 0.438-9.6 0.438-15.246 0.251-10.916-0.689-19.83-2.949-26.985-2.952-7.594-10.983-11.357-24.159-11.357h-19.325v74.043h15.31c7.842 0 13.865-0.683 18.072-2.19 4.397-1.573 7.468-3.953 9.29-7.153z" />
17
 <glyph unicode="&#xe614;" glyph-name="recEnable" horiz-adv-x="1142" d="M581.278 1025.708c284.857-0.19 514.807-230.517 514.427-514.997-0.378-285.047-230.073-514.553-514.869-514.615-284.541-0.062-515.311 230.517-514.933 514.422 0.439 285.936 230.009 515.439 515.375 515.19zM580.579 875.756c-201.764-0.123-364.666-163.032-364.478-364.663 0-202.018 162.524-364.735 364.478-364.984 202.018-0.316 365.174 163.030 365.048 365.423-0.252 201.767-163.156 364.35-365.048 364.224zM287.698 688.907h98.196c63.442 1.767 94.785-24.518 94.027-78.863 0.254-19.081-2.211-34.882-7.456-47.521-6.005-12.508-18.706-21.988-38.167-28.181v-0.819c28.373-6.259 43.031-23.573 43.981-51.946v-57.689c0-11.247 0.254-22.813 0.758-34.756 0.819-12.005 3.033-20.979 6.696-27.043h-71.846c-3.727 6.064-6.128 15.038-7.14 27.043-1.012 11.943-1.454 23.509-1.138 34.756v52.321c0 9.603-2.214 16.553-6.573 20.979-4.675 4.107-12.701 6.19-24.012 6.19h-14.599v-141.291h-72.73v326.82zM360.428 558.861h19.463c13.271 0 21.359 3.794 24.331 11.375 2.276 7.204 3.221 16.304 2.969 27.171 0 5.815-0.126 10.867-0.442 15.418-0.252 4.675-1.392 8.404-3.352 11.247-1.831 3.157-4.926 5.561-9.352 7.14-4.233 1.454-10.299 2.211-18.2 2.211h-15.418v-74.564zM498.372 688.907h162.082v-62.687h-89.35v-65.587h78.103v-62.685h-78.103v-73.11h92.822v-62.749h-165.557v326.818zM682.507 599.999c0.316 31.782 9.416 55.542 27.425 71.407 17.44 15.29 40.185 22.936 68.181 22.936 28.247 0 51.119-7.646 68.623-23 17.82-15.798 26.92-39.623 27.171-71.407v-30.333h-72.73v37.031c0.254 6.192-0.57 12.639-2.527 19.209-1.264 3.157-3.475 5.938-6.573 8.214-3.221 1.515-7.898 2.404-13.964 2.404-10.615-0.316-17.249-3.855-19.967-10.618-2.211-6.573-3.223-13.017-2.907-19.209v-161.956c0-2.273 0.126-4.865 0.38-7.772 0.568-3.411 1.454-6.824 2.527-10.233 2.717-7.775 9.352-11.756 19.967-12.007 6.067 0 10.744 1.261 13.964 3.791 3.098 2.15 5.309 4.867 6.573 8.216 1.96 7.33 2.782 13.33 2.527 18.007v47.837h72.73v-41.328c-1.451-61.547-33.364-93.015-95.794-94.469-62.685 1.454-94.53 32.922-95.607 94.343v148.937z" />
18
 <glyph unicode="&#xe614;" glyph-name="recEnable" horiz-adv-x="1142" d="M581.278 1025.708c284.857-0.19 514.807-230.517 514.427-514.997-0.378-285.047-230.073-514.553-514.869-514.615-284.541-0.062-515.311 230.517-514.933 514.422 0.439 285.936 230.009 515.439 515.375 515.19zM580.579 875.756c-201.764-0.123-364.666-163.032-364.478-364.663 0-202.018 162.524-364.735 364.478-364.984 202.018-0.316 365.174 163.030 365.048 365.423-0.252 201.767-163.156 364.35-365.048 364.224zM287.698 688.907h98.196c63.442 1.767 94.785-24.518 94.027-78.863 0.254-19.081-2.211-34.882-7.456-47.521-6.005-12.508-18.706-21.988-38.167-28.181v-0.819c28.373-6.259 43.031-23.573 43.981-51.946v-57.689c0-11.247 0.254-22.813 0.758-34.756 0.819-12.005 3.033-20.979 6.696-27.043h-71.846c-3.727 6.064-6.128 15.038-7.14 27.043-1.012 11.943-1.454 23.509-1.138 34.756v52.321c0 9.603-2.214 16.553-6.573 20.979-4.675 4.107-12.701 6.19-24.012 6.19h-14.599v-141.291h-72.73v326.82zM360.428 558.861h19.463c13.271 0 21.359 3.794 24.331 11.375 2.276 7.204 3.221 16.304 2.969 27.171 0 5.815-0.126 10.867-0.442 15.418-0.252 4.675-1.392 8.404-3.352 11.247-1.831 3.157-4.926 5.561-9.352 7.14-4.233 1.454-10.299 2.211-18.2 2.211h-15.418v-74.564zM498.372 688.907h162.082v-62.687h-89.35v-65.587h78.103v-62.685h-78.103v-73.11h92.822v-62.749h-165.557v326.818zM682.507 599.999c0.316 31.782 9.416 55.542 27.425 71.407 17.44 15.29 40.185 22.936 68.181 22.936 28.247 0 51.119-7.646 68.623-23 17.82-15.798 26.92-39.623 27.171-71.407v-30.333h-72.73v37.031c0.254 6.192-0.57 12.639-2.527 19.209-1.264 3.157-3.475 5.938-6.573 8.214-3.221 1.515-7.898 2.404-13.964 2.404-10.615-0.316-17.249-3.855-19.967-10.618-2.211-6.573-3.223-13.017-2.907-19.209v-161.956c0-2.273 0.126-4.865 0.38-7.772 0.568-3.411 1.454-6.824 2.527-10.233 2.717-7.775 9.352-11.756 19.967-12.007 6.067 0 10.744 1.261 13.964 3.791 3.098 2.15 5.309 4.867 6.573 8.216 1.96 7.33 2.782 13.33 2.527 18.007v47.837h72.73v-41.328c-1.451-61.547-33.364-93.015-95.794-94.469-62.685 1.454-94.53 32.922-95.607 94.343v148.937z" />
19
+<glyph unicode="&#xe616;" glyph-name="event_note" d="M598 426v-84h-300v84h300zM810 214v468h-596v-468h596zM810 896c46 0 86-40 86-86v-596c0-46-40-86-86-86h-596c-48 0-86 40-86 86v596c0 46 38 86 86 86h42v86h86v-86h340v86h86v-86h42zM726 598v-86h-428v86h428z" />
18
 <glyph unicode="&#xe61d;" glyph-name="phone-talk" d="M640 512c0 70-58 128-128 128v86c118 0 214-96 214-214h-86zM810 512c0 166-132 298-298 298v86c212 0 384-172 384-384h-86zM854 362c24 0 42-18 42-42v-150c0-24-18-42-42-42-400 0-726 326-726 726 0 24 18 42 42 42h150c24 0 42-18 42-42 0-54 8-104 24-152 4-14 2-32-10-44l-94-94c62-122 162-220 282-282l94 94c12 12 30 14 44 10 48-16 98-24 152-24z" />
20
 <glyph unicode="&#xe61d;" glyph-name="phone-talk" d="M640 512c0 70-58 128-128 128v86c118 0 214-96 214-214h-86zM810 512c0 166-132 298-298 298v86c212 0 384-172 384-384h-86zM854 362c24 0 42-18 42-42v-150c0-24-18-42-42-42-400 0-726 326-726 726 0 24 18 42 42 42h150c24 0 42-18 42-42 0-54 8-104 24-152 4-14 2-32-10-44l-94-94c62-122 162-220 282-282l94 94c12 12 30 14 44 10 48-16 98-24 152-24z" />
21
+<glyph unicode="&#xe80b;" glyph-name="public" d="M764 282c56 60 90 142 90 230 0 142-88 266-214 316v-18c0-46-40-84-86-84h-84v-86c0-24-20-42-44-42h-84v-86h256c24 0 42-18 42-42v-128h42c38 0 70-26 82-60zM470 174v82c-46 0-86 40-86 86v42l-204 204c-6-24-10-50-10-76 0-174 132-318 300-338zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
19
 <glyph unicode="&#xe901;" glyph-name="avatar" d="M512 204c106 0 200 56 256 138-2 84-172 132-256 132-86 0-254-48-256-132 56-82 150-138 256-138zM512 810c-70 0-128-58-128-128s58-128 128-128 128 58 128 128-58 128-128 128zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
22
 <glyph unicode="&#xe901;" glyph-name="avatar" d="M512 204c106 0 200 56 256 138-2 84-172 132-256 132-86 0-254-48-256-132 56-82 150-138 256-138zM512 810c-70 0-128-58-128-128s58-128 128-128 128 58 128 128-58 128-128 128zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
20
 <glyph unicode="&#xe902;" glyph-name="download" d="M726 470h-128v170h-172v-170h-128l214-214zM826 596c110-8 198-100 198-212 0-118-96-214-214-214h-554c-142 0-256 114-256 256 0 132 100 240 228 254 54 102 160 174 284 174 156 0 284-110 314-258z" />
23
 <glyph unicode="&#xe902;" glyph-name="download" d="M726 470h-128v170h-172v-170h-128l214-214zM826 596c110-8 198-100 198-212 0-118-96-214-214-214h-554c-142 0-256 114-256 256 0 132 100 240 228 254 54 102 160 174 284 174 156 0 284-110 314-258z" />
21
 <glyph unicode="&#xe903;" glyph-name="mic-camera-combined" d="M756.704 628.138l267.296 202.213v-635.075l-267.296 202.213v-191.923c0-12.085-11.296-21.863-25.216-21.863h-706.272c-13.92 0-25.216 9.777-25.216 21.863v612.25c0 12.085 11.296 21.863 25.216 21.863h706.272c13.92 0 25.216-9.777 25.216-21.863v-189.679zM371.338 376.228c47.817 0 86.529 40.232 86.529 89.811v184.835c0 49.651-38.713 89.883-86.529 89.883-47.788 0-86.515-40.232-86.515-89.883v-184.835c0-49.579 38.756-89.811 86.515-89.811v0zM356.754 314.070v-32.78h33.718v33.412c73.858 9.606 131.235 73.73 131.235 151.351v88.232h-30.636v-88.232c0-67.57-53.696-122.534-119.734-122.534-66.024 0-119.691 54.964-119.691 122.534v88.232h-30.636v-88.232c0-79.215 59.674-144.502 135.744-151.969v-0.014z" />
24
 <glyph unicode="&#xe903;" glyph-name="mic-camera-combined" d="M756.704 628.138l267.296 202.213v-635.075l-267.296 202.213v-191.923c0-12.085-11.296-21.863-25.216-21.863h-706.272c-13.92 0-25.216 9.777-25.216 21.863v612.25c0 12.085 11.296 21.863 25.216 21.863h706.272c13.92 0 25.216-9.777 25.216-21.863v-189.679zM371.338 376.228c47.817 0 86.529 40.232 86.529 89.811v184.835c0 49.651-38.713 89.883-86.529 89.883-47.788 0-86.515-40.232-86.515-89.883v-184.835c0-49.579 38.756-89.811 86.515-89.811v0zM356.754 314.070v-32.78h33.718v33.412c73.858 9.606 131.235 73.73 131.235 151.351v88.232h-30.636v-88.232c0-67.57-53.696-122.534-119.734-122.534-66.024 0-119.691 54.964-119.691 122.534v88.232h-30.636v-88.232c0-79.215 59.674-144.502 135.744-151.969v-0.014z" />

BIN
fonts/jitsi.ttf Näytä tiedosto


BIN
fonts/jitsi.woff Näytä tiedosto


+ 134
- 53
fonts/selection.json Näytä tiedosto

1
 {
1
 {
2
   "IcoMoonType": "selection",
2
   "IcoMoonType": "selection",
3
   "icons": [
3
   "icons": [
4
+    {
5
+      "icon": {
6
+        "paths": [
7
+          "M764 742c56-60 90-142 90-230 0-142-88-266-214-316v18c0 46-40 84-86 84h-84v86c0 24-20 42-44 42h-84v86h256c24 0 42 18 42 42v128h42c38 0 70 26 82 60zM470 850v-82c-46 0-86-40-86-86v-42l-204-204c-6 24-10 50-10 76 0 174 132 318 300 338zM512 86c236 0 426 190 426 426s-190 426-426 426-426-190-426-426 190-426 426-426z"
8
+        ],
9
+        "attrs": [],
10
+        "isMulticolor": false,
11
+        "isMulticolor2": false,
12
+        "tags": [
13
+          "public"
14
+        ],
15
+        "defaultCode": 59403,
16
+        "grid": 24
17
+      },
18
+      "attrs": [],
19
+      "properties": {
20
+        "ligatures": "public",
21
+        "id": 605,
22
+        "order": 920,
23
+        "prevSize": 24,
24
+        "code": 59403,
25
+        "name": "public"
26
+      },
27
+      "setIdx": 0,
28
+      "setId": 2,
29
+      "iconIdx": 605
30
+    },
31
+    {
32
+      "icon": {
33
+        "paths": [
34
+          "M598 598v84h-300v-84h300zM810 810v-468h-596v468h596zM810 128c46 0 86 40 86 86v596c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h42v-86h86v86h340v-86h86v86h42zM726 426v86h-428v-86h428z"
35
+        ],
36
+        "attrs": [],
37
+        "isMulticolor": false,
38
+        "isMulticolor2": false,
39
+        "tags": [
40
+          "event_note"
41
+        ],
42
+        "defaultCode": 58902,
43
+        "grid": 24
44
+      },
45
+      "attrs": [],
46
+      "properties": {
47
+        "ligatures": "event_note",
48
+        "id": 252,
49
+        "order": 919,
50
+        "prevSize": 24,
51
+        "code": 58902,
52
+        "name": "event_note"
53
+      },
54
+      "setIdx": 1,
55
+      "setId": 1,
56
+      "iconIdx": 0
57
+    },
58
+    {
59
+      "icon": {
60
+        "paths": [
61
+          "M512 854c166 0 298-134 298-300s-132-298-298-298-298 132-298 298 132 300 298 300zM812 316c52 66 84 148 84 238 0 212-172 384-384 384s-384-172-384-384 172-384 384-384c90 0 174 34 240 86l60-62c22 18 42 38 60 60zM470 598v-256h84v256h-84zM640 42v86h-256v-86h256z"
62
+        ],
63
+        "attrs": [],
64
+        "isMulticolor": false,
65
+        "isMulticolor2": false,
66
+        "tags": [
67
+          "timer"
68
+        ],
69
+        "defaultCode": 58405,
70
+        "grid": 24
71
+      },
72
+      "attrs": [],
73
+      "properties": {
74
+        "ligatures": "timer",
75
+        "id": 760,
76
+        "order": 916,
77
+        "prevSize": 24,
78
+        "code": 58405,
79
+        "name": "timer"
80
+      },
81
+      "setIdx": 1,
82
+      "setId": 1,
83
+      "iconIdx": 1
84
+    },
4
     {
85
     {
5
       "icon": {
86
       "icon": {
6
         "paths": [
87
         "paths": [
24
         "code": 57770,
105
         "code": 57770,
25
         "name": "bluetooth"
106
         "name": "bluetooth"
26
       },
107
       },
27
-      "setIdx": 0,
28
-      "setId": 2,
29
-      "iconIdx": 79
108
+      "setIdx": 1,
109
+      "setId": 1,
110
+      "iconIdx": 2
30
     },
111
     },
31
     {
112
     {
32
       "icon": {
113
       "icon": {
51
         "code": 58128,
132
         "code": 58128,
52
         "name": "headset"
133
         "name": "headset"
53
       },
134
       },
54
-      "setIdx": 0,
55
-      "setId": 2,
56
-      "iconIdx": 376
135
+      "setIdx": 1,
136
+      "setId": 1,
137
+      "iconIdx": 3
57
     },
138
     },
58
     {
139
     {
59
       "icon": {
140
       "icon": {
78
         "code": 58909,
159
         "code": 58909,
79
         "name": "phone-talk"
160
         "name": "phone-talk"
80
       },
161
       },
81
-      "setIdx": 0,
82
-      "setId": 2,
83
-      "iconIdx": 566
162
+      "setIdx": 1,
163
+      "setId": 1,
164
+      "iconIdx": 4
84
     },
165
     },
85
     {
166
     {
86
       "icon": {
167
       "icon": {
107
       },
188
       },
108
       "setIdx": 1,
189
       "setIdx": 1,
109
       "setId": 1,
190
       "setId": 1,
110
-      "iconIdx": 40
191
+      "iconIdx": 5
111
     },
192
     },
112
     {
193
     {
113
       "icon": {
194
       "icon": {
136
       },
217
       },
137
       "setIdx": 1,
218
       "setIdx": 1,
138
       "setId": 1,
219
       "setId": 1,
139
-      "iconIdx": 41
220
+      "iconIdx": 6
140
     },
221
     },
141
     {
222
     {
142
       "icon": {
223
       "icon": {
163
       },
244
       },
164
       "setIdx": 1,
245
       "setIdx": 1,
165
       "setId": 1,
246
       "setId": 1,
166
-      "iconIdx": 42
247
+      "iconIdx": 7
167
     },
248
     },
168
     {
249
     {
169
       "icon": {
250
       "icon": {
190
       },
271
       },
191
       "setIdx": 1,
272
       "setIdx": 1,
192
       "setId": 1,
273
       "setId": 1,
193
-      "iconIdx": 43
274
+      "iconIdx": 8
194
     },
275
     },
195
     {
276
     {
196
       "icon": {
277
       "icon": {
219
       },
300
       },
220
       "setIdx": 1,
301
       "setIdx": 1,
221
       "setId": 1,
302
       "setId": 1,
222
-      "iconIdx": 0
303
+      "iconIdx": 9
223
     },
304
     },
224
     {
305
     {
225
       "icon": {
306
       "icon": {
248
       },
329
       },
249
       "setIdx": 1,
330
       "setIdx": 1,
250
       "setId": 1,
331
       "setId": 1,
251
-      "iconIdx": 1
332
+      "iconIdx": 10
252
     },
333
     },
253
     {
334
     {
254
       "icon": {
335
       "icon": {
277
       },
358
       },
278
       "setIdx": 1,
359
       "setIdx": 1,
279
       "setId": 1,
360
       "setId": 1,
280
-      "iconIdx": 2
361
+      "iconIdx": 11
281
     },
362
     },
282
     {
363
     {
283
       "icon": {
364
       "icon": {
306
       },
387
       },
307
       "setIdx": 1,
388
       "setIdx": 1,
308
       "setId": 1,
389
       "setId": 1,
309
-      "iconIdx": 3
390
+      "iconIdx": 12
310
     },
391
     },
311
     {
392
     {
312
       "icon": {
393
       "icon": {
335
       },
416
       },
336
       "setIdx": 1,
417
       "setIdx": 1,
337
       "setId": 1,
418
       "setId": 1,
338
-      "iconIdx": 4
419
+      "iconIdx": 13
339
     },
420
     },
340
     {
421
     {
341
       "icon": {
422
       "icon": {
361
       },
442
       },
362
       "setIdx": 1,
443
       "setIdx": 1,
363
       "setId": 1,
444
       "setId": 1,
364
-      "iconIdx": 5
445
+      "iconIdx": 14
365
     },
446
     },
366
     {
447
     {
367
       "icon": {
448
       "icon": {
387
       },
468
       },
388
       "setIdx": 1,
469
       "setIdx": 1,
389
       "setId": 1,
470
       "setId": 1,
390
-      "iconIdx": 6
471
+      "iconIdx": 15
391
     },
472
     },
392
     {
473
     {
393
       "icon": {
474
       "icon": {
413
       },
494
       },
414
       "setIdx": 1,
495
       "setIdx": 1,
415
       "setId": 1,
496
       "setId": 1,
416
-      "iconIdx": 7
497
+      "iconIdx": 16
417
     },
498
     },
418
     {
499
     {
419
       "icon": {
500
       "icon": {
439
       },
520
       },
440
       "setIdx": 1,
521
       "setIdx": 1,
441
       "setId": 1,
522
       "setId": 1,
442
-      "iconIdx": 8
523
+      "iconIdx": 17
443
     },
524
     },
444
     {
525
     {
445
       "icon": {
526
       "icon": {
465
       },
546
       },
466
       "setIdx": 1,
547
       "setIdx": 1,
467
       "setId": 1,
548
       "setId": 1,
468
-      "iconIdx": 9
549
+      "iconIdx": 18
469
     },
550
     },
470
     {
551
     {
471
       "icon": {
552
       "icon": {
491
       },
572
       },
492
       "setIdx": 1,
573
       "setIdx": 1,
493
       "setId": 1,
574
       "setId": 1,
494
-      "iconIdx": 10
575
+      "iconIdx": 19
495
     },
576
     },
496
     {
577
     {
497
       "icon": {
578
       "icon": {
517
       },
598
       },
518
       "setIdx": 1,
599
       "setIdx": 1,
519
       "setId": 1,
600
       "setId": 1,
520
-      "iconIdx": 11
601
+      "iconIdx": 20
521
     },
602
     },
522
     {
603
     {
523
       "icon": {
604
       "icon": {
543
       },
624
       },
544
       "setIdx": 1,
625
       "setIdx": 1,
545
       "setId": 1,
626
       "setId": 1,
546
-      "iconIdx": 12
627
+      "iconIdx": 21
547
     },
628
     },
548
     {
629
     {
549
       "icon": {
630
       "icon": {
569
       },
650
       },
570
       "setIdx": 1,
651
       "setIdx": 1,
571
       "setId": 1,
652
       "setId": 1,
572
-      "iconIdx": 13
653
+      "iconIdx": 22
573
     },
654
     },
574
     {
655
     {
575
       "icon": {
656
       "icon": {
595
       },
676
       },
596
       "setIdx": 1,
677
       "setIdx": 1,
597
       "setId": 1,
678
       "setId": 1,
598
-      "iconIdx": 14
679
+      "iconIdx": 23
599
     },
680
     },
600
     {
681
     {
601
       "icon": {
682
       "icon": {
621
       },
702
       },
622
       "setIdx": 1,
703
       "setIdx": 1,
623
       "setId": 1,
704
       "setId": 1,
624
-      "iconIdx": 15
705
+      "iconIdx": 24
625
     },
706
     },
626
     {
707
     {
627
       "icon": {
708
       "icon": {
647
       },
728
       },
648
       "setIdx": 1,
729
       "setIdx": 1,
649
       "setId": 1,
730
       "setId": 1,
650
-      "iconIdx": 16
731
+      "iconIdx": 25
651
     },
732
     },
652
     {
733
     {
653
       "icon": {
734
       "icon": {
673
       },
754
       },
674
       "setIdx": 1,
755
       "setIdx": 1,
675
       "setId": 1,
756
       "setId": 1,
676
-      "iconIdx": 17
757
+      "iconIdx": 26
677
     },
758
     },
678
     {
759
     {
679
       "icon": {
760
       "icon": {
699
       },
780
       },
700
       "setIdx": 1,
781
       "setIdx": 1,
701
       "setId": 1,
782
       "setId": 1,
702
-      "iconIdx": 18
783
+      "iconIdx": 27
703
     },
784
     },
704
     {
785
     {
705
       "icon": {
786
       "icon": {
725
       },
806
       },
726
       "setIdx": 1,
807
       "setIdx": 1,
727
       "setId": 1,
808
       "setId": 1,
728
-      "iconIdx": 19
809
+      "iconIdx": 28
729
     },
810
     },
730
     {
811
     {
731
       "icon": {
812
       "icon": {
751
       },
832
       },
752
       "setIdx": 1,
833
       "setIdx": 1,
753
       "setId": 1,
834
       "setId": 1,
754
-      "iconIdx": 20
835
+      "iconIdx": 29
755
     },
836
     },
756
     {
837
     {
757
       "icon": {
838
       "icon": {
777
       },
858
       },
778
       "setIdx": 1,
859
       "setIdx": 1,
779
       "setId": 1,
860
       "setId": 1,
780
-      "iconIdx": 21
861
+      "iconIdx": 30
781
     },
862
     },
782
     {
863
     {
783
       "icon": {
864
       "icon": {
803
       },
884
       },
804
       "setIdx": 1,
885
       "setIdx": 1,
805
       "setId": 1,
886
       "setId": 1,
806
-      "iconIdx": 22
887
+      "iconIdx": 31
807
     },
888
     },
808
     {
889
     {
809
       "icon": {
890
       "icon": {
829
       },
910
       },
830
       "setIdx": 1,
911
       "setIdx": 1,
831
       "setId": 1,
912
       "setId": 1,
832
-      "iconIdx": 23
913
+      "iconIdx": 32
833
     },
914
     },
834
     {
915
     {
835
       "icon": {
916
       "icon": {
855
       },
936
       },
856
       "setIdx": 1,
937
       "setIdx": 1,
857
       "setId": 1,
938
       "setId": 1,
858
-      "iconIdx": 24
939
+      "iconIdx": 33
859
     },
940
     },
860
     {
941
     {
861
       "icon": {
942
       "icon": {
881
       },
962
       },
882
       "setIdx": 1,
963
       "setIdx": 1,
883
       "setId": 1,
964
       "setId": 1,
884
-      "iconIdx": 25
965
+      "iconIdx": 34
885
     },
966
     },
886
     {
967
     {
887
       "icon": {
968
       "icon": {
907
       },
988
       },
908
       "setIdx": 1,
989
       "setIdx": 1,
909
       "setId": 1,
990
       "setId": 1,
910
-      "iconIdx": 26
991
+      "iconIdx": 35
911
     },
992
     },
912
     {
993
     {
913
       "icon": {
994
       "icon": {
933
       },
1014
       },
934
       "setIdx": 1,
1015
       "setIdx": 1,
935
       "setId": 1,
1016
       "setId": 1,
936
-      "iconIdx": 27
1017
+      "iconIdx": 36
937
     },
1018
     },
938
     {
1019
     {
939
       "icon": {
1020
       "icon": {
959
       },
1040
       },
960
       "setIdx": 1,
1041
       "setIdx": 1,
961
       "setId": 1,
1042
       "setId": 1,
962
-      "iconIdx": 28
1043
+      "iconIdx": 37
963
     },
1044
     },
964
     {
1045
     {
965
       "icon": {
1046
       "icon": {
985
       },
1066
       },
986
       "setIdx": 1,
1067
       "setIdx": 1,
987
       "setId": 1,
1068
       "setId": 1,
988
-      "iconIdx": 29
1069
+      "iconIdx": 38
989
     },
1070
     },
990
     {
1071
     {
991
       "icon": {
1072
       "icon": {
1011
       },
1092
       },
1012
       "setIdx": 1,
1093
       "setIdx": 1,
1013
       "setId": 1,
1094
       "setId": 1,
1014
-      "iconIdx": 30
1095
+      "iconIdx": 39
1015
     },
1096
     },
1016
     {
1097
     {
1017
       "icon": {
1098
       "icon": {
1037
       },
1118
       },
1038
       "setIdx": 1,
1119
       "setIdx": 1,
1039
       "setId": 1,
1120
       "setId": 1,
1040
-      "iconIdx": 31
1121
+      "iconIdx": 40
1041
     },
1122
     },
1042
     {
1123
     {
1043
       "icon": {
1124
       "icon": {
1063
       },
1144
       },
1064
       "setIdx": 1,
1145
       "setIdx": 1,
1065
       "setId": 1,
1146
       "setId": 1,
1066
-      "iconIdx": 32
1147
+      "iconIdx": 41
1067
     },
1148
     },
1068
     {
1149
     {
1069
       "icon": {
1150
       "icon": {
1089
       },
1170
       },
1090
       "setIdx": 1,
1171
       "setIdx": 1,
1091
       "setId": 1,
1172
       "setId": 1,
1092
-      "iconIdx": 33
1173
+      "iconIdx": 42
1093
     },
1174
     },
1094
     {
1175
     {
1095
       "icon": {
1176
       "icon": {
1118
       },
1199
       },
1119
       "setIdx": 1,
1200
       "setIdx": 1,
1120
       "setId": 1,
1201
       "setId": 1,
1121
-      "iconIdx": 34
1202
+      "iconIdx": 43
1122
     },
1203
     },
1123
     {
1204
     {
1124
       "icon": {
1205
       "icon": {
1148
       },
1229
       },
1149
       "setIdx": 1,
1230
       "setIdx": 1,
1150
       "setId": 1,
1231
       "setId": 1,
1151
-      "iconIdx": 35
1232
+      "iconIdx": 44
1152
     },
1233
     },
1153
     {
1234
     {
1154
       "icon": {
1235
       "icon": {
1178
       },
1259
       },
1179
       "setIdx": 1,
1260
       "setIdx": 1,
1180
       "setId": 1,
1261
       "setId": 1,
1181
-      "iconIdx": 36
1262
+      "iconIdx": 45
1182
     },
1263
     },
1183
     {
1264
     {
1184
       "icon": {
1265
       "icon": {
1204
       },
1285
       },
1205
       "setIdx": 1,
1286
       "setIdx": 1,
1206
       "setId": 1,
1287
       "setId": 1,
1207
-      "iconIdx": 37
1288
+      "iconIdx": 46
1208
     },
1289
     },
1209
     {
1290
     {
1210
       "icon": {
1291
       "icon": {
1230
       },
1311
       },
1231
       "setIdx": 1,
1312
       "setIdx": 1,
1232
       "setId": 1,
1313
       "setId": 1,
1233
-      "iconIdx": 38
1314
+      "iconIdx": 47
1234
     },
1315
     },
1235
     {
1316
     {
1236
       "icon": {
1317
       "icon": {
1256
       },
1337
       },
1257
       "setIdx": 1,
1338
       "setIdx": 1,
1258
       "setId": 1,
1339
       "setId": 1,
1259
-      "iconIdx": 39
1340
+      "iconIdx": 48
1260
     }
1341
     }
1261
   ],
1342
   ],
1262
   "height": 1024,
1343
   "height": 1024,

+ 5
- 0
package-lock.json Näytä tiedosto

7064
         "minimist": "0.0.8"
7064
         "minimist": "0.0.8"
7065
       }
7065
       }
7066
     },
7066
     },
7067
+    "moment": {
7068
+      "version": "2.19.4",
7069
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.4.tgz",
7070
+      "integrity": "sha512-1xFTAknSLfc47DIxHDUbnJWC+UwgWxATmymaxIPQpmMh7LBm7ZbwVEsuushqwL2GYZU0jie4xO+TK44hJPjNSQ=="
7071
+    },
7067
     "morgan": {
7072
     "morgan": {
7068
       "version": "1.6.1",
7073
       "version": "1.6.1",
7069
       "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz",
7074
       "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz",

+ 1
- 0
package.json Näytä tiedosto

46
     "jwt-decode": "2.2.0",
46
     "jwt-decode": "2.2.0",
47
     "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#f71ff66fb26f9dd0b49baeeee239345ba268d46d",
47
     "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#f71ff66fb26f9dd0b49baeeee239345ba268d46d",
48
     "lodash": "4.17.4",
48
     "lodash": "4.17.4",
49
+    "moment": "2.19.4",
49
     "nuclear-js": "1.4.0",
50
     "nuclear-js": "1.4.0",
50
     "postis": "2.2.0",
51
     "postis": "2.2.0",
51
     "prop-types": "15.6.0",
52
     "prop-types": "15.6.0",

+ 134
- 53
react/features/base/font-icons/jitsi.json Näytä tiedosto

1
 {
1
 {
2
   "IcoMoonType": "selection",
2
   "IcoMoonType": "selection",
3
   "icons": [
3
   "icons": [
4
+    {
5
+      "icon": {
6
+        "paths": [
7
+          "M764 742c56-60 90-142 90-230 0-142-88-266-214-316v18c0 46-40 84-86 84h-84v86c0 24-20 42-44 42h-84v86h256c24 0 42 18 42 42v128h42c38 0 70 26 82 60zM470 850v-82c-46 0-86-40-86-86v-42l-204-204c-6 24-10 50-10 76 0 174 132 318 300 338zM512 86c236 0 426 190 426 426s-190 426-426 426-426-190-426-426 190-426 426-426z"
8
+        ],
9
+        "attrs": [],
10
+        "isMulticolor": false,
11
+        "isMulticolor2": false,
12
+        "tags": [
13
+          "public"
14
+        ],
15
+        "defaultCode": 59403,
16
+        "grid": 24
17
+      },
18
+      "attrs": [],
19
+      "properties": {
20
+        "ligatures": "public",
21
+        "id": 605,
22
+        "order": 920,
23
+        "prevSize": 24,
24
+        "code": 59403,
25
+        "name": "public"
26
+      },
27
+      "setIdx": 0,
28
+      "setId": 2,
29
+      "iconIdx": 605
30
+    },
31
+    {
32
+      "icon": {
33
+        "paths": [
34
+          "M598 598v84h-300v-84h300zM810 810v-468h-596v468h596zM810 128c46 0 86 40 86 86v596c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h42v-86h86v86h340v-86h86v86h42zM726 426v86h-428v-86h428z"
35
+        ],
36
+        "attrs": [],
37
+        "isMulticolor": false,
38
+        "isMulticolor2": false,
39
+        "tags": [
40
+          "event_note"
41
+        ],
42
+        "defaultCode": 58902,
43
+        "grid": 24
44
+      },
45
+      "attrs": [],
46
+      "properties": {
47
+        "ligatures": "event_note",
48
+        "id": 252,
49
+        "order": 919,
50
+        "prevSize": 24,
51
+        "code": 58902,
52
+        "name": "event_note"
53
+      },
54
+      "setIdx": 1,
55
+      "setId": 1,
56
+      "iconIdx": 0
57
+    },
58
+    {
59
+      "icon": {
60
+        "paths": [
61
+          "M512 854c166 0 298-134 298-300s-132-298-298-298-298 132-298 298 132 300 298 300zM812 316c52 66 84 148 84 238 0 212-172 384-384 384s-384-172-384-384 172-384 384-384c90 0 174 34 240 86l60-62c22 18 42 38 60 60zM470 598v-256h84v256h-84zM640 42v86h-256v-86h256z"
62
+        ],
63
+        "attrs": [],
64
+        "isMulticolor": false,
65
+        "isMulticolor2": false,
66
+        "tags": [
67
+          "timer"
68
+        ],
69
+        "defaultCode": 58405,
70
+        "grid": 24
71
+      },
72
+      "attrs": [],
73
+      "properties": {
74
+        "ligatures": "timer",
75
+        "id": 760,
76
+        "order": 916,
77
+        "prevSize": 24,
78
+        "code": 58405,
79
+        "name": "timer"
80
+      },
81
+      "setIdx": 1,
82
+      "setId": 1,
83
+      "iconIdx": 1
84
+    },
4
     {
85
     {
5
       "icon": {
86
       "icon": {
6
         "paths": [
87
         "paths": [
24
         "code": 57770,
105
         "code": 57770,
25
         "name": "bluetooth"
106
         "name": "bluetooth"
26
       },
107
       },
27
-      "setIdx": 0,
28
-      "setId": 2,
29
-      "iconIdx": 79
108
+      "setIdx": 1,
109
+      "setId": 1,
110
+      "iconIdx": 2
30
     },
111
     },
31
     {
112
     {
32
       "icon": {
113
       "icon": {
51
         "code": 58128,
132
         "code": 58128,
52
         "name": "headset"
133
         "name": "headset"
53
       },
134
       },
54
-      "setIdx": 0,
55
-      "setId": 2,
56
-      "iconIdx": 376
135
+      "setIdx": 1,
136
+      "setId": 1,
137
+      "iconIdx": 3
57
     },
138
     },
58
     {
139
     {
59
       "icon": {
140
       "icon": {
78
         "code": 58909,
159
         "code": 58909,
79
         "name": "phone-talk"
160
         "name": "phone-talk"
80
       },
161
       },
81
-      "setIdx": 0,
82
-      "setId": 2,
83
-      "iconIdx": 566
162
+      "setIdx": 1,
163
+      "setId": 1,
164
+      "iconIdx": 4
84
     },
165
     },
85
     {
166
     {
86
       "icon": {
167
       "icon": {
107
       },
188
       },
108
       "setIdx": 1,
189
       "setIdx": 1,
109
       "setId": 1,
190
       "setId": 1,
110
-      "iconIdx": 40
191
+      "iconIdx": 5
111
     },
192
     },
112
     {
193
     {
113
       "icon": {
194
       "icon": {
136
       },
217
       },
137
       "setIdx": 1,
218
       "setIdx": 1,
138
       "setId": 1,
219
       "setId": 1,
139
-      "iconIdx": 41
220
+      "iconIdx": 6
140
     },
221
     },
141
     {
222
     {
142
       "icon": {
223
       "icon": {
163
       },
244
       },
164
       "setIdx": 1,
245
       "setIdx": 1,
165
       "setId": 1,
246
       "setId": 1,
166
-      "iconIdx": 42
247
+      "iconIdx": 7
167
     },
248
     },
168
     {
249
     {
169
       "icon": {
250
       "icon": {
190
       },
271
       },
191
       "setIdx": 1,
272
       "setIdx": 1,
192
       "setId": 1,
273
       "setId": 1,
193
-      "iconIdx": 43
274
+      "iconIdx": 8
194
     },
275
     },
195
     {
276
     {
196
       "icon": {
277
       "icon": {
219
       },
300
       },
220
       "setIdx": 1,
301
       "setIdx": 1,
221
       "setId": 1,
302
       "setId": 1,
222
-      "iconIdx": 0
303
+      "iconIdx": 9
223
     },
304
     },
224
     {
305
     {
225
       "icon": {
306
       "icon": {
248
       },
329
       },
249
       "setIdx": 1,
330
       "setIdx": 1,
250
       "setId": 1,
331
       "setId": 1,
251
-      "iconIdx": 1
332
+      "iconIdx": 10
252
     },
333
     },
253
     {
334
     {
254
       "icon": {
335
       "icon": {
277
       },
358
       },
278
       "setIdx": 1,
359
       "setIdx": 1,
279
       "setId": 1,
360
       "setId": 1,
280
-      "iconIdx": 2
361
+      "iconIdx": 11
281
     },
362
     },
282
     {
363
     {
283
       "icon": {
364
       "icon": {
306
       },
387
       },
307
       "setIdx": 1,
388
       "setIdx": 1,
308
       "setId": 1,
389
       "setId": 1,
309
-      "iconIdx": 3
390
+      "iconIdx": 12
310
     },
391
     },
311
     {
392
     {
312
       "icon": {
393
       "icon": {
335
       },
416
       },
336
       "setIdx": 1,
417
       "setIdx": 1,
337
       "setId": 1,
418
       "setId": 1,
338
-      "iconIdx": 4
419
+      "iconIdx": 13
339
     },
420
     },
340
     {
421
     {
341
       "icon": {
422
       "icon": {
361
       },
442
       },
362
       "setIdx": 1,
443
       "setIdx": 1,
363
       "setId": 1,
444
       "setId": 1,
364
-      "iconIdx": 5
445
+      "iconIdx": 14
365
     },
446
     },
366
     {
447
     {
367
       "icon": {
448
       "icon": {
387
       },
468
       },
388
       "setIdx": 1,
469
       "setIdx": 1,
389
       "setId": 1,
470
       "setId": 1,
390
-      "iconIdx": 6
471
+      "iconIdx": 15
391
     },
472
     },
392
     {
473
     {
393
       "icon": {
474
       "icon": {
413
       },
494
       },
414
       "setIdx": 1,
495
       "setIdx": 1,
415
       "setId": 1,
496
       "setId": 1,
416
-      "iconIdx": 7
497
+      "iconIdx": 16
417
     },
498
     },
418
     {
499
     {
419
       "icon": {
500
       "icon": {
439
       },
520
       },
440
       "setIdx": 1,
521
       "setIdx": 1,
441
       "setId": 1,
522
       "setId": 1,
442
-      "iconIdx": 8
523
+      "iconIdx": 17
443
     },
524
     },
444
     {
525
     {
445
       "icon": {
526
       "icon": {
465
       },
546
       },
466
       "setIdx": 1,
547
       "setIdx": 1,
467
       "setId": 1,
548
       "setId": 1,
468
-      "iconIdx": 9
549
+      "iconIdx": 18
469
     },
550
     },
470
     {
551
     {
471
       "icon": {
552
       "icon": {
491
       },
572
       },
492
       "setIdx": 1,
573
       "setIdx": 1,
493
       "setId": 1,
574
       "setId": 1,
494
-      "iconIdx": 10
575
+      "iconIdx": 19
495
     },
576
     },
496
     {
577
     {
497
       "icon": {
578
       "icon": {
517
       },
598
       },
518
       "setIdx": 1,
599
       "setIdx": 1,
519
       "setId": 1,
600
       "setId": 1,
520
-      "iconIdx": 11
601
+      "iconIdx": 20
521
     },
602
     },
522
     {
603
     {
523
       "icon": {
604
       "icon": {
543
       },
624
       },
544
       "setIdx": 1,
625
       "setIdx": 1,
545
       "setId": 1,
626
       "setId": 1,
546
-      "iconIdx": 12
627
+      "iconIdx": 21
547
     },
628
     },
548
     {
629
     {
549
       "icon": {
630
       "icon": {
569
       },
650
       },
570
       "setIdx": 1,
651
       "setIdx": 1,
571
       "setId": 1,
652
       "setId": 1,
572
-      "iconIdx": 13
653
+      "iconIdx": 22
573
     },
654
     },
574
     {
655
     {
575
       "icon": {
656
       "icon": {
595
       },
676
       },
596
       "setIdx": 1,
677
       "setIdx": 1,
597
       "setId": 1,
678
       "setId": 1,
598
-      "iconIdx": 14
679
+      "iconIdx": 23
599
     },
680
     },
600
     {
681
     {
601
       "icon": {
682
       "icon": {
621
       },
702
       },
622
       "setIdx": 1,
703
       "setIdx": 1,
623
       "setId": 1,
704
       "setId": 1,
624
-      "iconIdx": 15
705
+      "iconIdx": 24
625
     },
706
     },
626
     {
707
     {
627
       "icon": {
708
       "icon": {
647
       },
728
       },
648
       "setIdx": 1,
729
       "setIdx": 1,
649
       "setId": 1,
730
       "setId": 1,
650
-      "iconIdx": 16
731
+      "iconIdx": 25
651
     },
732
     },
652
     {
733
     {
653
       "icon": {
734
       "icon": {
673
       },
754
       },
674
       "setIdx": 1,
755
       "setIdx": 1,
675
       "setId": 1,
756
       "setId": 1,
676
-      "iconIdx": 17
757
+      "iconIdx": 26
677
     },
758
     },
678
     {
759
     {
679
       "icon": {
760
       "icon": {
699
       },
780
       },
700
       "setIdx": 1,
781
       "setIdx": 1,
701
       "setId": 1,
782
       "setId": 1,
702
-      "iconIdx": 18
783
+      "iconIdx": 27
703
     },
784
     },
704
     {
785
     {
705
       "icon": {
786
       "icon": {
725
       },
806
       },
726
       "setIdx": 1,
807
       "setIdx": 1,
727
       "setId": 1,
808
       "setId": 1,
728
-      "iconIdx": 19
809
+      "iconIdx": 28
729
     },
810
     },
730
     {
811
     {
731
       "icon": {
812
       "icon": {
751
       },
832
       },
752
       "setIdx": 1,
833
       "setIdx": 1,
753
       "setId": 1,
834
       "setId": 1,
754
-      "iconIdx": 20
835
+      "iconIdx": 29
755
     },
836
     },
756
     {
837
     {
757
       "icon": {
838
       "icon": {
777
       },
858
       },
778
       "setIdx": 1,
859
       "setIdx": 1,
779
       "setId": 1,
860
       "setId": 1,
780
-      "iconIdx": 21
861
+      "iconIdx": 30
781
     },
862
     },
782
     {
863
     {
783
       "icon": {
864
       "icon": {
803
       },
884
       },
804
       "setIdx": 1,
885
       "setIdx": 1,
805
       "setId": 1,
886
       "setId": 1,
806
-      "iconIdx": 22
887
+      "iconIdx": 31
807
     },
888
     },
808
     {
889
     {
809
       "icon": {
890
       "icon": {
829
       },
910
       },
830
       "setIdx": 1,
911
       "setIdx": 1,
831
       "setId": 1,
912
       "setId": 1,
832
-      "iconIdx": 23
913
+      "iconIdx": 32
833
     },
914
     },
834
     {
915
     {
835
       "icon": {
916
       "icon": {
855
       },
936
       },
856
       "setIdx": 1,
937
       "setIdx": 1,
857
       "setId": 1,
938
       "setId": 1,
858
-      "iconIdx": 24
939
+      "iconIdx": 33
859
     },
940
     },
860
     {
941
     {
861
       "icon": {
942
       "icon": {
881
       },
962
       },
882
       "setIdx": 1,
963
       "setIdx": 1,
883
       "setId": 1,
964
       "setId": 1,
884
-      "iconIdx": 25
965
+      "iconIdx": 34
885
     },
966
     },
886
     {
967
     {
887
       "icon": {
968
       "icon": {
907
       },
988
       },
908
       "setIdx": 1,
989
       "setIdx": 1,
909
       "setId": 1,
990
       "setId": 1,
910
-      "iconIdx": 26
991
+      "iconIdx": 35
911
     },
992
     },
912
     {
993
     {
913
       "icon": {
994
       "icon": {
933
       },
1014
       },
934
       "setIdx": 1,
1015
       "setIdx": 1,
935
       "setId": 1,
1016
       "setId": 1,
936
-      "iconIdx": 27
1017
+      "iconIdx": 36
937
     },
1018
     },
938
     {
1019
     {
939
       "icon": {
1020
       "icon": {
959
       },
1040
       },
960
       "setIdx": 1,
1041
       "setIdx": 1,
961
       "setId": 1,
1042
       "setId": 1,
962
-      "iconIdx": 28
1043
+      "iconIdx": 37
963
     },
1044
     },
964
     {
1045
     {
965
       "icon": {
1046
       "icon": {
985
       },
1066
       },
986
       "setIdx": 1,
1067
       "setIdx": 1,
987
       "setId": 1,
1068
       "setId": 1,
988
-      "iconIdx": 29
1069
+      "iconIdx": 38
989
     },
1070
     },
990
     {
1071
     {
991
       "icon": {
1072
       "icon": {
1011
       },
1092
       },
1012
       "setIdx": 1,
1093
       "setIdx": 1,
1013
       "setId": 1,
1094
       "setId": 1,
1014
-      "iconIdx": 30
1095
+      "iconIdx": 39
1015
     },
1096
     },
1016
     {
1097
     {
1017
       "icon": {
1098
       "icon": {
1037
       },
1118
       },
1038
       "setIdx": 1,
1119
       "setIdx": 1,
1039
       "setId": 1,
1120
       "setId": 1,
1040
-      "iconIdx": 31
1121
+      "iconIdx": 40
1041
     },
1122
     },
1042
     {
1123
     {
1043
       "icon": {
1124
       "icon": {
1063
       },
1144
       },
1064
       "setIdx": 1,
1145
       "setIdx": 1,
1065
       "setId": 1,
1146
       "setId": 1,
1066
-      "iconIdx": 32
1147
+      "iconIdx": 41
1067
     },
1148
     },
1068
     {
1149
     {
1069
       "icon": {
1150
       "icon": {
1089
       },
1170
       },
1090
       "setIdx": 1,
1171
       "setIdx": 1,
1091
       "setId": 1,
1172
       "setId": 1,
1092
-      "iconIdx": 33
1173
+      "iconIdx": 42
1093
     },
1174
     },
1094
     {
1175
     {
1095
       "icon": {
1176
       "icon": {
1118
       },
1199
       },
1119
       "setIdx": 1,
1200
       "setIdx": 1,
1120
       "setId": 1,
1201
       "setId": 1,
1121
-      "iconIdx": 34
1202
+      "iconIdx": 43
1122
     },
1203
     },
1123
     {
1204
     {
1124
       "icon": {
1205
       "icon": {
1148
       },
1229
       },
1149
       "setIdx": 1,
1230
       "setIdx": 1,
1150
       "setId": 1,
1231
       "setId": 1,
1151
-      "iconIdx": 35
1232
+      "iconIdx": 44
1152
     },
1233
     },
1153
     {
1234
     {
1154
       "icon": {
1235
       "icon": {
1178
       },
1259
       },
1179
       "setIdx": 1,
1260
       "setIdx": 1,
1180
       "setId": 1,
1261
       "setId": 1,
1181
-      "iconIdx": 36
1262
+      "iconIdx": 45
1182
     },
1263
     },
1183
     {
1264
     {
1184
       "icon": {
1265
       "icon": {
1204
       },
1285
       },
1205
       "setIdx": 1,
1286
       "setIdx": 1,
1206
       "setId": 1,
1287
       "setId": 1,
1207
-      "iconIdx": 37
1288
+      "iconIdx": 46
1208
     },
1289
     },
1209
     {
1290
     {
1210
       "icon": {
1291
       "icon": {
1230
       },
1311
       },
1231
       "setIdx": 1,
1312
       "setIdx": 1,
1232
       "setId": 1,
1313
       "setId": 1,
1233
-      "iconIdx": 38
1314
+      "iconIdx": 47
1234
     },
1315
     },
1235
     {
1316
     {
1236
       "icon": {
1317
       "icon": {
1256
       },
1337
       },
1257
       "setIdx": 1,
1338
       "setIdx": 1,
1258
       "setId": 1,
1339
       "setId": 1,
1259
-      "iconIdx": 39
1340
+      "iconIdx": 48
1260
     }
1341
     }
1261
   ],
1342
   ],
1262
   "height": 1024,
1343
   "height": 1024,

+ 20
- 0
react/features/base/lib-jitsi-meet/native/Storage.js Näytä tiedosto

88
         return this.hasOwnProperty(key) ? this[key] : null;
88
         return this.hasOwnProperty(key) ? this[key] : null;
89
     }
89
     }
90
 
90
 
91
+    /**
92
+     * Returns the value associated with a specific key in this storage in an
93
+     * async manner. This method is required for those cases where we need
94
+     * the stored data but we're not sure yet whether the {@code Storage}
95
+     * is already initialised or not - e.g. on app start.
96
+     *
97
+     * @private
98
+     * @param {string} key - The name of the key to retrieve the value of.
99
+     * @returns {Promise}
100
+     */
101
+    _getItemAsync(key) {
102
+        return new Promise(resolve => {
103
+            AsyncStorage.getItem(
104
+                `${String(this._keyPrefix)}${key}`,
105
+                (error, result) => {
106
+                    resolve(result ? result : null);
107
+                });
108
+        });
109
+    }
110
+
91
     /**
111
     /**
92
      * Returns the name of the nth key in this storage.
112
      * Returns the name of the nth key in this storage.
93
      *
113
      *

+ 101
- 0
react/features/recent-list/components/AbstractRecentList.js Näytä tiedosto

1
+// @flow
2
+
3
+import { Component } from 'react';
4
+import { ListView } from 'react-native';
5
+
6
+import { getRecentRooms } from '../functions';
7
+
8
+import { appNavigate } from '../../app';
9
+
10
+/**
11
+ * The type of the React {@code Component} state of {@link AbstractRecentList}.
12
+ */
13
+type State = {
14
+
15
+    /**
16
+     *  The {@code ListView.DataSource} to be used for the {@code ListView}.
17
+     *  Its content comes from the native implementation of
18
+     *  {@code window.localStorage}.
19
+     */
20
+    dataSource: Object
21
+}
22
+
23
+/**
24
+ * The type of the React {@code Component} props of {@link AbstractRecentList}
25
+ */
26
+type Props = {
27
+
28
+    /**
29
+     * Redux store dispatch function.
30
+     */
31
+    dispatch: Dispatch<*>,
32
+}
33
+
34
+/**
35
+ * Implements a React {@link Component} which represents the list of
36
+ * conferences recently joined, similar to how a list of last dialed
37
+ * numbers list would do on a mobile
38
+ *
39
+ * @extends Component
40
+ */
41
+export default class AbstractRecentList extends Component<Props, State> {
42
+
43
+    /**
44
+    * The datasource that backs the {@code ListView}
45
+    */
46
+    listDataSource = new ListView.DataSource({
47
+        rowHasChanged: (r1, r2) =>
48
+            r1.conference !== r2.conference
49
+                && r1.dateTimeStamp !== r2.dateTimeStamp
50
+    });;
51
+
52
+    /**
53
+     * Initializes a new {@code AbstractRecentList} instance.
54
+     */
55
+    constructor() {
56
+        super();
57
+
58
+        this.state = {
59
+            dataSource: this.listDataSource.cloneWithRows([])
60
+        };
61
+    }
62
+
63
+    /**
64
+     * Implements React's {@link Component#componentWillMount()}. Invoked
65
+     * immediately before mounting occurs.
66
+     *
67
+     * @inheritdoc
68
+     */
69
+    componentWillMount() {
70
+        // this must be done asynchronously because we don't have the storage
71
+        // initiated on app startup immediately.
72
+        getRecentRooms().then(rooms => {
73
+            this.setState({
74
+                dataSource: this.listDataSource.cloneWithRows(rooms)
75
+            });
76
+        });
77
+    }
78
+
79
+    /**
80
+    * Creates a bound onPress action for the list item.
81
+    *
82
+    * @param {string} room - The selected room.
83
+    * @returns {Function}
84
+    */
85
+    _onSelect(room) {
86
+        return this._onJoin.bind(this, room);
87
+    }
88
+
89
+    /**
90
+    * Joins the selected room.
91
+    *
92
+    * @param {string} room - The selected room.
93
+    * @returns {void}
94
+    */
95
+    _onJoin(room) {
96
+        if (room) {
97
+            this.props.dispatch(appNavigate(room));
98
+        }
99
+    }
100
+
101
+}

+ 208
- 0
react/features/recent-list/components/RecentList.native.js Näytä tiedosto

1
+import React from 'react';
2
+import { ListView, Text, TouchableHighlight, View } from 'react-native';
3
+import { connect } from 'react-redux';
4
+
5
+import AbstractRecentList from './AbstractRecentList';
6
+import styles, { UNDERLAY_COLOR } from './styles';
7
+
8
+import { Icon } from '../../base/font-icons';
9
+
10
+/**
11
+ * The native container rendering the list of the recently joined rooms.
12
+ *
13
+ * @extends AbstractRecentList
14
+ */
15
+class RecentList extends AbstractRecentList {
16
+    /**
17
+     * Initializes a new {@code RecentList} instance.
18
+     *
19
+     */
20
+    constructor() {
21
+        super();
22
+
23
+        this._getAvatarStyle = this._getAvatarStyle.bind(this);
24
+        this._onSelect = this._onSelect.bind(this);
25
+        this._renderConfDuration = this._renderConfDuration.bind(this);
26
+        this._renderRow = this._renderRow.bind(this);
27
+        this._renderServerInfo = this._renderServerInfo.bind(this);
28
+    }
29
+
30
+    /**
31
+     * Implements React's {@link Component#render()}. Renders a list of
32
+     * recently joined rooms.
33
+     *
34
+     * @inheritdoc
35
+     * @returns {ReactElement}
36
+     */
37
+    render() {
38
+        if (!this.state.dataSource.getRowCount()) {
39
+            return null;
40
+        }
41
+
42
+        return (
43
+            <View style = { styles.container }>
44
+                <ListView
45
+                    dataSource = { this.state.dataSource }
46
+                    enableEmptySections = { true }
47
+                    renderRow = { this._renderRow } />
48
+            </View>
49
+        );
50
+    }
51
+
52
+    /**
53
+    * Renders the list of recently joined rooms.
54
+    *
55
+    * @private
56
+    * @param {Object} data - The row data to be rendered.
57
+    * @returns {ReactElement}
58
+    */
59
+    _renderRow(data) {
60
+        return (
61
+            <TouchableHighlight
62
+                onPress = { this._onSelect(data.conference) }
63
+                underlayColor = { UNDERLAY_COLOR } >
64
+                <View style = { styles.row } >
65
+                    <View style = { styles.avatarContainer } >
66
+                        <View style = { this._getAvatarStyle(data) } >
67
+                            <Text style = { styles.avatarContent }>
68
+                                { data.initials }
69
+                            </Text>
70
+                        </View>
71
+                    </View>
72
+                    <View style = { styles.detailsContainer } >
73
+                        <Text
74
+                            numberOfLines = { 1 }
75
+                            style = { styles.roomName }>
76
+                            { data.room }
77
+                        </Text>
78
+                        <View style = { styles.infoWithIcon } >
79
+                            <Icon
80
+                                name = 'event_note'
81
+                                style = { styles.inlineIcon } />
82
+                            <Text style = { styles.date }>
83
+                                { data.dateString }
84
+                            </Text>
85
+                        </View>
86
+                        {
87
+                            this._renderConfDuration(data)
88
+                        }
89
+                        {
90
+                            this._renderServerInfo(data)
91
+                        }
92
+                    </View>
93
+                </View>
94
+            </TouchableHighlight>
95
+        );
96
+    }
97
+
98
+    /**
99
+    * Assembles the style array of the avatar based on if the conference
100
+    * was a home or remote server conference (based on current app setting).
101
+    *
102
+    * @private
103
+    * @param {Object} recentListEntry - The recent list entry being rendered.
104
+    * @returns {Array<Object>}
105
+    */
106
+    _getAvatarStyle(recentListEntry) {
107
+        const avatarStyles = [ styles.avatar ];
108
+
109
+        if (recentListEntry.baseURL !== this.props._homeServer) {
110
+            avatarStyles.push(
111
+                this._getColorForServerName(recentListEntry.serverName)
112
+            );
113
+        }
114
+
115
+        return avatarStyles;
116
+    }
117
+
118
+    /**
119
+    * Returns a style (color) based on the server name, so then the
120
+    * same server will always be rendered with the same avatar color.
121
+    *
122
+    * @private
123
+    * @param {string} serverName - The recent list entry being rendered.
124
+    * @returns {Object}
125
+    */
126
+    _getColorForServerName(serverName) {
127
+        let nameHash = 0;
128
+
129
+        for (let i = 0; i < serverName.length; i++) {
130
+            nameHash += serverName.codePointAt(i);
131
+        }
132
+
133
+        return styles[`avatarRemoteServer${(nameHash % 5) + 1}`];
134
+    }
135
+
136
+    /**
137
+    * Renders the server info component based on if the entry was
138
+    * on a different server or not.
139
+    *
140
+    * @private
141
+    * @param {Object} recentListEntry - The recent list entry being rendered.
142
+    * @returns {ReactElement}
143
+    */
144
+    _renderServerInfo(recentListEntry) {
145
+        if (recentListEntry.baseURL !== this.props._homeServer) {
146
+            return (
147
+                <View style = { styles.infoWithIcon } >
148
+                    <Icon
149
+                        name = 'public'
150
+                        style = { styles.inlineIcon } />
151
+                    <Text style = { styles.serverName }>
152
+                        { recentListEntry.serverName }
153
+                    </Text>
154
+                </View>
155
+            );
156
+        }
157
+
158
+        return null;
159
+    }
160
+
161
+    /**
162
+    * Renders the conference duration if available.
163
+    *
164
+    * @private
165
+    * @param {Object} recentListEntry - The recent list entry being rendered.
166
+    * @returns {ReactElement}
167
+    */
168
+    _renderConfDuration(recentListEntry) {
169
+        if (recentListEntry.conferenceDurationString) {
170
+            return (
171
+                <View style = { styles.infoWithIcon } >
172
+                    <Icon
173
+                        name = 'timer'
174
+                        style = { styles.inlineIcon } />
175
+                    <Text style = { styles.confLength }>
176
+                        { recentListEntry.conferenceDurationString }
177
+                    </Text>
178
+                </View>
179
+            );
180
+        }
181
+
182
+        return null;
183
+    }
184
+}
185
+
186
+/**
187
+ * Maps (parts of) the Redux state to the associated RecentList's props.
188
+ *
189
+ * @param {Object} state - The Redux state.
190
+ * @private
191
+ * @returns {{
192
+ *     _homeServer: string
193
+ * }}
194
+ */
195
+function _mapStateToProps(state) {
196
+    return {
197
+        /**
198
+         * The default server name based on which we determine
199
+         * the render method.
200
+         *
201
+         * @private
202
+         * @type {string}
203
+         */
204
+        _homeServer: state['features/app'].app._getDefaultURL()
205
+    };
206
+}
207
+
208
+export default connect(_mapStateToProps)(RecentList);

+ 1
- 0
react/features/recent-list/components/index.js Näytä tiedosto

1
+export { default as RecentList } from './RecentList';

+ 154
- 0
react/features/recent-list/components/styles.js Näytä tiedosto

1
+import {
2
+    createStyleSheet,
3
+    BoxModel
4
+} from '../../base/styles';
5
+
6
+const AVATAR_OPACITY = 0.4;
7
+const AVATAR_SIZE = 65;
8
+const OVERLAY_FONT_COLOR = 'rgba(255, 255, 255, 0.6)';
9
+
10
+export const UNDERLAY_COLOR = 'rgba(255, 255, 255, 0.2)';
11
+
12
+/**
13
+ * The styles of the React {@code Components} of the feature: recent list
14
+ * {@code RecentList}.
15
+ */
16
+export default createStyleSheet({
17
+
18
+    /**
19
+    * The style of the actual avatar
20
+    */
21
+    avatar: {
22
+        width: AVATAR_SIZE,
23
+        height: AVATAR_SIZE,
24
+        alignItems: 'center',
25
+        backgroundColor: `rgba(23, 160, 219, ${AVATAR_OPACITY})`,
26
+        justifyContent: 'center',
27
+        borderRadius: AVATAR_SIZE
28
+    },
29
+
30
+    /**
31
+    * The style of the avatar container that makes the avatar rounded.
32
+    */
33
+    avatarContainer: {
34
+        flexDirection: 'row',
35
+        justifyContent: 'space-around',
36
+        alignItems: 'center',
37
+        paddingTop: 5
38
+    },
39
+
40
+    /**
41
+    * Simple {@code Text} content of the avatar (the actual initials)
42
+    */
43
+    avatarContent: {
44
+        color: OVERLAY_FONT_COLOR,
45
+        fontSize: 32,
46
+        fontWeight: '100',
47
+        backgroundColor: 'rgba(0, 0, 0, 0)',
48
+        textAlign: 'center'
49
+    },
50
+
51
+    /**
52
+    * List of styles of the avatar of a remote meeting
53
+    * (not the default server). The number of colors are limited
54
+    * because they should match nicely.
55
+    */
56
+    avatarRemoteServer1: {
57
+        backgroundColor: `rgba(232, 105, 156, ${AVATAR_OPACITY})`
58
+    },
59
+
60
+    avatarRemoteServer2: {
61
+        backgroundColor: `rgba(255, 198, 115, ${AVATAR_OPACITY})`
62
+    },
63
+
64
+    avatarRemoteServer3: {
65
+        backgroundColor: `rgba(128, 128, 255, ${AVATAR_OPACITY})`
66
+    },
67
+
68
+    avatarRemoteServer4: {
69
+        backgroundColor: `rgba(105, 232, 194, ${AVATAR_OPACITY})`
70
+    },
71
+
72
+    avatarRemoteServer5: {
73
+        backgroundColor: `rgba(234, 255, 128, ${AVATAR_OPACITY})`
74
+    },
75
+
76
+    /**
77
+    * Style of the conference length (if rendered)
78
+    */
79
+    confLength: {
80
+        color: OVERLAY_FONT_COLOR,
81
+        fontWeight: 'normal'
82
+    },
83
+
84
+    /**
85
+    * This is the top level container style of the list
86
+    */
87
+    container: {
88
+        flex: 1
89
+    },
90
+
91
+    /**
92
+    * Second line of the list (date).
93
+    * May be extended with server name later.
94
+    */
95
+    date: {
96
+        color: OVERLAY_FONT_COLOR
97
+    },
98
+
99
+    /**
100
+    * The style of the details container (right side) of the list
101
+    */
102
+    detailsContainer: {
103
+        flex: 1,
104
+        flexDirection: 'column',
105
+        justifyContent: 'center',
106
+        marginLeft: 2 * BoxModel.margin,
107
+        alignItems: 'flex-start'
108
+    },
109
+
110
+    /**
111
+    * The container for an info line with an inline icon.
112
+    */
113
+    infoWithIcon: {
114
+        flexDirection: 'row',
115
+        justifyContent: 'flex-start',
116
+        alignItems: 'center'
117
+    },
118
+
119
+    /**
120
+    * Style of an inline icon in an info line.
121
+    */
122
+    inlineIcon: {
123
+        color: OVERLAY_FONT_COLOR,
124
+        marginRight: 5
125
+    },
126
+
127
+    /**
128
+    * First line of the list (room name)
129
+    */
130
+    roomName: {
131
+        fontSize: 18,
132
+        fontWeight: 'bold',
133
+        color: OVERLAY_FONT_COLOR
134
+    },
135
+
136
+    /**
137
+    * The style of one single row in the list
138
+    */
139
+    row: {
140
+        padding: 8,
141
+        paddingBottom: 0,
142
+        flex: 1,
143
+        flexDirection: 'row',
144
+        alignItems: 'center'
145
+    },
146
+
147
+    /**
148
+    * Style of the server name component (if rendered)
149
+    */
150
+    serverName: {
151
+        color: OVERLAY_FONT_COLOR,
152
+        fontWeight: 'normal'
153
+    }
154
+});

+ 11
- 0
react/features/recent-list/constants.js Näytä tiedosto

1
+/**
2
+ * The max size of the list.
3
+ */
4
+export const LIST_SIZE = 30;
5
+
6
+/**
7
+ * The name of the {@code localStorage} item where recent rooms are stored.
8
+ *
9
+ * @type {string}
10
+ */
11
+export const RECENT_URL_STORAGE = 'recentURLs';

+ 132
- 0
react/features/recent-list/functions.js Näytä tiedosto

1
+// @flow
2
+
3
+import moment from 'moment';
4
+
5
+import { RECENT_URL_STORAGE } from './constants';
6
+
7
+import { i18next } from '../base/i18n';
8
+import { parseURIString } from '../base/util';
9
+
10
+/**
11
+* Retreives the recent room list and generates all the data needed
12
+* to be displayed.
13
+*
14
+* @returns {Promise} The {@code Promise} to be resolved when the list
15
+* is available.
16
+*/
17
+export function getRecentRooms(): Promise<Array<Object>> {
18
+    return new Promise(resolve => {
19
+        window.localStorage._getItemAsync(RECENT_URL_STORAGE)
20
+            .then(recentUrls => {
21
+                if (recentUrls) {
22
+                    const recentUrlsObj = JSON.parse(recentUrls);
23
+                    const recentRoomDS = [];
24
+
25
+                    for (const entry of recentUrlsObj) {
26
+                        const location = parseURIString(entry.conference);
27
+
28
+                        if (location && location.room && location.hostname) {
29
+                            recentRoomDS.push({
30
+                                baseURL:
31
+                                    `${location.protocol}//${location.host}`,
32
+                                conference: entry.conference,
33
+                                dateTimeStamp: entry.date,
34
+                                conferenceDuration: entry.conferenceDuration,
35
+                                dateString: _getDateString(
36
+                                    entry.date
37
+                                ),
38
+                                conferenceDurationString: _getLengthString(
39
+                                    entry.conferenceDuration
40
+                                ),
41
+                                initials: _getInitials(location.room),
42
+                                room: location.room,
43
+                                serverName: location.hostname
44
+                            });
45
+                        }
46
+                    }
47
+
48
+                    resolve(recentRoomDS.reverse());
49
+                } else {
50
+                    resolve([]);
51
+                }
52
+            });
53
+    });
54
+}
55
+
56
+/**
57
+* Retreives the recent URL list as a list of objects.
58
+*
59
+* @returns {Array} The list of already stored recent URLs.
60
+*/
61
+export function getRecentUrls() {
62
+    let recentUrls = window.localStorage.getItem(RECENT_URL_STORAGE);
63
+
64
+    if (recentUrls) {
65
+        recentUrls = JSON.parse(recentUrls);
66
+    } else {
67
+        recentUrls = [];
68
+    }
69
+
70
+    return recentUrls;
71
+}
72
+
73
+/**
74
+* Updates the recent URL list.
75
+*
76
+* @param {Array} recentUrls - The new URL list.
77
+* @returns {void}
78
+*/
79
+export function updaterecentUrls(recentUrls: Array<Object>) {
80
+    window.localStorage.setItem(
81
+        RECENT_URL_STORAGE,
82
+        JSON.stringify(recentUrls)
83
+    );
84
+}
85
+
86
+/**
87
+* Returns a well formatted date string to be displayed in the list.
88
+*
89
+* @private
90
+* @param {number} dateTimeStamp - The UTC timestamp to be converted to String.
91
+* @returns {string}
92
+*/
93
+function _getDateString(dateTimeStamp: number) {
94
+    const date = new Date(dateTimeStamp);
95
+
96
+    if (date.toDateString() === new Date().toDateString()) {
97
+        // the date is today, we use fromNow format
98
+
99
+        return moment(date)
100
+                .locale(i18next.language)
101
+                .fromNow();
102
+    }
103
+
104
+    return moment(date)
105
+            .locale(i18next.language)
106
+            .format('lll');
107
+}
108
+
109
+/**
110
+* Returns a well formatted duration string to be displayed
111
+* as the conference length.
112
+*
113
+* @private
114
+* @param {number} duration - The duration in MS.
115
+* @returns {string}
116
+*/
117
+function _getLengthString(duration: number) {
118
+    return moment.duration(duration)
119
+            .locale(i18next.language)
120
+            .humanize();
121
+}
122
+
123
+/**
124
+* Returns the initials supposed to be used based on the room name.
125
+*
126
+* @private
127
+* @param {string} room - The room name.
128
+* @returns {string}
129
+*/
130
+function _getInitials(room: string) {
131
+    return room && room.charAt(0) ? room.charAt(0).toUpperCase() : '?';
132
+}

+ 3
- 0
react/features/recent-list/index.js Näytä tiedosto

1
+export * from './components';
2
+
3
+import './middleware';

+ 106
- 0
react/features/recent-list/middleware.js Näytä tiedosto

1
+/* @flow */
2
+
3
+import { LIST_SIZE } from './constants';
4
+import { getRecentUrls, updaterecentUrls } from './functions';
5
+
6
+import { CONFERENCE_WILL_LEAVE, SET_ROOM } from '../base/conference';
7
+import { MiddlewareRegistry } from '../base/redux';
8
+
9
+/**
10
+ * Middleware that captures joined rooms so then it can be saved to
11
+ * {@code localStorage}
12
+ *
13
+ * @param {Store} store - Redux store.
14
+ * @returns {Function}
15
+ */
16
+MiddlewareRegistry.register(store => next => action => {
17
+    switch (action.type) {
18
+    case CONFERENCE_WILL_LEAVE:
19
+        return _updateConferenceDuration(store, next, action);
20
+
21
+    case SET_ROOM:
22
+        return _storeJoinedRoom(store, next, action);
23
+    }
24
+
25
+    return next(action);
26
+});
27
+
28
+/**
29
+* Stores the recently joined room in {@code localStorage}.
30
+*
31
+* @param {Store} store - The redux store in which the specified action is being
32
+* dispatched.
33
+* @param {Dispatch} next - The redux dispatch function to dispatch the
34
+* specified action to the specified store.
35
+* @param {Action} action - The redux action CONFERENCE_JOINED which is being
36
+* dispatched in the specified store.
37
+* @returns {Object} The new state that is the result of the reduction of the
38
+* specified action.
39
+*/
40
+function _storeJoinedRoom(store, next, action) {
41
+    const result = next(action);
42
+    const { room } = action;
43
+
44
+    if (room) {
45
+        const { locationURL } = store.getState()['features/base/connection'];
46
+        const conferenceLink = locationURL.href;
47
+
48
+        // if the current conference is already in the list,
49
+        // we remove it to add it
50
+        // to the top at the end
51
+        const recentUrls = getRecentUrls().filter(
52
+            entry => entry.conference !== conferenceLink
53
+        );
54
+
55
+        // please note, this is a reverse sorted array
56
+        // (newer elements at the end)
57
+        recentUrls.push({
58
+            conference: conferenceLink,
59
+            date: Date.now(),
60
+            conferenceDuration: 0
61
+        });
62
+
63
+        // maximising the size
64
+        recentUrls.splice(0, recentUrls.length - LIST_SIZE);
65
+
66
+        updaterecentUrls(recentUrls);
67
+    }
68
+
69
+    return result;
70
+}
71
+
72
+/**
73
+* Updates the conference length when left.
74
+*
75
+* @private
76
+* @param {Store} store - The redux store in which the specified action is being
77
+* dispatched.
78
+* @param {Dispatch} next - The redux dispatch function to dispatch the
79
+* specified action to the specified store.
80
+* @param {Action} action - The redux action CONFERENCE_JOINED which is being
81
+* dispatched in the specified store.
82
+* @returns {Object} The new state that is the result of the reduction of the
83
+* specified action.
84
+*/
85
+function _updateConferenceDuration(store, next, action) {
86
+    const result = next(action);
87
+    const { locationURL } = store.getState()['features/base/connection'];
88
+
89
+    if (locationURL && locationURL.href) {
90
+        const recentUrls = getRecentUrls();
91
+
92
+        if (recentUrls.length > 0
93
+            && recentUrls[recentUrls.length - 1].conference
94
+                === locationURL.href) {
95
+            // the last conference start was stored
96
+            // so we need to update the length
97
+
98
+            recentUrls[recentUrls.length - 1].conferenceDuration
99
+                = Date.now() - recentUrls[recentUrls.length - 1].date;
100
+
101
+            updaterecentUrls(recentUrls);
102
+        }
103
+    }
104
+
105
+    return result;
106
+}

+ 8
- 8
react/features/welcome/components/WelcomePage.native.js Näytä tiedosto

2
 import { TextInput, TouchableHighlight, View } from 'react-native';
2
 import { TextInput, TouchableHighlight, View } from 'react-native';
3
 import { connect } from 'react-redux';
3
 import { connect } from 'react-redux';
4
 
4
 
5
+import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
6
+import LocalVideoTrackUnderlay from './LocalVideoTrackUnderlay';
7
+import styles, { PLACEHOLDER_TEXT_COLOR } from './styles';
8
+
5
 import { translate } from '../../base/i18n';
9
 import { translate } from '../../base/i18n';
6
 import { MEDIA_TYPE } from '../../base/media';
10
 import { MEDIA_TYPE } from '../../base/media';
7
 import { Link, LoadingIndicator, Text } from '../../base/react';
11
 import { Link, LoadingIndicator, Text } from '../../base/react';
8
 import { ColorPalette } from '../../base/styles';
12
 import { ColorPalette } from '../../base/styles';
9
 import { createDesiredLocalTracks } from '../../base/tracks';
13
 import { createDesiredLocalTracks } from '../../base/tracks';
10
-
11
-import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
12
-import LocalVideoTrackUnderlay from './LocalVideoTrackUnderlay';
13
-import styles from './styles';
14
+import { RecentList } from '../../recent-list';
14
 
15
 
15
 /**
16
 /**
16
  * The URL at which the privacy policy is available to the user.
17
  * The URL at which the privacy policy is available to the user.
67
         return (
68
         return (
68
             <LocalVideoTrackUnderlay style = { styles.welcomePage }>
69
             <LocalVideoTrackUnderlay style = { styles.welcomePage }>
69
                 <View style = { styles.roomContainer }>
70
                 <View style = { styles.roomContainer }>
70
-                    <Text style = { styles.title }>
71
-                        { t('welcomepage.roomname') }
72
-                    </Text>
73
                     <TextInput
71
                     <TextInput
74
                         accessibilityLabel = { 'Input room name.' }
72
                         accessibilityLabel = { 'Input room name.' }
75
                         autoCapitalize = 'none'
73
                         autoCapitalize = 'none'
77
                         autoCorrect = { false }
75
                         autoCorrect = { false }
78
                         autoFocus = { false }
76
                         autoFocus = { false }
79
                         onChangeText = { this._onRoomChange }
77
                         onChangeText = { this._onRoomChange }
80
-                        placeholder = { t('welcomepage.roomnamePlaceHolder') }
78
+                        placeholder = { t('welcomepage.roomname') }
79
+                        placeholderTextColor = { PLACEHOLDER_TEXT_COLOR }
81
                         style = { styles.textInput }
80
                         style = { styles.textInput }
82
                         underlineColorAndroid = 'transparent'
81
                         underlineColorAndroid = 'transparent'
83
                         value = { this.state.room } />
82
                         value = { this.state.room } />
84
                     {
83
                     {
85
                         this._renderJoinButton()
84
                         this._renderJoinButton()
86
                     }
85
                     }
86
+                    <RecentList />
87
                 </View>
87
                 </View>
88
                 {
88
                 {
89
                     this._renderLegalese()
89
                     this._renderLegalese()

+ 4
- 1
react/features/welcome/components/styles.js Näytä tiedosto

10
  */
10
  */
11
 const TEXT_COLOR = ColorPalette.white;
11
 const TEXT_COLOR = ColorPalette.white;
12
 
12
 
13
+export const PLACEHOLDER_TEXT_COLOR = 'rgba(255, 255, 255, 0.3)';
14
+
13
 /**
15
 /**
14
  * The styles of the React {@code Components} of the feature welcome including
16
  * The styles of the React {@code Components} of the feature welcome including
15
  * {@code WelcomePage} and {@code BlankPage}.
17
  * {@code WelcomePage} and {@code BlankPage}.
83
         flex: 1,
85
         flex: 1,
84
         flexDirection: 'column',
86
         flexDirection: 'column',
85
         justifyContent: 'center',
87
         justifyContent: 'center',
86
-        margin: 3 * BoxModel.margin
88
+        margin: 3 * BoxModel.margin,
89
+        marginBottom: BoxModel.margin
87
     },
90
     },
88
 
91
 
89
     /**
92
     /**

Loading…
Peruuta
Tallenna