Compare commits

...

435 Commits

Author SHA1 Message Date
David Baker
15e4c01c5d Add max old space fix to publish workflow too 2023-03-28 15:47:59 +01:00
David Baker
1307d89175 Merge pull request #975 from vector-im/dbkr/update_js_sdk_20230328
Update js-sdk
2023-03-28 15:40:30 +01:00
David Baker
d53be695f9 Work around Vite unbounded memory usage
Port fix from otel branch where it appears to be working
2023-03-28 15:33:11 +01:00
David Baker
247d15cbb5 Update js-sdk
for da03c3b529
2023-03-28 15:24:33 +01:00
Robin
71b1d0c6b1 Merge pull request #970 from robintown/matrix-widget-api
Update matrix-widget-api
2023-03-22 13:58:36 -04:00
Robin Townsend
76c0277301 Update matrix-js-sdk 2023-03-22 11:41:41 -04:00
Robin Townsend
698bea93e3 Update matrix-widget-api 2023-03-22 11:33:50 -04:00
Robin
ff90e507a6 Merge pull request #963 from alariej/navigator_mediasession_fix
Fix for Android WebView, which does not support navigator.mediaSession
2023-03-17 13:20:05 -04:00
alariej
1bf1813a77 Fix for Android WebView, which does not support navigator.mediaSession 2023-03-17 17:20:16 +01:00
Robin
7aa902853a Merge pull request #956 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2023-03-11 00:49:06 -05:00
lunarna-gh
49b23160f3 Translated using Weblate (Polish)
Currently translated at 97.2% (139 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/pl/
2023-03-11 01:33:43 +00:00
Timo
b68d4bf51b Update README.md (#953)
Only a tiny typo
2023-03-10 14:42:24 +01:00
Robin
3e081ac936 Merge pull request #890 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2023-03-08 10:53:58 -05:00
Weblate
7e1d5fff14 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/
2023-03-07 16:33:45 +00:00
Jozef Gaal
ca1f502e62 Translated using Weblate (Slovak)
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/sk/
2023-03-07 16:33:44 +00:00
Open Culture Foundation
1913abc682 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/zh_Hant/
2023-03-07 16:33:44 +00:00
Peter Chen
345891dbdf Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/zh_Hant/
2023-03-07 16:33:44 +00:00
Jeff Huang
29082adb73 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/zh_Hant/
2023-03-07 16:33:44 +00:00
Avery
3dc288574e Translated using Weblate (Spanish)
Currently translated at 98.6% (141 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/es/
2023-03-07 16:33:44 +00:00
Priit Jõerüüt
03c15d5b07 Translated using Weblate (Estonian)
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2023-03-07 16:33:44 +00:00
Ihor Hordiichuk
6fceeec323 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/uk/
2023-03-07 16:33:44 +00:00
Glandos
44762afd2a Translated using Weblate (French)
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fr/
2023-03-07 16:33:44 +00:00
Linerly
fa97f51907 Translated using Weblate (Indonesian)
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/id/
2023-03-07 16:33:44 +00:00
Vri
a15ce32ecf Translated using Weblate (German)
Currently translated at 100.0% (143 of 143 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/de/
2023-03-07 16:33:44 +00:00
Weblate
4a3b7bc6dd Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/
2023-03-07 16:33:44 +00:00
DarkCoder15
a1cb52c613 Translated using Weblate (Russian)
Currently translated at 100.0% (142 of 142 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ru/
2023-03-07 16:33:44 +00:00
Jozef Gaal
4cfa726df1 Translated using Weblate (Slovak)
Currently translated at 100.0% (142 of 142 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/sk/
2023-03-07 16:33:44 +00:00
Priit Jõerüüt
e31de96679 Translated using Weblate (Estonian)
Currently translated at 100.0% (142 of 142 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2023-03-07 16:33:44 +00:00
Ihor Hordiichuk
16ec643e84 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (142 of 142 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/uk/
2023-03-07 16:33:44 +00:00
Glandos
fa62b97b27 Translated using Weblate (French)
Currently translated at 100.0% (142 of 142 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fr/
2023-03-07 16:33:44 +00:00
Linerly
3e072aed3c Translated using Weblate (Indonesian)
Currently translated at 100.0% (142 of 142 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/id/
2023-03-07 16:33:44 +00:00
Vri
bac795e1e8 Translated using Weblate (German)
Currently translated at 100.0% (142 of 142 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/de/
2023-03-07 16:33:44 +00:00
Suguru Hirahara
ba48ade3b7 Translated using Weblate (Japanese)
Currently translated at 80.8% (114 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-03-07 16:33:44 +00:00
Suguru Hirahara
0fab702d70 Translated using Weblate (Japanese)
Currently translated at 80.1% (113 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-03-07 16:33:44 +00:00
Suguru Hirahara
7f8c0153ed Translated using Weblate (Japanese)
Currently translated at 76.5% (108 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-03-07 16:33:44 +00:00
Suguru Hirahara
d35c13b903 Translated using Weblate (Japanese)
Currently translated at 75.8% (107 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-03-07 16:33:44 +00:00
Enrico Schwendig
ee4760351c add end-to-end test workflow (#885)
* e2e: add end-to-end test workflow

- The tests are executed in a Docker container. 
-  The static users are connected via `matrix-js-sdk Client`. 
-  A test user connecting to the conference via EC.
2023-03-06 09:45:42 +01:00
Enrico Schwendig
0c66b32b49 matrix-js-sdk: update to last develop branch with call group fix (#941) 2023-03-03 08:06:10 +01:00
Robin
5eb552e36a Merge pull request #935 from alariej/alariej
Add e2eEnabled parameter to Widget client
2023-03-02 16:07:04 -05:00
Enrico Schwendig
29e41c7227 Allow Element Call to be started without audio / video interface (#924)
* config: add feature in `config.json`

* groupCall: adjust connection state in feed if allowCallWithoutVideoAndAudio

* matrix-js-sdk: update version for allowCallWithoutVideoAndAudio

- I modified the SDK so that mute unmute work without media and check device permission inside the SDK
- allowCallWithoutVideoAndAudio is only checked at one point outside the SDK

* docu: add join group call without media docu in READMe

---------

Co-authored-by: Robin Townsend <robin@robin.town>
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
2023-03-02 18:48:32 +01:00
alariej
58d87db55f Add e2eEnabled parameter to Widget client 2023-03-01 14:30:25 +01:00
Timo
0423a494c4 Checkbox for analytics opt in & settings redesign (#934) 2023-03-01 13:47:36 +01:00
David Baker
2454daeef9 Merge pull request #932 from vector-im/dbkr/allow_full_alias_input
Behave sensibly if a full room alias is entered
2023-02-28 14:12:10 +00:00
David Baker
64703fd3cc Typo
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
2023-02-28 14:09:52 +00:00
David Baker
53bc8eb82f Behave sensibly if a full room alias is entered
Check explicitly to see if the room name that's enetered into the box
looks like a room alias and if so, do the sensible thing.

Fixes https://github.com/vector-im/element-call/issues/852
2023-02-28 13:50:24 +00:00
Robin
cdf2d560b8 Merge pull request #911 from robintown/big-grid
New grid system
2023-02-19 09:02:57 -05:00
Robin
9dff42b437 Merge pull request #919 from robintown/ignore-coverage
Add coverage reports to .gitignore
2023-02-16 11:32:29 -05:00
Robin Townsend
1fc181dc28 Document useReactiveState 2023-02-15 16:38:49 -05:00
Robin Townsend
fbc72283d4 Add missing copyright headers 2023-02-15 16:20:58 -05:00
Robin Townsend
9a0dfad5f9 Add coverage reports to .gitignore 2023-02-15 15:13:39 -05:00
Robin Townsend
efbf319fa1 Explain why we cast the tile springs 2023-02-13 22:40:26 -05:00
Robin Townsend
ef4a62ca62 Document useMergedRefs 2023-02-13 22:38:27 -05:00
Robin Townsend
8c818b9ce1 Get 100% test coverage on grid operations 2023-02-13 22:24:04 -05:00
Robin Townsend
58ed372afa Fix type and lint errors 2023-02-13 21:57:57 -05:00
Robin Townsend
69e6ba93c1 Add a switch to toggle between the new and old grids 2023-02-13 20:36:42 -05:00
Robin Townsend
b2b2f0bb15 Merge branch 'main' into big-grid 2023-02-13 18:54:19 -05:00
Robin Townsend
8d0bf4cacc Test grid operations 2023-02-13 18:35:50 -05:00
Robin Townsend
5448744871 Document grid operations 2023-02-13 18:35:23 -05:00
David Baker
933dc4e2d3 Merge pull request #910 from vector-im/dbkr/ignore_media_action
Don't pause audio streams on media actions
2023-02-13 17:35:33 +01:00
David Baker
605dd44df0 Rename other instance of variable 2023-02-13 15:49:58 +00:00
David Baker
07a4de638f Don't pause audio streams on media actions
This adds handlers for the media actions to do nothing, otherwise
they cause the audio element for a random participant to get paused.

Fixes https://github.com/vector-im/element-call/issues/855
2023-02-13 15:20:48 +00:00
Timo
eda11cfc08 Inform that the user that config keys are missing (#880) 2023-02-09 12:57:54 +01:00
Robin Townsend
d852e33413 Document the component 2023-02-08 00:32:08 -05:00
Robin Townsend
8d46687a54 Refactor grid state tracking 2023-02-07 23:27:49 -05:00
Robin Townsend
978b0f08e8 Move grid algorithms into a separate file 2023-02-07 22:13:50 -05:00
Robin Townsend
374c68e3c0 Fix tiles enlarging to the wrong place on mobile 2023-02-05 01:17:28 -05:00
Robin Townsend
82ac775124 Fix scrolling on mobile 2023-02-05 00:55:12 -05:00
Robin Townsend
6adcf95aaa Implement different column counts and mobile layout 2023-02-04 00:43:53 -05:00
Robin Townsend
206730ffc0 Fix infinite loop when a tile can't be enlarged 2023-02-03 16:52:42 -05:00
Robin Townsend
1e858f6ba3 Fix a typo 2023-02-03 16:27:49 -05:00
Robin Townsend
22382413dc Make drag and drop mobile-friendly 2023-02-03 15:42:47 -05:00
Robin Townsend
6cd939db0c Fix a crash when there's only 1 tile and it gets shrunk 2023-02-03 09:11:25 -05:00
Robin Townsend
42e4f6ce83 Don't allow the grid to overflow horizontally 2023-02-03 08:44:35 -05:00
David Baker
aabca7ebff Merge pull request #895 from vector-im/revert-893-dbkr/yarn_upgrade_jan23
Revert "Yarn upgrade"
2023-02-02 14:42:05 +00:00
David Baker
579b91abff Revert "Yarn upgrade" 2023-02-02 14:32:44 +00:00
David Baker
e3b4a695d6 Merge pull request #893 from vector-im/dbkr/yarn_upgrade_jan23
Yarn upgrade
2023-02-02 13:47:00 +00:00
David Baker
e1abbd5291 Yarn upgrade
Along with some type fixes to make typescript happy again. Hopefully
they are sensible.
2023-02-02 12:49:54 +00:00
Robin Townsend
4fc8598e36 Keep tile elements in a stable order 2023-02-01 11:50:52 -05:00
Robin Townsend
6784d2ba97 Remove redundant key prop 2023-02-01 11:50:25 -05:00
Robin Townsend
0915e327e1 Implement somewhat working drag & drop and improve render memoization 2023-02-01 11:32:10 -05:00
Robin Townsend
eedf8a6d1b Make tiles draggable (but not yet droppable) 2023-02-01 00:17:22 -05:00
Robin Townsend
d7db845f3b Scroll snap was a bad idea 2023-01-30 23:52:46 -05:00
Robin Townsend
82c7293308 Replace premature animation optimization with a potentially wiser one 2023-01-30 23:44:19 -05:00
Robin Townsend
0166eb67fb Make avatars scale smoothly during animations 2023-01-30 23:43:45 -05:00
Robin Townsend
e3081c1c06 Try out a snappier spring 2023-01-30 23:32:26 -05:00
Robin Townsend
f540f48461 Fix some layout bugs 2023-01-30 23:32:00 -05:00
Robin Townsend
55dece274f Fix some tile resizing bugs 2023-01-30 17:04:43 -05:00
Robin
b12e52d972 Merge pull request #866 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2023-01-30 14:00:59 -05:00
Suguru Hirahara
82f2fd05b5 Translated using Weblate (Japanese)
Currently translated at 74.4% (105 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-30 18:25:09 +00:00
Genbuchan
b4c6684ff5 Translated using Weblate (Japanese)
Currently translated at 74.4% (105 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-30 18:25:09 +00:00
Robin Townsend
4e73c07cb2 Try out scroll snapping 2023-01-30 09:35:40 -05:00
Robin Townsend
3805a2f20e Format with Prettier 2023-01-29 21:56:07 -05:00
Robin Townsend
4e35984900 Extract tile size change logic into a function 2023-01-29 21:54:53 -05:00
Robin Townsend
e99294c3f1 Simplify some code 2023-01-29 21:45:10 -05:00
DarkCoder15
32fb14107f Translated using Weblate (Russian)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ru/
2023-01-27 15:33:29 +00:00
afr4283
14a5e53e65 Translated using Weblate (Polish)
Currently translated at 97.1% (137 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/pl/
2023-01-27 15:33:29 +00:00
Šimon Brandner
24fea189dc Translated using Weblate (Czech)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/cs/
2023-01-27 15:33:29 +00:00
Genbuchan
0f73527ccf Translated using Weblate (Japanese)
Currently translated at 72.3% (102 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-27 15:33:29 +00:00
Suguru Hirahara
e0b94b51ab Translated using Weblate (Japanese)
Currently translated at 72.3% (102 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-27 15:33:29 +00:00
David Baker
ee0c623866 Merge pull request #884 from vector-im/dbkr/posthog_pr_previews
Add posthog to PR preview builds
2023-01-26 17:24:48 +00:00
Šimon Brandner
c321deecba Merge pull request #882 from dinosmm/patch-2 2023-01-26 17:27:40 +01:00
David Baker
b7ac131614 Add posthog to PR preview builds 2023-01-26 14:59:54 +00:00
Dino
acade92d70 Removed one more reference to Synapse
I forgot to remove one reference to Synapse previously.
2023-01-26 14:50:32 +00:00
Dino
6e275b9221 Clarified homeserver requirements
I clarified homeserver requirements (i.e. that Element Call needs a homeserver like Synapse but not necessarily Synapse), and also edited some other parts for clarity. I also updated the recommendation to not log in to an existing homeserver based on my new findings that Element Call *may* allow you to log in to an existing HS but log in is unreliable.
2023-01-26 14:24:53 +00:00
Dino
42d5db6d0f Update README.md
Updated README.md to include more detailed information about the limitations of Element Call and a recommended homeserver set up.
2023-01-26 10:35:30 +00:00
Robin Townsend
8912daa922 Make tiles resizable and fix some miscellaneous bugs 2023-01-25 23:51:36 -05:00
Robin Townsend
045103dbc9 Backfill the grid as people leave by moving tiles along paths 2023-01-25 02:30:52 -05:00
David Baker
0f2a62a59f Merge pull request #870 from vector-im/dbkr/fix_rageshake_modal_mobile
Fix the rageshake modal on mobile
2023-01-23 20:21:23 +00:00
David Baker
d2631a3e02 Fix the rageshake modal on mobile
As per comment

Unsure if this is the best fix - ideally we wouldn't go into no-controls
mode at all, but this part doesn't know whether the dialog is open so
the only thing we could really do is tweak the threshold, or possibly
guess based on width instead?
2023-01-23 17:52:02 +00:00
David Baker
41b72440a0 Merge pull request #869 from vector-im/dbkr/suppress_dup_ptt_unhold
Avoid duplicate PTT button 'unhold' events
2023-01-23 16:59:54 +00:00
David Baker
d65464e4db Avoid duplicate PTT button 'unhold' events
We called the 'unhold' function even if the button wasn't held which
probably will have been generating unmute events even when we weren't
muted.

Also use separate handlers for events so we can have specific log lines
(and also see where the event comes from when caught in the debugger).
2023-01-23 16:53:24 +00:00
Robin Townsend
59f3b05c07 Merge branch 'main' into big-grid 2023-01-23 08:57:04 -05:00
Robin
4f0a780ecf Merge pull request #863 from robintown/demo-screenshot
Add a demo screenshot to the README
2023-01-20 15:38:48 -05:00
David Baker
b8c1dd4c78 Merge pull request #865 from vector-im/dbkr/wait_until_loaded_before_registering
Don't try to register users until client is loaded
2023-01-20 18:32:14 +00:00
Robin
cf5e9ba2f9 Merge pull request #864 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2023-01-20 13:21:12 -05:00
David Baker
4f8bd18efd Don't try to register users until client is loaded 2023-01-20 17:59:57 +00:00
Suguru Hirahara
f56177b96a Translated using Weblate (Japanese)
Currently translated at 65.9% (93 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:20:44 +00:00
Genbuchan
85b206c270 Translated using Weblate (Japanese)
Currently translated at 65.9% (93 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:20:43 +00:00
Suguru Hirahara
bf7c45b0bc Translated using Weblate (Japanese)
Currently translated at 64.5% (91 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:20:30 +00:00
Genbuchan
906fcdf72e Translated using Weblate (Japanese)
Currently translated at 64.5% (91 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:20:29 +00:00
Suguru Hirahara
17a3e14d09 Translated using Weblate (Japanese)
Currently translated at 63.1% (89 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:20:07 +00:00
Genbuchan
26e1772c75 Translated using Weblate (Japanese)
Currently translated at 63.1% (89 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:20:07 +00:00
Suguru Hirahara
edfb8709d1 Translated using Weblate (Japanese)
Currently translated at 60.9% (86 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:19:33 +00:00
Genbuchan
7798128cbd Translated using Weblate (Japanese)
Currently translated at 60.9% (86 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:19:33 +00:00
Suguru Hirahara
5c3c15266a Translated using Weblate (Japanese)
Currently translated at 41.1% (58 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:14:22 +00:00
Genbuchan
ea7bfb5afb Translated using Weblate (Japanese)
Currently translated at 41.1% (58 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:14:22 +00:00
Suguru Hirahara
f940063e03 Translated using Weblate (Japanese)
Currently translated at 34.7% (49 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:12:49 +00:00
Genbuchan
a56d974f48 Translated using Weblate (Japanese)
Currently translated at 34.7% (49 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:12:49 +00:00
Suguru Hirahara
435f6f1ae9 Translated using Weblate (Japanese)
Currently translated at 31.2% (44 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:11:53 +00:00
Genbuchan
375db2a47b Translated using Weblate (Japanese)
Currently translated at 31.2% (44 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:11:53 +00:00
Suguru Hirahara
ed1b1c3d3e Translated using Weblate (Japanese)
Currently translated at 29.7% (42 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:11:39 +00:00
Genbuchan
ddb3637d79 Translated using Weblate (Japanese)
Currently translated at 29.7% (42 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:11:39 +00:00
Suguru Hirahara
85d5946d6a Translated using Weblate (Japanese)
Currently translated at 28.3% (40 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:11:26 +00:00
Genbuchan
3cdb413587 Translated using Weblate (Japanese)
Currently translated at 28.3% (40 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:11:25 +00:00
Suguru Hirahara
5ac1212988 Translated using Weblate (Japanese)
Currently translated at 21.2% (30 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:09:41 +00:00
Genbuchan
c9c0ed85f8 Translated using Weblate (Japanese)
Currently translated at 21.2% (30 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:09:40 +00:00
Suguru Hirahara
e4b2180bc2 Translated using Weblate (Japanese)
Currently translated at 19.1% (27 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:09:04 +00:00
Genbuchan
cab8a71ac2 Translated using Weblate (Japanese)
Currently translated at 19.1% (27 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:09:04 +00:00
Suguru Hirahara
ff5ff175fd Translated using Weblate (Japanese)
Currently translated at 17.7% (25 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:08:27 +00:00
Genbuchan
26e1530882 Translated using Weblate (Japanese)
Currently translated at 17.7% (25 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:08:27 +00:00
Suguru Hirahara
35386b5e16 Translated using Weblate (Japanese)
Currently translated at 17.0% (24 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:08:17 +00:00
Genbuchan
18fe2daea7 Translated using Weblate (Japanese)
Currently translated at 17.0% (24 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:08:17 +00:00
Suguru Hirahara
5f24bf0b9c Translated using Weblate (Japanese)
Currently translated at 14.1% (20 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:07:45 +00:00
Genbuchan
990a08f4f6 Translated using Weblate (Japanese)
Currently translated at 14.1% (20 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:07:45 +00:00
Suguru Hirahara
af565ecd77 Translated using Weblate (Japanese)
Currently translated at 7.0% (10 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:05:44 +00:00
Genbuchan
e3d72e1104 Translated using Weblate (Japanese)
Currently translated at 7.0% (10 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:05:44 +00:00
Suguru Hirahara
29ea2cfe90 Translated using Weblate (Japanese)
Currently translated at 5.6% (8 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:04:22 +00:00
Genbuchan
008ecd7409 Translated using Weblate (Japanese)
Currently translated at 5.6% (8 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:04:21 +00:00
Suguru Hirahara
3220b030fb Translated using Weblate (Japanese)
Currently translated at 4.9% (7 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:03:57 +00:00
Genbuchan
0b1689e6f7 Translated using Weblate (Japanese)
Currently translated at 4.9% (7 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:03:57 +00:00
Suguru Hirahara
74255d0554 Translated using Weblate (Japanese)
Currently translated at 4.2% (6 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:03:43 +00:00
Genbuchan
a55046148f Translated using Weblate (Japanese)
Currently translated at 4.2% (6 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:03:43 +00:00
Genbuchan
6acbf792fc Translated using Weblate (Japanese)
Currently translated at 2.8% (4 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:02:49 +00:00
Suguru Hirahara
1cbda01051 Translated using Weblate (Japanese)
Currently translated at 2.1% (3 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:02:33 +00:00
Suguru Hirahara
f61b2db80d Translated using Weblate (Japanese)
Currently translated at 2.1% (3 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:02:33 +00:00
Genbuchan
17d273135f Translated using Weblate (Japanese)
Currently translated at 2.1% (3 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ja/
2023-01-20 17:02:33 +00:00
Robin Townsend
9e8dadcc44 Add a demo screenshot to the README 2023-01-20 10:51:28 -05:00
David Baker
785756dc91 Merge pull request #862 from vector-im/dbkr/ptt_null_member_workarounds
Don't crash if we can't find our own member event
2023-01-20 13:20:04 +00:00
David Baker
785fa51e0c Use merged js-sdk commit 2023-01-20 13:12:03 +00:00
David Baker
47c2e9e101 Don't crash if we can't find our own member event 2023-01-20 12:10:58 +00:00
David Baker
0bb18be4ef Merge pull request #861 from vector-im/dbkr/dont_lowercase_room_ids
Fix joining rooms by ID
2023-01-20 10:57:46 +00:00
David Baker
81997624d4 Fix joining rooms by ID
We use this in embedded mode. Regressed by https://github.com/vector-im/element-call/pull/860

Lowercasing room IDs obviously makes them break, so… don't do that.
2023-01-20 10:51:52 +00:00
David Baker
c2883e52bb Merge pull request #860 from vector-im/dbkr/lowercase_room_alias
Lowercase room alias before joining
2023-01-20 09:43:28 +00:00
David Baker
7e1033f5a4 Add colon in comment
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
2023-01-20 09:35:50 +00:00
David Baker
524f530dce Lowercase room alias before joining 2023-01-19 19:20:42 +00:00
Robin Townsend
46d1351d83 More fixes 2023-01-18 13:38:29 -05:00
Robin Townsend
2318d75bc7 prettier 2023-01-18 11:33:40 -05:00
Robin Townsend
486674c442 fixes 2023-01-18 11:32:51 -05:00
Robin Townsend
d3fba7fd5f WIP minus unfinished split grid layouts 2023-01-18 10:52:12 -05:00
David Baker
9437a00997 Merge pull request #853 from vector-im/dbkr/better_rageshake
Change rageshake to save much more regularly
2023-01-17 10:20:26 +00:00
David Baker
e1c4042d15 Add units to constant 2023-01-17 10:16:55 +00:00
David Baker
860aff4958 Change rageshake persistence to throttled flushing
Rather than every 30 seconds. This way we'll save logs for sessions
lasting less than 30 seconds which we previously didn't. Also save
on window unload just in case that doesn't catch everything.

Plus remove some more unused params.
2023-01-16 17:27:49 +00:00
David Baker
13b1dcf785 Mostly cosmetic fixes to rageshake
* Remove duplicate copyright header
 * Remove ts-ignores by just using the objects directly rather than via
   event.target
 * Use error.message rather than errorCode which TS doesn't know about
   and may or may not exist.
 * Remove some unused things like the skip rageshake function and
   the option to init rageshakes without storage.
 * Turn single function with a boolean param to make it take two entirely
   separate code paths into two functions.
2023-01-16 16:43:45 +00:00
Robin
035498a8eb Merge pull request #849 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2023-01-15 22:20:48 -05:00
Avery
030ca29664 Translated using Weblate (Spanish)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/es/
2023-01-14 15:33:25 +00:00
David Baker
ecdeb97502 Merge pull request #848 from vector-im/dbkr/uncecryptable_todevice
Log undecryptable to-device events
2023-01-13 21:44:39 +00:00
David Baker
6168109894 Use merged js-sdk commit 2023-01-13 21:41:21 +00:00
David Baker
a2a1a9032a Use js-sdk from branch 2023-01-13 18:33:58 +00:00
David Baker
abd909c03a Log undecryptable to-device events
Listen for the new undecryptable to-device event event and log
events for it in Posthog & Sentry, and make it visible in the
call flow diagram.
2023-01-13 18:27:22 +00:00
David Baker
be1db442d9 Merge pull request #846 from vector-im/dbkr/prevent_keyrepeat_mute_spam
Prevent mute event spam from key repeats
2023-01-13 11:59:34 +00:00
David Baker
afdce66896 Merge remote-tracking branch 'origin/main' into dbkr/prevent_keyrepeat_mute_spam 2023-01-13 11:57:02 +00:00
David Baker
1b08a5cac3 Rename file 2023-01-13 11:56:29 +00:00
David Baker
843e7690fa Merge pull request #845 from vector-im/dbkr/disable_keyboard_shortcuts_rageshake
Disable keyboard shortcuts when feedback modal is open
2023-01-13 11:55:51 +00:00
David Baker
a5977fc992 Rename to useCallViewKeyboardShortcuts 2023-01-13 11:52:40 +00:00
David Baker
6277359d30 Merge pull request #844 from vector-im/dbkr/fix_cache
Fix caching headers on Docker image
2023-01-13 10:39:50 +00:00
David Baker
73682b67ba Merge pull request #843 from vector-im/dbkr/dev_mode_idb_no_worker
Use IndexedDB storage in dev mode, just without the worker
2023-01-13 10:14:01 +00:00
David Baker
f2193302c1 Prevent mute event spam from key repeats 2023-01-12 18:26:21 +00:00
David Baker
9ba4ce429f Disable keyboard shortcuts when feedback modal is open 2023-01-12 17:31:19 +00:00
David Baker
d9b0e08ea2 Fix caching headers on Docker image 2023-01-12 16:20:37 +00:00
David Baker
5f26534496 Use IndexedDB storage in dev mode, just without the worker
As per comment, we can't use workers in Vite dev mode. We previously
fell back to the memory store but this ends up with it working significantly
differently in dev mode to production, eg. dev mode would always start
by doing an initial sync, so old to-device messages would arrive again.

There's no need to fall all the way back to the memory store though,
we can use the IndexedDB store without the worker.
2023-01-12 15:17:46 +00:00
David Baker
30688715cd Revert f20fc78bd7 2023-01-12 13:20:11 +00:00
David Baker
f20fc78bd7 Use branch of js-sdk with Olm debugging
Pulls in changes from https://github.com/matrix-org/matrix-js-sdk/pull/3055

Not intended to stay long-term.
2023-01-12 11:28:15 +00:00
Robin
741233909d Merge pull request #829 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2023-01-09 13:35:43 -05:00
Robin
4e0f4a8dc7 Merge pull request #835 from robintown/unmuted-when-speaking
Work around mute state updates being slow
2023-01-09 13:35:05 -05:00
Šimon Brandner
0d151452ba Merge pull request #833 from vector-im/SimonBrandner/feat/hide-audio 2023-01-09 19:28:04 +01:00
Robin Townsend
4fd76f9599 Work around mute state updates being slow
Since the app already determines when someone is speaking, we can use that information to make it less obvious when to-device messages are being slow to deliver mute state updates.
2023-01-09 11:10:59 -05:00
Robin
d123793deb Merge pull request #832 from robintown/update-js-sdk
Update matrix-js-sdk
2023-01-09 10:52:19 -05:00
Robin Townsend
449c1c9d79 Try updating Olm to fix type errors 2023-01-09 10:49:01 -05:00
Robin Townsend
de5b58792e Update matrix-js-sdk 2023-01-09 10:32:05 -05:00
Robin Townsend
7769074410 Merge branch 'main' into update-js-sdk 2023-01-09 10:31:39 -05:00
Šimon Brandner
881054e265 Hide local volume controls for tiles with no audio
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
2023-01-07 10:09:20 +01:00
Robin
767f9cdc4a Merge pull request #831 from robintown/no-video-mute
Leave audio elements unmuted regardless of mute state
2023-01-06 12:08:13 -05:00
Robin Townsend
946f564f84 Update matrix-js-sdk 2023-01-06 10:39:29 -05:00
Robin Townsend
468e389324 Leave audio elements unmuted regardless of mute state 2023-01-06 10:26:10 -05:00
Jozef Gaal
62e98f6c47 Translated using Weblate (Slovak)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/sk/
2023-01-06 09:33:22 +00:00
Priit Jõerüüt
de31c099e3 Translated using Weblate (Estonian)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2023-01-06 09:33:22 +00:00
Ihor Hordiichuk
49cae76387 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/uk/
2023-01-06 09:33:22 +00:00
Glandos
d45ea78ddb Translated using Weblate (French)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fr/
2023-01-06 09:33:22 +00:00
Linerly
dcbc3ed865 Translated using Weblate (Indonesian)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/id/
2023-01-06 09:33:22 +00:00
Vri
ff19135d4e Translated using Weblate (German)
Currently translated at 100.0% (141 of 141 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/de/
2023-01-06 09:33:22 +00:00
Robin
de7343d16a Merge pull request #821 from robintown/save-lockfile
Save lockfile
2023-01-05 10:35:52 -05:00
Timo
e5135a41ba Add call id to mute events (#827) 2023-01-05 11:05:22 +01:00
Timo
67d1c29d6a decrease wait after call ended to 10ms (#825)
* decrease wait after call ended to 10ms

* new order of widget requests to avoid pip flicker
2023-01-05 00:01:57 +01:00
Robin
7ee6b02aeb Merge pull request #820 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2023-01-04 09:12:43 -05:00
Robin
6b021b9f70 Merge pull request #822 from robintown/reduce-local-feed
Reduce the size of the local feed in 1:1 calls at small window sizes
2023-01-04 09:05:49 -05:00
Robin Townsend
faa8f95f97 Reduce the size of the local feed in 1:1 calls at small window sizes 2023-01-04 08:38:24 -05:00
Robin Townsend
c09fec5f88 Save lockfile 2023-01-04 08:25:26 -05:00
Weblate
b711a67893 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/
2023-01-04 12:33:23 +00:00
Jozef Gaal
a30bded3ee Translated using Weblate (Slovak)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/sk/
2023-01-04 12:33:22 +00:00
Priit Jõerüüt
0349f5306c Translated using Weblate (Estonian)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2023-01-04 12:33:22 +00:00
Ihor Hordiichuk
6980652cbc Translated using Weblate (Ukrainian)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/uk/
2023-01-04 12:33:22 +00:00
Glandos
eff56d7ce4 Translated using Weblate (French)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fr/
2023-01-04 12:33:22 +00:00
Linerly
1a66c455f6 Translated using Weblate (Indonesian)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/id/
2023-01-04 12:33:22 +00:00
Vri
7163db357c Translated using Weblate (German)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/de/
2023-01-04 12:33:22 +00:00
Robin
e5572210d3 Merge pull request #813 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2023-01-03 23:06:48 -05:00
David Baker
11a262b58f Merge pull request #819 from vector-im/dbkr/prefix_other_fullscreen_apis
Use prefixed versions of other fullscreen APIs too
2023-01-03 22:56:49 +00:00
David Baker
62e4e80ca3 Merge pull request #818 from vector-im/dbkr/fix_copyright_headers
Fix copyright headers
2023-01-03 22:56:40 +00:00
David Baker
f55cc21289 Enable rageshake in preview builds (#817) 2023-01-03 22:56:21 +00:00
David Baker
c34a1f7f65 Use prefixed versions of other fullscreen APIs too 2023-01-03 18:35:00 +00:00
David Baker
70b693ef3c Revert d2175b4
Unintentionally comitted to main
2023-01-03 18:34:27 +00:00
David Baker
d2175b40a4 Use prefixed versions of other fullscreen APIs too 2023-01-03 18:33:11 +00:00
David Baker
1830acbddf Fix copyright pt. 2: CSS files 2023-01-03 16:58:38 +00:00
David Baker
df9c1fed2a Fix copyright headers
This is an Element project (in the vector-im repo) so the Copyright
should be for New Vector: it was incorrectly attributed to the
foundation for some files (and some files were missing headers).
2023-01-03 16:55:26 +00:00
Timo
05be247946 send posthog callEnded events instantly in embedded mode (prohibit missing events) (#816)
Signed-off-by: Timo K <timok@element.io>
Co-authored-by: Timo K <timok@element.io>
2023-01-03 17:09:21 +01:00
Timo
1f5c22e325 Posthog new api key (#815)
new api key

Signed-off-by: Timo K <timok@element.io>
Co-authored-by: Timo K <timok@element.io>
2023-01-03 16:59:06 +01:00
David Baker
b9ee9583e4 Fix fullscreen on Safari (#814)
* Fix fullscreen on Safari

Safari only supports it via the webkit prefix

Fixes https://github.com/vector-im/element-call/issues/539

* NOT THAT LOGGER, VSCODE
2023-01-03 11:24:10 +00:00
David Baker
fef503c65d Upload source maps to sentry (#810)
* Pretend to upload source maps to sentry

* Build release not in docker so we can upload source maps sensibly

and also upload the release as a plain tarball while we're at it

* fix yaml

* Try specifying version this way

* test rebuild

* pass secrets through

* Too many sentries

* It's almost 2023 and we're still having BSD vs GNU tar issues

* Maybe get sensible tag name & release identifier

* Wrong plugin, and also try the 'release' option which might the right thing

* Try a different github action

see if github likes that any better

* add contents write permission

and switch to the asset upload plugin that had the helpful doc

* actually put release name in tarball path

* copy docker config to right path

* Prettify vite config

* Only activate sentry plugin if we have secrets

* Use env var for tag name

* Also spelling env correctly would likely help

* Fix variable syntax

* Put env var in correct place

One day maybe I will not find yaml syntax confusing
2023-01-03 10:48:48 +00:00
David Baker
dc37c83aac Merge pull request #809 from vector-im/dbkr/optional_rageshake
Don't show option to submit bug reports if no endpoint configured
2023-01-03 09:55:08 +00:00
Avery
398e238bfb Translated using Weblate (Spanish)
Currently translated at 100.0% (139 of 139 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/es/
2023-01-02 16:33:20 +00:00
David Baker
10819ed044 Merge pull request #812 from vector-im/dg/use_env_variable
Use environment variable for branch name
2022-12-23 10:39:10 +00:00
Davide Girardi
6edcdd3890 Use environment variable for branch name 2022-12-23 10:53:02 +01:00
Robin
5e47a439ca Merge pull request #811 from vector-im/dbkr/gha_filter_on_head_repo
Add conditional on head_repo on Netlify main GHA job
2022-12-22 18:51:20 -05:00
David Baker
d1091eda17 Add conditional on head_repo on Netlify main GHA job
As per comment
2022-12-22 20:22:54 +00:00
Timo
0488cbdd8c Change posthog key and host to selfhosted instance (#775)
* change posthog key and host

* Refresh Key

* change key again
2022-12-22 19:59:29 +01:00
David Baker
5823cd41e8 Translate separately so the i18n gets less confused 2022-12-22 14:23:19 +00:00
David Baker
de0f2e65a5 Don't show option to submit bug reports if no endpoint configured 2022-12-22 14:12:49 +00:00
David Baker
891ff86b49 Merge pull request #808 from vector-im/dbkr/remove_overflow_fullscreen
Remove the overflow menu button in fullscreen mode
2022-12-22 13:28:14 +00:00
David Baker
d7d7bee685 Remove the overflow menu button in fullscreen mode
It didn't work and fixing it is a bit of a project: see comment

https://github.com/vector-im/element-call/issues/807
2022-12-22 12:16:05 +00:00
David Baker
2c2aded094 Merge pull request #806 from vector-im/dbkr/too_many_olms
Remove Olm from devDependencies
2022-12-21 22:21:04 +00:00
David Baker
f35b50d89f Remove Olm from devDependencies
It was in devDependencies as well as dependencies for some reason
2022-12-21 18:49:49 +00:00
David Baker
0880faf312 Merge pull request #799 from vector-im/dbkr/sample_config
Make sample config just have the HS config
2022-12-21 17:58:43 +00:00
David Baker
51be754ad8 Merge pull request #798 from vector-im/dbkr/move_to_config_file
Move default homeserver to config file
2022-12-21 17:57:16 +00:00
David Baker
70522ed8da Also add comment 2022-12-21 15:26:24 +00:00
David Baker
3581aceb5a Addd ResolvedConfigOptions back 2022-12-21 15:25:08 +00:00
David Baker
16e8ea3420 Merge pull request #801 from vector-im/dbkr/pr_preview_use_branch_config
Use config from the branch we built on PR previews
2022-12-21 15:23:08 +00:00
David Baker
29f48f25f4 Actually remove the bit that's no longer neccessary 2022-12-21 15:17:34 +00:00
David Baker
089234ae09 Use config from the branch we built on PR previews
No harm in doing this - just as easy to override config in the code
itself.
2022-12-21 15:11:24 +00:00
David Baker
4dd823eca4 Merge pull request #800 from vector-im/dbkr/pr_preview
Add deploy previews
2022-12-21 14:42:35 +00:00
David Baker
6bc5b16b02 These appear to be important? 2022-12-21 13:09:41 +00:00
David Baker
f67eb328bf Add permissions, fix artifact name, filter branches 2022-12-21 12:36:00 +00:00
David Baker
1c824da32b Add config & redirects files 2022-12-21 12:08:08 +00:00
David Baker
1442e57a23 Prettify workflow file 2022-12-21 12:01:06 +00:00
David Baker
39e92b9e2e Add deploy previews
Using workflow from element-web
2022-12-21 11:57:15 +00:00
David Baker
c879090a34 Re-jig config accessors
We only ever used the static instance() method to get to the config
object, so just make a static instance that returns the ConfigOptions
directly, throwing an exception if it's not yet initialised. This way
the types can all be non-optional (plus it's shorter).
2022-12-21 10:17:53 +00:00
David Baker
6303b357ab Update default homeserver to match what the docs say 2022-12-21 10:01:37 +00:00
David Baker
b3d97810a8 Unused import 2022-12-21 09:44:28 +00:00
David Baker
eaf14a0562 Don't send rageshakes or start sentry if we don't have config for them 2022-12-21 09:42:27 +00:00
David Baker
fd3c0d9fc6 Don't guess the server name from the URL
It only uses the default HS URL anywayso just use the default
server name.
2022-12-21 09:27:25 +00:00
Robin
7765cfe1c2 Merge pull request #792 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2022-12-20 15:32:38 -05:00
David Baker
b94562d43b Indent config sample properly 2022-12-20 18:26:10 +00:00
David Baker
19e478f2a9 Make sample config just have the HS config
The other options are things people usually won't need or want to
set, so just keep it to the basics.

 * Rename config sample to match element-web
 * Update / simplify build instructions
 * Rename nginx config file to differentiate it from EC config
2022-12-20 18:13:08 +00:00
David Baker
d6b8ecdfd1 Remove default HS env var from build 2022-12-20 17:42:20 +00:00
David Baker
47ade7ee3c Add default HS for CD deployment 2022-12-20 17:37:07 +00:00
David Baker
23387ee75f Fix syntax 2022-12-20 17:32:04 +00:00
David Baker
c85d1c1d9c Don't touch the product name option for now 2022-12-20 17:30:47 +00:00
David Baker
96de515e56 Move default homeserver to config file 2022-12-20 17:26:45 +00:00
David Baker
e4c25bcc69 Merge pull request #797 from vector-im/dbkr/fix_docker_build
Fix docker build
2022-12-20 13:34:00 +00:00
David Baker
824ed06f36 Fix docker build
Remove the element-call directory level which isn't necessary any
more (accidentally removed the `cd element-call` in #794).
2022-12-20 11:44:27 +00:00
David Baker
aa57cf039a Merge pull request #794 from vector-im/dbkr/simplify_build
Simplify build process
2022-12-19 18:55:41 +00:00
David Baker
850d6a40cc Simplify build process
* We don't need to check out the js-sdk separately anymore
 * Remove the vite proxying: there's no need since Matrix HSes allow
   cross origin requests. This will let us move the default homeserver
   config to the config file (in a separate PR...)
 * Remove the product name variable which just set it to the default anyway
2022-12-19 18:43:42 +00:00
David Baker
282a4853cf Merge pull request #791 from vector-im/dbkr/spatial_audio_ff_only
Make spatial audio Firefox-only
2022-12-19 15:22:33 +00:00
David Baker
7c26bdbda3 Put the maximised conditional back
and comment it
2022-12-19 15:10:25 +00:00
David Baker
4ad5ea49c2 Merge remote-tracking branch 'origin/main' into dbkr/spatial_audio_ff_only 2022-12-19 13:18:12 +00:00
Timo
e3aa810230 Posthog widget embedding (#767)
* load analytics id from url in embedded mode

Signed-off-by: Timo K <timok@element.io>

* add start call in the widget code path

Signed-off-by: Timo K <timok@element.io>

* send group call id instead of call name

Signed-off-by: Timo K <timok@element.io>

* generate analyticsid based on account analyticsid
This make it impossible to find users from the element web posthog instance
in the element call instance

* move registration type setup PosthogAnalytics.ts

* Order identificaition and tracking.
This fixes an issue that the widget version did not identify the user before sneding
the first track event.
Because start call is called right after app startup.

Signed-off-by: Timo K <timok@element.io>
2022-12-19 12:16:59 +01:00
Jozef Gaal
db2e0758de Translated using Weblate (Slovak)
Currently translated at 100.0% (139 of 139 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/sk/
2022-12-18 18:33:16 +00:00
Šimon Brandner
39467f434e Translated using Weblate (Czech)
Currently translated at 100.0% (139 of 139 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/cs/
2022-12-18 18:33:15 +00:00
Jozef Gaal
fddf344923 Added translation using Weblate (Slovak) 2022-12-17 14:04:38 +00:00
Toomore Chiang
f806538e2c Translated using Weblate (Chinese (Traditional))
Currently translated at 9.3% (13 of 139 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/zh_Hant/
2022-12-17 11:33:15 +00:00
David Baker
c6ad2003f0 Add other missing file 2022-12-16 17:28:52 +00:00
David Baker
9aed344a80 Add missing file 2022-12-16 17:25:28 +00:00
David Baker
d8b4fea6fc i18n 2022-12-16 17:22:38 +00:00
David Baker
0c55efe4b6 Don't reorder imports - 3rd time's a charm 2022-12-16 17:20:52 +00:00
David Baker
c93df1fd06 Don't reorder import try 2 2022-12-16 17:19:40 +00:00
David Baker
c30eb19021 Don't reorder imports 2022-12-16 17:18:52 +00:00
David Baker
2d8c33d66d Merge remote-tracking branch 'origin/main' into dbkr/spatial_audio_ff_only 2022-12-16 17:17:30 +00:00
David Baker
223793a445 Make spatial audio Firefox-only
Hopefully explained in comment: we have a heisenbug where we sometimes
lack audio from a certain participant, so this simplifies the audio
path by removing the workaround required to do AEC with spatial audio
on chrome.
2022-12-16 17:12:17 +00:00
Robin
b60a92112f Merge pull request #779 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2022-12-16 11:54:25 -05:00
Toomore Chiang
b017faac36 Added translation using Weblate (Chinese (Traditional)) 2022-12-16 11:00:52 +00:00
Rodion Borisov
1615b6e559 Translated using Weblate (Russian)
Currently translated at 97.8% (136 of 139 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ru/
2022-12-16 11:00:52 +00:00
MomentQYC
d71542a757 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (139 of 139 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/zh_Hans/
2022-12-16 11:00:52 +00:00
phardyle
eb8a1cea45 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (139 of 139 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/zh_Hans/
2022-12-16 11:00:52 +00:00
MomentQYC
a44a716100 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (139 of 139 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/zh_Hans/
2022-12-16 11:00:52 +00:00
MomentQYC
34a4403135 Added translation using Weblate (Chinese (Simplified)) 2022-12-16 11:00:52 +00:00
Robin
cfe5ce977e Merge pull request #790 from robintown/no-controls
Hide controls completely in picture-in-picture view
2022-12-14 07:37:34 -05:00
Robin Townsend
102ce87bb0 Hide controls completely in picture-in-picture view
This is to prepare for upcoming design changes to the picture-in-picture view in Element Web.
2022-12-13 18:20:30 -05:00
Robin
f9845617b3 Merge pull request #783 from robintown/font-params
Add URL params to control fonts
2022-12-10 18:55:35 -05:00
Robin
1ec598453b Merge pull request #784 from robintown/prettier-everything
Apply Prettier to the entire project
2022-12-10 18:55:15 -05:00
Robin
4659e58be8 Merge pull request #785 from robintown/leave-icon
Update the leave icon
2022-12-10 18:54:58 -05:00
Robin
9f6cacb3b6 Merge pull request #782 from robintown/yarn-lock
Save lockfile
2022-12-09 15:09:02 -05:00
Robin Townsend
32168fb467 Update the leave icon 2022-12-09 14:41:43 -05:00
Robin Townsend
90ef5505bb Apply Prettier to the entire project
This ensures that our tests will be formatted by Prettier, among other things.
2022-12-09 14:34:25 -05:00
Robin Townsend
acc41c532e Add URL params to control fonts
This was also a good chance to switch to the semantic font size names used in Compound.
2022-12-09 14:31:13 -05:00
Robin Townsend
fb4fe0e928 Save lockfile 2022-12-09 08:40:58 -05:00
Šimon Brandner
e6e18dd3f9 Merge pull request #774 from vector-im/SimonBrandner/task/refactor-calls
Don't expose `calls` on `GroupCall`
2022-12-05 18:46:56 +01:00
Šimon Brandner
357a3be90d Update js-sdk
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
2022-12-05 18:45:04 +01:00
Šimon Brandner
be6f21c7e1 Upgrade js-sdk
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
2022-12-04 15:59:01 +01:00
Šimon Brandner
6d8ae91b6c Don't expose calls on GroupCall
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
2022-12-04 15:50:21 +01:00
Robin
5bd0429e98 Merge pull request #772 from robintown/toolbar-animation
Subtly animate video tile toolbars
2022-12-02 13:03:16 -05:00
Robin Townsend
0a38395bdc Subtly animate video tile toolbars 2022-12-02 12:44:31 -05:00
Robin
29d8f03a43 Merge pull request #719 from RiotTranslateBot/weblate-element-call-element-call
Translations update from Weblate
2022-12-01 08:38:21 -05:00
Weblate
c3a9760f22 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/
2022-12-01 12:33:11 +00:00
Danial Behzadi
086bacc10e Translated using Weblate (Persian)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fa/
2022-12-01 12:33:11 +00:00
Genbuchan
1b78461ee8 Added translation using Weblate (Japanese) 2022-12-01 12:33:11 +00:00
Glandos
0464515f3e Translated using Weblate (French)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fr/
2022-12-01 12:33:11 +00:00
Priit Jõerüüt
978c408ab3 Translated using Weblate (Estonian)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2022-12-01 12:33:11 +00:00
Ihor Hordiichuk
d6a800166a Translated using Weblate (Ukrainian)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/uk/
2022-12-01 12:33:11 +00:00
Linerly
70620d8294 Translated using Weblate (Indonesian)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/id/
2022-12-01 12:33:11 +00:00
Vri
18606d46fa Translated using Weblate (German)
Currently translated at 100.0% (140 of 140 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/de/
2022-12-01 12:33:11 +00:00
Erik Bedami
0e3a2afb4e Translated using Weblate (Czech)
Currently translated at 63.5% (87 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/cs/
2022-12-01 12:33:11 +00:00
Avery
4de0edc359 Translated using Weblate (Spanish)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/es/
2022-12-01 12:33:11 +00:00
Priit Jõerüüt
3a752b8f12 Translated using Weblate (Estonian)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2022-12-01 12:33:11 +00:00
Ihor Hordiichuk
f81ef3e134 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/uk/
2022-12-01 12:33:11 +00:00
Glandos
593e7a788a Translated using Weblate (French)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fr/
2022-12-01 12:33:11 +00:00
Platon Terekhov
09f4bdef8e Translated using Weblate (Russian)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/ru/
2022-12-01 12:33:11 +00:00
Linerly
88d358f976 Translated using Weblate (Indonesian)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/id/
2022-12-01 12:33:11 +00:00
Vri
a8394ebc56 Translated using Weblate (German)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/de/
2022-12-01 12:33:11 +00:00
Weblate
fde1712809 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/
2022-12-01 12:33:11 +00:00
Avery
a4b6e4ff54 Translated using Weblate (Spanish)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/es/
2022-12-01 12:33:11 +00:00
Priit Jõerüüt
d7dc76a93d Translated using Weblate (Estonian)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2022-12-01 12:33:11 +00:00
Ihor Hordiichuk
6340fb7c13 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/uk/
2022-12-01 12:33:11 +00:00
Glandos
21ffcd503b Translated using Weblate (French)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fr/
2022-12-01 12:33:11 +00:00
Linerly
63dc5744f3 Translated using Weblate (Indonesian)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/id/
2022-12-01 12:33:11 +00:00
Vri
e363fe8367 Translated using Weblate (German)
Currently translated at 100.0% (137 of 137 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/de/
2022-12-01 12:33:11 +00:00
Avery
d6d919bce9 Translated using Weblate (Spanish)
Currently translated at 100.0% (135 of 135 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/es/
2022-12-01 12:33:11 +00:00
Priit Jõerüüt
7e4c04d54e Translated using Weblate (Estonian)
Currently translated at 100.0% (135 of 135 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2022-12-01 12:33:11 +00:00
Ihor Hordiichuk
3c1d86214a Translated using Weblate (Ukrainian)
Currently translated at 100.0% (135 of 135 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/uk/
2022-12-01 12:33:11 +00:00
Glandos
37654bce7c Translated using Weblate (French)
Currently translated at 100.0% (135 of 135 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/fr/
2022-12-01 12:33:11 +00:00
Linerly
33f983d254 Translated using Weblate (Indonesian)
Currently translated at 100.0% (135 of 135 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/id/
2022-12-01 12:33:11 +00:00
Vri
6a116a4413 Translated using Weblate (German)
Currently translated at 100.0% (135 of 135 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/de/
2022-12-01 12:33:11 +00:00
aethralis
c9a9aa399c Translated using Weblate (Estonian)
Currently translated at 100.0% (132 of 132 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/et/
2022-12-01 12:33:11 +00:00
Avery
f8795931c1 Translated using Weblate (Spanish)
Currently translated at 100.0% (132 of 132 strings)

Translation: Element Call/element-call
Translate-URL: https://translate.element.io/projects/element-call/element-call/es/
2022-12-01 12:33:11 +00:00
Robin
bba60189e9 Merge pull request #769 from robintown/dont-start-calls
Don't start new calls in widget mode
2022-11-30 08:37:17 -05:00
Robin Townsend
44e22e2684 Don't start new calls in widget mode
In widget mode, it's the client's duty to start the call.
2022-11-29 15:47:39 -05:00
Robin
aa828fe9f5 Merge pull request #761 from robintown/update-js-sdk
Enable users to join calls from multiple devices
2022-11-28 16:37:15 -05:00
Robin Townsend
aec034182b Update matrix-js-sdk 2022-11-28 16:34:50 -05:00
Robin Townsend
5ba7267164 Fix lints 2022-11-28 16:15:47 -05:00
David Baker
5c735f0936 Merge pull request #763 from vector-im/dbkr/pointer_event_leak
Fix click leaking through to DOM element underneath
2022-11-23 10:15:26 +00:00
David Baker
9c08a69226 Add import
And also Prettier says hi apparently
2022-11-23 10:11:55 +00:00
David Baker
40a0958e0d Use useCallback
Co-authored-by: Robin <robin@robin.town>
2022-11-23 10:06:14 +00:00
David Baker
098be75415 Fix click leaking through to DOM element underneath
See comment, although this is quite hack - I'm torn on whether this
is worth it for the bugfix. Upgrading react-aria doesn't fix it either
(and also breaks everything in React strict mode).

Fixes https://github.com/vector-im/element-call/issues/762
2022-11-22 19:01:50 +00:00
Robin Townsend
13def24f7e Enable users to join calls from multiple devices 2022-11-21 12:39:48 -05:00
David Baker
46e429c37b Merge pull request #756 from vector-im/dbkr/rageshake_request_in_title
Put rageshake request ID in title of debug log submission
2022-11-17 16:54:05 +00:00
David Baker
eab8b1d095 Put rageshake request ID in title of debug log submission 2022-11-17 16:06:41 +00:00
David Baker
b92acd4822 Merge pull request #752 from vector-im/dbkr/waiting_for_media
Add a 'waiting for video' state to media tiles
2022-11-16 16:41:27 +00:00
David Baker
93aafb1415 Remove mystery blank line
Co-authored-by: Robin <robin@robin.town>
2022-11-16 16:39:35 +00:00
David Baker
734d330a10 CamcelCase for enum values 2022-11-16 10:45:49 +00:00
David Baker
432f7ef93a i18n update 2022-11-15 17:34:56 +00:00
David Baker
5623fa415f Also update connection states when participants change 2022-11-15 17:33:58 +00:00
David Baker
f2746ab994 Pass user's connection state for their screenshare feed 2022-11-15 17:19:09 +00:00
David Baker
80f07a5454 Add a 'waiting for video' state to media tiles
This will show if the call is waiting for media to connect (in practice
doesn't actually seem to happen all that often) but also show if the
media connection is lost, with the js-sdk change.

Requires https://github.com/matrix-org/matrix-js-sdk/pull/2880
Fixes: https://github.com/vector-im/element-call/issues/669
2022-11-15 16:13:33 +00:00
Erik Johnston
18139f78d2 Merge pull request #749 from vector-im/erikj/mute_shortcuts
Add 'm' and 'space' shortcuts for mute/unmuting during a call
2022-11-15 13:21:22 +00:00
Erik Johnston
a2bbe61292 Update help text 2022-11-14 20:58:39 +00:00
Erik Johnston
6855e61c47 Correctly handle window losing focus 2022-11-14 20:58:39 +00:00
Erik Johnston
d09c3d8374 Add 'v' shortcut 2022-11-14 16:14:16 +00:00
Erik Johnston
67b97e63ca Use useEventTarget 2022-11-14 16:12:19 +00:00
Erik Johnston
4cd49dee4b Update description 2022-11-14 16:11:42 +00:00
Erik Johnston
0aadb7e60c Add a straw man description to the setting 2022-11-14 11:29:42 +00:00
Erik Johnston
c67e7ebc2c Put PTTButton shortcuts behind the new shortcut 2022-11-14 10:40:02 +00:00
Erik Johnston
b30ef953b4 Put keyboard shortcuts behind settings flag 2022-11-14 10:24:03 +00:00
Erik Johnston
c9330debd4 Lint take2? 2022-11-11 16:02:24 +00:00
Erik Johnston
456194312b Lint 2022-11-11 16:00:32 +00:00
Erik Johnston
cb85733426 Add 'm' and 'space' shortcuts for mute/unmuting during a call 2022-11-11 15:53:58 +00:00
Robin
6ef41b924d Merge pull request #743 from robintown/config
Improve config documentation and setup
2022-11-11 08:19:40 -05:00
David Baker
24299c09b1 Merge pull request #747 from vector-im/dbkr/create_room_logging
Make room / call creation logging more accurate
2022-11-10 21:56:18 +00:00
David Baker
ab860b8655 Use logger
Co-authored-by: Robin <robin@robin.town>
2022-11-10 21:43:49 +00:00
David Baker
f69e032a52 Use logger (and fix typo)
Co-authored-by: Robin <robin@robin.town>
2022-11-10 21:43:40 +00:00
David Baker
bd08166a50 Make room / call creation logging more accurate
It said it was creating the room when actually it was creating the call
2022-11-10 19:10:10 +00:00
Robin
d8688413f5 Merge pull request #745 from robintown/brand
Actually remove Matrix Video Chat branding for real
2022-11-10 07:34:57 -05:00
Robin Townsend
556f975552 Actually remove Matrix Video Chat branding for real 2022-11-09 17:23:22 -05:00
Robin Townsend
12079ded4f Add instructions to put config.json inside public/ 2022-11-09 10:55:21 -05:00
Robin Townsend
62988e6b46 Make the sample config usable without any edits 2022-11-09 10:54:13 -05:00
Robin Townsend
0e478f4c20 Add config documentation, and better types 2022-11-09 10:54:04 -05:00
Robin Townsend
9bf1b6f928 Remove unused variables from .env.example 2022-11-09 10:53:00 -05:00
Robin
3f341de78f Merge pull request #739 from robintown/develop-js-sdk
Switch to the develop branch of matrix-js-sdk
2022-11-08 16:13:43 -05:00
Robin Townsend
6498d2bd19 Update matrix-js-sdk 2022-11-08 16:11:19 -05:00
Robin Townsend
15bb710394 Merge branch 'main' into develop-js-sdk 2022-11-08 16:10:43 -05:00
Robin
57bf934bc2 Merge pull request #736 from robintown/missing-audio-logs
Add logs to debug missing spatial audio
2022-11-08 14:53:28 -05:00
Robin
7553983655 Merge pull request #741 from robintown/copy
Improve the analytics opt-in copy
2022-11-08 08:36:31 -05:00
Robin Townsend
ca6d75e384 Improve the analytics opt-in copy 2022-11-08 07:53:17 -05:00
David Baker
85b02a3589 Merge pull request #728 from vector-im/dbkr/aria-describedby
Add aria-describedby associations
2022-11-07 22:45:37 +00:00
Robin Townsend
ba6c3fac7d Update matrix-js-sdk 2022-11-07 15:51:54 -05:00
Robin Townsend
b5f7b52a63 CI?? hello??? 2022-11-07 14:38:03 -05:00
Robin Townsend
88ec0d7c2f Maybe fix CI? 2022-11-07 14:35:28 -05:00
Robin Townsend
5f84cb5790 Fix lint 2022-11-07 14:03:28 -05:00
Robin Townsend
fb75c1536b Merge branch 'main' into missing-audio-logs 2022-11-07 14:00:22 -05:00
Robin
715bec5949 Merge pull request #737 from robintown/double-audio
Disable spatial audio for the maximized speaker
2022-11-07 13:59:07 -05:00
David Baker
c91dfdfe9d Merge pull request #738 from vector-im/dbkr/change_branch
Don't check out group-call branch in build script
2022-11-07 18:14:40 +00:00
Robin Townsend
667f902278 Switch to the develop branch of matrix-js-sdk 2022-11-07 12:50:59 -05:00
David Baker
e133625405 Don't check out group-call branch in build script
This build script might change more soon (we shouldn't really need
to checkout & link the js-sdk at all) but for now let's just switch
the branch now group-call is merged.
2022-11-07 17:37:40 +00:00
Timo
01244c1873 Posthog load settings on startup (#734)
Signed-off-by: Timo K <timok@element.io>
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
2022-11-07 18:00:35 +01:00
Robin Townsend
70344fd40f Disable spatial audio for the maximized speaker 2022-11-07 11:50:05 -05:00
Robin Townsend
0a5701b9fa Add logs to debug missing spatial audio
And potentially fix it, by recreating the source node when the stream changes.
2022-11-07 11:46:10 -05:00
David Baker
85959046a5 Merge pull request #727 from vector-im/dbkr/fix_join_call_close_button
Fix close button on join call modal
2022-11-07 14:07:38 +00:00
David Baker
7444763008 Merge pull request #729 from vector-im/dbkr/minor_a11y_fixes
A couple of minor a11y fixes
2022-11-07 14:06:29 +00:00
David Baker
d5a5ce9860 Don't pass potentially undefined 'desc' to useId
Also use the useId that comes with React 18.
2022-11-07 14:05:58 +00:00
David Baker
e5feba8c26 Make Home link description translateable 2022-11-07 12:33:06 +00:00
David Baker
3cac74df24 Add aria-describedBy to textarea and use useID 2022-11-07 12:28:54 +00:00
David Baker
51572b5787 Make onClose required in Modal 2022-11-07 12:23:21 +00:00
Timo
bcbc20b53d Create advanced section for telemetry checkbox (#725)
Signed-off-by: Timo K <timok@element.io>
Co-authored-by: Timo K <timok@element.io>
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
2022-11-05 11:13:56 +01:00
David Baker
5c8562088d A couple of minor a11y fixes
Picked up by Axe
2022-11-04 18:31:21 +00:00
David Baker
58e505cd38 Add aria-describedby associations 2022-11-04 18:10:53 +00:00
David Baker
509fd65156 Fix close button on join call modal
It just errored as we didn't pass onClose through to the modal
2022-11-04 17:56:37 +00:00
Timo
cafac39733 moves style init to initializer. fix i18n loading (#723)
Co-authored-by: Timo K <timok@element.io>
2022-11-04 18:29:40 +01:00
Timo
123763afec Disable posthog in widgets (#726)
Co-authored-by: Timo K <timok@element.io>
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
2022-11-04 17:31:07 +01:00
Timo
72503d0335 Add posthog Telemetry (Anonymity Logic + call duration telemetry) (#658)
Co-authored-by: Timo K <timok@element.io>
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
2022-11-04 13:07:14 +01:00
David Baker
d5326ed9ee Merge pull request #717 from vector-im/dbkr/add_main_cd_config_file
Add config file for CD version
2022-11-03 20:33:31 +00:00
Robin
6a619de67b Merge pull request #720 from robintown/fix-screenshare-crash
Fix a crash when someone leaves while screensharing
2022-11-03 16:20:11 -04:00
Robin Townsend
a47bd13db6 Fix a crash when someone leaves while screensharing 2022-11-03 16:11:57 -04:00
David Baker
0cd2ad6242 Add config file for CD version 2022-11-03 19:01:13 +00:00
Timo
78a313c373 Async config file (#682)
* initial

* only donwload config once

* formatting

* update sample config

* sentry

* refactor load state

* fix build yaml

* Upper case enums

* change how defaults work. review fixes

* abstract initialization

* copyright

* gitignore styleing

* refactor initialization

* use dafualt as fallback

* internalInstance rename

* review

* remove acidentally added posthog file

* DSN rename

* update Copyright

* remove olm from the initializer

Co-authored-by: Timo K <timok@element.io>
2022-11-03 19:43:41 +01:00
Robin Townsend
806a9032e1 Update matrix-js-sdk 2022-11-03 14:41:14 -04:00
Robin
02e1d602d9 Merge pull request #708 from robintown/join-polish
Improve the visual experience of joining a call
2022-11-03 14:01:22 -04:00
Robin
1e02afe1c1 Merge pull request #709 from robintown/crisp-avatars
Fix blurry avatars
2022-11-03 14:01:04 -04:00
Robin Townsend
2d5f413a1f Improve the visual experience of joining a call
Because useMeasure always returns a width and height of zero on the first render, various call UI elements would flash in and out of existence or animate in from the wrong place when joining a call. This poses an accessibility issue, and is generally unpleasant.
2022-11-02 23:17:36 -04:00
Robin Townsend
093bf7c1a1 Fix blurry avatars 2022-11-02 23:12:43 -04:00
205 changed files with 6399 additions and 1355 deletions

View File

@@ -1,19 +1,12 @@
####
# App Config
# Build-time app config
# Environment files are documented here:
# https://vitejs.dev/guide/env-and-mode.html#env-files
####
# Used for determining the homeserver to use for short urls etc.
# VITE_DEFAULT_HOMESERVER=http://localhost:8008
# VITE_FALLBACK_STUN_ALLOWED=false
# Used for submitting debug logs to an external rageshake server
# VITE_RAGESHAKE_SUBMIT_URL=http://localhost:9110/api/submit
# The Sentry DSN to use for error reporting. Leave undefined to disable.
# VITE_SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0
# VITE_CUSTOM_THEME=true
# VITE_THEME_ACCENT=#0dbd8b
# VITE_THEME_ACCENT_20=#0dbd8b33

View File

@@ -1,42 +1,34 @@
module.exports = {
plugins: [
"matrix-org",
],
extends: [
plugins: ["matrix-org"],
extends: ["plugin:matrix-org/react", "plugin:matrix-org/a11y", "prettier"],
env: {
browser: true,
node: true,
},
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
rules: {
"jsx-a11y/media-has-caption": ["off"],
},
overrides: [
{
files: ["src/**/*.{ts,tsx}"],
extends: [
"plugin:matrix-org/typescript",
"plugin:matrix-org/react",
"plugin:matrix-org/a11y",
"prettier",
],
env: {
browser: true,
node: true,
],
rules: {
// We're aiming to convert this code to strict mode
"@typescript-eslint/no-non-null-assertion": "off",
},
},
parserOptions: {
"ecmaVersion": "latest",
"sourceType": "module",
},
rules: {
"jsx-a11y/media-has-caption": ["off"],
},
overrides: [
{
files: [
"src/**/*.{ts,tsx}",
],
extends: [
"plugin:matrix-org/typescript",
"plugin:matrix-org/react",
"prettier",
],
rules: {
// We're aiming to convert this code to strict mode
"@typescript-eslint/no-non-null-assertion": "off",
},
},
],
settings: {
react: {
version: "detect",
},
],
settings: {
react: {
version: "detect",
},
},
};

View File

@@ -42,7 +42,7 @@ body:
id: browser
attributes:
label: Browser information
description: Which browser are you using? Which version?
description: Which browser are you using? Which version?
placeholder: e.g. Chromium Version 92.0.4515.131
validations:
required: false
@@ -58,10 +58,10 @@ body:
id: rageshake
attributes:
label: Will you send logs?
description: |
description: |
To send them, press the 'Submit Feedback' button and check 'Include Debug Logs'. Please link to this issue in the description field.
options:
- 'Yes'
- 'No'
- "Yes"
- "No"
validations:
required: true

View File

@@ -1,12 +1,8 @@
name: Build
on:
pull_request: {}
push:
branches: [main]
env:
VITE_DEFAULT_HOMESERVER: "https://call.ems.host"
VITE_SENTRY_DSN: https://b1e328d49be3402ba96101338989fb35@sentry.matrix.org/41
VITE_SENTRY_ENVIRONMENT: main-branch-cd
VITE_RAGESHAKE_SUBMIT_URL: https://element.io/bugreports/submit
jobs:
build:
name: Build
@@ -17,11 +13,19 @@ jobs:
- name: Yarn cache
uses: actions/setup-node@v3
with:
cache: 'yarn'
cache: "yarn"
- name: Install dependencies
run: "yarn install"
- name: Build
run: "yarn run build"
env:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
# This appears to be necessary to stop Vite from OOMing
# https://github.com/vitejs/vite/issues/2433
NODE_OPTIONS: "--max-old-space-size=16384"
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:

24
.github/workflows/e2e.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Run E2E tests
on:
workflow_run:
workflows: ["deploy"]
types:
- completed
branches-ignore:
- "main"
jobs:
e2e:
name: E2E tests runs on Element Call
runs-on: ubuntu-latest
steps:
- name: Check out test private repo
uses: actions/checkout@v3
with:
repository: vector-im/static-call-participant
ref: refs/heads/main
path: static-call-participant
token: ${{ secrets.GH_E2E_TEST_TOKEN }}
- name: Build E2E Image
run: "cd static-call-participant && docker build --no-cache --tag matrixdotorg/chrome-node-static-call-participant:latest ."
- name: Run E2E tests in container
run: "docker run --rm -v '${{ github.workspace }}/static-call-participant/callemshost-users.txt:/opt/app/callemshost-users.txt' matrixdotorg/chrome-node-static-call-participant:latest ./e2e.sh"

View File

@@ -11,7 +11,7 @@ jobs:
- name: Yarn cache
uses: actions/setup-node@v3
with:
cache: 'yarn'
cache: "yarn"
- name: Install dependencies
run: "yarn install"
- name: Prettier

View File

@@ -4,13 +4,19 @@ on:
workflows: ["Build"]
types:
- completed
branches:
- "main"
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
deployments: write
if: github.event.workflow_run.conclusion == 'success'
# Important: the 'branches' filter above will match the 'main' branch on forks,
# so we need to check the head repo too in order to not run on PRs from forks
# We check the branch name again too just for completeness
# (Is there a nicer way to see if a PR is from a fork?)
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_repository.full_name == 'vector-im/element-call' && github.event.workflow_run.head_branch == 'main'
steps:
- name: Create Deployment
uses: bobheadxi/deployments@v1
@@ -21,7 +27,7 @@ jobs:
env: main-branch-cd
ref: ${{ github.event.workflow_run.head_sha }}
- name: 'Download artifact'
- name: "Download artifact"
uses: actions/github-script@v3.1.0
with:
script: |
@@ -49,6 +55,9 @@ jobs:
# We fetch from github directly as we don't bother checking out the repo
run: curl -s https://raw.githubusercontent.com/vector-im/element-call/main/config/netlify_redirects > dist/_redirects
- name: Add config file
run: curl -s https://raw.githubusercontent.com/vector-im/element-call/main/config/element_io_develop.json > dist/config.json
- name: Deploy to Netlify
id: netlify
uses: nwtgck/actions-netlify@v1.2.3

81
.github/workflows/netlify-pr.yaml vendored Normal file
View File

@@ -0,0 +1,81 @@
name: Netlify PR Preview
on:
workflow_run:
workflows: ["Build"]
types:
- completed
branches-ignore:
- "main"
jobs:
deploy:
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
permissions:
deployments: write
environment: Netlify
steps:
- name: 📝 Create Deployment
uses: bobheadxi/deployments@v1
id: deployment
with:
step: start
token: ${{ secrets.GITHUB_TOKEN }}
env: Netlify
ref: ${{ github.event.workflow_run.head_sha }}
desc: |
Do you trust the author of this PR? Maybe this build will steal your keys or give you malware.
Exercise caution. Use test accounts.
- id: prdetails
uses: matrix-org/pr-details-action@v1.2
with:
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
branch: ${{ github.event.workflow_run.head_branch }}
# There's a 'download artifact' action, but it hasn't been updated for the workflow_run action
# (https://github.com/actions/download-artifact/issues/60) so instead we get this mess:
- name: 📥 Download artifact
uses: dawidd6/action-download-artifact@v2
with:
run_id: ${{ github.event.workflow_run.id }}
name: build
path: webapp
- name: Add redirects file
# We fetch from github directly as we don't bother checking out the repo
run: curl -s https://raw.githubusercontent.com/vector-im/element-call/main/config/netlify_redirects > webapp/_redirects
- name: Add config file
env:
HEADBRACH: ${{ github.event.workflow_run.head_branch }}
run: curl -s "https://raw.githubusercontent.com/vector-im/element-call/${HEADBRACH}/config/element_io_preview.json" > webapp/config.json
- name: ☁️ Deploy to Netlify
id: netlify
uses: nwtgck/actions-netlify@v1.2
with:
publish-dir: webapp
deploy-message: "Deploy from GitHub Actions"
# These don't work because we're in workflow_run
enable-pull-request-comment: false
enable-commit-comment: false
alias: pr${{ steps.prdetails.outputs.pr_id }}
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
timeout-minutes: 1
- name: 🚦 Update deployment status
uses: bobheadxi/deployments@v1
if: always()
with:
step: finish
override: false
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
env: ${{ steps.deployment.outputs.env }}
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
env_url: ${{ steps.netlify.outputs.deploy-url }}
desc: |
Do you trust the author of this PR? Maybe this build will steal your keys or give you malware.
Exercise caution. Use test accounts.

View File

@@ -13,7 +13,7 @@ jobs:
name: Build & publish
runs-on: ubuntu-latest
permissions:
contents: read
contents: write # required to upload release asset
packages: write
steps:
- name: Check it out
@@ -26,6 +26,36 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Yarn cache
uses: actions/setup-node@v3
with:
cache: "yarn"
- name: Install dependencies
run: "yarn install"
- name: Build
run: "yarn run build"
env:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
VITE_APP_VERSION: ${{ github.event.release.tag_name }}
# This appears to be necessary to stop Vite from OOMing
# https://github.com/vitejs/vite/issues/2433
NODE_OPTIONS: "--max-old-space-size=16384"
- name: Create Tarball
env:
GITHUB_TAG_NAME: ${{ github.event.release.tag_name }}
run: |
tar --numeric-owner --transform "s/dist/element-call-${GITHUB_TAG_NAME}/" -cvzf element-call-${GITHUB_TAG_NAME}.tar.gz dist
- name: Upload
uses: alexellis/upload-assets@0.4.0
env:
GITHUB_TOKEN: ${{ github.token }}
with:
asset_paths: '["element-call-${{ github.event.release.tag_name }}.tar.gz"]'
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38

View File

@@ -2,7 +2,7 @@ name: Move new issues into triage board
on:
issues:
types: [ opened ]
types: [opened]
jobs:
add-to-project:
@@ -13,13 +13,13 @@ jobs:
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:

2
.gitignore vendored
View File

@@ -5,3 +5,5 @@ dist
dist-ssr
*.local
.idea/
public/config.json
/coverage

View File

@@ -5,18 +5,18 @@
"editor.tabSize": 2,
"[typescriptreact]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}

View File

@@ -1,4 +1,3 @@
Contributing code to Element
============================
# Contributing code to Element
Element follows the same pattern as the [matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/blob/develop/CONTRIBUTING.md).

View File

@@ -1,15 +1,7 @@
FROM --platform=$BUILDPLATFORM node:16-buster as builder
WORKDIR /src
COPY . /src/element-call
RUN element-call/scripts/dockerbuild.sh
# App
FROM nginxinc/nginx-unprivileged:alpine
COPY --from=builder /src/element-call/dist /app
COPY config/default.conf /etc/nginx/conf.d/
COPY ./dist /app
COPY config/nginx.conf /etc/nginx/conf.d/default.conf
USER root

View File

@@ -5,6 +5,8 @@
Full mesh group calls powered by [Matrix](https://matrix.org), implementing [MatrixRTC](https://github.com/matrix-org/matrix-spec-proposals/blob/matthew/group-voip/proposals/3401-group-voip.md).
![A demo of Element Call with six people](demo.jpg)
To try it out, visit our hosted version at [call.element.io](https://call.element.io). You can also find the latest development version continuously deployed to [element-call.netlify.app](https://element-call.netlify.app).
## Host it yourself
@@ -15,19 +17,19 @@ Until prebuilt tarballs are available, you'll need to build Element Call from so
git clone https://github.com/vector-im/element-call.git
cd element-call
yarn
cp .env.example .env
```
You can now edit the configuration in `.env` to your liking. The most important thing is to set `VITE_DEFAULT_HOMESERVER` to the homeserver that the app should use, such as `https://call.ems.host`.
Next, build the project:
```
yarn build
```
If all went well, you can now find the build output under `dist` as a series of static files. These can be hosted using any web server of your choice.
You may also wish to add a configuration file (Element Call uses the domain it's hosted on as a Homeserver URL by default,
but you can change this in the config file). This goes in `public/config.json` - you can use the sample as a starting point:
```
cp config/config.sample.json public/config.json
# edit public/config.json
```
Because Element Call uses client-side routing, your server must be able to route any requests to non-existing paths back to `/index.html`. For example, in Nginx you can achieve this with the `try_files` directive:
```
@@ -40,14 +42,35 @@ server {
}
```
By default, the app expects you to have a Matrix homeserver (such as [Synapse](https://matrix-org.github.io/synapse/latest/setup/installation.html)) installed locally and running on port 8008. If you wish to use a homeserver on a different URL or one that is hosted on a different server, you can add a config file as above, and include the homeserver URL that you'd like to use.
Element Call requires a homeserver with registration enabled without any 3pid or token requirements, if you want it to be used by unregistered users. Furthermore, it is not recommended to use it with an existing homeserver where user accounts have joined normal rooms, as it may not be able to handle those yet and it may behave unreliably.
Therefore, to use a self-hosted homeserver, this is recommended to be a new server where any user account created has not joined any normal rooms anywhere in the Matrix federated network. The homeserver used can be setup to disable federation, so as to prevent spam registrations (if you keep registrations open) and to ensure Element Call continues to work in case any user decides to log in to their Element Call account using the standard Element app and joins normal rooms that Element Call cannot handle.
### Features
#### Allow joining group calls without a camera and a microphone
You can allow joining a group call without video and audio enabling this feature in your `config.json`:
```json
{
...
"features": {
"feature_group_calls_without_video_and_audio": true
}
}
```
## Development
Element Call is built against the `robertlong/group-call` branch of [matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/pull/2553). To get started, clone, install, and link the package:
Element Call is built against [matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/pull/2553). To get started, clone, install, and link the package:
```
git clone https://github.com/matrix-org/matrix-js-sdk.git
cd matrix-js-sdk
git switch robertlong/group-call
yarn
yarn link
```
@@ -59,20 +82,17 @@ git clone https://github.com/vector-im/element-call.git
cd element-call
yarn
yarn link matrix-js-sdk
cp .env.example .env
```
By default, the app expects you to have [Synapse](https://matrix-org.github.io/synapse/latest/setup/installation.html) installed locally and running on port 8008. If you wish to use another homeserver, you can set it in your `.env` file.
You're now ready to launch the development server:
```
yarn dev
```
## Config
## Configuration
Configuration options are documented in the `.env` file.
There are currently two different config files. `.env` holds variables that are used at build time, while `public/config.json` holds variables that are used at runtime. Documentation and default values for `public/config.json` can be found in [ConfigOptions.ts](src/config/ConfigOptions.ts).
## Translation

View File

@@ -0,0 +1,8 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://call.ems.host",
"server_name": "call.ems.host"
}
}
}

View File

@@ -1,10 +0,0 @@
server {
listen 8080;
server_name localhost;
location / {
root /app;
try_files $uri /$uri /index.html;
}
}

View File

@@ -0,0 +1,19 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://call.ems.host",
"server_name": "call.ems.host"
}
},
"posthog": {
"api_key": "phc_rXGHx9vDmyEvyRxPziYtdVIv0ahEv8A9uLWFcCi1WcU",
"api_host": "https://posthog-element-call.element.io"
},
"sentry": {
"environment": "main-branch-cd",
"DSN": "https://b1e328d49be3402ba96101338989fb35@sentry.matrix.org/41"
},
"rageshake": {
"submit_url": "https://element.io/bugreports/submit"
}
}

View File

@@ -0,0 +1,15 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://call.ems.host",
"server_name": "call.ems.host"
}
},
"posthog": {
"api_key": "phc_rXGHx9vDmyEvyRxPziYtdVIv0ahEv8A9uLWFcCi1WcU",
"api_host": "https://posthog-element-call.element.io"
},
"rageshake": {
"submit_url": "https://element.io/bugreports/submit"
}
}

25
config/nginx.conf Normal file
View File

@@ -0,0 +1,25 @@
server {
listen 8080;
server_name localhost;
root /app;
location / {
# disable cache entriely by default (apart from Etag which is accurate enough)
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
# also turn off last-modified since they are just the timestamps of the file in the docker image
# and may or may not bear any resemblance to when the resource changed
add_header Last-Modified "";
try_files $uri /$uri /index.html;
}
# assets can be cached because they have hashed filenames
location /assets {
expires 1w;
add_header Cache-Control "public, no-transform";
}
}

BIN
demo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

View File

@@ -6,11 +6,13 @@ export default {
createOldCatalogs: false,
defaultNamespace: "app",
lexers: {
ts: [{
lexer: "JavascriptLexer",
functions: ["t", "translatedError"],
functionsNamespace: ["useTranslation", "withTranslation"],
}],
ts: [
{
lexer: "JavascriptLexer",
functions: ["t", "translatedError"],
functionsNamespace: ["useTranslation", "withTranslation"],
},
],
},
locales: ["en-GB"],
output: "public/locales/$LOCALE/$NAMESPACE.json",

View File

@@ -7,8 +7,8 @@
"serve": "vite preview",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"prettier:check": "prettier -c src",
"prettier:format": "prettier -w src",
"prettier:check": "prettier -c .",
"prettier:format": "prettier -w .",
"lint": "yarn lint:types && yarn lint:js",
"lint:js": "eslint --max-warnings 0 src",
"lint:types": "tsc",
@@ -18,7 +18,7 @@
},
"dependencies": {
"@juggle/resize-observer": "^3.3.1",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz",
"@react-aria/button": "^3.3.4",
"@react-aria/dialog": "^3.1.4",
"@react-aria/focus": "^3.5.0",
@@ -45,12 +45,14 @@
"i18next": "^21.10.0",
"i18next-browser-languagedetector": "^6.1.8",
"i18next-http-backend": "^1.4.4",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#7ec726e10be835588d4b188fcd3d137b4690d79a",
"matrix-widget-api": "^1.0.0",
"lodash": "^4.17.21",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#da03c3b529576a8fcde6f2c9a171fa6cca012830",
"matrix-widget-api": "^1.3.1",
"mermaid": "^8.13.8",
"normalize.css": "^8.0.1",
"pako": "^2.0.4",
"postcss-preset-env": "^7",
"posthog-js": "^1.29.0",
"re-resizable": "^6.9.0",
"react": "18",
"react-dom": "18",
@@ -61,11 +63,12 @@
"react-use-clipboard": "^1.0.7",
"react-use-measure": "^2.1.1",
"sdp-transform": "^2.14.1",
"tinyqueue": "^2.0.3",
"unique-names-generator": "^4.6.0"
},
"devDependencies": {
"@babel/core": "^7.16.5",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
"@sentry/vite-plugin": "^0.3.0",
"@storybook/react": "^6.5.0-alpha.5",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
@@ -85,7 +88,7 @@
"i18next-parser": "^6.6.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.2.2",
"jest-environment-jsdom": "^29.2.2",
"jest-environment-jsdom": "^29.3.1",
"prettier": "^2.6.2",
"sass": "^1.42.1",
"storybook-builder-vite": "^0.1.12",

View File

@@ -1,20 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.png" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0"
/>
<title><%- title %></title>
<script>
window.global = window;
</script>
</head>
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>
<%- title %>
</title>
<script>
window.global = window;
</script>
</head>
<body>
<div id="root"></div>
</body>
</html>
<body>
<div id="root"></div>
</body>
</html>

View File

@@ -1,7 +1,6 @@
{
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Вече имате акаунт?</0><1><0>Влезте с него</0> или <2>Влезте като гост</2></1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Създайте акаунт</0> или <2>Влезте като гост</2>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Възникна грешка.</0><1>Изпращнето на debug логове ще ни помогне да открием проблема.</1>",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Защо не настройте парола за да запазите акаунта си?</0><1>Ще можете да запазите името и аватара си за бъдещи разговори</1>",
"Accept camera/microphone permissions to join the call.": "Приемете разрешенията за камера/микрофон за да се присъедините в разговора.",
"Accept microphone permissions to join the call.": "Приемете разрешението за микрофона за да се присъедините в разговора.",
@@ -29,7 +28,6 @@
"Developer": "Разработчик",
"Display name": "Име/псевдоним",
"Download debug logs": "Изтеглете debug логове",
"Entering room…": "Влизане в стаята…",
"Exit full screen": "Излез от цял екран",
"Fetching group call timed out.": "Изтече времето за взимане на груповия разговор.",
"Freedom": "Свобода",

View File

@@ -79,5 +79,62 @@
"Invite": "Pozvat",
"Inspector": "Insepktor",
"Incompatible versions!": "Nekompatibilní verze!",
"Incompatible versions": "Nekompatibilní verze"
"Incompatible versions": "Nekompatibilní verze",
"{{name}} is talking…": "{{name}} mluví…",
"{{name}} is presenting": "{{name}} prezentuje",
"{{name}} (Connecting...)": "{{name}} (Připojení...)",
"{{displayName}}, your call is now ended": "{{displayName}}, váš hovor je nyní ukončen",
"{{count}} people connected|other": "{{count}} lidí připojeno",
"{{count}} people connected|one": "{{count}} lidí připojeno",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "Tato možnost způsobí, že zvuk účastníků hovoru se bude tvářit jako by přicházel z místa, kde jsou umístěni na obrazovce.(Experimentální možnost: může způsobit nestabilitu audia.)",
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>": "Tato stárnka je chráněna pomocí ReCAPTCHA a Google <2>zásad ochrany osobních údajů</2> a <6>podmínky služby</6> platí.<9></9>Kliknutím na \"Registrovat\", souhlasíte s <12>Pravidly a podmínkami</12>",
"Walkie-talkie call name": "Jméno vysílačkového hovoru",
"Walkie-talkie call": "Vysílačkový hovor",
"{{roomName}} - Walkie-talkie call": "{{roomName}} - Vysílačkový hovor",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Zapnout jedno-klávesové zkratky, např. 'm' pro vypnutí/zapnutí mikrofonu.",
"{{names}}, {{name}}": "{{names}}, {{name}}",
"Talking…": "Mluvení…",
"Talk over speaker": "Mluvit přes mluvčího",
"Spotlight": "Soustředěný mód",
"Single-key keyboard shortcuts": "Jedno-klávesová klávesnice",
"Release to stop": "Pusťte pro ukončení",
"Release spacebar key to stop": "Pusťte mezerník pro ukončení",
"Recaptcha not loaded": "Recaptcha se nenačetla",
"Recaptcha dismissed": "Recaptcha byla zamítnuta",
"Press and hold to talk over {{name}}": "Zmáčkněte a držte, abyste mluvili přes {{name}}",
"Press and hold spacebar to talk over {{name}}": "Zmáčkněte a držte mezerník, abyste mluvili přes {{name}}",
"Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}</1>": "Ostatní uživatelé se pokoušejí připojit k tomuto hovoru s nekompatibilních verzí. Tito uživatelé by se měli ujistit, že stránku načetli znovu:<1>{userLis}</1>",
"Not registered yet? <2>Create an account</2>": "Nejste registrovaní? <2>Vytvořit účet</2>",
"More menu": "Další možnosti",
"Join existing call?": "Připojit se k existujícimu hovoru?",
"Include debug logs": "Zahrnout ladící záznamy",
"Home": "Domov",
"Having trouble? Help us fix it.": "Máte problémy? Pomozte nám je spravit.",
"Grid layout menu": "Menu rozložení",
"Go": "Pokračovat",
"Full screen": "Zvětšit na celou obrazovku",
"Freedom": "Volný",
"Fetching group call timed out.": "Vypršel časový limit načítání skupinového hovoru.",
"Exit full screen": "Ukončit režim celé obrazovky",
"Element Call Home": "Domov Element Call",
"Download debug logs": "Stáhnout ladící záznamy",
"Display name": "Zobrazované jméno",
"Developer": "Vývojář",
"Details": "Detaily",
"Description (optional)": "Popis (nepovinný)",
"Debug log request": "Žádost o protokoly ladění",
"Debug log": "Protokoly ladění",
"Create account": "Vytvořit účet",
"Copy": "Kopírovat",
"Call type menu": "Menu typu hovoru",
"By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>": "Kliknutím na \"Připojit se do hovoru\", odsouhlasíte naše <2>Terms and conditions</2>",
"By clicking \"Go\", you agree to our <2>Terms and conditions</2>": "Kliknutím na \"Pokračovat\", odsouhlasíte naše <2>Terms and conditions</2>",
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.": "Jiný uživatel v tomto hovoru má problémy. Abychom mohli diagnostikovat problém, rádi bychom shromáždili protokoly ladění.",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Proč neskončit nastavením hesla, abyste mohli účet použít znovu?</0><1>Budete si moci nechat své jméno a nastavit si avatar pro budoucí hovory </1>",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Připojit se</0><1>Or</1><2>Zkopírovat odkaz a připojit se později</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Už máte účet?</0><1><0>Přihlásit se</0> Or <2>Jako host</2></1>",
"{{name}} (Waiting for video...)": "{{name}} (Čekání na video...)",
"This feature is only supported on Firefox.": "Tato funkce je podporována jen ve Firefoxu.",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Odeslání ladících záznamů nám pomůže diagnostikovat problém.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Oops, něco se pokazilo.</0>"
}

View File

@@ -1,7 +1,6 @@
{
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Du hast bereits ein Konto?</0><1><0>Anmelden</0> Oder <2>Als Gast betreten</2></1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Konto erstellen</0> Oder <2>Als Gast betreten</2>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Hoppla, da ist etwas schief gelaufen.</0><1>Die Übermittlung von Debug-Protokollen wird uns helfen, das Problem zu finden.</1>",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Warum vergibst du nicht abschließend ein Passwort, um dein Konto zu erhalten?</0><1>Du kannst deinen Namen behalten und ein Profilbild für zukünftige Anrufe festlegen.</1>",
"Accept camera/microphone permissions to join the call.": "Erlaube Zugriff auf Kamera/Mikrofon um dem Anruf beizutreten.",
"Accept microphone permissions to join the call.": "Erlaube Zugriff auf das Mikrofon um dem Anruf beizutreten.",
@@ -14,7 +13,7 @@
"Call type menu": "Anruftyp Menü",
"Camera": "Kamera",
"Camera {{n}}": "Kamera {{n}}",
"Camera/microphone permissions needed to join the call.": "Kamera-/Mikrofonberechtigung für die Teilnahme am Anruf erforderlich.",
"Camera/microphone permissions needed to join the call.": "Für die Teilnahme am Anruf sind Kamera- und Mikrofonberechtigungen erforderlich.",
"Change layout": "Layout ändern",
"Close": "Schließen",
"Confirm password": "Passwort bestätigen",
@@ -29,7 +28,6 @@
"Developer": "Entwickler",
"Display name": "Anzeigename",
"Download debug logs": "Debug-Protokolle herunterladen",
"Entering room…": "Betrete Raum …",
"Exit full screen": "Vollbildmodus verlassen",
"Freedom": "Freiraum",
"Full screen": "Vollbild",
@@ -130,5 +128,18 @@
"Walkie-talkie call name": "Name des Walkie-Talkie-Anrufs",
"Sending debug logs…": "Sende Debug-Protokolle …",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Anruf beitreten</0><1>Oder</1><2>Anruflink kopieren und später beitreten</2>",
"{{name}} (Connecting...)": "{{name}} (verbindet sich …)"
"{{name}} (Connecting...)": "{{name}} (verbindet sich …)",
"Copy": "Kopieren",
"Element Call Home": "Element Call-Startseite",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Ob Tastenkürzel mit nur einer Taste aktiviert sein sollen, z. B. „m“ um das Mikrofon stumm/aktiv zu schalten.",
"Single-key keyboard shortcuts": "Ein-Tasten-Tastenkürzel",
"{{name}} (Waiting for video...)": "{{name}} (Warte auf Video …)",
"This feature is only supported on Firefox.": "Diese Funktion wird nur in Firefox unterstützt.",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Übermittelte Problemberichte helfen uns, Fehler zu beheben.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Hoppla, etwas ist schiefgelaufen.</0>",
"Use the upcoming grid system": "Nutze das kommende Rastersystem",
"Privacy Policy": "Datenschutzerklärung",
"Expose developer settings in the settings window.": "Zeige die Entwicklereinstellungen im Einstellungsfenster.",
"Developer Settings": "Entwicklereinstellungen",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "Mit dem Anwählen dieses Feldes akzeptierst du die Sammlung anonymer Daten, die wir zur Verbesserung deiner Erfahrung verwenden. Weitere Informationen dazu, welche Daten wir sammeln, findest du in unserer "
}

View File

@@ -3,6 +3,7 @@
"{{count}} people connected|other": "{{count}} people connected",
"{{displayName}}, your call is now ended": "{{displayName}}, your call is now ended",
"{{name}} (Connecting...)": "{{name}} (Connecting...)",
"{{name}} (Waiting for video...)": "{{name}} (Waiting for video...)",
"{{name}} is presenting": "{{name}} is presenting",
"{{name}} is talking…": "{{name}} is talking…",
"{{names}}, {{name}}": "{{names}}, {{name}}",
@@ -10,7 +11,8 @@
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Create an account</0> Or <2>Access as a guest</2>",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>",
"<0>Oops, something's gone wrong.</0>": "<0>Oops, something's gone wrong.</0>",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Submitting debug logs will help us track down the problem.</0>",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>",
"Accept camera/microphone permissions to join the call.": "Accept camera/microphone permissions to join the call.",
"Accept microphone permissions to join the call.": "Accept microphone permissions to join the call.",
@@ -19,6 +21,7 @@
"Avatar": "Avatar",
"By clicking \"Go\", you agree to our <2>Terms and conditions</2>": "By clicking \"Go\", you agree to our <2>Terms and conditions</2>",
"By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>": "By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ",
"Call link copied": "Call link copied",
"Call type menu": "Call type menu",
"Camera": "Camera",
@@ -29,6 +32,7 @@
"Confirm password": "Confirm password",
"Connection lost": "Connection lost",
"Copied!": "Copied!",
"Copy": "Copy",
"Copy and share this call link": "Copy and share this call link",
"Create account": "Create account",
"Debug log": "Debug log",
@@ -36,10 +40,12 @@
"Description (optional)": "Description (optional)",
"Details": "Details",
"Developer": "Developer",
"Developer Settings": "Developer Settings",
"Display name": "Display name",
"Download debug logs": "Download debug logs",
"Entering room": "Entering room",
"Element Call Home": "Element Call Home",
"Exit full screen": "Exit full screen",
"Expose developer settings in the settings window.": "Expose developer settings in the settings window.",
"Fetching group call timed out.": "Fetching group call timed out.",
"Freedom": "Freedom",
"Full screen": "Full screen",
@@ -79,6 +85,7 @@
"Press and hold spacebar to talk over {{name}}": "Press and hold spacebar to talk over {{name}}",
"Press and hold to talk": "Press and hold to talk",
"Press and hold to talk over {{name}}": "Press and hold to talk over {{name}}",
"Privacy Policy": "Privacy Policy",
"Profile": "Profile",
"Recaptcha dismissed": "Recaptcha dismissed",
"Recaptcha not loaded": "Recaptcha not loaded",
@@ -99,6 +106,7 @@
"Show call inspector": "Show call inspector",
"Sign in": "Sign in",
"Sign out": "Sign out",
"Single-key keyboard shortcuts": "Single-key keyboard shortcuts",
"Spatial audio": "Spatial audio",
"Speaker": "Speaker",
"Speaker {{n}}": "Speaker {{n}}",
@@ -111,11 +119,13 @@
"Talking…": "Talking…",
"Thanks! We'll get right on it.": "Thanks! We'll get right on it.",
"This call already exists, would you like to join?": "This call already exists, would you like to join?",
"This feature is only supported on Firefox.": "This feature is only supported on Firefox.",
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>": "This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)",
"Turn off camera": "Turn off camera",
"Turn on camera": "Turn on camera",
"Unmute microphone": "Unmute microphone",
"Use the upcoming grid system": "Use the upcoming grid system",
"User ID": "User ID",
"User menu": "User menu",
"Username": "Username",
@@ -128,6 +138,7 @@
"Walkie-talkie call": "Walkie-talkie call",
"Walkie-talkie call name": "Walkie-talkie call name",
"WebRTC is not supported or is being blocked in this browser.": "WebRTC is not supported or is being blocked in this browser.",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.",
"Yes, join call": "Yes, join call",
"You can't talk at the same time": "You can't talk at the same time",
"Your recent calls": "Your recent calls"

View File

@@ -91,12 +91,11 @@
"Home": "Inicio",
"Having trouble? Help us fix it.": "¿Tienes problemas? Ayúdanos a resolverlos.",
"Grid layout menu": "Menú de distribución de cuadrícula",
"Go": "Empezar",
"Go": "Comenzar",
"Full screen": "Pantalla completa",
"Freedom": "Libre",
"Fetching group call timed out.": "Se ha agotado el tiempo de espera para obtener la llamada grupal.",
"Exit full screen": "Salir de pantalla completa",
"Entering room…": "Entrando a la sala…",
"Download debug logs": "Descargar registros de depuración",
"Display name": "Nombre a mostrar",
"Developer": "Desarrollador",
@@ -120,7 +119,6 @@
"Audio": "Audio",
"Avatar": "Avatar",
"Accept camera/microphone permissions to join the call.": "Acepta los permisos de cámara/micrófono para unirte a la llamada.",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Ups, algo ha salido mal.</0><1>Enviar los registros de depuración nos ayudará a localizar el problema.</1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Crear una cuenta</0> o <2>Acceder como invitado</2>",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Unirse ahora</0><1>Or</1><2>Copiar el enlace y unirse más tarde</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>¿Ya tienes una cuenta?</0><1><0>Iniciar sesión</0> o <2>Acceder como invitado</2></1>",
@@ -130,5 +128,16 @@
"{{name}} (Connecting...)": "{{name}} (Conectando...)",
"{{displayName}}, your call is now ended": "{{displayName}}, tu llamada ha finalizado",
"{{count}} people connected|other": "{{count}} personas conectadas",
"{{count}} people connected|one": "{{count}} persona conectada"
"{{count}} people connected|one": "{{count}} persona conectada",
"Element Call Home": "Inicio de Element Call",
"Copy": "Copiar",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Habilita los atajos de teclado de una sola tecla, por ejemplo 'm' para silenciar/desilenciar el micrófono.",
"Single-key keyboard shortcuts": "Atajos de teclado de una sola tecla",
"{{name}} (Waiting for video...)": "{{name}} (Esperando al video...)",
"This feature is only supported on Firefox.": "Esta característica solo está disponible en Firefox.",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Subir los registros de depuración nos ayudará a encontrar el problema.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Ups, algo ha salido mal.</0>",
"Privacy Policy": "Política de privacidad",
"Expose developer settings in the settings window.": "Muestra los ajustes de desarrollador en la ventana de ajustes.",
"Developer Settings": "Ajustes de desarrollador"
}

View File

@@ -1,8 +1,7 @@
{
"Accept camera/microphone permissions to join the call.": "Kõnega anna õigused kaamera/mikrofoni kasutamiseks.",
"Accept camera/microphone permissions to join the call.": "Kõnega liitumiseks anna õigused kaamera/mikrofoni kasutamiseks.",
"Accept microphone permissions to join the call.": "Kõnega liitumiseks anna õigused mikrofoni kasutamiseks.",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Kas hoopis tahad salasõna seadistada ja sellega oma kasutajakonto alles jätta?</0><1>Siis saad säilitada oma nime ja määrata tunnuspildi, mida saad kasutada tulevastes kõnedes</1>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Ups, midagi läks valesti.</0><1>Logide saatmine meile aitab meil probleemi lahendada.</1>",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Kas soovid salasõna seadistada ja sellega oma kasutajakonto alles jätta?</0><1>Nii saad säilitada oma nime ja määrata profiilipildi, mida saad kasutada tulevastes kõnedes</1>",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Liitu kõnega kohe</0><1> Või</1><2>Kopeeri kõne link ja liitu hiljem</2>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Loo konto</0> Või <2>Sisene külalisena</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>On sul juba konto?</0><1><0>Logi sisse</0> Või <2>Logi sisse külalisena</2></1>",
@@ -28,7 +27,6 @@
"Freedom": "Vaba",
"Fetching group call timed out.": "Grupikõne kättesaamine aegus.",
"Exit full screen": "Välju täisekraanivaatest",
"Entering room…": "Ruumi sisenemine…",
"Download debug logs": "Lae alla veatuvastuslogid",
"Display name": "Kuvatav nimi",
"Developer": "Arendaja",
@@ -130,5 +128,18 @@
"Walkie-talkie call name": "Walkie-talkie stiilis kõne nimi",
"WebRTC is not supported or is being blocked in this browser.": "WebRTC pole kas selles brauseris toetatud või on keelatud.",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "Muudab kõneleja heli nii, nagu tuleks see sealt, kus on tema pilt ekraanil. (See on katseline funktsionaalsus ja võib mõjutada heli stabiilsust.)",
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>": "Siin saidis on kasutusel ReCAPTCHA ning kehtivad Google <2>privaatsuspoliitika</2> ja <6>teenusetingimused</6>.<9></9>Klikkides „Registreeru“, nõustud meie <12>kasutustingimustega</12>"
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>": "Siin saidis on kasutusel ReCAPTCHA ning kehtivad Google <2>privaatsuspoliitika</2> ja <6>teenusetingimused</6>.<9></9>Klikkides „Registreeru“, nõustud meie <12>kasutustingimustega</12>",
"Element Call Home": "Element Call Home",
"Copy": "Kopeeri",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Kas kasutame üheklahvilisi kiirklahve, näiteks „m“ mikrofoni sisse/välja lülitamiseks.",
"Single-key keyboard shortcuts": "Üheklahvilised kiirklahvid",
"{{name}} (Waiting for video...)": "{{name}} (Ootame videovoo algust...)",
"This feature is only supported on Firefox.": "See funktsionaalsus on toetatud vaid Firefoxis.",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Kui saadad meile vealogid, siis on lihtsam vea põhjust otsida.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Ohoo, midagi on nüüd katki.</0>",
"Use the upcoming grid system": "Kasuta tulevast ruudustiku-põhist paigutust",
"Privacy Policy": "Privaatsuspoliitika",
"Expose developer settings in the settings window.": "Näita seadistuste aknas arendajale vajalikke seadeid.",
"Developer Settings": "Arendaja seadistused",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "Selle valiku märkimisel lubad meil koguda anonüümseid andmeid, mida me pruugime sinu kasutajakogemuse parandamiseks. Üksikasjalikumat teavet meie kogutavate andmete kohta leiad siit - "
}

View File

@@ -33,7 +33,6 @@
"Full screen": "تمام صحفه",
"Freedom": "آزادی",
"Exit full screen": "خروج از حالت تمام صفحه",
"Entering room…": "درحال وارد شدن به اتاق…",
"Download debug logs": "دانلود لاگ عیب‌یابی",
"Display name": "نام نمایشی",
"Developer": "توسعه دهنده",
@@ -62,7 +61,6 @@
"Accept microphone permissions to join the call.": "پذیرفتن دسترسی به میکروفون برای پیوستن به تماس.",
"Accept camera/microphone permissions to join the call.": "پذیرفتن دسترسی دوربین/ میکروفون برای پیوستن به تماس.",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>چرا یک رمز عبور برای حساب کاربری خود تنظیم نمی‌کنید؟</0><1>شما می‌توانید نام خود را حفظ کنید و یک آواتار برای تماس‌های آینده بسازید</1>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>اوه، مشکلی پیش آمده.</0><1>ثبت کردن لاگ رفع اشکال به پیدا کردن مشکل توسط ما کمک میکند</1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>ساخت حساب کاربری</0> Or <2>دسترسی به عنوان میهمان</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>از قبل حساب کاربری دارید؟</0><1><0>ورود</0> Or <2>به عنوان یک میهمان وارد شوید</2></1>",
"{{roomName}} - Walkie-talkie call": "{{roomName}} - تماس واکی-تاکی",
@@ -91,7 +89,7 @@
"Registering…": "ثبت‌نام…",
"Register": "ثبت‌نام",
"Recaptcha not loaded": "کپچا بارگیری نشد",
"Recaptcha dismissed": "بازکپچا رد شد",
"Recaptcha dismissed": "ریکپچا رد شد",
"Press and hold to talk over {{name}}": "برای صحبت فشار دهید و نگه‌دارید {{name}}",
"Press and hold to talk": "برای صحبت فشار دهید و نگه‌دارید",
"Press and hold spacebar to talk over {{name}}": "برای صحبت کردن دکمه اسپیس بار را فشار دهید و نگه دارید {{name}}",
@@ -108,7 +106,7 @@
"Having trouble? Help us fix it.": "با مشکلی رو به رو شدید؟ به ما کمک کنید رفعش کنیم.",
"Grid layout menu": "منوی طرح‌بندی شبکه‌ای",
"Fetching group call timed out.": "زمان اتصال به مکالمه گروهی تمام شد.",
"You can't talk at the same time": "شما نمی توانید همزمان تماس بگیرید",
"You can't talk at the same time": "نمی توانید همزمان صحبت کنید",
"Yes, join call": "بله، به تماس بپیوندید",
"WebRTC is not supported or is being blocked in this browser.": "WebRTC (ارتباطات رسانه‌ای بلادرنگ مانند انتقال صدا، ویدئو و داده‌) در این مرورگر پشتیبانی نمی‌شود یا در حال مسدود شدن است.",
"Walkie-talkie call name": "نامِ تماسِ واکی-تاکی",
@@ -118,8 +116,8 @@
"Video call name": "نامِ تماسِ تصویری",
"Version: {{version}}": "نسخه: {{نسخه}}",
"User menu": "فهرست کاربر",
"Unmute microphone": "میکروفون را باصدا کنید",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "این کار باعث می‌شود صدای بلندگو از جایی که کاشی‌های آن روی صفحه قرار گرفته است به نظر برسد. (ویژگی آزمایشی: این ممکن است بر پایداری صدا تأثیر بگذارد.)",
"Unmute microphone": "ناخموشی میکروفون",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "این کار باعث می‌شود به نظر برسد صدای بلندگو از جایی که کاشی‌اش روی صفحه قرار گرفته می‌آید (ویژگی آزمایشی: ممکن است بر پایداری صدا تأثیر بگذارد.)",
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>": "این سایت توسط ReCAPTCHA محافظت می شود و <2>خط مشی رازداری</2> و <6>شرایط خدمات</6> Google اعمال می شود.<9></9>با کلیک کردن بر روی \"ثبت نام\"، شما با <12 >شرایط و ضوابط </12> ما موافقت می کنید",
"This call already exists, would you like to join?": "این تماس از قبل وجود دارد، می‌خواهید بپیوندید؟",
"Thanks! We'll get right on it.": "با تشکر! ما به درستی آن را انجام خواهیم داد.",
@@ -128,5 +126,12 @@
"Submitting feedback…": "در حال ارسال بازخورد…",
"Submit feedback": "بازخورد ارائه دهید",
"Stop sharing screen": "توقف اشتراک‌گذاری صفحه نمایش",
"Spatial audio": "صدای فضایی"
"Spatial audio": "صدای جهت‌دار",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "این که میان‌برهای صفحه‌کلید تک‌کلیده مثل m برای خموشی و ناخموشی میکروفون به کار بیفتند یا نه.",
"Single-key keyboard shortcuts": "میان‌برهای صفحه‌کلید تک‌کلیده",
"Element Call Home": "خانهٔ تماس المنت",
"Copy": "رونوشت",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>اکنون به تماس پیوسته</0><1>یا</1><2>پیوند تماس را رونوشت کرده و بعداً بپیوندید</2>",
"{{name}} (Waiting for video...)": "{{name}} (منتظر تصویر…)",
"{{name}} (Connecting...)": "{{name}} (وصل شدن…)"
}

View File

@@ -1,6 +1,5 @@
{
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Créer un compte</0> Or <2>Accès invité</2>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Mince, une erreur est survenue.</0><1>Envoyer les journaux de débogage nous aidera à résoudre le problème.</1>",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Pourquoi ne pas créer un mot de passe pour conserver votre compte ?</0><1>Vous pourrez garder votre nom et définir un avatar pour vos futurs appels</1>",
"Accept camera/microphone permissions to join the call.": "Autorisez laccès à votre caméra et microphone pour rejoindre lappel.",
"Accept microphone permissions to join the call.": "Autorisez laccès au microphone pour rejoindre lappel.",
@@ -28,7 +27,6 @@
"Developer": "Développeur",
"Display name": "Nom daffichage",
"Download debug logs": "Télécharger les journaux de débogage",
"Entering room…": "Entrée dans le salon…",
"Exit full screen": "Quitter le plein écran",
"Freedom": "Libre",
"Full screen": "Plein écran",
@@ -130,5 +128,18 @@
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Vous avez déjà un compte ?</0><1><0>Se connecter</0> Ou <2>Accès invité</2></1>",
"Sending debug logs…": "Envoi des journaux de débogage…",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Rejoindre lappel maintenant</0><1>Ou</1><2>Copier le lien de lappel et rejoindre plus tard</2>",
"{{name}} (Connecting...)": "{{name}} (Connexion…)"
"{{name}} (Connecting...)": "{{name}} (Connexion…)",
"Element Call Home": "Accueil Element Call",
"Copy": "Copier",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Bascule sur les raccourcis clavier à touche unique, par exemple « m » pour désactiver / activer le micro.",
"Single-key keyboard shortcuts": "Raccourcis clavier en une touche",
"{{name}} (Waiting for video...)": "{{name}} (En attente de vidéo…)",
"This feature is only supported on Firefox.": "Cette fonctionnalité est prise en charge dans Firefox uniquement.",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Soumettre les journaux de débogage nous aidera à déterminer le problème.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Oups, quelque chose sest mal passé.</0>",
"Use the upcoming grid system": "Utiliser le futur système de grille",
"Privacy Policy": "Politique de confidentialité",
"Expose developer settings in the settings window.": "Affiche les paramètres développeurs dans la fenêtre des paramètres.",
"Developer Settings": "Paramètres développeurs",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "En cochant cette case vous consentez à la collecte de données anonymes, que nous nous utilisons pour améliorer votre expérience. Vous trouverez plus dinformations sur les données collectées dans notre "
}

View File

@@ -1,7 +1,6 @@
{
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Sudah punya akun?</0><1><0>Masuk</0> Atau <2>Akses sebagai tamu</2></1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Buat akun</0> Atau <2>Akses sebagai tamu</2>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Aduh, ada yang salah.</0><1>Mengirimkan catatan pengawakutuan akan membantu kami melacak masalahnya.</1>",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Kenapa tidak selesaikan dengan mengatur sebuah kata sandi untuk menjaga akun Anda?</0><1>Anda akan dapat tetap menggunakan nama Anda dan atur sebuah avatar untuk digunakan dalam panggilan di masa mendatang</1>",
"Accept camera/microphone permissions to join the call.": "Terima izin kamera/mikrofon untuk bergabung ke panggilan.",
"Accept microphone permissions to join the call.": "Terima izin mikrofon untuk bergabung ke panggilan.",
@@ -29,7 +28,6 @@
"Developer": "Pengembang",
"Display name": "Nama tampilan",
"Download debug logs": "Unduh catatan pengawakutuan",
"Entering room…": "Memasuki ruangan…",
"Exit full screen": "Keluar dari layar penuh",
"Fetching group call timed out.": "Waktu pendapatan panggilan grup habis.",
"Freedom": "Bebas",
@@ -130,5 +128,18 @@
"{{roomName}} - Walkie-talkie call": "{{roomName}} - Panggilan protofon",
"Sending debug logs…": "Mengirimkan catatan pengawakutuan…",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Bergabung panggilan sekarang</0><1>Atau</1><2>Salin tautan dan bergabung nanti</2>",
"{{name}} (Connecting...)": "{{name}} (Menghubungkan...)"
"{{name}} (Connecting...)": "{{name}} (Menghubungkan...)",
"Element Call Home": "Beranda Element Call",
"Copy": "Salin",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Apakah pintasan papan ketik seharusnya diaktifkan, mis. 'm' untuk membisukan/menyuarakan mikrofon.",
"Single-key keyboard shortcuts": "Pintasan papan ketik satu tombol",
"{{name}} (Waiting for video...)": "{{name}} (Menunggu video...)",
"This feature is only supported on Firefox.": "Fitur ini hanya didukung di Firefox.",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Mengirim catatan pengawakutuan akan membantu kami melacak masalahnya.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Aduh, ada yang salah.</0>",
"Use the upcoming grid system": "Gunakan sistem kisi yang akan segera datang",
"Privacy Policy": "Kebijakan Privasi kami",
"Expose developer settings in the settings window.": "Ekspos pengaturan pengembang dalam jendela pengaturan.",
"Developer Settings": "Pengaturan Pengembang",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "Dengan mencentang kotak ini Anda setuju untuk pengumpulan data anonim, yang kami gunakan untuk meningkatkan pengalaman. Anda dapat mempelajari lebih banyak informasi tentang data yang kami lacak di "
}

114
public/locales/ja/app.json Normal file
View File

@@ -0,0 +1,114 @@
{
"{{name}} (Connecting...)": "{{name}}(接続しています…)",
"{{count}} people connected|other": "{{count}}人が接続済",
"{{count}} people connected|one": "{{count}}人が接続済",
"{{name}} (Waiting for video...)": "{{name}}(ビデオを待機しています…)",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>既にアカウントをお持ちですか?</0><1><0>ログイン</0>または<2>ゲストとしてアクセス</2></1>",
"{{roomName}} - Walkie-talkie call": "{{roomName}} - トランシーバー通話",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>アカウントを作成</0>または<2>ゲストとしてアクセス</2>",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>今すぐ通話に参加</0><1>または</1><2>通話リンクをコピーし、後で参加</2>",
"Accept camera/microphone permissions to join the call.": "通話に参加するには、カメラ・マイクの許可が必要です。",
"<0>Oops, something's gone wrong.</0>": "<0>何かがうまく行きませんでした。</0>",
"Camera/microphone permissions needed to join the call.": "通話に参加する場合、カメラ・マイクの許可が必要です。",
"Camera": "カメラ",
"Call link copied": "通話リンクをコピーしました",
"By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>": "「今すぐ通話に参加」をクリックすると、<2>利用規約</2>に同意したとみなされます",
"By clicking \"Go\", you agree to our <2>Terms and conditions</2>": "「続行」をクリックすると、 <2>利用規約</2>に同意したとみなされます",
"Avatar": "アバター",
"Accept microphone permissions to join the call.": "通話に参加するには、マイクの許可が必要です。",
"Audio": "音声",
"Connection lost": "接続が切断されました",
"Confirm password": "パスワードを確認",
"Close": "閉じる",
"Change layout": "レイアウトを変更",
"Copied!": "コピーしました!",
"Copy and share this call link": "通話リンクをコピーし共有",
"Copy": "コピー",
"Description (optional)": "概要(任意)",
"Debug log": "デバッグログ",
"Create account": "アカウントを作成",
"Having trouble? Help us fix it.": "問題が起きましたか?修正にご協力ください。",
"Go": "続行",
"Fetching group call timed out.": "グループ通話の取得がタイムアウトしました。",
"Element Call Home": "Element Call ホーム",
"Download debug logs": "デバッグログをダウンロード",
"Display name": "表示名",
"Developer": "開発者",
"Details": "詳細",
"Full screen": "全画面表示",
"Exit full screen": "全画面表示を終了",
"Include debug logs": "デバッグログを含める",
"Home": "ホーム",
"Incompatible versions!": "互換性のないバージョンです!",
"Incompatible versions": "互換性のないバージョン",
"Join existing call?": "既存の通話に参加しますか?",
"Join call now": "今すぐ通話に参加",
"Join call": "通話に参加",
"Invite": "招待",
"Invite people": "連絡先を招待",
"Not registered yet? <2>Create an account</2>": "アカウントがありませんか? <2>アカウントを作成</2>",
"Mute microphone": "マイクをミュート",
"Microphone permissions needed to join the call.": "通話の参加にはマイクの許可が必要です。",
"Microphone": "マイク",
"Login": "ログイン",
"Logging in…": "ログインしています…",
"Loading…": "読み込んでいます…",
"Loading room…": "ルームを読み込んでいます…",
"Leave": "退出",
"Version: {{version}}": "バージョン:{{version}}",
"Username": "ユーザー名",
"User menu": "ユーザーメニュー",
"User ID": "ユーザーID",
"Unmute microphone": "マイクのミュートを解除",
"Turn on camera": "カメラをつける",
"Turn off camera": "カメラを切る",
"Submitting feedback…": "フィードバックを送信しています…",
"Submit feedback": "フィードバックを送信",
"Stop sharing screen": "画面共有を停止",
"Spotlight": "スポットライト",
"Send debug logs": "デバッグログを送信",
"Sign out": "サインアウト",
"Sign in": "サインイン",
"Share screen": "画面共有",
"Settings": "設定",
"Sending…": "送信しています…",
"Sending debug logs…": "デバッグログを送信しています…",
"Saving…": "保存しています…",
"Save": "保存",
"Return to home screen": "ホーム画面に戻る",
"Registering…": "登録しています…",
"Register": "登録",
"Profile": "プロフィール",
"Press and hold spacebar to talk": "スペースを長押しで会話",
"Passwords must match": "パスワードが一致する必要があります",
"Password": "パスワード",
"Speaker": "スピーカー",
"Video call name": "ビデオ通話の名称",
"Video call": "ビデオ通話",
"Video": "ビデオ",
"Waiting for other participants…": "他の参加者を待機しています…",
"Waiting for network": "ネットワークを待機しています",
"Walkie-talkie call name": "トランシーバー通話の名称",
"Walkie-talkie call": "トランシーバー通話",
"Camera {{n}}": "カメラ {{n}}",
"{{name}} is talking…": "{{name}}が話しています…",
"Yes, join call": "はい、通話に参加",
"Spatial audio": "空間オーディオ",
"Select an option": "オプションを選択",
"Debug log request": "デバッグログを要求",
"Your recent calls": "最近の通話",
"You can't talk at the same time": "同時に会話することはできません",
"WebRTC is not supported or is being blocked in this browser.": "お使いのブラウザでWebRTCがサポートされていないか、またはブロックされています。",
"Login to your account": "アカウントにログイン",
"Freedom": "自由",
"{{displayName}}, your call is now ended": "{{displayName}}、通話が終了しました",
"Talking…": "話しています…",
"Remove": "削除",
"No": "いいえ",
"This feature is only supported on Firefox.": "この機能はFirefoxでのみサポートされています。",
"This call already exists, would you like to join?": "この通話は既に存在します。参加しますか?",
"Take me Home": "ホームに戻る",
"Press and hold to talk": "押し続けて会話",
"{{name}} is presenting": "{{name}}が画面を共有しています",
"{{names}}, {{name}}": "{{names}}、{{name}}"
}

View File

@@ -1,7 +1,6 @@
{
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "",
"<0>Create an account</0> Or <2>Access as a guest</2>": "",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "",
"{{count}} people connected|one": "{{count}}명 연결됨",
"{{count}} people connected|other": "{{count}}명 연결됨",
"{{displayName}}, your call is now ended": "{{displayName}}님, 전화가 종료되었습니다",

View File

@@ -91,7 +91,6 @@
"Freedom": "Wolność",
"Fetching group call timed out.": "Przekroczono limit czasu na uzyskanie połączenia grupowego.",
"Exit full screen": "Zamknij pełny ekran",
"Entering room…": "Wchodzenie do pokoju…",
"Download debug logs": "Pobierz dzienniki debugowania",
"Display name": "Wyświetlana nazwa",
"Developer": "Deweloper",
@@ -118,7 +117,6 @@
"Accept microphone permissions to join the call.": "Przyznaj uprawnienia do mikrofonu aby dołączyć do połączenia.",
"Accept camera/microphone permissions to join the call.": "Przyznaj uprawnienia do kamery/mikrofonu aby dołączyć do połączenia.",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Może zechcesz ustawić hasło, aby zachować swoje konto?</0><1>Będziesz w stanie utrzymać swoją nazwę i ustawić awatar do wyświetlania podczas połączeń w przyszłości</1>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Ups, coś poszło nie tak.</0><1>Przesłanie dzienników debugowania pomoże nam odnaleźć ten błąd.</1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Utwórz konto</0> Albo <2>Dołącz jako gość</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Masz już konto?</0><1><0>Zaloguj się</0> Albo <2>Dołącz jako gość</2></1>",
"{{roomName}} - Walkie-talkie call": "{{roomName}} - połączenie walkie-talkie",
@@ -126,5 +124,18 @@
"{{name}} is talking…": "{{name}} mówi…",
"{{name}} is presenting": "{{name}} prezentuje",
"{{displayName}}, your call is now ended": "{{displayName}}, twoje połączenie zostało zakończone",
"{{count}} people connected|one": "{{count}} osoba połączona"
"{{count}} people connected|one": "{{count}} osoba połączona",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Czy włączyć skróty klawiszowe pojedynczych klawiszy, np. 'm' aby wyciszyć/załączyć mikrofon.",
"This feature is only supported on Firefox.": "Ta funkcjonalność jest dostępna tylko w Firefox.",
"Single-key keyboard shortcuts": "Skróty klawiszowe (pojedyncze klawisze)",
"Copy": "Kopiuj",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Wysłanie logów debuggowania pomoże nam ustalić przyczynę problemu.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Ojej, coś poszło nie tak.</0>",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Dołącz do rozmowy teraz</0><1>Or</1><2>Skopiuj link do rozmowy i dołącz później</2>",
"{{name}} (Waiting for video...)": "{{name}} (Oczekiwanie na wideo...)",
"{{name}} (Connecting...)": "{{name}} (Łączenie...)",
"Expose developer settings in the settings window.": "Wyświetlaj opcje programisty w oknie ustawień.",
"Element Call Home": "Strona główna Element Call",
"Developer Settings": "Opcje programisty",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "Zaznaczając to pole, wyrażasz zgodę na gromadzenie anonimowych danych, które wykorzystujemy do poprawy Twoich doświadczeń. Więcej informacji o tym, jakie dane śledzimy, można znaleźć w naszym "
}

View File

@@ -3,7 +3,6 @@
"Saving…": "Сохранение…",
"Registering…": "Регистрация…",
"Logging in…": "Вход…",
"Entering room…": "Вход в комнату…",
"{{names}}, {{name}}": "{{names}}, {{name}}",
"Waiting for other participants…": "Ожидание других участников…",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "Эта функция балансирует звук к расположению плитки на экране. (Экспериментальная функция: может повлиять на стабильность аудио.)",
@@ -65,7 +64,6 @@
"Debug log request": "Запрос журнала отладки",
"Debug log": "Журнал отладки",
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.": "У одного из участников звонка есть неполадки. Чтобы лучше диагностировать похожие проблемы, нам нужен журнал отладки.",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Ой, что-то пошло не так.</0><1>Отправив журнал отладки, вы поможете нам найти проблемный участок.</1>",
"Send debug logs": "Отправить журнал отладки",
"Save": "Сохранить",
"Return to home screen": "Вернуться в Начало",
@@ -128,5 +126,16 @@
"{{name}} is presenting": "{{name}} показывает",
"{{displayName}}, your call is now ended": "{{displayName}}, ваш звонок завершён",
"{{count}} people connected|other": "{{count}} подключилось",
"{{count}} people connected|one": "{{count}} подключился"
"{{count}} people connected|one": "{{count}} подключился",
"Element Call Home": "Главная Element Call",
"Copy": "Копировать",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Присоединиться сейчас</0><1>или<1><2>cкопировать ссылку на звонок и присоединиться позже</2>",
"{{name}} (Connecting...)": "{{name}} (Соединение...)",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Включить горячие клавиши, например 'm' чтобы отключить/включить микрофон.",
"This feature is only supported on Firefox.": "Эта возможность доступна только в Firefox.",
"Single-key keyboard shortcuts": "Горячие клавиши",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Отправка журналов поможет нам найти и устранить проблему.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Упс, что-то пошло не так.</0>",
"{{name}} (Waiting for video...)": "{{name}} (Ожидание видео...)",
"Use the upcoming grid system": "Использовать сеточный показ"
}

145
public/locales/sk/app.json Normal file
View File

@@ -0,0 +1,145 @@
{
"Spotlight": "Stredobod",
"Local volume": "Lokálna hlasitosť",
"Include debug logs": "Zahrnúť záznamy o ladení",
"Fetching group call timed out.": "Vypršal čas načítania skupinového volania.",
"Element Call Home": "Domov Element Call",
"You can't talk at the same time": "Nemôžete hovoriť naraz",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Či chcete povoliť jednotlačidlové klávesové skratky, napr. \"m\" na stlmenie/zapnutie mikrofónu.",
"Waiting for other participants…": "Čaká sa na ďalších účastníkov…",
"Waiting for network": "Čakanie na sieť",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "Zvuk reproduktora tak bude vyzerať, akoby vychádzal z miesta, kde je na obrazovke umiestnená jeho ikona. (Experimentálna funkcia: môže to mať vplyv na stabilitu zvuku.)",
"Thanks! We'll get right on it.": "Vďaka! Hneď sa do toho pustíme.",
"Talking…": "Rozprávanie…",
"Talk over speaker": "Hovor cez reproduktor",
"Take me Home": "Zober ma domov",
"Submitting feedback…": "Odosielanie spätnej väzby…",
"Submit feedback": "Odoslať spätnú väzbu",
"Stop sharing screen": "Zastaviť zdieľanie obrazovky",
"Single-key keyboard shortcuts": "Jednotlačidlové klávesové skratky",
"Show call inspector": "Zobraziť inšpektora hovorov",
"Share screen": "Zdieľať obrazovku",
"Sending…": "Odosielanie…",
"Sending debug logs…": "Odosielanie záznamov o ladení…",
"Send debug logs": "Odoslať záznamy o ladení",
"Select an option": "Vyberte možnosť",
"Saving…": "Ukladanie…",
"Save": "Uložiť",
"Return to home screen": "Návrat na domovskú obrazovku",
"Remove": "Odstrániť",
"Release spacebar key to stop": "Pustite medzerník pre ukončenie",
"Release to stop": "Pustite pre ukončenie",
"Registering…": "Registrácia…",
"Register": "Registrovať sa",
"Recaptcha not loaded": "Recaptcha sa nenačítala",
"Recaptcha dismissed": "Recaptcha zamietnutá",
"Profile": "Profil",
"Press and hold to talk over {{name}}": "Stlačte a podržte pre hovor cez {{name}}",
"Press and hold to talk": "Stlačte a podržte pre hovor",
"Press and hold spacebar to talk over {{name}}": "Stlačte a podržte medzerník, ak chcete hovoriť cez {{name}}",
"Press and hold spacebar to talk": "Stlačte a podržte medzerník, ak chcete hovoriť",
"Passwords must match": "Heslá sa musia zhodovať",
"Password": "Heslo",
"Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}</1>": "Ostatní používatelia sa pokúšajú pripojiť k tomuto hovoru z nekompatibilných verzií. Títo používatelia by sa mali uistiť, že si obnovili svoje prehliadače:<1>{userLis}</1>",
"Not registered yet? <2>Create an account</2>": "Ešte nie ste zaregistrovaný? <2>Vytvorte si účet</2>",
"Not now, return to home screen": "Teraz nie, vrátiť sa na domovskú obrazovku",
"No": "Nie",
"Mute microphone": "Stlmiť mikrofón",
"More menu": "Ponuka viac",
"More": "Viac",
"Microphone permissions needed to join the call.": "Povolenie mikrofónu je potrebné na pripojenie k hovoru.",
"Microphone {{n}}": "Mikrofón {{n}}",
"Microphone": "Mikrofón",
"Login to your account": "Prihláste sa do svojho konta",
"Login": "Prihlásiť sa",
"Logging in…": "Prihlasovanie…",
"Loading…": "Načítanie…",
"Loading room…": "Načítanie miestnosti…",
"Leave": "Opustiť",
"Join existing call?": "Pripojiť sa k existujúcemu hovoru?",
"Join call now": "Pripojiť sa k hovoru teraz",
"Join call": "Pripojiť sa k hovoru",
"Invite people": "Pozvať ľudí",
"Invite": "Pozvať",
"Inspector": "Inšpektor",
"Incompatible versions!": "Nekompatibilné verzie!",
"Incompatible versions": "Nekompatibilné verzie",
"Home": "Domov",
"Having trouble? Help us fix it.": "Máte problém? Pomôžte nám ho opraviť.",
"Grid layout menu": "Ponuka rozloženia mriežky",
"Go": "Prejsť",
"Full screen": "Zobrazenie na celú obrazovku",
"Freedom": "Sloboda",
"Exit full screen": "Ukončiť zobrazenie na celú obrazovku",
"Download debug logs": "Stiahnuť záznamy ladenia",
"Your recent calls": "Vaše nedávne hovory",
"Yes, join call": "Áno, pripojiť sa k hovoru",
"WebRTC is not supported or is being blocked in this browser.": "WebRTC nie je podporované alebo je v tomto prehliadači blokované.",
"Walkie-talkie call name": "Názov vysielačkového hovoru",
"Walkie-talkie call": "Vysielačkový hovor",
"Video call name": "Názov video hovoru",
"Video call": "Video hovor",
"Video": "Video",
"Version: {{version}}": "Verzia: {{version}}",
"Username": "Meno používateľa",
"User menu": "Používateľské menu",
"User ID": "ID používateľa",
"Unmute microphone": "Zrušiť stlmenie mikrofónu",
"Turn on camera": "Zapnúť kameru",
"Turn off camera": "Vypnúť kameru",
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>": "Táto stránka je chránená systémom ReCAPTCHA a platia na ňu <2>Pravidlá ochrany osobných údajov</2> a <6>Podmienky poskytovania služieb</6> spoločnosti Google.<9></9>Kliknutím na tlačidlo \"Registrovať sa\" vyjadrujete súhlas s našimi <12>Podmienkami poskytovania služieb</12>",
"This call already exists, would you like to join?": "Tento hovor už existuje, chceli by ste sa k nemu pripojiť?",
"Speaker {{n}}": "Reproduktor {{n}}",
"Speaker": "Reproduktor",
"Spatial audio": "Priestorový zvuk",
"Sign out": "Odhlásiť sa",
"Sign in": "Prihlásiť sa",
"Settings": "Nastavenia",
"Display name": "Zobrazované meno",
"Developer": "Vývojár",
"Details": "Podrobnosti",
"Description (optional)": "Popis (voliteľné)",
"Debug log request": "Žiadosť o záznam ladenia",
"Debug log": "Záznam o ladení",
"Create account": "Vytvoriť účet",
"Copy and share this call link": "Skopírovať a zdieľať tento odkaz na hovor",
"Copy": "Kopírovať",
"Copied!": "Skopírované!",
"Connection lost": "Strata spojenia",
"Confirm password": "Potvrdiť heslo",
"Close": "Zatvoriť",
"Change layout": "Zmeniť rozloženie",
"Camera/microphone permissions needed to join the call.": "Povolenie kamery/mikrofónu je potrebné na pripojenie k hovoru.",
"Camera {{n}}": "Kamera {{n}}",
"Camera": "Kamera",
"Call type menu": "Ponuka typu hovoru",
"Call link copied": "Odkaz na hovor skopírovaný",
"By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>": "Kliknutím na \"Pripojiť sa k hovoru\" súhlasíte s našimi <2>Podmienkami</2>",
"By clicking \"Go\", you agree to our <2>Terms and conditions</2>": "Kliknutím na tlačidlo \"Prejsť\" súhlasíte s našimi <2>Podmienkami</2>",
"Avatar": "Obrázok",
"Audio": "Audio",
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.": "Ďalší používateľ v tomto hovore má problém. Aby sme mohli lepšie diagnostikovať tieto problémy, chceli by sme získať záznam o ladení.",
"Accept camera/microphone permissions to join the call.": "Prijmite povolenia kamery/mikrofónu, aby ste sa mohli pripojiť k hovoru.",
"Accept microphone permissions to join the call.": "Prijmite povolenia mikrofónu, aby ste sa mohli pripojiť k hovoru.",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Prečo neskončiť nastavením hesla, aby ste si zachovali svoj účet? </0><1>Budete si môcť ponechať svoje meno a nastaviť obrázok, ktorý sa bude používať pri budúcich hovoroch</1>",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Pripojiť sa k hovoru teraz</0><1>alebo</1><2>Kopírovať odkaz na hovor a pripojiť sa neskôr</2>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Vytvoriť konto</0> Alebo <2>Prihlásiť sa ako hosť</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Už máte konto?</0><1><0>Prihláste sa</0> Alebo <2>Prihlásiť sa ako hosť</2></1>",
"{{roomName}} - Walkie-talkie call": "{{roomName}} - Vysielačkový hovor",
"{{names}}, {{name}}": "{{names}}, {{name}}",
"{{name}} is talking…": "{{name}} rozpráva…",
"{{name}} is presenting": "{{name}} prezentuje",
"{{name}} (Waiting for video...)": "{{name}} (Čaká sa na video...)",
"{{name}} (Connecting...)": "{{name}} (Pripájanie...)",
"{{displayName}}, your call is now ended": "{{displayName}}, váš hovor je teraz ukončený",
"{{count}} people connected|other": "{{count}} osôb pripojených",
"{{count}} people connected|one": "{{count}} osoba pripojená",
"This feature is only supported on Firefox.": "Táto funkcia je podporovaná len v prehliadači Firefox.",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Odoslanie záznamov ladenia nám pomôže nájsť problém.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Hups, niečo sa pokazilo.</0>",
"Use the upcoming grid system": "Použiť pripravovaný systém mriežky",
"Privacy Policy": "Zásady ochrany osobných údajov",
"Expose developer settings in the settings window.": "Zobraziť nastavenia pre vývojárov v okne nastavení.",
"Developer Settings": "Nastavenia pre vývojárov",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "Označením tohto políčka súhlasíte so zhromažďovaním anonymných údajov, ktoré používame na zlepšenie vašich skúseností. Viac informácií o tom, ktoré údaje sledujeme, nájdete v našich "
}

View File

@@ -26,7 +26,6 @@
"Developer": "Geliştirici",
"Display name": "Ekran adı",
"Download debug logs": "Hata ayıklama kütüğünü indir",
"Entering room…": "Odaya giriliyor…",
"Exit full screen": "Tam ekranı terk et",
"Fetching group call timed out.": "Grup çağrısı zaman aşımına uğradı.",
"Freedom": "Özgürlük",
@@ -96,7 +95,6 @@
"{{names}}, {{name}}": "{{names}}, {{name}}",
"{{name}} is presenting": "{{name}} sunuyor",
"{{name}} is talking…": "{{name}} konuşuyor…",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Hoop, bir şeyler yanlış.</0><1>Hata ayıklama kütüğünü göndermek sorunu incelememize yardımcı olur.</1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Hesap oluştur</0> yahut <2>Konuk olarak gir</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Mevcut hesabınız mı var?</0><1><0>Gir</0> yahut <2>Konuk girişi</2></1>"
}

View File

@@ -91,7 +91,6 @@
"Freedom": "Свобода",
"Fetching group call timed out.": "Вичерпано час очікування групового виклику.",
"Exit full screen": "Вийти з повноекранного режиму",
"Entering room…": "Вхід у кімнату…",
"Download debug logs": "Завантажити журнали зневадження",
"Display name": "Показуване ім'я",
"Developer": "Розробнику",
@@ -119,7 +118,6 @@
"Accept microphone permissions to join the call.": "Надайте дозволи на використання мікрофонів для приєднання до виклику.",
"Accept camera/microphone permissions to join the call.": "Надайте дозвіл на використання камери/мікрофона для приєднання до виклику.",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Чому б не завершити, налаштувавши пароль для збереження свого облікового запису?</0><1>Ви зможете зберегти своє ім'я та встановити аватарку для подальшого користування під час майбутніх викликів</1>",
"<0>Oops, something's gone wrong.</0><1>Submitting debug logs will help us track down the problem.</1>": "<0>Халепа, щось пішло не так.</0><1>Надсилання журналів зневадження допоможе нам виявити проблему.</1>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Створити обліковий запис</0> або <2>Отримати доступ як гість</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Уже маєте обліковий запис?</0><1><0>Увійти</0> Or <2>Отримати доступ як гість</2></1>",
"{{roomName}} - Walkie-talkie call": "{{roomName}} - Виклик-рація",
@@ -130,5 +128,18 @@
"{{count}} people connected|other": "{{count}} під'єдналися",
"{{count}} people connected|one": "{{count}} під'єднується",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Приєднатися до виклику зараз</0><1>Or</1><2>Скопіювати посилання на виклик і приєднатися пізніше</2>",
"{{name}} (Connecting...)": "{{name}} (З'єднання...)"
"{{name}} (Connecting...)": "{{name}} (З'єднання...)",
"Element Call Home": "Домівка Element Call",
"Copy": "Копіювати",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Чи вмикати/вимикати мікрофон однією клавішею, наприклад, «m» для ввімкнення/вимкнення мікрофона.",
"Single-key keyboard shortcuts": "Одноклавішні комбінації клавіш",
"{{name}} (Waiting for video...)": "{{name}} (Очікування на відео...)",
"This feature is only supported on Firefox.": "Ця функція підтримується лише в браузері Firefox.",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Надсилання журналів зневадження допоможе нам виявити проблему.</0>",
"<0>Oops, something's gone wrong.</0>": "<0>Йой, щось пішло не за планом.</0>",
"Use the upcoming grid system": "Використовувати майбутню сіткову систему",
"Privacy Policy": "Політика приватності",
"Expose developer settings in the settings window.": "Відкрийте налаштування розробника у вікні налаштувань.",
"Developer Settings": "Налаштування розробника",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "Ставлячи прапорець у цьому полі, ви погоджуєтеся на збір анонімних даних, які ми використовуємо для поліпшення роботи. Ви можете знайти більше інформації про те, які дані ми відстежуємо в нашому "
}

View File

@@ -0,0 +1,137 @@
{
"Your recent calls": "最近通话",
"You can't talk at the same time": "你不能在同一时间发言",
"Yes, join call": "是,加入通话",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "是否启用单键键盘快捷键,例如,'m'可使麦克风静音/取消静音。",
"WebRTC is not supported or is being blocked in this browser.": "此浏览器不支持WebRTC或WebRTC被浏览器阻止。",
"Walkie-talkie call name": "对讲机通话名称",
"Walkie-talkie call": "对讲机通话",
"Waiting for other participants…": "等待其他参与者……",
"Waiting for network": "正在等待网络",
"Video call name": "视频通话名称",
"Video call": "视频通话",
"Video": "视频",
"Version: {{version}}": "版本:{{version}}",
"Username": "用户名",
"User menu": "用户菜单",
"User ID": "用户ID",
"Unmute microphone": "取消麦克风静音",
"Turn on camera": "开启摄像头",
"Turn off camera": "关闭摄像头",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "这将使发言人的音频看起来像是来自他们在屏幕上的位置。(实验性功能:这可能影响音频的稳定性)",
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>": "本网站受reCaptcha保护并适用Google<2>隐私政策</2>和<6>服务条款</6>。<9></9>点击\"注册\"则表明您同意我们的<12>条款和条件</12>",
"This call already exists, would you like to join?": "该通话已存在,你想加入吗?",
"Thanks! We'll get right on it.": "谢谢!我们会马上去做的。",
"Talking…": "正在发言……",
"Talk over speaker": "通过扬声器发言",
"Take me Home": "返回主页",
"Submitting feedback…": "正在提交反馈……",
"Submit feedback": "提交反馈",
"Stop sharing screen": "停止屏幕共享",
"Spotlight": "聚焦模式",
"Speaker {{n}}": "发言人 {{n}}",
"Speaker": "发言人",
"Spatial audio": "空间音频",
"Single-key keyboard shortcuts": "单键键盘快捷方式",
"Sign out": "注销登录",
"Sign in": "登录",
"Audio": "音频",
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.": "这个通话中的另一个用户出现了问题。为了更好地诊断这些问题,我们想收集调试日志。",
"Accept microphone permissions to join the call.": "授予麦克风权限以加入通话。",
"Accept camera/microphone permissions to join the call.": "授予摄像头/麦克风权限以加入通话。",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>为什么不设置一个密码来保留你的账户?</0><1>你将可以保留你的名字并设置一个头像,以便在未来的通话中使用。</1>",
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>现在加入通话</0><1>或</1><2>复制通话链接并稍后加入</2>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>创建账户</0> Or <2>以访客身份继续</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>已有账户?</0><1><0>登录</0> Or <2>以访客身份继续</2></1>",
"{{roomName}} - Walkie-talkie call": "{{roomName}} - 对讲机通话",
"{{names}}, {{name}}": "{{names}}, {{name}}",
"{{name}} is talking…": "{{name}}正在发言……",
"{{name}} is presenting": "{{name}}正在展示",
"{{name}} (Waiting for video...)": "{{name}}(等待视频……)",
"{{name}} (Connecting...)": "{{name}} (正在连接……)",
"{{displayName}}, your call is now ended": "{{displayName}},您的通话已结束",
"{{count}} people connected|other": "{{count}}人已连接",
"{{count}} people connected|one": "{{count}}人已连接",
"Inspector": "检查器",
"Show call inspector": "显示通话检查器",
"Share screen": "屏幕共享",
"Settings": "设置",
"Sending…": "正在发送……",
"Sending debug logs…": "正在发送调试日志……",
"Send debug logs": "发送调试日志",
"Select an option": "选择一个选项",
"Saving…": "正在保存……",
"Save": "保存",
"Return to home screen": "返回主页",
"Remove": "移除",
"Release to stop": "松开后停止",
"Release spacebar key to stop": "松开空格键停止",
"Registering…": "正在注册……",
"Register": "注册",
"Recaptcha not loaded": "reCaptcha未加载",
"Recaptcha dismissed": "reCaptcha验证失败",
"Profile": "个人信息",
"Press and hold to talk over {{name}}": "按住不放即可与 {{name}} 通话",
"Press and hold to talk": "按住不放即可通话",
"Press and hold spacebar to talk over {{name}}": "按住空格键,与 {{name}} 对话",
"Press and hold spacebar to talk": "按住空格键发言",
"Passwords must match": "密码必须匹配",
"Password": "密码",
"Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}</1>": "其他用户正试图从不兼容的版本加入这一呼叫。这些用户应该确保已经刷新了浏览器:<1>{userLis}</1>",
"Not registered yet? <2>Create an account</2>": "还没有注册? <2>创建账户<2>",
"Not now, return to home screen": "暂不,先返回主页",
"No": "否",
"Mute microphone": "麦克风静音",
"More menu": "更多",
"More": "更多",
"Microphone permissions needed to join the call.": "加入通话需要麦克风权限。",
"Microphone {{n}}": "麦克风 {{n}}",
"Microphone": "麦克风",
"Login to your account": "登录你的账户",
"Login": "登录",
"Logging in…": "登录中……",
"Local volume": "本地音量",
"Loading…": "加载中……",
"Loading room…": "加载房间中……",
"Leave": "离开",
"Join existing call?": "加入现有的通话?",
"Join call now": "现在加入通话",
"Join call": "加入通话",
"Invite people": "邀请他人",
"Invite": "邀请",
"Incompatible versions!": "版本不兼容!",
"Incompatible versions": "不兼容版本",
"Include debug logs": "包含调试日志",
"Home": "主页",
"Having trouble? Help us fix it.": "遇到麻烦?帮助我们解决问题。",
"Grid layout menu": "网格布局菜单",
"Go": "开始",
"Full screen": "全屏",
"Freedom": "自由模式",
"Fetching group call timed out.": "获取群组通话超时。",
"Exit full screen": "退出全屏",
"Element Call Home": "Element Call 主页",
"Download debug logs": "下载调试日志",
"Display name": "显示名称",
"Developer": "开发者",
"Details": "详情",
"Description (optional)": "描述(可选)",
"Debug log request": "调试日志请求",
"Debug log": "调试日志",
"Create account": "创建账户",
"Copy and share this call link": "复制并分享该链接",
"Copy": "复制",
"Copied!": "已复制!",
"Connection lost": "连接丢失",
"Confirm password": "确认密码",
"Close": "关闭",
"By clicking \"Go\", you agree to our <2>Terms and conditions</2>": "点击开始则代表同意我们的<2>条款和条件<2>",
"Change layout": "更改布局",
"Camera/microphone permissions needed to join the call.": "加入通话需要摄像头/麦克风权限。",
"Camera {{n}}": "摄像头 {{n}}",
"Camera": "摄像头",
"Call type menu": "通话类型菜单",
"Call link copied": "链接已复制",
"By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>": "点击“现在加入”则表示同意我们的<2>条款与条件<2>",
"Avatar": "头像"
}

View File

@@ -0,0 +1,145 @@
{
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>現在加入通話</0><1>或</1><2>複製通話連結,稍後再加入</2>",
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>建立帳號</0> 或<2>以訪客身份登入</2>",
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>已經有帳號?</0><1><0>登入</0> 或<2>以訪客身份登入</2></1>",
"{{roomName}} - Walkie-talkie call": "{{roomName}} - 對講機式通話",
"{{names}}, {{name}}": "{{names}}, {{name}}",
"{{name}} is talking…": "{{name}} 正在發言…",
"{{name}} is presenting": "{{name}} 已上線",
"{{name}} (Waiting for video...)": "{{name}} (等候視訊中...)",
"{{name}} (Connecting...)": "{{name}} (連結中...)",
"{{displayName}}, your call is now ended": "{{displayName}},您的通話已結束",
"{{count}} people connected|other": "{{count}} 人已連結",
"{{count}} people connected|one": "{{count}} 人已連結",
"Use the upcoming grid system": "使用即將推出的網格系統",
"Privacy Policy": "隱私權政策",
"Expose developer settings in the settings window.": "在設定視窗中顯示開發者設定。",
"Developer Settings": "開發者設定",
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "勾選這個選取盒,代表您同意我們以匿名方式收集資料,用於改善您的使用體驗。您可以在下列位置找到我們會收集哪些資料的相關資訊: ",
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>送出除錯紀錄,可幫助我們修正問題。</0>",
"<0>Oops, something's gone wrong.</0>": "<0>喔喔,有些地方怪怪的。</0>",
"Your recent calls": "您最近的通話",
"You can't talk at the same time": "您無法在同一時間發言",
"Yes, join call": "是,加入對話",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "是否要啟用快捷鍵,例如:開/關麥克風。",
"WebRTC is not supported or is being blocked in this browser.": "此瀏覽器未支援 WebRTC 或 WebRTC 被瀏覽器封鎖。",
"Walkie-talkie call name": "對講機式通話名稱",
"Walkie-talkie call": "即時通話",
"Waiting for other participants…": "等待其他參加者…",
"Waiting for network": "等待網路連線",
"Video call name": "視訊通話姓名",
"Video call": "視訊通話",
"Video": "視訊",
"Version: {{version}}": "版本: {{version}}",
"Username": "使用者名稱",
"User menu": "使用者選單",
"User ID": "使用者 ID",
"Unmute microphone": "取消麥克風靜音",
"Turn on camera": "開啟相機",
"Turn off camera": "關閉相機",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "這會使得發言者的聲音聽起來,像從他們在畫面中的位置傳來(實驗性功能:這可能會影響語音的穩定性。)",
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>Terms and conditions</12>": "此網站使用Google 驗證碼技術保護,適用<2>隱私條款</2> 與<6>條款與細則</6> 。<9></9>按下「註冊」,表示您同意我們的<12>條款與細則</12>",
"This feature is only supported on Firefox.": "只有 Firefox 支援此功能。",
"This call already exists, would you like to join?": "通話已經開始,請問您要加入嗎?",
"Thanks! We'll get right on it.": "謝謝您!我們會盡快處理。",
"Talking…": "對話中…",
"Talk over speaker": "以擴音對話",
"Take me Home": "帶我回主畫面",
"Submitting feedback…": "遞交回饋…",
"Submit feedback": "遞交回覆",
"Stop sharing screen": "停止分享螢幕畫面",
"Spotlight": "聚焦",
"Speaker {{n}}": "發言者{{n}}",
"Speaker": "發言者",
"Spatial audio": "空間音效",
"Single-key keyboard shortcuts": "快捷鍵",
"Sign out": "登出",
"Sign in": "登入",
"Show call inspector": "顯示通話稽查員",
"Share screen": "分享畫面",
"Settings": "設定",
"Sending…": "傳送中…",
"Sending debug logs…": "傳送除錯記錄檔中…",
"Send debug logs": "傳送除錯紀錄",
"Select an option": "選擇一個選項",
"Saving…": "儲存中…",
"Save": "儲存",
"Return to home screen": "回到首頁",
"Remove": "移除",
"Release to stop": "放開以停止",
"Release spacebar key to stop": "放開空白鍵以停止",
"Registering…": "註冊中…",
"Register": "註冊",
"Recaptcha not loaded": "驗證碼未載入",
"Recaptcha dismissed": "略過驗證碼",
"Profile": "個人檔案",
"Press and hold to talk over {{name}}": "與{{name}}對話時,請按住按鍵",
"Press and hold to talk": "請按住按鍵來發言",
"Press and hold spacebar to talk over {{name}}": "與{{name}}對話時,請按住空白鍵",
"Press and hold spacebar to talk": "說話時請按住空白鍵",
"Passwords must match": "密碼必須相符",
"Password": "密碼",
"Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}</1>": "有使用者試著加入通話,但他們的軟體版本不相容。這些使用者需要確認已將瀏覽器更新到最新版本:<1>{userLis}</1>",
"Not registered yet? <2>Create an account</2>": "還沒註冊嗎?<2>建立帳號</2>",
"Not now, return to home screen": "現在不行,回到首頁",
"No": "否",
"Mute microphone": "麥克風靜音",
"More menu": "更多選單",
"More": "更多",
"Microphone permissions needed to join the call.": "加入通話前需要取得麥克風的權限。",
"Microphone {{n}}": "麥克風 {{n}}",
"Microphone": "麥克風",
"Login to your account": "登入您的帳號",
"Login": "登入",
"Logging in…": "登入中…",
"Local volume": "您的音量",
"Loading…": "載入中…",
"Loading room…": "載入聊天室…",
"Leave": "離開",
"Join existing call?": "加入已開始的通話嗎?",
"Join call now": "現在加入通話",
"Join call": "加入通話",
"Invite people": "邀請夥伴",
"Invite": "邀請",
"Inspector": "稽查員",
"Incompatible versions!": "不相容版本!",
"Incompatible versions": "不相容版本",
"Include debug logs": "包含除錯紀錄",
"Home": "首頁",
"Having trouble? Help us fix it.": "遇到問題嗎?請讓我們協助您。",
"Grid layout menu": "格框式清單",
"Go": "前往",
"Full screen": "全螢幕",
"Freedom": "自由",
"Fetching group call timed out.": "加入群組對話已逾時。",
"Exit full screen": "退出全螢幕",
"Element Call Home": "Element Call 首頁",
"Download debug logs": "下載偵錯報告",
"Display name": "顯示名稱",
"Developer": "開發者",
"Details": "詳細說明",
"Description (optional)": "描述(選擇性)",
"Debug log request": "請求偵錯報告",
"Debug log": "除錯紀錄",
"Create account": "建立帳號",
"Copy and share this call link": "複製並分享通話連結",
"Copy": "複製",
"Copied!": "已複製!",
"Connection lost": "連線中斷",
"Confirm password": "確認密碼",
"Close": "關閉",
"Change layout": "變更排列",
"Camera/microphone permissions needed to join the call.": "加入通話需要取得相機/麥克風的權限。",
"Camera {{n}}": "相機 {{n}}",
"Camera": "相機",
"Call type menu": "通話類型選單",
"Call link copied": "已複製通話連結",
"By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>": "當您按下「加入通話」,您也同時同意了我們的條款與細則",
"By clicking \"Go\", you agree to our <2>Terms and conditions</2>": "當您按下「前往」,你也同意了我們的條款與細則",
"Avatar": "大頭照",
"Audio": "語音",
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.": "這通對話中的另一位使用者遇到了某些問題。為了診斷問題,我們將會建立除錯紀錄。",
"Accept microphone permissions to join the call.": "請授權使用您的麥克風以加入通話。",
"Accept camera/microphone permissions to join the call.": "請授權使用您的相機/麥克風以加入對話。",
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>何不設定密碼以保留此帳號?</0><1>您可以保留暱稱並設定頭像,以便未來通話時使用</1>"
}

View File

@@ -2,22 +2,7 @@
set -ex
export VITE_DEFAULT_HOMESERVER=https://call.ems.host
export VITE_SENTRY_DSN=https://b1e328d49be3402ba96101338989fb35@sentry.matrix.org/41
export VITE_RAGESHAKE_SUBMIT_URL=https://element.io/bugreports/submit
export VITE_PRODUCT_NAME="Element Call"
git clone https://github.com/matrix-org/matrix-js-sdk.git
cd matrix-js-sdk
git checkout robertlong/group-call
yarn install
yarn run build
yarn link
cd ../element-call
export VITE_APP_VERSION=$(git describe --tags --abbrev=0)
yarn link matrix-js-sdk
yarn install
yarn run build

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,6 +17,12 @@ limitations under the License.
import "matrix-js-sdk/src/@types/global";
declare global {
interface Document {
// Safari only supports this prefixed, so tell the type system about it
webkitExitFullscreen: () => void;
webkitFullscreenElement: HTMLElement | null;
}
interface Window {
// TODO: https://gitlab.matrix.org/matrix-org/olm/-/issues/10
OLM_OPTIONS: Record<string, string>;
@@ -27,4 +33,9 @@ declare global {
interface MediaElement extends HTMLVideoElement {
setSinkId: (id: string) => void;
}
interface HTMLElement {
// Safari only supports this prefixed, so tell the type system about it
webkitRequestFullscreen: () => void;
}
}

View File

@@ -1,2 +1,18 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// <reference types="vite/client" />
/// <reference types="vite-plugin-svgr/client" />

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { Suspense } from "react";
import React, { Suspense, useEffect, useState } from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import * as Sentry from "@sentry/react";
import { OverlayProvider } from "@react-aria/overlays";
@@ -28,7 +28,8 @@ import { ClientProvider } from "./ClientContext";
import { usePageFocusStyle } from "./usePageFocusStyle";
import { SequenceDiagramViewerPage } from "./SequenceDiagramViewerPage";
import { InspectorContextProvider } from "./room/GroupCallInspector";
import { CrashView } from "./FullScreenView";
import { CrashView, LoadingView } from "./FullScreenView";
import { Initializer } from "./initializer";
const SentryRoute = Sentry.withSentryRouting(Route);
@@ -37,42 +38,54 @@ interface AppProps {
}
export default function App({ history }: AppProps) {
const [loaded, setLoaded] = useState(false);
useEffect(() => {
Initializer.init()?.then(() => {
setLoaded(true);
});
});
usePageFocusStyle();
const errorPage = <CrashView />;
return (
<Router history={history}>
<Suspense fallback={null}>
<ClientProvider>
<InspectorContextProvider>
<Sentry.ErrorBoundary fallback={errorPage}>
<OverlayProvider>
<Switch>
<SentryRoute exact path="/">
<HomePage />
</SentryRoute>
<SentryRoute exact path="/login">
<LoginPage />
</SentryRoute>
<SentryRoute exact path="/register">
<RegisterPage />
</SentryRoute>
<SentryRoute path="/room/:roomId?">
<RoomPage />
</SentryRoute>
<SentryRoute path="/inspector">
<SequenceDiagramViewerPage />
</SentryRoute>
<SentryRoute path="*">
<RoomRedirect />
</SentryRoute>
</Switch>
</OverlayProvider>
</Sentry.ErrorBoundary>
</InspectorContextProvider>
</ClientProvider>
</Suspense>
{loaded ? (
<Suspense fallback={null}>
<ClientProvider>
<InspectorContextProvider>
<Sentry.ErrorBoundary fallback={errorPage}>
<OverlayProvider>
<Switch>
<SentryRoute exact path="/">
<HomePage />
</SentryRoute>
<SentryRoute exact path="/login">
<LoginPage />
</SentryRoute>
<SentryRoute exact path="/register">
<RegisterPage />
</SentryRoute>
<SentryRoute path="/room/:roomId?">
<RoomPage />
</SentryRoute>
<SentryRoute path="/inspector">
<SequenceDiagramViewerPage />
</SentryRoute>
<SentryRoute path="*">
<RoomRedirect />
</SentryRoute>
</Switch>
</OverlayProvider>
</Sentry.ErrorBoundary>
</InspectorContextProvider>
</ClientProvider>
</Suspense>
) : (
<LoadingView />
)}
</Router>
);
}

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.avatar {
position: relative;
color: var(--primary-content);

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useMemo, CSSProperties } from "react";
import classNames from "classnames";
import { MatrixClient } from "matrix-js-sdk/src/client";

View File

@@ -25,24 +25,29 @@ import React, {
useRef,
} from "react";
import { useHistory } from "react-router-dom";
import { MatrixClient, ClientEvent } from "matrix-js-sdk/src/client";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { MatrixClient } from "matrix-js-sdk/src/client";
import { logger } from "matrix-js-sdk/src/logger";
import { useTranslation } from "react-i18next";
import { ErrorView } from "./FullScreenView";
import {
initClient,
defaultHomeserver,
CryptoStoreIntegrityError,
fallbackICEServerAllowed,
} from "./matrix-utils";
import { widget } from "./widget";
import {
PosthogAnalytics,
RegistrationType,
} from "./analytics/PosthogAnalytics";
import { translatedError } from "./TranslatedError";
import { useEventTarget } from "./useEvents";
import { Config } from "./config/Config";
declare global {
interface Window {
matrixclient: MatrixClient;
isPasswordlessUser: boolean;
}
}
@@ -54,6 +59,9 @@ export interface Session {
tempPassword?: string;
}
const loadChannel =
"BroadcastChannel" in window ? new BroadcastChannel("load") : null;
const loadSession = (): Session => {
const data = localStorage.getItem("matrix-auth-store");
if (data) return JSON.parse(data);
@@ -114,7 +122,6 @@ export const ClientProvider: FC<Props> = ({ children }) => {
if (widget) {
// We're inside a widget, so let's engage *matryoshka mode*
logger.log("Using a matryoshka client");
return {
client: await widget.client,
isPasswordlessUser: false,
@@ -135,7 +142,7 @@ export const ClientProvider: FC<Props> = ({ children }) => {
return {
client: await initClient(
{
baseUrl: defaultHomeserver,
baseUrl: Config.defaultHomeserverUrl(),
accessToken: access_token,
userId: user_id,
deviceId: device_id,
@@ -151,7 +158,7 @@ export const ClientProvider: FC<Props> = ({ children }) => {
try {
const client = await initClient(
{
baseUrl: defaultHomeserver,
baseUrl: Config.defaultHomeserverUrl(),
accessToken: access_token,
userId: user_id,
deviceId: device_id,
@@ -279,51 +286,34 @@ export const ClientProvider: FC<Props> = ({ children }) => {
error: undefined,
});
history.push("/");
PosthogAnalytics.instance.setRegistrationType(RegistrationType.Guest);
}, [history, client]);
const { t } = useTranslation();
// To protect against multiple sessions writing to the same storage
// simultaneously, we send a broadcast message that shuts down all other
// running instances of the app. This isn't necessary if the app is running in
// a widget though, since then it'll be mostly stateless.
useEffect(() => {
// To protect against multiple sessions writing to the same storage
// simultaneously, we send a to-device message that shuts down all other
// running instances of the app. This isn't necessary if the app is running
// in a widget though, since then it'll be mostly stateless.
if (!widget && client) {
const loadTime = Date.now();
if (!widget) loadChannel?.postMessage({});
}, []);
const onToDeviceEvent = (event: MatrixEvent) => {
if (event.getType() !== "org.matrix.call_duplicate_session") return;
useEventTarget(
loadChannel,
"message",
useCallback(() => {
client?.stopClient();
const content = event.getContent();
if (content.session_id === client.getSessionId()) return;
if (content.timestamp > loadTime) {
client?.stopClient();
setState((prev) => ({
...prev,
error: translatedError(
"This application has been opened in another tab.",
t
),
}));
}
};
client.on(ClientEvent.ToDeviceEvent, onToDeviceEvent);
client.sendToDevice("org.matrix.call_duplicate_session", {
[client.getUserId()]: {
"*": { session_id: client.getSessionId(), timestamp: loadTime },
},
});
return () => {
client?.removeListener(ClientEvent.ToDeviceEvent, onToDeviceEvent);
};
}
}, [client, t]);
setState((prev) => ({
...prev,
error: translatedError(
"This application has been opened in another tab.",
t
),
}));
}, [client, setState, t])
);
const context = useMemo<ClientState>(
() => ({
@@ -351,7 +341,8 @@ export const ClientProvider: FC<Props> = ({ children }) => {
useEffect(() => {
window.matrixclient = client;
}, [client]);
window.isPasswordlessUser = isPasswordlessUser;
}, [client, isPasswordlessUser]);
if (error) {
return <ErrorView error={error} />;

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.facepile {
width: 100%;
position: relative;

View File

@@ -32,7 +32,7 @@ const overlapMap: Partial<Record<Size, number>> = {
interface Props extends HTMLAttributes<HTMLDivElement> {
className: string;
client: MatrixClient;
participants: RoomMember[];
members: RoomMember[];
max?: number;
size?: Size;
}
@@ -40,7 +40,7 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
export function Facepile({
className,
client,
participants,
members,
max = 3,
size = Size.XS,
...rest
@@ -51,14 +51,14 @@ export function Facepile({
const _overlap = overlapMap[size];
const title = useMemo(() => {
return participants.reduce<string | null>(
return members.reduce<string | null>(
(prev, curr) =>
prev === null
? curr.name
: t("{{names}}, {{name}}", { names: prev, name: curr.name }),
null
) as string;
}, [participants, t]);
}, [members, t]);
return (
<div
@@ -66,12 +66,11 @@ export function Facepile({
title={title}
style={{
width:
Math.min(participants.length, max + 1) * (_size - _overlap) +
_overlap,
Math.min(members.length, max + 1) * (_size - _overlap) + _overlap,
}}
{...rest}
>
{participants.slice(0, max).map((member, i) => {
{members.slice(0, max).map((member, i) => {
const avatarUrl = member.getMxcAvatarUrl();
return (
<Avatar
@@ -84,11 +83,11 @@ export function Facepile({
/>
);
})}
{participants.length > max && (
{members.length > max && (
<Avatar
key="additional"
size={size}
fallback={`+${participants.length - max}`}
fallback={`+${members.length - max}`}
className={styles.avatar}
style={{ left: max * (_size - _overlap) }}
/>

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.page {
position: relative;
display: flex;

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { ReactNode, useCallback, useEffect } from "react";
import { useLocation } from "react-router-dom";
import classNames from "classnames";
@@ -9,6 +25,7 @@ import { useSubmitRageshake } from "./settings/submit-rageshake";
import { ErrorMessage } from "./input/Input";
import styles from "./FullScreenView.module.css";
import { translatedError, TranslatedError } from "./TranslatedError";
import { Config } from "./config/Config";
interface FullScreenViewProps {
className?: string;
@@ -98,7 +115,7 @@ export function CrashView() {
logsComponent = <div>{t("Thanks! We'll get right on it.")}</div>;
} else if (sending) {
logsComponent = <div>{t("Sending…")}</div>;
} else {
} else if (Config.get().rageshake?.submit_url) {
logsComponent = (
<Button
size="lg"
@@ -115,8 +132,13 @@ export function CrashView() {
<FullScreenView>
<Trans>
<h1>Oops, something's gone wrong.</h1>
<p>Submitting debug logs will help us track down the problem.</p>
</Trans>
{Config.get().rageshake?.submit_url && (
<Trans>
<p>Submitting debug logs will help us track down the problem.</p>
</Trans>
)}
<div className={styles.sendLogsSection}>{logsComponent}</div>
{error && (
<ErrorMessage error={translatedError("Couldn't send debug logs!", t)} />

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.header {
position: relative;
display: flex;
@@ -131,7 +147,7 @@
}
.leftNav h3 {
font-size: 18px;
font-size: var(--font-size-subtitle);
}
.nav {

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import classNames from "classnames";
import React, { HTMLAttributes, ReactNode, useCallback, useRef } from "react";
import { Link } from "react-router-dom";
@@ -88,8 +104,14 @@ interface HeaderLogoProps {
}
export function HeaderLogo({ className }: HeaderLogoProps) {
const { t } = useTranslation();
return (
<Link className={classNames(styles.headerLogo, className)} to="/">
<Link
className={classNames(styles.headerLogo, className)}
to="/"
aria-label={t("Element Call Home")}
>
<Logo />
</Link>
);

View File

@@ -24,11 +24,13 @@ import { Body } from "./typography/Typography";
interface Props {
userIds: Set<string>;
room: Room;
onClose: () => void;
}
export const IncompatibleVersionModal: React.FC<Props> = ({
userIds,
room,
onClose,
...rest
}) => {
const { t } = useTranslation();
@@ -38,7 +40,12 @@ export const IncompatibleVersionModal: React.FC<Props> = ({
);
return (
<Modal title={t("Incompatible versions")} isDismissable {...rest}>
<Modal
title={t("Incompatible versions")}
isDismissable
onClose={onClose}
{...rest}
>
<ModalContent>
<Body>
<Trans>

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { IndexedDBStoreWorker } from "matrix-js-sdk/src/indexeddb-worker";
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.listBox {
margin: 0;
padding: 0;
@@ -19,7 +35,7 @@
padding: 8px 16px;
outline: none;
cursor: pointer;
font-size: 15px;
font-size: var(--font-size-body);
min-height: 32px;
}

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useRef } from "react";
import React, { useCallback, useRef } from "react";
import { useListBox, useOption, AriaListBoxOptions } from "@react-aria/listbox";
import { ListState } from "@react-stately/list";
import { Node } from "@react-types/shared";
@@ -73,6 +73,22 @@ function Option<T>({ item, state, className }: OptionProps<T>) {
ref
);
// Hack: remove the onPointerUp event handler and re-wire it to
// onClick. Chrome Android triggers a click event after the onpointerup
// event which leaks through to elements underneath the z-indexed select
// popover. preventDefault / stopPropagation don't have any effect, even
// adding just a dummy onClick handler still doesn't work, but it's fine
// if we handle just onClick.
// https://github.com/vector-im/element-call/issues/762
const origPointerUp = optionProps.onPointerUp;
delete optionProps.onPointerUp;
optionProps.onClick = useCallback(
(e) => {
origPointerUp(e as unknown as React.PointerEvent<HTMLElement>);
},
[origPointerUp]
);
return (
<li
{...optionProps}

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.menu {
width: 100%;
padding: 0;
@@ -12,7 +28,10 @@
align-items: center;
padding: 0 12px;
color: var(--primary-content);
font-size: 14px;
font-size: var(--font-size-body);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.menuItem > * {

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { Key, useRef, useState } from "react";
import { AriaMenuOptions, useMenu, useMenuItem } from "@react-aria/menu";
import { TreeState, useTreeState } from "@react-stately/tree";

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.modalOverlay {
position: fixed;
z-index: 100;
@@ -29,7 +45,7 @@
.modalHeader h3 {
font-weight: 600;
font-size: 24px;
font-size: var(--font-size-title);
margin: 0;
}

View File

@@ -43,7 +43,7 @@ export interface ModalProps extends OverlayProps, AriaDialogProps {
children: ReactNode;
className?: string;
mobileFullScreen?: boolean;
onClose?: () => void;
onClose: () => void;
}
export function Modal({

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.tooltip {
background-color: var(--system);
flex-direction: row;
@@ -8,7 +24,7 @@
border-radius: 8px;
max-width: 135px;
width: max-content;
font-size: 12px;
font-size: var(--font-size-caption);
font-weight: 500;
text-align: center;
}

View File

@@ -21,30 +21,64 @@ export interface UrlParams {
roomAlias: string | null;
roomId: string | null;
viaServers: string[];
// Whether the app is running in embedded mode, and should keep the user
// confined to the current room
/**
* Whether the app is running in embedded mode, and should keep the user
* confined to the current room.
*/
isEmbedded: boolean;
// Whether the app should pause before joining the call until it sees an
// io.element.join widget action, allowing it to be preloaded
/**
* Whether the app should pause before joining the call until it sees an
* io.element.join widget action, allowing it to be preloaded.
*/
preload: boolean;
// Whether to hide the room header when in a call
/**
* Whether to hide the room header when in a call.
*/
hideHeader: boolean;
// Whether to hide the screen-sharing button
/**
* Whether to hide the screen-sharing button.
*/
hideScreensharing: boolean;
// Whether to start a walkie-talkie call instead of a video call
/**
* Whether to start a walkie-talkie call instead of a video call.
*/
isPtt: boolean;
// Whether to use end-to-end encryption
/**
* Whether to use end-to-end encryption.
*/
e2eEnabled: boolean;
// The user's ID (only used in matryoshka mode)
/**
* The user's ID (only used in matryoshka mode).
*/
userId: string | null;
// The display name to use for auto-registration
/**
* The display name to use for auto-registration.
*/
displayName: string | null;
// The device's ID (only used in matryoshka mode)
/**
* The device's ID (only used in matryoshka mode).
*/
deviceId: string | null;
// The base URL of the homeserver to use for media lookups in matryoshka mode
/**
* The base URL of the homeserver to use for media lookups in matryoshka mode.
*/
baseUrl: string | null;
// The BCP 47 code of the language the app should use
/**
* The BCP 47 code of the language the app should use.
*/
lang: string | null;
/**
* The fonts which the interface should use, if not empty.
*/
fonts: string[];
/**
* The factor by which to scale the interface's font size.
*/
fontScale: number | null;
/**
* The Posthog analytics ID. It is only available if the user has given consent for sharing telemetry in element web.
*/
analyticsID: string | null;
}
/**
@@ -81,6 +115,8 @@ export const getUrlParams = (
? fragment
: fragment.substring(0, fragmentQueryStart);
const fontScale = parseFloat(getParam("fontScale") ?? "");
return {
roomAlias: fragmentRoute.length > 1 ? fragmentRoute : null,
roomId: getParam("roomId"),
@@ -96,6 +132,9 @@ export const getUrlParams = (
deviceId: getParam("deviceId"),
baseUrl: getParam("baseUrl"),
lang: getParam("lang"),
fonts: getAllParams("font"),
fontScale: Number.isNaN(fontScale) ? null : fontScale,
analyticsID: getParam("analyticsID"),
};
};

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.menuIcon {
width: 24px;
height: 24px;
@@ -10,13 +26,13 @@
.avatar {
width: 24px;
height: 24px;
font-size: 12px;
font-size: var(--font-size-caption);
}
@media (min-width: 800px) {
.avatar {
width: 32px;
height: 32px;
font-size: 15px;
font-size: var(--font-size-body);
}
}

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useCallback, useMemo } from "react";
import { Item } from "@react-stately/collections";
import { useLocation } from "react-router-dom";

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useCallback } from "react";
import { useHistory, useLocation } from "react-router-dom";

View File

@@ -0,0 +1,20 @@
import { t } from "i18next";
import React from "react";
import { Link } from "../typography/Typography";
export const optInDescription: () => JSX.Element = () => {
return (
<>
<>
{t(
"By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our "
)}
</>
<Link color="primary" href="https://element.io/privacy">
<>{t("Privacy Policy")}</>
</Link>
.
</>
);
};

View File

@@ -0,0 +1,421 @@
/*
Copyright 2022 The New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import posthog, { CaptureOptions, PostHog, Properties } from "posthog-js";
import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClient } from "matrix-js-sdk";
import { Buffer } from "buffer";
import { widget } from "../widget";
import { getSetting, setSetting, settingsBus } from "../settings/useSetting";
import {
CallEndedTracker,
CallStartedTracker,
LoginTracker,
SignupTracker,
MuteCameraTracker,
MuteMicrophoneTracker,
UndecryptableToDeviceEventTracker,
} from "./PosthogEvents";
import { Config } from "../config/Config";
import { getUrlParams } from "../UrlParams";
/* Posthog analytics tracking.
*
* Anonymity behaviour is as follows:
*
* - If Posthog isn't configured in `config.json`, events are not sent.
* - If [Do Not Track](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/doNotTrack) is
* enabled, events are not sent (this detection is built into posthog and turned on via the
* `respect_dnt` flag being passed to `posthog.init`).
* - If the posthog analytics are explicitly activated by the user in the element call settings,
* a randomised analytics ID is created and stored in account_data for that user (shared between devices)
* so that the user can be identified in posthog.
*/
export interface IPosthogEvent {
// The event name that will be used by PostHog. Event names should use camelCase.
eventName: string;
// do not allow these to be sent manually, we enqueue them all for caching purposes
$set?: void;
$set_once?: void;
}
export enum Anonymity {
Disabled,
Anonymous,
Pseudonymous,
}
export enum RegistrationType {
Guest,
Registered,
}
interface PlatformProperties {
appVersion: string;
matrixBackend: "embedded" | "jssdk";
}
interface PosthogSettings {
project_api_key?: string;
api_host?: string;
}
export class PosthogAnalytics {
/* Wrapper for Posthog analytics.
* 3 modes of anonymity are supported, governed by this.anonymity
* - Anonymity.Disabled means *no data* is passed to posthog
* - Anonymity.Anonymous means no identifier is passed to posthog
* - Anonymity.Pseudonymous means an analytics ID stored in account_data and shared between devices
* is passed to posthog.
*
* To update anonymity, call updateAnonymityFromSettings() or you can set it directly via setAnonymity().
*
* To pass an event to Posthog:
*
* 1. Declare a type for the event, extending IPosthogEvent.
*/
private static ANALYTICS_EVENT_TYPE = "im.vector.analytics";
// set true during the constructor if posthog config is present, otherwise false
private static internalInstance: PosthogAnalytics | null = null;
private identificationPromise: Promise<void>;
private readonly enabled: boolean = false;
private anonymity = Anonymity.Disabled;
private platformSuperProperties = {};
private registrationType: RegistrationType = RegistrationType.Guest;
public static get instance(): PosthogAnalytics {
if (!this.internalInstance) {
this.internalInstance = new PosthogAnalytics(posthog);
}
return this.internalInstance;
}
constructor(private readonly posthog: PostHog) {
const posthogConfig: PosthogSettings = {
project_api_key: Config.get().posthog?.api_key,
api_host: Config.get().posthog?.api_host,
};
if (posthogConfig.project_api_key && posthogConfig.api_host) {
if (
PosthogAnalytics.getPlatformProperties().matrixBackend === "embedded"
) {
const { analyticsID } = getUrlParams();
// if the embedding platform (element web) already got approval to communicating with posthog
// element call can also send events to posthog
setSetting("opt-in-analytics", Boolean(analyticsID));
}
this.posthog.init(posthogConfig.project_api_key, {
api_host: posthogConfig.api_host,
autocapture: false,
mask_all_text: true,
mask_all_element_attributes: true,
capture_pageview: false,
sanitize_properties: this.sanitizeProperties,
respect_dnt: true,
advanced_disable_decide: true,
});
this.enabled = true;
} else {
logger.info(
"Posthog is not enabled because there is no api key or no host given in the config"
);
this.enabled = false;
}
this.startListeningToSettingsChanges();
const optInAnalytics = getSetting("opt-in-analytics", false);
this.updateAnonymityAndIdentifyUser(optInAnalytics);
}
private sanitizeProperties = (
properties: Properties,
_eventName: string
): Properties => {
// Callback from posthog to sanitize properties before sending them to the server.
// Here we sanitize posthog's built in properties which leak PII e.g. url reporting.
// See utils.js _.info.properties in posthog-js.
if (this.anonymity == Anonymity.Anonymous) {
// drop referrer information for anonymous users
properties["$referrer"] = null;
properties["$referring_domain"] = null;
properties["$initial_referrer"] = null;
properties["$initial_referring_domain"] = null;
// drop device ID, which is a UUID persisted in local storage
properties["$device_id"] = null;
}
// the url leaks a lot of private data like the call name or the user.
// Its stripped down to the bare minimum to only give insights about the host (develop, main or sfu)
properties["$current_url"] = (properties["$current_url"] as string)
.split("/")
.slice(0, 3)
.join("");
return properties;
};
private registerSuperProperties(properties: Properties) {
if (this.enabled) {
this.posthog.register(properties);
}
}
private static getPlatformProperties(): PlatformProperties {
const appVersion = import.meta.env.VITE_APP_VERSION || "dev";
return {
appVersion,
matrixBackend: widget ? "embedded" : "jssdk",
};
}
private capture(
eventName: string,
properties: Properties,
options?: CaptureOptions
) {
if (!this.enabled) {
return;
}
this.posthog.capture(eventName, { ...properties }, options);
}
public isEnabled(): boolean {
return this.enabled;
}
setAnonymity(anonymity: Anonymity): void {
// Update this.anonymity.
// To update the anonymity typically you want to call updateAnonymityFromSettings
// to ensure this value is in step with the user's settings.
if (
this.enabled &&
(anonymity == Anonymity.Disabled || anonymity == Anonymity.Anonymous)
) {
// when transitioning to Disabled or Anonymous ensure we clear out any prior state
// set in posthog e.g. distinct ID
this.posthog.reset();
// Restore any previously set platform super properties
this.updateSuperProperties();
}
this.anonymity = anonymity;
}
private static getRandomAnalyticsId(): string {
return [...crypto.getRandomValues(new Uint8Array(16))]
.map((c) => c.toString(16))
.join("");
}
public async identifyUser(analyticsIdGenerator: () => string) {
if (this.anonymity == Anonymity.Pseudonymous && this.enabled) {
// Check the user's account_data for an analytics ID to use. Storing the ID in account_data allows
// different devices to send the same ID.
let analyticsID = await this.getAnalyticsId();
try {
if (!analyticsID && !widget) {
// only try setting up a new analytics ID in the standalone app.
// Couldn't retrieve an analytics ID from user settings, so create one and set it on the server.
// Note there's a race condition here - if two devices do these steps at the same time, last write
// wins, and the first writer will send tracking with an ID that doesn't match the one on the server
// until the next time account data is refreshed and this function is called (most likely on next
// page load). This will happen pretty infrequently, so we can tolerate the possibility.
const accountDataAnalyticsId = analyticsIdGenerator();
await this.setAccountAnalyticsId(accountDataAnalyticsId);
analyticsID = await this.hashedEcAnalyticsId(accountDataAnalyticsId);
}
} catch (e) {
// The above could fail due to network requests, but not essential to starting the application,
// so swallow it.
logger.log("Unable to identify user for tracking" + e.toString());
}
if (analyticsID) {
this.posthog.identify(analyticsID);
} else {
logger.info(
"No analyticsID is availble. Should not try to setup posthog"
);
}
}
}
async getAnalyticsId() {
const client: MatrixClient = window.matrixclient;
let accountAnalyticsId;
if (widget) {
accountAnalyticsId = getUrlParams().analyticsID;
} else {
const accountData = await client.getAccountDataFromServer(
PosthogAnalytics.ANALYTICS_EVENT_TYPE
);
accountAnalyticsId = accountData?.id;
}
if (accountAnalyticsId) {
// we dont just use the element web analytics ID because that would allow to associate
// users between the two posthog instances. By using a hash from the username and the element web analytics id
// it is not possible to conclude the element web posthog user id from the element call user id and vice versa.
return await this.hashedEcAnalyticsId(accountAnalyticsId);
}
return null;
}
async hashedEcAnalyticsId(accountAnalyticsId: string): Promise<string> {
const client: MatrixClient = window.matrixclient;
const posthogIdMaterial = "ec" + accountAnalyticsId + client.getUserId();
const bufferForPosthogId = await crypto.subtle.digest(
"sha-256",
Buffer.from(posthogIdMaterial, "utf-8")
);
const view = new Int32Array(bufferForPosthogId);
return Array.from(view)
.map((b) => Math.abs(b).toString(16).padStart(2, "0"))
.join("");
}
async setAccountAnalyticsId(analyticsID: string) {
if (!widget) {
const client = window.matrixclient;
// the analytics ID only needs to be set in the standalone version.
const accountData = await client.getAccountDataFromServer(
PosthogAnalytics.ANALYTICS_EVENT_TYPE
);
await client.setAccountData(
PosthogAnalytics.ANALYTICS_EVENT_TYPE,
Object.assign({ id: analyticsID }, accountData)
);
}
}
public getAnonymity(): Anonymity {
return this.anonymity;
}
public logout(): void {
if (this.enabled) {
this.posthog.reset();
}
this.setAnonymity(Anonymity.Disabled);
}
public updateSuperProperties() {
// Update super properties in posthog with our platform (app version, platform).
// These properties will be subsequently passed in every event.
//
// This only needs to be done once per page lifetime. Note that getPlatformProperties
this.platformSuperProperties = PosthogAnalytics.getPlatformProperties();
this.registerSuperProperties({
...this.platformSuperProperties,
registrationType:
this.registrationType == RegistrationType.Guest
? "Guest"
: "Registered",
});
}
private userRegisteredInThisSession(): boolean {
// only if the signup end got tracked the end time is set. Otherwise its default value is Date(0).
return this.eventSignup.getSignupEndTime() > new Date(0);
}
public async updateAnonymityAndIdentifyUser(
pseudonymousOptIn: boolean
): Promise<void> {
// Update this.anonymity based on the user's analytics opt-in settings
const anonymity = pseudonymousOptIn
? Anonymity.Pseudonymous
: Anonymity.Disabled;
this.setAnonymity(anonymity);
if (anonymity === Anonymity.Pseudonymous) {
this.setRegistrationType(
window.matrixclient.isGuest() || window.isPasswordlessUser
? RegistrationType.Guest
: RegistrationType.Registered
);
// store the promise to await posthog-tracking-events until the identification is done.
this.identificationPromise = this.identifyUser(
PosthogAnalytics.getRandomAnalyticsId
);
await this.identificationPromise;
if (this.userRegisteredInThisSession()) {
this.eventSignup.track();
}
}
if (anonymity !== Anonymity.Disabled) {
this.updateSuperProperties();
}
}
public async trackEvent<E extends IPosthogEvent>(
{ eventName, ...properties }: E,
options?: CaptureOptions
): Promise<void> {
if (this.identificationPromise) {
// only make calls to posthog after the identificaion is done
await this.identificationPromise;
}
if (
this.anonymity == Anonymity.Disabled ||
this.anonymity == Anonymity.Anonymous
)
return;
this.capture(eventName, properties, options);
}
public startListeningToSettingsChanges(): void {
// Listen to account data changes from sync so we can observe changes to relevant flags and update.
// This is called -
// * On page load, when the account data is first received by sync
// * On login
// * When another device changes account data
// * When the user changes their preferences on this device
// Note that for new accounts, pseudonymousAnalyticsOptIn won't be set, so updateAnonymityFromSettings
// won't be called (i.e. this.anonymity will be left as the default, until the setting changes)
settingsBus.on("opt-in-analytics", (optInAnalytics) => {
this.updateAnonymityAndIdentifyUser(optInAnalytics);
});
}
public setRegistrationType(registrationType: RegistrationType): void {
this.registrationType = registrationType;
if (
this.anonymity == Anonymity.Disabled ||
this.anonymity == Anonymity.Anonymous
)
return;
this.updateSuperProperties();
}
// ----- Events
public eventCallEnded = new CallEndedTracker();
public eventSignup = new SignupTracker();
public eventCallStarted = new CallStartedTracker();
public eventLogin = new LoginTracker();
public eventMuteMicrophone = new MuteMicrophoneTracker();
public eventMuteCamera = new MuteCameraTracker();
public eventUndecryptableToDevice = new UndecryptableToDeviceEventTracker();
}

View File

@@ -0,0 +1,165 @@
/*
Copyright 2022 The New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import {
IPosthogEvent,
PosthogAnalytics,
RegistrationType,
} from "./PosthogAnalytics";
interface CallEnded extends IPosthogEvent {
eventName: "CallEnded";
callId: string;
callParticipantsOnLeave: number;
callParticipantsMax: number;
callDuration: number;
}
export class CallEndedTracker {
private cache: { startTime: Date; maxParticipantsCount: number } = {
startTime: new Date(0),
maxParticipantsCount: 0,
};
cacheStartCall(time: Date) {
this.cache.startTime = time;
}
cacheParticipantCountChanged(count: number) {
this.cache.maxParticipantsCount = Math.max(
count,
this.cache.maxParticipantsCount
);
}
track(callId: string, callParticipantsNow: number, sendInstantly: boolean) {
PosthogAnalytics.instance.trackEvent<CallEnded>(
{
eventName: "CallEnded",
callId: callId,
callParticipantsMax: this.cache.maxParticipantsCount,
callParticipantsOnLeave: callParticipantsNow,
callDuration: (Date.now() - this.cache.startTime.getTime()) / 1000,
},
{ send_instantly: sendInstantly }
);
}
}
interface CallStarted extends IPosthogEvent {
eventName: "CallStarted";
callId: string;
}
export class CallStartedTracker {
track(callId: string) {
PosthogAnalytics.instance.trackEvent<CallStarted>({
eventName: "CallStarted",
callId: callId,
});
}
}
interface Signup extends IPosthogEvent {
eventName: "Signup";
signupDuration: number;
}
export class SignupTracker {
private cache: { signupStart: Date; signupEnd: Date } = {
signupStart: new Date(0),
signupEnd: new Date(0),
};
cacheSignupStart(time: Date) {
this.cache.signupStart = time;
}
getSignupEndTime() {
return this.cache.signupEnd;
}
cacheSignupEnd(time: Date) {
this.cache.signupEnd = time;
}
track() {
PosthogAnalytics.instance.trackEvent<Signup>({
eventName: "Signup",
signupDuration: Date.now() - this.cache.signupStart.getTime(),
});
PosthogAnalytics.instance.setRegistrationType(RegistrationType.Registered);
}
}
interface Login extends IPosthogEvent {
eventName: "Login";
}
export class LoginTracker {
track() {
PosthogAnalytics.instance.trackEvent<Login>({
eventName: "Login",
});
PosthogAnalytics.instance.setRegistrationType(RegistrationType.Registered);
}
}
interface MuteMicrophone {
eventName: "MuteMicrophone";
targetMuteState: "mute" | "unmute";
callId: string;
}
export class MuteMicrophoneTracker {
track(targetIsMute: boolean, callId: string) {
PosthogAnalytics.instance.trackEvent<MuteMicrophone>({
eventName: "MuteMicrophone",
targetMuteState: targetIsMute ? "mute" : "unmute",
callId,
});
}
}
interface MuteCamera {
eventName: "MuteCamera";
targetMuteState: "mute" | "unmute";
callId: string;
}
export class MuteCameraTracker {
track(targetIsMute: boolean, callId: string) {
PosthogAnalytics.instance.trackEvent<MuteCamera>({
eventName: "MuteCamera",
targetMuteState: targetIsMute ? "mute" : "unmute",
callId,
});
}
}
interface UndecryptableToDeviceEvent {
eventName: "UndecryptableToDeviceEvent";
callId: string;
}
export class UndecryptableToDeviceEventTracker {
track(callId: string) {
PosthogAnalytics.instance.trackEvent<UndecryptableToDeviceEvent>({
eventName: "UndecryptableToDeviceEvent",
callId,
});
}
}

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.logo {
max-width: 300px;
margin: 80px 0;
@@ -36,7 +52,7 @@
.formContainer h4 {
font-weight: normal;
font-size: 18px;
font-size: var(--font-size-subtitle);
margin-bottom: 0;
}
@@ -48,7 +64,7 @@
.formContainer button {
height: 48px;
width: 100%;
font-size: 15px;
font-size: var(--font-size-body);
font-weight: 600;
}
@@ -61,7 +77,7 @@
.authLinks {
margin-bottom: 100px;
font-size: 15px;
font-size: var(--font-size-body);
}
.authLinks a {

View File

@@ -14,14 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, {
FC,
FormEvent,
useCallback,
useRef,
useState,
useMemo,
} from "react";
import React, { FC, FormEvent, useCallback, useRef, useState } from "react";
import { useHistory, useLocation, Link } from "react-router-dom";
import { Trans, useTranslation } from "react-i18next";
@@ -29,10 +22,11 @@ import { ReactComponent as Logo } from "../icons/LogoLarge.svg";
import { useClient } from "../ClientContext";
import { FieldRow, InputField, ErrorMessage } from "../input/Input";
import { Button } from "../button";
import { defaultHomeserver, defaultHomeserverHost } from "../matrix-utils";
import styles from "./LoginPage.module.css";
import { useInteractiveLogin } from "./useInteractiveLogin";
import { usePageTitle } from "../usePageTitle";
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
import { Config } from "../config/Config";
export const LoginPage: FC = () => {
const { t } = useTranslation();
@@ -40,7 +34,7 @@ export const LoginPage: FC = () => {
const { setClient } = useClient();
const login = useInteractiveLogin();
const homeserver = defaultHomeserver; // TODO: Make this configurable
const homeserver = Config.defaultHomeserverUrl(); // TODO: Make this configurable
const usernameRef = useRef<HTMLInputElement>();
const passwordRef = useRef<HTMLInputElement>();
const history = useHistory();
@@ -64,6 +58,7 @@ export const LoginPage: FC = () => {
} else {
history.push("/");
}
PosthogAnalytics.instance.eventLogin.track();
})
.catch((error) => {
setError(error);
@@ -73,14 +68,6 @@ export const LoginPage: FC = () => {
[login, location, history, homeserver, setClient]
);
const homeserverHost = useMemo(() => {
try {
return new URL(homeserver).host;
} catch (error) {
return defaultHomeserverHost;
}
}, [homeserver]);
return (
<>
<div className={styles.container}>
@@ -100,7 +87,7 @@ export const LoginPage: FC = () => {
autoCorrect="off"
autoCapitalize="none"
prefix="@"
suffix={`:${homeserverHost}`}
suffix={`:${Config.defaultServerName()}`}
/>
</FieldRow>
<FieldRow>

View File

@@ -31,7 +31,6 @@ import { Trans, useTranslation } from "react-i18next";
import { FieldRow, InputField, ErrorMessage } from "../input/Input";
import { Button } from "../button";
import { useClient } from "../ClientContext";
import { defaultHomeserverHost } from "../matrix-utils";
import { useInteractiveRegistration } from "./useInteractiveRegistration";
import styles from "./LoginPage.module.css";
import { ReactComponent as Logo } from "../icons/LogoLarge.svg";
@@ -39,6 +38,8 @@ import { LoadingView } from "../FullScreenView";
import { useRecaptcha } from "./useRecaptcha";
import { Caption, Link } from "../typography/Typography";
import { usePageTitle } from "../usePageTitle";
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
import { Config } from "../config/Config";
export const RegisterPage: FC = () => {
const { t } = useTranslation();
@@ -98,6 +99,7 @@ export const RegisterPage: FC = () => {
}
setClient(newClient, session);
PosthogAnalytics.instance.eventSignup.cacheSignupEnd(new Date());
};
submit()
@@ -142,6 +144,8 @@ export const RegisterPage: FC = () => {
if (loading) {
return <LoadingView />;
} else {
PosthogAnalytics.instance.eventSignup.cacheSignupStart(new Date());
}
return (
@@ -161,7 +165,7 @@ export const RegisterPage: FC = () => {
autoCorrect="off"
autoCapitalize="none"
prefix="@"
suffix={`:${defaultHomeserverHost}`}
suffix={`:${Config.defaultServerName()}`}
/>
</FieldRow>
<FieldRow>

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ import { useCallback } from "react";
import { InteractiveAuth } from "matrix-js-sdk/src/interactive-auth";
import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
import { initClient, defaultHomeserver } from "../matrix-utils";
import { initClient } from "../matrix-utils";
import { Session } from "../ClientContext";
export const useInteractiveLogin = () =>
@@ -59,7 +59,7 @@ export const useInteractiveLogin = () =>
const client = await initClient(
{
baseUrl: defaultHomeserver,
baseUrl: homeserver,
accessToken: access_token,
userId: user_id,
deviceId: device_id,

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,8 +18,9 @@ import { useState, useEffect, useCallback, useRef } from "react";
import { InteractiveAuth } from "matrix-js-sdk/src/interactive-auth";
import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
import { initClient, defaultHomeserver } from "../matrix-utils";
import { initClient } from "../matrix-utils";
import { Session } from "../ClientContext";
import { Config } from "../config/Config";
export const useInteractiveRegistration = (): [
string,
@@ -37,7 +38,9 @@ export const useInteractiveRegistration = (): [
const authClient = useRef<MatrixClient>();
if (!authClient.current) {
authClient.current = createClient({ baseUrl: defaultHomeserver });
authClient.current = createClient({
baseUrl: Config.defaultHomeserverUrl(),
});
}
useEffect(() => {
@@ -92,7 +95,7 @@ export const useInteractiveRegistration = (): [
const client = await initClient(
{
baseUrl: defaultHomeserver,
baseUrl: Config.defaultHomeserverUrl(),
accessToken: access_token,
userId: user_id,
deviceId: device_id,

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -41,7 +41,7 @@ limitations under the License.
.copyButton {
padding: 7px 15px;
border-radius: 8px;
font-size: 14px;
font-size: var(--font-size-body);
font-weight: 700;
}
@@ -142,7 +142,7 @@ limitations under the License.
.copyButton span {
font-weight: 600;
font-size: 15px;
font-size: var(--font-size-body);
margin-right: 10px;
overflow: hidden;
white-space: nowrap;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -48,6 +48,7 @@ export function CopyButton({
className={className}
onPress={setCopied}
iconStyle={isCopied ? "stroke" : "fill"}
aria-label={t("Copy")}
>
{isCopied ? (
<>

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

77
src/config/Config.ts Normal file
View File

@@ -0,0 +1,77 @@
/*
Copyright 2021-2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import {
DEFAULT_CONFIG,
ConfigOptions,
ResolvedConfigOptions,
} from "./ConfigOptions";
export class Config {
private static internalInstance: Config;
public static get(): ConfigOptions {
if (!this.internalInstance?.config)
throw new Error("Config instance read before config got initialized");
return this.internalInstance.config;
}
public static init(): Promise<void> {
if (Config.internalInstance?.initPromise) {
return Config.internalInstance.initPromise;
}
Config.internalInstance = new Config();
Config.internalInstance.initPromise = new Promise<void>((resolve) => {
downloadConfig("../config.json").then((config) => {
Config.internalInstance.config = { ...DEFAULT_CONFIG, ...config };
resolve();
});
});
return Config.internalInstance.initPromise;
}
// Convenience accessors
public static defaultHomeserverUrl(): string | undefined {
return Config.get().default_server_config["m.homeserver"].base_url;
}
public static defaultServerName(): string | undefined {
return Config.get().default_server_config["m.homeserver"].server_name;
}
public config?: ResolvedConfigOptions;
private initPromise?: Promise<void>;
}
async function downloadConfig(
configJsonFilename: string
): Promise<ConfigOptions> {
const url = new URL(configJsonFilename, window.location.href);
url.searchParams.set("cachebuster", Date.now().toString());
const res = await fetch(url, {
cache: "no-cache",
method: "GET",
});
if (!res.ok || res.status === 404 || res.status === 0) {
// Lack of a config isn't an error, we should just use the defaults.
// Also treat a blank config as no config, assuming the status code is 0, because we don't get 404s from file:
// URIs so this is the only way we can not fail if the file doesn't exist when loading from a file:// URI.
return DEFAULT_CONFIG;
}
return res.json();
}

View File

@@ -0,0 +1,75 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export interface ConfigOptions {
/**
* The Posthog endpoint to which analytics data will be sent.
*/
posthog?: {
api_key: string;
api_host: string;
};
/**
* The Sentry endpoint to which crash data will be sent.
*/
sentry?: {
DSN: string;
environment: string;
};
/**
* The rageshake server to which feedback and debug logs will be sent.
*/
rageshake?: {
submit_url: string;
};
// Describes the default homeserver to use. The same format as Element Web
// (without identity servers as we don't use them).
default_server_config?: {
["m.homeserver"]: {
base_url: string;
server_name: string;
};
};
/**
* Allow to join a group calls without audio and video.
* TEMPORARY: Is a feature that's not proved and experimental
*/
features?: {
feature_group_calls_without_video_and_audio: boolean;
};
}
// Overrides members from ConfigOptions that are always provided by the
// default config and are therefore non-optional.
export interface ResolvedConfigOptions extends ConfigOptions {
default_server_config: {
["m.homeserver"]: {
base_url: string;
server_name: string;
};
};
}
export const DEFAULT_CONFIG: ResolvedConfigOptions = {
default_server_config: {
["m.homeserver"]: {
base_url: "http://localhost:8008",
server_name: "localhost",
},
},
};

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.form {
display: flex;
flex-direction: column;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.callTileSpacer,
.callTile {
width: 329px;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -92,7 +92,7 @@ function CallTile({
<Facepile
className={styles.facePile}
client={client}
participants={participants}
members={participants}
/>
)}
</div>

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.label {
margin-bottom: 0;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.buttons {
margin-bottom: 0;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ import styles from "./JoinExistingCallModal.module.css";
interface Props {
onJoin: (e: PressEvent) => void;
onClose: (e: PressEvent) => void;
onClose: () => void;
// TODO: add used parameters for <Modal>
[index: string]: unknown;
}
@@ -33,7 +33,12 @@ export function JoinExistingCallModal({ onJoin, onClose, ...rest }: Props) {
const { t } = useTranslation();
return (
<Modal title={t("Join existing call?")} isDismissable {...rest}>
<Modal
title={t("Join existing call?")}
isDismissable
{...rest}
onClose={onClose}
>
<ModalContent>
<p>{t("This call already exists, would you like to join?")}</p>
<FieldRow rightAlign className={styles.buttons}>

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.form {
padding: 0 24px;
justify-content: center;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,7 +24,11 @@ import { useHistory } from "react-router-dom";
import { MatrixClient } from "matrix-js-sdk/src/client";
import { useTranslation } from "react-i18next";
import { createRoom, roomAliasLocalpartFromRoomName } from "../matrix-utils";
import {
createRoom,
roomAliasLocalpartFromRoomName,
sanitiseRoomNameInput,
} from "../matrix-utils";
import { useGroupCallRooms } from "./useGroupCallRooms";
import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
import commonStyles from "./common.module.css";
@@ -38,6 +42,8 @@ import { JoinExistingCallModal } from "./JoinExistingCallModal";
import { Title } from "../typography/Typography";
import { Form } from "../form/Form";
import { CallType, CallTypeDropdown } from "./CallTypeDropdown";
import { useOptInAnalytics } from "../settings/useSetting";
import { optInDescription } from "../analytics/AnalyticsOptInDescription";
interface Props {
client: MatrixClient;
@@ -48,6 +54,7 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
const [callType, setCallType] = useState(CallType.Video);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error>();
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
const history = useHistory();
const { t } = useTranslation();
const { modalState, modalProps } = useModalTriggerState();
@@ -57,7 +64,10 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
e.preventDefault();
const data = new FormData(e.target as HTMLFormElement);
const roomNameData = data.get("callName");
const roomName = typeof roomNameData === "string" ? roomNameData : "";
const roomName =
typeof roomNameData === "string"
? sanitiseRoomNameInput(roomNameData)
: "";
const ptt = callType === CallType.Radio;
async function submit() {
@@ -134,6 +144,15 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
{loading ? t("Loading…") : t("Go")}
</Button>
</FieldRow>
<InputField
id="optInAnalytics"
type="checkbox"
checked={optInAnalytics}
description={optInDescription()}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setOptInAnalytics(event.target.checked)
}
/>
{error && (
<FieldRow className={styles.fieldRow}>
<ErrorMessage error={error} />

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.footer {
display: flex;
flex-direction: column;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2022 Matrix.org Foundation C.I.C.
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,7 +24,11 @@ import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
import { UserMenuContainer } from "../UserMenuContainer";
import { FieldRow, InputField, ErrorMessage } from "../input/Input";
import { Button } from "../button";
import { createRoom, roomAliasLocalpartFromRoomName } from "../matrix-utils";
import {
createRoom,
roomAliasLocalpartFromRoomName,
sanitiseRoomNameInput,
} from "../matrix-utils";
import { useInteractiveRegistration } from "../auth/useInteractiveRegistration";
import { useModalTriggerState } from "../Modal";
import { JoinExistingCallModal } from "./JoinExistingCallModal";
@@ -35,12 +39,15 @@ import { CallType, CallTypeDropdown } from "./CallTypeDropdown";
import styles from "./UnauthenticatedView.module.css";
import commonStyles from "./common.module.css";
import { generateRandomName } from "../auth/generateRandomName";
import { useOptInAnalytics } from "../settings/useSetting";
import { optInDescription } from "../analytics/AnalyticsOptInDescription";
export const UnauthenticatedView: FC = () => {
const { setClient } = useClient();
const [callType, setCallType] = useState(CallType.Video);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error>();
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
const [privacyPolicyUrl, recaptchaKey, register] =
useInteractiveRegistration();
const { execute, reset, recaptchaId } = useRecaptcha(recaptchaKey);
@@ -54,7 +61,7 @@ export const UnauthenticatedView: FC = () => {
(e) => {
e.preventDefault();
const data = new FormData(e.target as HTMLFormElement);
const roomName = data.get("callName") as string;
const roomName = sanitiseRoomNameInput(data.get("callName") as string);
const displayName = data.get("displayName") as string;
const ptt = callType === CallType.Radio;
@@ -148,6 +155,15 @@ export const UnauthenticatedView: FC = () => {
autoComplete="off"
/>
</FieldRow>
<InputField
id="optInAnalytics"
type="checkbox"
checked={optInAnalytics}
description={optInDescription()}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setOptInAnalytics(event.target.checked)
}
/>
<Caption>
<Trans>
By clicking "Go", you agree to our{" "}

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.container {
display: flex;
min-height: calc(100% - 64px);

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