WIP
This commit is contained in:
parent
122ffeeab5
commit
d5e638c8f7
5 changed files with 121 additions and 30 deletions
|
|
@ -39,6 +39,7 @@
|
||||||
"color-hash": "^2.0.1",
|
"color-hash": "^2.0.1",
|
||||||
"events": "^3.3.0",
|
"events": "^3.3.0",
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#ebcb26f1b3b9e2d709615fde03f9ce6ac77871f1",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#ebcb26f1b3b9e2d709615fde03f9ce6ac77871f1",
|
||||||
|
"matrix-widget-api": "^0.1.0-beta.18",
|
||||||
"mermaid": "^8.13.8",
|
"mermaid": "^8.13.8",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"pako": "^2.0.4",
|
"pako": "^2.0.4",
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,10 @@ import React, {
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import { MatrixClient, ClientEvent } from "matrix-js-sdk/src/client";
|
import { MatrixClient, ClientEvent } from "matrix-js-sdk/src/client";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
import { ErrorView } from "./FullScreenView";
|
import { ErrorView } from "./FullScreenView";
|
||||||
import { initClient, defaultHomeserver } from "./matrix-utils";
|
import { initClient, initMatroskaClient, defaultHomeserver } from "./matrix-utils";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
|
@ -86,9 +87,23 @@ export const ClientProvider: FC = ({ children }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const restore = async (): Promise<
|
const init = async (): Promise<
|
||||||
Pick<ClientProviderState, "client" | "isPasswordlessUser">
|
Pick<ClientProviderState, "client" | "isPasswordlessUser">
|
||||||
> => {
|
> => {
|
||||||
|
const query = new URLSearchParams(window.location.search);
|
||||||
|
const widgetId = query.get("widgetId");
|
||||||
|
const parentUrl = query.get("parentUrl");
|
||||||
|
|
||||||
|
if (widgetId && parentUrl) {
|
||||||
|
// We're inside a widget, so let's engage *Matroska mode*
|
||||||
|
logger.log("Using a Matroska client");
|
||||||
|
|
||||||
|
return {
|
||||||
|
client: await initMatroskaClient(widgetId, parentUrl),
|
||||||
|
isPasswordlessUser: false,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// We're running as a standalone application
|
||||||
try {
|
try {
|
||||||
const session = loadSession();
|
const session = loadSession();
|
||||||
|
|
||||||
|
|
@ -97,6 +112,7 @@ export const ClientProvider: FC = ({ children }) => {
|
||||||
const { user_id, device_id, access_token, passwordlessUser } =
|
const { user_id, device_id, access_token, passwordlessUser } =
|
||||||
session;
|
session;
|
||||||
|
|
||||||
|
logger.log("Using a standalone client");
|
||||||
const client = await initClient({
|
const client = await initClient({
|
||||||
baseUrl: defaultHomeserver,
|
baseUrl: defaultHomeserver,
|
||||||
accessToken: access_token,
|
accessToken: access_token,
|
||||||
|
|
@ -110,13 +126,13 @@ export const ClientProvider: FC = ({ children }) => {
|
||||||
|
|
||||||
return { client: undefined, isPasswordlessUser: false };
|
return { client: undefined, isPasswordlessUser: false };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
|
||||||
clearSession();
|
clearSession();
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
restore()
|
init()
|
||||||
.then(({ client, isPasswordlessUser }) => {
|
.then(({ client, isPasswordlessUser }) => {
|
||||||
setState({
|
setState({
|
||||||
client,
|
client,
|
||||||
|
|
@ -126,7 +142,8 @@ export const ClientProvider: FC = ({ children }) => {
|
||||||
userName: client?.getUserIdLocalpart(),
|
userName: client?.getUserIdLocalpart(),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch((err) => {
|
||||||
|
logger.error(err);
|
||||||
setState({
|
setState({
|
||||||
client: undefined,
|
client: undefined,
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,17 @@ import { MemoryStore } from "matrix-js-sdk/src/store/memory";
|
||||||
import { IndexedDBCryptoStore } from "matrix-js-sdk/src/crypto/store/indexeddb-crypto-store";
|
import { IndexedDBCryptoStore } from "matrix-js-sdk/src/crypto/store/indexeddb-crypto-store";
|
||||||
import { LocalStorageCryptoStore } from "matrix-js-sdk/src/crypto/store/localStorage-crypto-store";
|
import { LocalStorageCryptoStore } from "matrix-js-sdk/src/crypto/store/localStorage-crypto-store";
|
||||||
import { MemoryCryptoStore } from "matrix-js-sdk/src/crypto/store/memory-crypto-store";
|
import { MemoryCryptoStore } from "matrix-js-sdk/src/crypto/store/memory-crypto-store";
|
||||||
import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
|
import { createClient, createRoomWidgetClient, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||||
import { ICreateClientOpts } from "matrix-js-sdk/src/matrix";
|
import { ICreateClientOpts } from "matrix-js-sdk/src/matrix";
|
||||||
import { ClientEvent } from "matrix-js-sdk/src/client";
|
import { ClientEvent } from "matrix-js-sdk/src/client";
|
||||||
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
import { Visibility, Preset } from "matrix-js-sdk/src/@types/partials";
|
import { Visibility, Preset } from "matrix-js-sdk/src/@types/partials";
|
||||||
import {
|
import {
|
||||||
GroupCallIntent,
|
GroupCallIntent,
|
||||||
GroupCallType,
|
GroupCallType,
|
||||||
} from "matrix-js-sdk/src/webrtc/groupCall";
|
} from "matrix-js-sdk/src/webrtc/groupCall";
|
||||||
import { ISyncStateData, SyncState } from "matrix-js-sdk/src/sync";
|
import { ISyncStateData, SyncState } from "matrix-js-sdk/src/sync";
|
||||||
|
import { WidgetApi } from "matrix-widget-api";
|
||||||
|
|
||||||
import IndexedDBWorker from "./IndexedDBWorker?worker";
|
import IndexedDBWorker from "./IndexedDBWorker?worker";
|
||||||
|
|
||||||
|
|
@ -42,6 +44,63 @@ function waitForSync(client: MatrixClient) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The event types that the app needs to be able to send/receive in Matroska
|
||||||
|
// mode in order to function
|
||||||
|
const SEND_RECV_STATE = [
|
||||||
|
{ eventType: EventType.RoomMember },
|
||||||
|
{ eventType: EventType.GroupCallPrefix },
|
||||||
|
{ eventType: EventType.GroupCallMemberPrefix },
|
||||||
|
];
|
||||||
|
const SEND_RECV_TO_DEVICE = [
|
||||||
|
EventType.CallInvite,
|
||||||
|
EventType.CallCandidates,
|
||||||
|
EventType.CallAnswer,
|
||||||
|
EventType.CallHangup,
|
||||||
|
EventType.CallReject,
|
||||||
|
EventType.CallSelectAnswer,
|
||||||
|
EventType.CallNegotiate,
|
||||||
|
EventType.CallSDPStreamMetadataChanged,
|
||||||
|
EventType.CallSDPStreamMetadataChangedPrefix,
|
||||||
|
EventType.CallReplaces,
|
||||||
|
"org.matrix.call_duplicate_session",
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function initMatroskaClient(
|
||||||
|
widgetId: string, parentUrl: string,
|
||||||
|
): Promise<MatrixClient> {
|
||||||
|
// In this mode, we use a special client which routes all requests through
|
||||||
|
// the host application via the widget API
|
||||||
|
|
||||||
|
// The rest of the data we need is encoded in the fragment so as to avoid
|
||||||
|
// leaking it to the server
|
||||||
|
const fragmentQueryStart = window.location.hash.indexOf("?");
|
||||||
|
const roomId = window.location.hash.substring(0, fragmentQueryStart);
|
||||||
|
const fragmentQuery = new URLSearchParams(window.location.hash.substring(fragmentQueryStart));
|
||||||
|
|
||||||
|
// Since all data should be coming from the host application, there's no
|
||||||
|
// need to persist anything, and therefore we can use the default stores
|
||||||
|
// We don't even need to set up crypto!
|
||||||
|
const client = createRoomWidgetClient(
|
||||||
|
new WidgetApi(widgetId, new URL(parentUrl).origin),
|
||||||
|
{
|
||||||
|
sendState: SEND_RECV_STATE,
|
||||||
|
receiveState: SEND_RECV_STATE,
|
||||||
|
sendToDevice: SEND_RECV_TO_DEVICE,
|
||||||
|
receiveToDevice: SEND_RECV_TO_DEVICE,
|
||||||
|
},
|
||||||
|
roomId,
|
||||||
|
{
|
||||||
|
baseUrl: "",
|
||||||
|
userId: fragmentQuery.get("userId"),
|
||||||
|
deviceId: fragmentQuery.get("deviceId"),
|
||||||
|
timelineSupport: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await client.startClient();
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
export async function initClient(
|
export async function initClient(
|
||||||
clientOptions: ICreateClientOpts
|
clientOptions: ICreateClientOpts
|
||||||
): Promise<MatrixClient> {
|
): Promise<MatrixClient> {
|
||||||
|
|
@ -83,7 +142,7 @@ export async function initClient(
|
||||||
...storeOpts,
|
...storeOpts,
|
||||||
...clientOptions,
|
...clientOptions,
|
||||||
useAuthorizationHeader: true,
|
useAuthorizationHeader: true,
|
||||||
// Use a relatively low timeout for API calls: this is a realtime application
|
// Use a relatively low timeout for API calls: this is a realtime app
|
||||||
// so we don't want API calls taking ages, we'd rather they just fail.
|
// so we don't want API calls taking ages, we'd rather they just fail.
|
||||||
localTimeoutMs: 5000,
|
localTimeoutMs: 5000,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ async function fetchGroupCall(
|
||||||
viaServers = undefined,
|
viaServers = undefined,
|
||||||
timeout = 5000
|
timeout = 5000
|
||||||
) {
|
) {
|
||||||
const { roomId } = await client.joinRoom(roomIdOrAlias, { viaServers });
|
//const { roomId } = await client.joinRoom(roomIdOrAlias, { viaServers });
|
||||||
|
const roomId = roomIdOrAlias;
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let timeoutId;
|
let timeoutId;
|
||||||
|
|
|
||||||
19
yarn.lock
19
yarn.lock
|
|
@ -2868,6 +2868,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
|
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
|
||||||
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
|
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
|
||||||
|
|
||||||
|
"@types/events@^3.0.0":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
||||||
|
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
|
||||||
|
|
||||||
"@types/glob@*", "@types/glob@^7.1.1", "@types/glob@^7.1.3":
|
"@types/glob@*", "@types/glob@^7.1.1", "@types/glob@^7.1.3":
|
||||||
version "7.2.0"
|
version "7.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
|
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
|
||||||
|
|
@ -8602,9 +8607,9 @@ matrix-events-sdk@^0.0.1-beta.7:
|
||||||
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz#5ffe45eba1f67cc8d7c2377736c728b322524934"
|
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz#5ffe45eba1f67cc8d7c2377736c728b322524934"
|
||||||
integrity sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA==
|
integrity sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA==
|
||||||
|
|
||||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#404f8e130e44a78b0159c55902df1b129b3816d1":
|
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#ebcb26f1b3b9e2d709615fde03f9ce6ac77871f1":
|
||||||
version "17.2.0"
|
version "18.1.0"
|
||||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/404f8e130e44a78b0159c55902df1b129b3816d1"
|
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/ebcb26f1b3b9e2d709615fde03f9ce6ac77871f1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.12.5"
|
"@babel/runtime" "^7.12.5"
|
||||||
another-json "^0.2.0"
|
another-json "^0.2.0"
|
||||||
|
|
@ -8618,6 +8623,14 @@ matrix-events-sdk@^0.0.1-beta.7:
|
||||||
request "^2.88.2"
|
request "^2.88.2"
|
||||||
unhomoglyph "^1.0.6"
|
unhomoglyph "^1.0.6"
|
||||||
|
|
||||||
|
matrix-widget-api@^0.1.0-beta.18:
|
||||||
|
version "0.1.0-beta.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-0.1.0-beta.18.tgz#4efd30edec3eeb4211285985464c062fcab59795"
|
||||||
|
integrity sha512-kCpcs6rrB94Mmr2/1gBJ+6auWyZ5UvOMOn5K2VFafz2/NDMzZg9OVWj9KFYnNAuwwBE5/tCztYEj6OQ+hgbwOQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/events" "^3.0.0"
|
||||||
|
events "^3.2.0"
|
||||||
|
|
||||||
md5.js@^1.3.4:
|
md5.js@^1.3.4:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
|
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue