From 1ad11ed25fa55fc00db7c0c21e7438d6d54ec001 Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Mon, 17 Aug 2020 17:48:13 +0100 Subject: [PATCH] Implement minimum amount for a working matrix.to --- package.json | 3 + src/App.tsx | 30 ++++- src/clients/Element.io.ts | 53 ++++++++ src/clients/element.svg | 6 + src/clients/index.ts | 29 ++++ src/clients/types.ts | 82 ++++++++++++ src/components/Avatar.stories.tsx | 1 + src/components/Avatar.tsx | 26 ++-- src/components/Button.stories.tsx | 2 +- src/components/CreateLinkTile.stories.tsx | 2 +- src/components/CreateLinkTile.tsx | 14 +- src/components/EventPreview.tsx | 3 +- src/components/Input.stories.tsx | 4 +- src/components/InviteTile.stories.tsx | 55 ++++---- src/components/InviteTile.tsx | 35 ++--- src/components/LinkPreview.tsx | 126 ++++++++++++++++++ src/components/MatrixTile.stories.tsx | 2 +- src/components/RoomPreview.tsx | 4 +- src/components/TextButton.stories.tsx | 4 +- src/components/Tile.stories.tsx | 2 +- src/components/UserPreview.tsx | 6 +- src/contexts/ClientContext.ts | 9 +- src/index.scss | 2 + src/pages/LinkRouter.tsx | 50 +++++++ src/parser/parser.ts | 6 +- src/parser/types.ts | 3 +- src/utils/cypher-wrapper.ts | 88 ++++++++++++ yarn.lock | 155 ++++++++++++++++++++-- 28 files changed, 703 insertions(+), 99 deletions(-) create mode 100644 src/clients/Element.io.ts create mode 100644 src/clients/element.svg create mode 100644 src/clients/index.ts create mode 100644 src/clients/types.ts create mode 100644 src/components/LinkPreview.tsx create mode 100644 src/pages/LinkRouter.tsx create mode 100644 src/utils/cypher-wrapper.ts diff --git a/package.json b/package.json index b128806..32e1186 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "classnames": "^2.2.6", "formik": "^2.1.4", + "matrix-cypher": "^0.1.12", "react": "^16.13.1", "react-dom": "^16.13.1", "react-scripts": "3.4.1", @@ -67,12 +68,14 @@ "@types/node": "^12.0.0", "@types/react": "^16.9.0", "@types/react-dom": "^16.9.0", + "@types/react-router-dom": "^5.1.5", "@types/yup": "^0.29.3", "eslint-config-matrix-org": "^0.1.0", "husky": "^4.2.5", "lint-staged": "^10.2.7", "node-sass": "^4.14.1", "prettier": "^2.0.5", + "react-router-dom": "^5.2.0", "storybook-addon-designs": "^5.4.0", "ts-jest": "^26.1.4", "typescript": "~3.7.2" diff --git a/src/App.tsx b/src/App.tsx index f44cfa3..748d405 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,18 +15,42 @@ limitations under the License. */ import React from "react"; -import "./App.scss"; import SingleColumn from "./layouts/SingleColumn"; import CreateLinkTile from "./components/CreateLinkTile"; import MatrixTile from "./components/MatrixTile"; +import Tile from "./components/Tile"; +import LinkRouter from "./pages/LinkRouter"; + +import "./App.scss"; + +/* eslint-disable no-restricted-globals */ const App: React.FC = () => { + let page = ( + <> +
{" "} + + ); + if (location.hash) { + console.log(location.hash); + if (location.hash.startsWith("#/")) { + page = ; + } else { + console.log("asdfadf"); + page = ( + + Links should be in the format {location.host}/#/{"<"} + matrix-resource-identifier{">"} + + ); + } + } + return (
- -
+ {page}
diff --git a/src/clients/Element.io.ts b/src/clients/Element.io.ts new file mode 100644 index 0000000..015c31d --- /dev/null +++ b/src/clients/Element.io.ts @@ -0,0 +1,53 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +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 { LinkedClient, Maturity, ClientKind } from "./types"; +import { LinkKind } from "../parser/types"; +import logo from "./element.svg"; + +const Element: LinkedClient = { + kind: ClientKind.LINKED_CLIENT, + name: "Element", + author: "Element", + logo: logo, + homepage: "https://element.io", + maturity: Maturity.STABLE, + description: "Fully-featured Matrix client for the Web", + tags: [], + toUrl: (link) => { + switch (link.kind) { + case LinkKind.Alias: + case LinkKind.RoomId: + return new URL( + `https://app.element.io/#/room/${link.identifier}` + ); + case LinkKind.UserId: + return new URL( + `https://app.element.io/#/user/${link.identifier}` + ); + case LinkKind.Permalink: + return new URL( + `https://app.element.io/#/room/${link.identifier}` + ); + case LinkKind.GroupId: + return new URL( + `https://app.element.io/#/group/${link.identifier}` + ); + } + }, +}; + +export default Element; diff --git a/src/clients/element.svg b/src/clients/element.svg new file mode 100644 index 0000000..95ecfa1 --- /dev/null +++ b/src/clients/element.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/clients/index.ts b/src/clients/index.ts new file mode 100644 index 0000000..ac67755 --- /dev/null +++ b/src/clients/index.ts @@ -0,0 +1,29 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +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 { Client } from "./types"; + +import Element from "./Element.io"; + +/* + * All the supported clients of matrix.to + */ +const clients: Client[] = [Element]; + +/* + * All the supported clients of matrix.to + */ +export default clients; diff --git a/src/clients/types.ts b/src/clients/types.ts new file mode 100644 index 0000000..4d21ac4 --- /dev/null +++ b/src/clients/types.ts @@ -0,0 +1,82 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +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 { SafeLink } from "../parser/types"; + +/* + * A collection of descriptive tags that can be added to + * a clients description. + */ +export enum Tag { + IOS = "IOS", + ANDROID = "ANDROID", + DESKTOP = "DESKTOP", +} + +/* + * A collection of states used for describing a clients maturity. + */ +export enum Maturity { + ALPHA = "ALPHA", + LATE_ALPHA = "LATE ALPHA", + BETA = "BETA", + LATE_BETA = "LATE_BETA", + STABLE = "STABLE", +} + +/* + * Used for constructing the discriminated union of all client types. + */ +export enum ClientKind { + LINKED_CLIENT = "LINKED_CLIENT", + TEXT_CLIENT = "TEXT_CLIENT", +} + +/* + * The descriptive details of a client + */ +export interface ClientDescription { + name: string; + author: string; + homepage: string; + logo: string; + description: string; + tags: Tag[]; + maturity: Maturity; +} + +/* + * A client which can be opened using a link with the matrix resource. + */ +export interface LinkedClient extends ClientDescription { + kind: ClientKind.LINKED_CLIENT; + toUrl(parsedLink: SafeLink): URL; +} + +/* + * A client which provides isntructions for how to access the descired + * resource. + */ +export interface TextClient extends ClientDescription { + kind: ClientKind.TEXT_CLIENT; + toInviteString(parsedLink: SafeLink): string; +} + +/* + * A description for a client as well as a method for converting matrix.to + * links to the client's specific representation. + */ +export type Client = LinkedClient | TextClient; diff --git a/src/components/Avatar.stories.tsx b/src/components/Avatar.stories.tsx index d586c6f..2a8de36 100644 --- a/src/components/Avatar.stories.tsx +++ b/src/components/Avatar.stories.tsx @@ -35,5 +35,6 @@ export const Default: React.FC<{}> = () => ( avatar_url: "mxc://matrix.org/EqMZYbAYhREvHXvYFyfxOlkf", displayname: "Jorik Schellekens", }} + userId="@jorik:matrix.org" /> ); diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 1a73b9f..5651cc6 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -16,9 +16,9 @@ limitations under the License. import React, { useEffect, useState } from "react"; import classNames from "classnames"; -import { convertMXCtoMediaQuery } from "cypher"; -import { Room } from "cypher/src/schemas/PublicRoomsSchema"; -import { User } from "cypher/src/schemas/UserSchema"; +import { Room, User } from "matrix-cypher"; + +import { convertMXCtoMediaQuery } from "../utils/cypher-wrapper"; import logo from "../imgs/matrix-logo.svg"; import "./Avatar.scss"; @@ -38,7 +38,7 @@ const Avatar: React.FC = ({ className, avatarUrl, label }: IProps) => { return ( setSrc(logo)} + onError={(): void => setSrc(logo)} alt={label} className={classNames("avatar", className)} /> @@ -47,18 +47,24 @@ const Avatar: React.FC = ({ className, avatarUrl, label }: IProps) => { interface IPropsUserAvatar { user: User; + userId: string; } export const UserAvatar: React.FC = ({ user, + userId, }: IPropsUserAvatar) => ( ); @@ -74,7 +80,7 @@ export const RoomAvatar: React.FC = ({ room.avatar_url ? convertMXCtoMediaQuery( // TODO: replace with correct client - "matrix.org", + "https://matrix.org", room.avatar_url ) : "" diff --git a/src/components/Button.stories.tsx b/src/components/Button.stories.tsx index 2699e27..2514b6d 100644 --- a/src/components/Button.stories.tsx +++ b/src/components/Button.stories.tsx @@ -22,7 +22,7 @@ import Button from "./Button"; export default { title: "Button" }; -export const WithText = () => ( +export const WithText: React.FC = () => ( diff --git a/src/components/CreateLinkTile.stories.tsx b/src/components/CreateLinkTile.stories.tsx index cc71fc3..f247506 100644 --- a/src/components/CreateLinkTile.stories.tsx +++ b/src/components/CreateLinkTile.stories.tsx @@ -29,4 +29,4 @@ export default { }, }; -export const Default = () => ; +export const Default: React.FC = () => ; diff --git a/src/components/CreateLinkTile.tsx b/src/components/CreateLinkTile.tsx index aed0f60..4d557e7 100644 --- a/src/components/CreateLinkTile.tsx +++ b/src/components/CreateLinkTile.tsx @@ -28,7 +28,9 @@ interface ILinkNotCreatedTileProps { setLink: React.Dispatch>; } -const LinkNotCreatedTile = (props: ILinkNotCreatedTileProps) => { +const LinkNotCreatedTile: React.FC = ( + props: ILinkNotCreatedTileProps +) => { return (

@@ -48,7 +50,7 @@ const LinkNotCreatedTile = (props: ILinkNotCreatedTileProps) => { ) .required("Required"), })} - onSubmit={(values) => { + onSubmit={(values): void => { props.setLink( document.location.protocol + "//" + @@ -80,7 +82,7 @@ const LinkCreatedTile: React.FC = (props) => { const buttonRef = useRef(null); // Focus button on render - useEffect(() => { + useEffect((): void => { if (buttonRef && buttonRef.current) { buttonRef.current.focus(); } @@ -88,13 +90,15 @@ const LinkCreatedTile: React.FC = (props) => { return ( - props.setLink("")}> + props.setLink("")}> Create another lnk

{props.link}

{userId}

- +
); diff --git a/src/contexts/ClientContext.ts b/src/contexts/ClientContext.ts index 0b14e47..95cb97e 100644 --- a/src/contexts/ClientContext.ts +++ b/src/contexts/ClientContext.ts @@ -16,8 +16,7 @@ limitations under the License. import React from "react"; -import { Client, discoverServer } from "cypher"; -import { prefixFetch } from "cypher/src/utils/fetch"; +import { prefixFetch, Client, discoverServer } from "matrix-cypher"; type State = { clientURL: string; @@ -62,4 +61,8 @@ export const reducer = async (state: State, action: Action): Promise => { // The null is a hack to make the type checker happy // create context does not need an argument -export default React.createContext(null); +const { Provider, Consumer } = React.createContext(null); + +// Quick rename to make importing easier +export const ClientProvider = Provider; +export const ClientConsumer = Consumer; diff --git a/src/index.scss b/src/index.scss index f65a37d..83fd0f2 100644 --- a/src/index.scss +++ b/src/index.scss @@ -38,6 +38,8 @@ body, line-height: 24px; color: $font; + + overflow: scroll; } h1 { diff --git a/src/pages/LinkRouter.tsx b/src/pages/LinkRouter.tsx new file mode 100644 index 0000000..827ff8f --- /dev/null +++ b/src/pages/LinkRouter.tsx @@ -0,0 +1,50 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +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 from "react"; + +import Tile from "../components/Tile"; +import LinkPreview from "../components/LinkPreview"; +import { parseHash } from "../parser/parser"; +import { LinkKind } from "../parser/types"; + +interface IProps { + link: string; +} + +const LinkRouter: React.FC = ({ link }: IProps) => { + // our room id's will be stored in the hash + const parsedLink = parseHash(link); + console.log({ link }); + + let feedback: JSX.Element; + switch (parsedLink.kind) { + case LinkKind.ParseFailed: + feedback = ( + +

Invalid matrix.to link

+

{link}

+
+ ); + break; + default: + feedback = ; + } + + return feedback; +}; + +export default LinkRouter; diff --git a/src/parser/parser.ts b/src/parser/parser.ts index 59a9a57..0eb01fa 100644 --- a/src/parser/parser.ts +++ b/src/parser/parser.ts @@ -20,7 +20,7 @@ export const roomVerifiers: Verifier[] = [ [/^!([^/:]+?):(.+)$/, LinkKind.RoomId], ]; export const verifiers: Verifier[] = [ - [/^[!#]([^/:]+?):(.+?)\/\$([^/:]+?):(.+?)$/, LinkKind.Permalink], + [/^[!#]([^/:]+?):(.+?)\/\$([^/:]+?)$/, LinkKind.Permalink], [/^@([^/:]+?):(.+)$/, LinkKind.UserId], [/^\+([^/:]+?):(.+)$/, LinkKind.GroupId], ...roomVerifiers, @@ -56,7 +56,9 @@ export function identifyTypeFromRegex( * Parses a permalink. * Assumes the permalink is correct. */ -export function parsePermalink(identifier: string): Permalink { +export function parsePermalink( + identifier: string +): Pick { const [roomLink, eventId] = identifier.split("/"); const roomKind = identifyTypeFromRegex( roomLink, diff --git a/src/parser/types.ts b/src/parser/types.ts index f4366e5..35c2d2a 100644 --- a/src/parser/types.ts +++ b/src/parser/types.ts @@ -49,6 +49,5 @@ export interface ParseFailed { originalLink: string; } +export type Link = Alias | RoomId | UserId | Permalink | GroupId | ParseFailed; export type SafeLink = Alias | RoomId | UserId | Permalink | GroupId; - -export type Link = SafeLink | ParseFailed; diff --git a/src/utils/cypher-wrapper.ts b/src/utils/cypher-wrapper.ts new file mode 100644 index 0000000..fba177b --- /dev/null +++ b/src/utils/cypher-wrapper.ts @@ -0,0 +1,88 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +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 { + Client, + getUserDetails as cGetUserDetails, + User, + getRoomDetails as cGetRoomDetails, + searchPublicRooms as cSearchPublicRooms, + Room, + convertMXCtoMediaQuery as cConvertMXCtoMediaQuery, + getRoomIdFromAlias as cGetRoomIdFromAlias, + RoomAlias, +} from "matrix-cypher"; + +/* + * Gets the details for a user + */ +export function getUserDetails(client: Client, userId: string): Promise { + return cGetUserDetails(client, userId).catch(() => ({ + displayname: userId, + })); +} + +function defaultRoom(roomId: string): Room { + return { + aliases: [roomId], + topic: "Unable to find room details.", + canonical_alias: roomId, + name: roomId, + num_joined_members: 0, + room_id: roomId, + guest_can_join: true, + avatar_url: "", + world_readable: false, + }; +} + +/* + * Gets the details of a room if that room is public + */ +export function getRoomDetails( + clients: Client[], + roomId: string +): Promise { + return cGetRoomDetails(clients, roomId).catch(() => defaultRoom(roomId)); +} + +/* + * Searches the public rooms of a homeserver for the metadata of a particular + */ +export function searchPublicRooms( + client: Client, + roomId: string +): Promise { + return cSearchPublicRooms(client, roomId).catch(() => defaultRoom(roomId)); +} + +export function convertMXCtoMediaQuery(clientURL: string, mxc: string): string { + try { + return cConvertMXCtoMediaQuery(clientURL, mxc); + } catch { + return ""; + } +} + +export function getRoomIdFromAlias( + client: Client, + roomAlias: string +): Promise { + return cGetRoomIdFromAlias(client, roomAlias).catch(() => ({ + room_id: roomAlias, + servers: [], + })); +} diff --git a/yarn.lock b/yarn.lock index 69d9523..280197a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2345,6 +2345,23 @@ dependencies: "@types/react" "*" +"@types/react-router-dom@^5.1.5": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.5.tgz#7c334a2ea785dbad2b2dcdd83d2cf3d9973da090" + integrity sha512-ArBM4B1g3BWLGbaGvwBGO75GNFbLDUthrDojV2vHLih/Tq8M+tgvY1DSwkuNrPSwdp/GUL93WSEpTZs8nVyJLw== + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.8.tgz#4614e5ba7559657438e17766bb95ef6ed6acc3fa" + integrity sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg== + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react-syntax-highlighter@11.0.4": version "11.0.4" resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz#d86d17697db62f98046874f62fdb3e53a0bbc4cd" @@ -4834,6 +4851,13 @@ create-react-context@0.3.0, create-react-context@^0.3.0: gud "^1.0.0" warning "^4.0.3" +cross-fetch@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.5.tgz#2739d2981892e7ab488a7ad03b92df2816e03f4c" + integrity sha512-FFLcLtraisj5eteosnX1gf01qYDCOc4fDy0+euOt8Kn9YBY2NtXL/pCoYPavw24NIQkQqm5ZOLsGD5Zzj0gyew== + dependencies: + node-fetch "2.6.0" + cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -5695,7 +5719,7 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0, es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5: +es-abstract@^1.17.0, es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5, es-abstract@^1.17.6: version "1.17.6" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== @@ -5712,6 +5736,17 @@ es-abstract@^1.17.0, es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es- string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" +es-aggregate-error@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/es-aggregate-error/-/es-aggregate-error-1.0.4.tgz#60662b73fddb1656e7bd6bd4285321406c567d2d" + integrity sha512-syuWJHsRD5TJ3nwqjf8eFEeGLJM6OxUjVFz0dMg2b/GB/Ub5VAFiQPEVB6ewdU2VHgkOJBo00uYwPmo7fyfzEg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.6" + function-bind "^1.1.1" + functions-have-names "^1.2.1" + globalthis "^1.0.1" + es-array-method-boxes-properly@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" @@ -6804,7 +6839,7 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -functions-have-names@^1.2.0: +functions-have-names@^1.2.0, functions-have-names@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.1.tgz#a981ac397fa0c9964551402cdc5533d7a4d52f91" integrity sha512-j48B/ZI7VKs3sgeI2cZp7WXWmZXu7Iq5pl5/vptV5N2mq+DGFuS/ulaDjtaoLpYzuD6u8UgrUKHfgo7fDTSiBA== @@ -6969,7 +7004,7 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" -globalthis@^1.0.0: +globalthis@^1.0.0, globalthis@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.1.tgz#40116f5d9c071f9e8fb0037654df1ab3a83b7ef9" integrity sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw== @@ -7174,6 +7209,18 @@ highlight.js@~9.13.0: resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== +history@^4.9.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" + integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^3.0.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^1.0.1" + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -7183,7 +7230,7 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.3.0: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -8031,6 +8078,11 @@ is-wsl@^2.1.1: dependencies: is-docker "^2.0.0" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -8118,7 +8170,7 @@ iterate-iterator@^1.0.1: resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw== -iterate-value@^1.0.0: +iterate-value@^1.0.0, iterate-value@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== @@ -9050,7 +9102,7 @@ loglevelnext@^1.0.1: es6-symbol "^3.1.1" object.assign "^4.1.0" -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -9179,6 +9231,15 @@ material-colors@^1.2.1: resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46" integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg== +matrix-cypher@^0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/matrix-cypher/-/matrix-cypher-0.1.11.tgz#3152f47c097943592a12729f9c9340f56b130393" + integrity sha512-fwEntUxC79ycItPl8PRhiJD1oBgOSrMaOjkmt3eYHvmj1F4ylUyxRl3pJICAqZdUeBpbRrMFDhg7oWtGp9v2Ng== + dependencies: + cross-fetch "^3.0.5" + promise.any "^2.0.1" + zod "^1.10.2" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -9374,6 +9435,14 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +mini-create-react-context@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz#df60501c83151db69e28eac0ef08b4002efab040" + integrity sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA== + dependencies: + "@babel/runtime" "^7.5.5" + tiny-warning "^1.0.3" + mini-css-extract-plugin@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" @@ -9605,7 +9674,7 @@ node-ensure@^0.0.0: resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7" integrity sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc= -node-fetch@^2.6.0: +node-fetch@2.6.0, node-fetch@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== @@ -10304,6 +10373,13 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -11265,6 +11341,18 @@ promise.allsettled@^1.0.0: function-bind "^1.1.1" iterate-value "^1.0.0" +promise.any@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise.any/-/promise.any-2.0.1.tgz#381c8f31b5312865c6c2a8104ff501f7f847e66d" + integrity sha512-3amHUuhVhkhFVw8mAM33pyt1zBoYK9O9SorjWbE+E3zSTb4AUpJmK5+rt5g6OCtZpgBlT1cTxF/bp/SNeMQSUQ== + dependencies: + array.prototype.map "^1.0.1" + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + es-aggregate-error "^1.0.2" + function-bind "^1.1.1" + iterate-value "^1.0.1" + promise.prototype.finally@^3.1.0: version "3.1.2" resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.2.tgz#b8af89160c9c673cefe3b4c4435b53cfd0287067" @@ -11689,7 +11777,7 @@ react-inspector@^4.0.0: is-dom "^1.0.9" prop-types "^15.6.1" -react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.9.0: +react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.9.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -11743,6 +11831,35 @@ react-redux@^7.0.2: prop-types "^15.7.2" react-is "^16.9.0" +react-router-dom@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" + integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.2.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" + integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + mini-create-react-context "^0.4.0" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + react-scripts@3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a" @@ -12236,6 +12353,11 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pathname@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" + integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== + resolve-url-loader@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz#28931895fa1eab9be0647d3b2958c100ae3c0bf0" @@ -13556,7 +13678,12 @@ tiny-emitter@^2.0.0: resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== -tiny-warning@^1.0.2: +tiny-invariant@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" + integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + +tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== @@ -14002,6 +14129,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +value-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" + integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -14679,3 +14811,8 @@ yup@^0.29.1: property-expr "^2.0.2" synchronous-promise "^2.0.13" toposort "^2.0.2" + +zod@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/zod/-/zod-1.10.2.tgz#fd2585bfcabc6a1dee267815ce0a036f184a5473" + integrity sha512-/T7CBnpJNf2hOlFburyOSP56nedBqrhwTgrwTKp3xPcZzfdRgRXORVHgDLMOIUQUVJyZbDrQqbS2RHuU/2XmHg==