Merge pull request #126 from matrix-org/matrixtwo/groups
Add rudimentary group support
This commit is contained in:
commit
dd372dbb50
9 changed files with 223 additions and 78 deletions
|
@ -25,4 +25,5 @@ limitations under the License.
|
||||||
|
|
||||||
.avatarNoCrop {
|
.avatarNoCrop {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Room, User } from '../matrix-cypher';
|
import { Group, Room, User } from '../matrix-cypher';
|
||||||
|
|
||||||
import { getMediaQueryFromMCX } from '../utils/cypher-wrapper';
|
import { getMediaQueryFromMCX } from '../utils/cypher-wrapper';
|
||||||
import logo from '../imgs/chat-icon.svg';
|
import logo from '../imgs/chat-icon.svg';
|
||||||
|
@ -35,12 +35,15 @@ const Avatar: React.FC<IProps> = ({ className, avatarUrl, label }: IProps) => {
|
||||||
setSrc(avatarUrl);
|
setSrc(avatarUrl);
|
||||||
}, [avatarUrl]);
|
}, [avatarUrl]);
|
||||||
|
|
||||||
|
const _className = classNames('avatar', className, {
|
||||||
|
avatarNoCrop: src === logo,
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
src={src}
|
src={src}
|
||||||
onError={(): void => setSrc(logo)}
|
onError={(): void => setSrc(logo)}
|
||||||
alt={label}
|
alt={label}
|
||||||
className={classNames('avatar', className)}
|
className={_className}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -73,4 +76,17 @@ export const RoomAvatar: React.FC<IPropsRoomAvatar> = ({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
interface IPropsGroupAvatar {
|
||||||
|
group: Group;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GroupAvatar: React.FC<IPropsGroupAvatar> = ({
|
||||||
|
group,
|
||||||
|
}: IPropsGroupAvatar) => (
|
||||||
|
<Avatar
|
||||||
|
avatarUrl={getMediaQueryFromMCX(group.avatar_url)}
|
||||||
|
label={group.name}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
export default Avatar;
|
export default Avatar;
|
||||||
|
|
26
src/components/GroupPreview.scss
Normal file
26
src/components/GroupPreview.scss
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.groupPreview {
|
||||||
|
> .avatar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
}
|
44
src/components/GroupPreview.tsx
Normal file
44
src/components/GroupPreview.tsx
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
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 { Group } from '../matrix-cypher';
|
||||||
|
|
||||||
|
import { GroupAvatar } from './Avatar';
|
||||||
|
|
||||||
|
import './GroupPreview.scss';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
group: Group;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GroupPreview: React.FC<IProps> = ({ group }: IProps) => {
|
||||||
|
const description = group.long_description
|
||||||
|
? group.long_description
|
||||||
|
: group.short_description
|
||||||
|
? group.short_description
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="groupPreview">
|
||||||
|
<GroupAvatar group={group} />
|
||||||
|
<h1>{group.name}</h1>
|
||||||
|
{description ? <p>{description}</p> : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GroupPreview;
|
|
@ -22,6 +22,7 @@ import InviteTile from './InviteTile';
|
||||||
import { SafeLink, LinkKind } from '../parser/types';
|
import { SafeLink, LinkKind } from '../parser/types';
|
||||||
import UserPreview, { WrappedInviterPreview } from './UserPreview';
|
import UserPreview, { WrappedInviterPreview } from './UserPreview';
|
||||||
import EventPreview from './EventPreview';
|
import EventPreview from './EventPreview';
|
||||||
|
import GroupPreview from './GroupPreview';
|
||||||
import HomeserverOptions from './HomeserverOptions';
|
import HomeserverOptions from './HomeserverOptions';
|
||||||
import DefaultPreview from './DefaultPreview';
|
import DefaultPreview from './DefaultPreview';
|
||||||
import Toggle from './Toggle';
|
import Toggle from './Toggle';
|
||||||
|
@ -31,6 +32,7 @@ import {
|
||||||
getRoomFromAlias,
|
getRoomFromAlias,
|
||||||
getRoomFromPermalink,
|
getRoomFromPermalink,
|
||||||
getUser,
|
getUser,
|
||||||
|
getGroup,
|
||||||
} from '../utils/cypher-wrapper';
|
} from '../utils/cypher-wrapper';
|
||||||
import { ClientContext } from '../contexts/ClientContext';
|
import { ClientContext } from '../contexts/ClientContext';
|
||||||
import useHSs from '../utils/getHS';
|
import useHSs from '../utils/getHS';
|
||||||
|
@ -86,6 +88,13 @@ const invite = async ({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
case LinkKind.GroupId:
|
||||||
|
return (
|
||||||
|
<GroupPreview
|
||||||
|
group={await getGroup(clientAddress, link.identifier)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Todo Implement events
|
// Todo Implement events
|
||||||
return <></>;
|
return <></>;
|
||||||
|
|
|
@ -16,28 +16,24 @@ limitations under the License.
|
||||||
|
|
||||||
/* eslint-disable import/first */
|
/* eslint-disable import/first */
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import any from 'promise.any';
|
import any from 'promise.any';
|
||||||
any.shim()
|
any.shim();
|
||||||
|
|
||||||
import VersionSchema from './schemas/VersionSchema';
|
import VersionSchema from './schemas/VersionSchema';
|
||||||
import WellKnownSchema from './schemas/WellKnownSchema';
|
import WellKnownSchema from './schemas/WellKnownSchema';
|
||||||
import UserSchema, { User } from './schemas/UserSchema';
|
import UserSchema, { User } from './schemas/UserSchema';
|
||||||
import RoomAliasSchema, {
|
import RoomAliasSchema, { RoomAlias } from './schemas/RoomAliasSchema';
|
||||||
RoomAlias,
|
|
||||||
} from './schemas/RoomAliasSchema';
|
|
||||||
import PublicRoomsSchema, {
|
import PublicRoomsSchema, {
|
||||||
PublicRooms,
|
PublicRooms,
|
||||||
Room,
|
Room,
|
||||||
} from './schemas/PublicRoomsSchema';
|
} from './schemas/PublicRoomsSchema';
|
||||||
import EventSchema, {
|
import EventSchema, { Event } from './schemas/EventSchema';
|
||||||
Event,
|
import GroupSchema, { Group } from './schemas/GroupSchema';
|
||||||
} from './schemas/EventSchema';
|
|
||||||
import { ensure } from './utils/promises';
|
import { ensure } from './utils/promises';
|
||||||
import { prefixFetch, parseJSON } from './utils/fetch';
|
import { prefixFetch, parseJSON } from './utils/fetch';
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A client is a resolved homeserver name wrapped in a lambda'd fetch
|
* A client is a resolved homeserver name wrapped in a lambda'd fetch
|
||||||
*/
|
*/
|
||||||
|
@ -46,7 +42,7 @@ export type Client = (path: string) => Promise<Response>;
|
||||||
/*
|
/*
|
||||||
* Confirms that the target homeserver is properly configured and operational
|
* Confirms that the target homeserver is properly configured and operational
|
||||||
*/
|
*/
|
||||||
export const validateHS = (host: string) =>
|
export const validateHS = (host: string): Promise<string> =>
|
||||||
prefixFetch(host)('/_matrix/client/versions')
|
prefixFetch(host)('/_matrix/client/versions')
|
||||||
.then(parseJSON)
|
.then(parseJSON)
|
||||||
.then(VersionSchema.parse)
|
.then(VersionSchema.parse)
|
||||||
|
@ -56,47 +52,43 @@ export const validateHS = (host: string) =>
|
||||||
* Discovers the correct domain name for the host according to the spec's
|
* Discovers the correct domain name for the host according to the spec's
|
||||||
* discovery rules
|
* discovery rules
|
||||||
*/
|
*/
|
||||||
export const discoverServer = (host: string) =>
|
export const discoverServer = (host: string): Promise<string> =>
|
||||||
prefixFetch(host)('/.well-known/matrix/client')
|
prefixFetch(host)('/.well-known/matrix/client')
|
||||||
.then(resp => resp.ok
|
.then((resp) =>
|
||||||
? resp.json()
|
resp.ok
|
||||||
.then(WellKnownSchema.parse)
|
? resp
|
||||||
.then(content => {
|
.json()
|
||||||
if (content === undefined) return host;
|
.then(WellKnownSchema.parse)
|
||||||
else if (
|
.then((content) => {
|
||||||
'm.homeserver' in content && content['m.homeserver']
|
if (content === undefined) return host;
|
||||||
) {
|
else if (
|
||||||
return content['m.homeserver'].base_url
|
'm.homeserver' in content &&
|
||||||
} else {
|
content['m.homeserver']
|
||||||
return host
|
) {
|
||||||
}
|
return content['m.homeserver'].base_url;
|
||||||
})
|
} else {
|
||||||
: ensure(
|
return host;
|
||||||
resp.status === 404,
|
}
|
||||||
() => host,
|
})
|
||||||
),
|
: ensure(resp.status === 404, () => host)
|
||||||
)
|
)
|
||||||
.then(validateHS)
|
.then(validateHS);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Takes a hs domain and resolves it to it's current domain and returns a
|
* Takes a hs domain and resolves it to it's current domain and returns a
|
||||||
* client
|
* client
|
||||||
*/
|
*/
|
||||||
export async function client(host: string): Promise<Client> {
|
export async function client(host: string): Promise<Client> {
|
||||||
return prefixFetch(await discoverServer(host))
|
return prefixFetch(await discoverServer(host));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets the details for a user
|
* Gets the details for a user
|
||||||
*/
|
*/
|
||||||
export function getUserDetails(
|
export function getUserDetails(client: Client, userId: string): Promise<User> {
|
||||||
client: Client,
|
|
||||||
userId: string,
|
|
||||||
): Promise<User> {
|
|
||||||
return client(`/_matrix/client/r0/profile/${userId}`)
|
return client(`/_matrix/client/r0/profile/${userId}`)
|
||||||
.then(parseJSON)
|
.then(parseJSON)
|
||||||
.then(UserSchema.parse)
|
.then(UserSchema.parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -104,7 +96,7 @@ export function getUserDetails(
|
||||||
*/
|
*/
|
||||||
export function getRoomIdFromAlias(
|
export function getRoomIdFromAlias(
|
||||||
client: Client,
|
client: Client,
|
||||||
roomAlias: string,
|
roomAlias: string
|
||||||
): Promise<RoomAlias> {
|
): Promise<RoomAlias> {
|
||||||
const encodedRoomAlias = encodeURIComponent(roomAlias);
|
const encodedRoomAlias = encodeURIComponent(roomAlias);
|
||||||
return client(`/_matrix/client/r0/directory/room/${encodedRoomAlias}`)
|
return client(`/_matrix/client/r0/directory/room/${encodedRoomAlias}`)
|
||||||
|
@ -112,23 +104,6 @@ export function getRoomIdFromAlias(
|
||||||
.then(RoomAliasSchema.parse);
|
.then(RoomAliasSchema.parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets the details of a room if that room is public
|
|
||||||
*/
|
|
||||||
export function getRoomDetails(clients: Client[], roomId: string): Promise<Room> {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
return Promise.any(clients.map(client => searchPublicRooms(client, roomId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets a list of all public rooms on a hs
|
|
||||||
*/
|
|
||||||
export function getPublicRooms(client: Client): Promise<PublicRooms> {
|
|
||||||
return getPublicRoomsUnsafe(client)
|
|
||||||
.then(PublicRoomsSchema.parse)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Similar to getPubliRooms however id doesn't confirm the data returned from
|
* Similar to getPubliRooms however id doesn't confirm the data returned from
|
||||||
* the hs is correct
|
* the hs is correct
|
||||||
|
@ -138,8 +113,14 @@ export function getPublicRooms(client: Client): Promise<PublicRooms> {
|
||||||
*/
|
*/
|
||||||
export function getPublicRoomsUnsafe(client: Client): Promise<PublicRooms> {
|
export function getPublicRoomsUnsafe(client: Client): Promise<PublicRooms> {
|
||||||
// TODO: Do not assume server will return all results in one go
|
// TODO: Do not assume server will return all results in one go
|
||||||
return client('/_matrix/client/r0/publicRooms')
|
return client('/_matrix/client/r0/publicRooms').then(parseJSON);
|
||||||
.then(parseJSON)
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets a list of all public rooms on a hs
|
||||||
|
*/
|
||||||
|
export function getPublicRooms(client: Client): Promise<PublicRooms> {
|
||||||
|
return getPublicRoomsUnsafe(client).then(PublicRoomsSchema.parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -147,20 +128,33 @@ export function getPublicRoomsUnsafe(client: Client): Promise<PublicRooms> {
|
||||||
*/
|
*/
|
||||||
export function searchPublicRooms(
|
export function searchPublicRooms(
|
||||||
client: Client,
|
client: Client,
|
||||||
roomId: string,
|
roomId: string
|
||||||
): Promise<Room> {
|
): Promise<Room> {
|
||||||
// we use the unsage version here because the safe one is sloooow
|
// we use the unsage version here because the safe one is sloooow
|
||||||
return getPublicRoomsUnsafe(client)
|
return getPublicRoomsUnsafe(client).then((rooms) => {
|
||||||
.then(rooms => {
|
const [match] = rooms.chunk.filter((chunk) => chunk.room_id === roomId);
|
||||||
const [match] = rooms.chunk.filter(
|
return match !== undefined
|
||||||
chunk => chunk.room_id === roomId,
|
? Promise.resolve(match)
|
||||||
);
|
: Promise.reject(
|
||||||
return match !== undefined
|
new Error(
|
||||||
? Promise.resolve(match)
|
`This server knowns no public room with id ${roomId}`
|
||||||
: Promise.reject(new Error(
|
)
|
||||||
`This server knowns no public room with id ${roomId}`,
|
);
|
||||||
));
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets the details of a room if that room is public
|
||||||
|
*/
|
||||||
|
export function getRoomDetails(
|
||||||
|
clients: Client[],
|
||||||
|
roomId: string
|
||||||
|
): Promise<Room> {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||||
|
// @ts-ignore
|
||||||
|
return Promise.any(
|
||||||
|
clients.map((client) => searchPublicRooms(client, roomId))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -169,24 +163,33 @@ export function searchPublicRooms(
|
||||||
export async function getEvent(
|
export async function getEvent(
|
||||||
client: Client,
|
client: Client,
|
||||||
roomIdOrAlias: string,
|
roomIdOrAlias: string,
|
||||||
eventId: string,
|
eventId: string
|
||||||
): Promise<Event> {
|
): Promise<Event> {
|
||||||
return client(`/_matrix/client/r0/rooms/${roomIdOrAlias}/event/${eventId}`)
|
return client(`/_matrix/client/r0/rooms/${roomIdOrAlias}/event/${eventId}`)
|
||||||
.then(parseJSON)
|
.then(parseJSON)
|
||||||
.then(EventSchema.parse);
|
.then(EventSchema.parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets community information
|
||||||
|
*/
|
||||||
|
export async function getGroupDetails(
|
||||||
|
client: Client,
|
||||||
|
groupId: string
|
||||||
|
): Promise<Group> {
|
||||||
|
return client(`/_matrix/client/r0/groups/${groupId}/profile`)
|
||||||
|
.then(parseJSON)
|
||||||
|
.then(GroupSchema.parse);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets an mxc resource
|
* Gets an mxc resource
|
||||||
*/
|
*/
|
||||||
export function convertMXCtoMediaQuery(
|
export function convertMXCtoMediaQuery(clientURL: string, mxc: string): string {
|
||||||
clientURL: string,
|
|
||||||
mxc: string,
|
|
||||||
): string {
|
|
||||||
// mxc://matrix.org/EqMZYbAYhREvHXvYFyfxOlkf
|
// mxc://matrix.org/EqMZYbAYhREvHXvYFyfxOlkf
|
||||||
const matches = mxc.match(/mxc:\/\/(.+)\/(.+)/)
|
const matches = mxc.match(/mxc:\/\/(.+)\/(.+)/);
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
throw new Error(`mxc invalid: ${JSON.stringify({mxc})}`);
|
throw new Error(`mxc invalid: ${JSON.stringify({ mxc })}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${clientURL}/_matrix/media/r0/download/${matches[1]}/${matches[2]}`;
|
return `${clientURL}/_matrix/media/r0/download/${matches[1]}/${matches[2]}`;
|
||||||
|
|
27
src/matrix-cypher/schemas/GroupSchema.ts
Normal file
27
src/matrix-cypher/schemas/GroupSchema.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
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 { object, string, TypeOf } from 'zod';
|
||||||
|
|
||||||
|
const GroupSchema = object({
|
||||||
|
name: string(),
|
||||||
|
avatar_url: string().optional(),
|
||||||
|
short_description: string().optional(),
|
||||||
|
long_description: string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Group = TypeOf<typeof GroupSchema>;
|
||||||
|
export default GroupSchema;
|
|
@ -15,10 +15,10 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './EventSchema';
|
export * from './EventSchema';
|
||||||
|
export * from './GroupSchema';
|
||||||
export * from './PublicRoomsSchema';
|
export * from './PublicRoomsSchema';
|
||||||
export * from './RoomAliasSchema';
|
export * from './RoomAliasSchema';
|
||||||
export * from './UserSchema';
|
export * from './UserSchema';
|
||||||
export * from './VersionSchema';
|
export * from './VersionSchema';
|
||||||
export * from './WellKnownSchema';
|
export * from './WellKnownSchema';
|
||||||
export * from './index';
|
export * from './index';
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,12 @@ import {
|
||||||
Room,
|
Room,
|
||||||
RoomAlias,
|
RoomAlias,
|
||||||
User,
|
User,
|
||||||
|
Group,
|
||||||
getRoomIdFromAlias,
|
getRoomIdFromAlias,
|
||||||
searchPublicRooms,
|
searchPublicRooms,
|
||||||
getUserDetails,
|
getUserDetails,
|
||||||
convertMXCtoMediaQuery,
|
convertMXCtoMediaQuery,
|
||||||
|
getGroupDetails,
|
||||||
} from '../matrix-cypher';
|
} from '../matrix-cypher';
|
||||||
import { LinkKind, Permalink } from '../parser/types';
|
import { LinkKind, Permalink } from '../parser/types';
|
||||||
|
|
||||||
|
@ -72,6 +74,11 @@ export const fallbackRoom = ({
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const fallbackGroup = (groupId: string): Group => ({
|
||||||
|
name: groupId,
|
||||||
|
short_description: `The ${groupId} group`,
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tries to fetch room details from an alias. If it fails it uses
|
* Tries to fetch room details from an alias. If it fails it uses
|
||||||
* a `fallbackRoom`
|
* a `fallbackRoom`
|
||||||
|
@ -169,3 +176,15 @@ export function getMediaQueryFromMCX(mxc?: string): string {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getGroup(
|
||||||
|
clientURL: string,
|
||||||
|
groupId: string
|
||||||
|
): Promise<Group> {
|
||||||
|
try {
|
||||||
|
const resolvedClient = await client(clientURL);
|
||||||
|
return await getGroupDetails(resolvedClient, groupId);
|
||||||
|
} catch {
|
||||||
|
return fallbackGroup(groupId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue