Merge branch 'main' into big-grid
This commit is contained in:
commit
59f3b05c07
9 changed files with 126 additions and 11 deletions
|
@ -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).
|
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).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
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).
|
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
|
## Host it yourself
|
||||||
|
|
BIN
demo.jpg
Normal file
BIN
demo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 179 KiB |
|
@ -46,7 +46,7 @@
|
||||||
"i18next-browser-languagedetector": "^6.1.8",
|
"i18next-browser-languagedetector": "^6.1.8",
|
||||||
"i18next-http-backend": "^1.4.4",
|
"i18next-http-backend": "^1.4.4",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#7b10fa367df357b51c2e78e220d39e5e7967f9e3",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#64197bf4db6486d77708125d7fb2e8d7fe001f14",
|
||||||
"matrix-widget-api": "^1.0.0",
|
"matrix-widget-api": "^1.0.0",
|
||||||
"mermaid": "^8.13.8",
|
"mermaid": "^8.13.8",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
|
|
|
@ -1 +1,95 @@
|
||||||
{}
|
{
|
||||||
|
"{{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.": "通話に参加する場合、カメラ・マイクの許可が必要です。",
|
||||||
|
"Allow analytics": "アナリティクスを許可",
|
||||||
|
"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": "音声",
|
||||||
|
"Advanced": "高度",
|
||||||
|
"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": "トランシーバー通話"
|
||||||
|
}
|
||||||
|
|
|
@ -211,6 +211,12 @@ export function fullAliasFromRoomName(
|
||||||
return `#${roomAliasLocalpartFromRoomName(roomName)}:${client.getDomain()}`;
|
return `#${roomAliasLocalpartFromRoomName(roomName)}:${client.getDomain()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XXX: What is this trying to do? It looks like it's getting the localpart from
|
||||||
|
* a room alias, but why is it splitting on hyphens and then putting spaces in??
|
||||||
|
* @param roomId
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function roomNameFromRoomId(roomId: string): string {
|
export function roomNameFromRoomId(roomId: string): string {
|
||||||
return roomId
|
return roomId
|
||||||
.match(/([^:]+):.*$/)[1]
|
.match(/([^:]+):.*$/)[1]
|
||||||
|
|
|
@ -50,9 +50,9 @@ export const RoomPage: FC = () => {
|
||||||
const [isRegistering, setIsRegistering] = useState(false);
|
const [isRegistering, setIsRegistering] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// If we're not already authed and we've been given a display name as
|
// If we've finished loading, are not already authed and we've been given a display name as
|
||||||
// a URL param, automatically register a passwordless user
|
// a URL param, automatically register a passwordless user
|
||||||
if (!isAuthenticated && displayName) {
|
if (!loading && !isAuthenticated && displayName) {
|
||||||
setIsRegistering(true);
|
setIsRegistering(true);
|
||||||
registerPasswordlessUser(displayName).finally(() => {
|
registerPasswordlessUser(displayName).finally(() => {
|
||||||
setIsRegistering(false);
|
setIsRegistering(false);
|
||||||
|
@ -63,6 +63,7 @@ export const RoomPage: FC = () => {
|
||||||
displayName,
|
displayName,
|
||||||
setIsRegistering,
|
setIsRegistering,
|
||||||
registerPasswordlessUser,
|
registerPasswordlessUser,
|
||||||
|
loading,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const groupCallView = useCallback(
|
const groupCallView = useCallback(
|
||||||
|
|
|
@ -52,12 +52,22 @@ export const useLoadGroupCall = (
|
||||||
|
|
||||||
const fetchOrCreateRoom = async (): Promise<Room> => {
|
const fetchOrCreateRoom = async (): Promise<Room> => {
|
||||||
try {
|
try {
|
||||||
const room = await client.joinRoom(roomIdOrAlias, { viaServers });
|
// We lowercase the localpart when we create the room, so we must lowercase
|
||||||
|
// it here too (we just do the whole alias). We can't do the same to room IDs
|
||||||
|
// though.
|
||||||
|
const sanitisedIdOrAlias =
|
||||||
|
roomIdOrAlias[0] === "#"
|
||||||
|
? roomIdOrAlias.toLowerCase()
|
||||||
|
: roomIdOrAlias;
|
||||||
|
|
||||||
|
const room = await client.joinRoom(sanitisedIdOrAlias, {
|
||||||
|
viaServers,
|
||||||
|
});
|
||||||
logger.info(
|
logger.info(
|
||||||
`Joined ${roomIdOrAlias}, waiting room to be ready for group calls`
|
`Joined ${sanitisedIdOrAlias}, waiting room to be ready for group calls`
|
||||||
);
|
);
|
||||||
await client.waitUntilRoomReadyForGroupCalls(room.roomId);
|
await client.waitUntilRoomReadyForGroupCalls(room.roomId);
|
||||||
logger.info(`${roomIdOrAlias}, is ready for group calls`);
|
logger.info(`${sanitisedIdOrAlias}, is ready for group calls`);
|
||||||
return room;
|
return room;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -113,12 +113,14 @@ export const usePTT = (
|
||||||
},
|
},
|
||||||
setState,
|
setState,
|
||||||
] = useState(() => {
|
] = useState(() => {
|
||||||
|
// slightly concerningly, this can end up null as we seem to sometimes get
|
||||||
|
// here before the room state contains our own member event
|
||||||
const roomMember = groupCall.room.getMember(client.getUserId());
|
const roomMember = groupCall.room.getMember(client.getUserId());
|
||||||
|
|
||||||
const activeSpeakerFeed = getActiveSpeakerFeed(userMediaFeeds, groupCall);
|
const activeSpeakerFeed = getActiveSpeakerFeed(userMediaFeeds, groupCall);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isAdmin: roomMember.powerLevel >= 100,
|
isAdmin: roomMember ? roomMember.powerLevel >= 100 : false,
|
||||||
talkOverEnabled: false,
|
talkOverEnabled: false,
|
||||||
pttButtonHeld: false,
|
pttButtonHeld: false,
|
||||||
activeSpeakerUserId: activeSpeakerFeed ? activeSpeakerFeed.userId : null,
|
activeSpeakerUserId: activeSpeakerFeed ? activeSpeakerFeed.userId : null,
|
||||||
|
|
|
@ -10362,9 +10362,9 @@ matrix-events-sdk@0.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd"
|
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd"
|
||||||
integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==
|
integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==
|
||||||
|
|
||||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#7b10fa367df357b51c2e78e220d39e5e7967f9e3":
|
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#64197bf4db6486d77708125d7fb2e8d7fe001f14":
|
||||||
version "23.0.0"
|
version "23.1.1"
|
||||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/7b10fa367df357b51c2e78e220d39e5e7967f9e3"
|
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/64197bf4db6486d77708125d7fb2e8d7fe001f14"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.12.5"
|
"@babel/runtime" "^7.12.5"
|
||||||
"@matrix-org/matrix-sdk-crypto-js" "^0.1.0-alpha.2"
|
"@matrix-org/matrix-sdk-crypto-js" "^0.1.0-alpha.2"
|
||||||
|
|
Loading…
Add table
Reference in a new issue