Implement better fallbacks

This commit is contained in:
Jorik Schellekens 2020-08-18 11:07:26 +01:00
parent 1ad11ed25f
commit 0ac4116b24
3 changed files with 122 additions and 97 deletions

View file

@ -18,7 +18,7 @@ import React, { useEffect, useState } from "react";
import classNames from "classnames";
import { Room, User } from "matrix-cypher";
import { convertMXCtoMediaQuery } from "../utils/cypher-wrapper";
import { getMediaQueryFromMCX } from "../utils/cypher-wrapper";
import logo from "../imgs/matrix-logo.svg";
import "./Avatar.scss";
@ -55,15 +55,7 @@ export const UserAvatar: React.FC<IPropsUserAvatar> = ({
userId,
}: IPropsUserAvatar) => (
<Avatar
avatarUrl={
user.avatar_url
? convertMXCtoMediaQuery(
// TODO: replace with correct client
"https://matrix.org",
user.avatar_url
)
: ""
}
avatarUrl={getMediaQueryFromMCX(user.avatar_url)}
label={user.displayname ? user.displayname : userId}
/>
);
@ -76,15 +68,7 @@ export const RoomAvatar: React.FC<IPropsRoomAvatar> = ({
room,
}: IPropsRoomAvatar) => (
<Avatar
avatarUrl={
room.avatar_url
? convertMXCtoMediaQuery(
// TODO: replace with correct client
"https://matrix.org",
room.avatar_url
)
: ""
}
avatarUrl={getMediaQueryFromMCX(room.avatar_url)}
label={room.name || room.room_id}
/>
);

View file

@ -15,46 +15,36 @@ limitations under the License.
*/
import React, { useState, useEffect } from "react";
import { Client, getEvent, client } from "matrix-cypher";
import { getEvent, client } from "matrix-cypher";
import {
getRoomIdFromAlias,
searchPublicRooms,
getUserDetails,
} from "../utils/cypher-wrapper";
import { RoomPreviewWithTopic } from "./RoomPreview";
import InviteTile from "./InviteTile";
import { SafeLink } from "../parser/types";
import { LinkKind } from "../parser/types";
import { SafeLink, LinkKind } from "../parser/types";
import UserPreview from "./UserPreview";
import EventPreview from "./EventPreview";
import Clients from "../clients";
import {
getRoomFromId,
getRoomFromAlias,
getRoomFromPermalink,
getUser,
} from "../utils/cypher-wrapper";
interface IProps {
link: SafeLink;
}
// TODO: replace with client fetch
const defaultClient: () => Promise<Client> = () => client("https://matrix.org");
const LOADING: JSX.Element = <>Generating invite</>;
const invite = async ({ link }: { link: SafeLink }): Promise<JSX.Element> => {
// TODO: replace with client fetch
const defaultClient = await client("https://matrix.org");
switch (link.kind) {
case LinkKind.Alias:
return (
<RoomPreviewWithTopic
room={
await searchPublicRooms(
await defaultClient(),
(
await getRoomIdFromAlias(
await defaultClient(),
link.identifier
)
).room_id
)
await getRoomFromAlias(defaultClient, link.identifier)
}
/>
);
@ -62,24 +52,14 @@ const invite = async ({ link }: { link: SafeLink }): Promise<JSX.Element> => {
case LinkKind.RoomId:
return (
<RoomPreviewWithTopic
room={
await searchPublicRooms(
await defaultClient(),
link.identifier
)
}
room={await getRoomFromId(defaultClient, link.identifier)}
/>
);
case LinkKind.UserId:
return (
<UserPreview
user={
await getUserDetails(
await defaultClient(),
link.identifier
)
}
user={await getUser(defaultClient, link.identifier)}
userId={link.identifier}
/>
);
@ -87,15 +67,10 @@ const invite = async ({ link }: { link: SafeLink }): Promise<JSX.Element> => {
case LinkKind.Permalink:
return (
<EventPreview
room={
await searchPublicRooms(
await defaultClient(),
link.identifier
)
}
room={await getRoomFromPermalink(defaultClient, link)}
event={
await getEvent(
await defaultClient(),
defaultClient,
link.roomLink,
link.eventId
)

View file

@ -16,73 +16,139 @@ limitations under the License.
import {
Client,
getUserDetails as cGetUserDetails,
User,
getRoomDetails as cGetRoomDetails,
searchPublicRooms as cSearchPublicRooms,
Room,
convertMXCtoMediaQuery as cConvertMXCtoMediaQuery,
getRoomIdFromAlias as cGetRoomIdFromAlias,
RoomAlias,
User,
getRoomIdFromAlias,
searchPublicRooms,
getUserDetails,
convertMXCtoMediaQuery,
} from "matrix-cypher";
import { LinkKind, Permalink } from "../parser/types";
/* This is a collection of methods for providing fallback metadata
* for cypher queries
*/
/*
* Gets the details for a user
* Returns an instance of User with fallback information instead
* of fetched metadata
*/
export function getUserDetails(client: Client, userId: string): Promise<User> {
return cGetUserDetails(client, userId).catch(() => ({
displayname: userId,
}));
}
export const fallbackUser = (userId: string): User => ({
displayname: userId,
});
function defaultRoom(roomId: string): Room {
/*
* Returns an instance of Room with fallback information instead
* of fecthed metadata
*/
export const fallbackRoom = ({
identifier,
roomId,
roomAlias,
}: {
identifier: string;
roomId?: string;
roomAlias?: string;
}): Room => {
const roomId_ = roomId ? roomId : identifier;
const roomAlias_ = roomAlias ? roomAlias : identifier;
return {
aliases: [roomId],
aliases: [roomAlias_],
topic: "Unable to find room details.",
canonical_alias: roomId,
name: roomId,
canonical_alias: roomAlias_,
name: roomAlias_,
num_joined_members: 0,
room_id: roomId,
room_id: roomId_,
guest_can_join: true,
avatar_url: "",
world_readable: false,
};
}
};
/*
* Gets the details of a room if that room is public
* Tries to fetch room details from an alias. If it fails it uses
* a `fallbackRoom`
*/
export function getRoomDetails(
clients: Client[],
roomId: string
export async function getRoomFromAlias(
client: Client,
roomAlias: string
): Promise<Room> {
return cGetRoomDetails(clients, roomId).catch(() => defaultRoom(roomId));
let resolvedRoomAlias: RoomAlias;
try {
resolvedRoomAlias = await getRoomIdFromAlias(client, roomAlias);
} catch {
return fallbackRoom({ identifier: roomAlias });
}
try {
return await searchPublicRooms(client, resolvedRoomAlias.room_id);
} catch {
return fallbackRoom({
identifier: roomAlias,
roomId: resolvedRoomAlias.room_id,
roomAlias: roomAlias,
});
}
}
/*
* Searches the public rooms of a homeserver for the metadata of a particular
* Tries to fetch room details from a roomId. If it fails it uses
* a `fallbackRoom`
*/
export function searchPublicRooms(
export async function getRoomFromId(
client: Client,
roomId: string
): Promise<Room> {
return cSearchPublicRooms(client, roomId).catch(() => defaultRoom(roomId));
try {
return await searchPublicRooms(client, roomId);
} catch {
return fallbackRoom({ identifier: roomId });
}
}
export function convertMXCtoMediaQuery(clientURL: string, mxc: string): string {
/*
* Tries to fetch user details. If it fails it uses a `fallbackUser`
*/
export async function getUser(client: Client, userId: string): Promise<User> {
try {
return cConvertMXCtoMediaQuery(clientURL, mxc);
return await getUserDetails(client, userId);
} catch {
return fallbackUser(userId);
}
}
/*
* Tries to fetch room details from a permalink. If it fails it uses
* a `fallbackRoom`
*/
export async function getRoomFromPermalink(
client: Client,
link: Permalink
): Promise<Room> {
switch (link.roomKind) {
case LinkKind.Alias:
return getRoomFromAlias(client, link.roomLink);
case LinkKind.RoomId:
return getRoomFromId(client, link.roomLink);
}
}
/*
* tries to convert an mxc to a media query. If it fails it
* uses the empty string
*/
export function getMediaQueryFromMCX(mxc?: string): string {
if (!mxc) {
return "";
}
try {
return convertMXCtoMediaQuery(
// TODO: replace with correct client
"https://matrix.org",
mxc
);
} catch {
return "";
}
}
export function getRoomIdFromAlias(
client: Client,
roomAlias: string
): Promise<RoomAlias> {
return cGetRoomIdFromAlias(client, roomAlias).catch(() => ({
room_id: roomAlias,
servers: [],
}));
}