Skip to content
Snippets Groups Projects
LinkPreview.tsx 5.43 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
    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, { useState, useEffect, useContext } from 'react';
    
    import { getEvent, client } from '../matrix-cypher';
    
    
    import { RoomPreviewWithTopic } from './RoomPreview';
    import InviteTile from './InviteTile';
    import { SafeLink, LinkKind } from '../parser/types';
    
    import UserPreview, { WrappedInviterPreview } from './UserPreview';
    
    import EventPreview from './EventPreview';
    
    import GroupPreview from './GroupPreview';
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
    import HomeserverOptions from './HomeserverOptions';
    import DefaultPreview from './DefaultPreview';
    
    import Details from './Details';
    
    import { clientMap } from '../clients';
    
    import {
        getRoomFromId,
        getRoomFromAlias,
        getRoomFromPermalink,
        getUser,
    
        getGroup,
    
    } from '../utils/cypher-wrapper';
    
    import { ClientContext } from '../contexts/ClientContext';
    
    import useHSs from '../utils/getHS';
    
    
    interface IProps {
        link: SafeLink;
    }
    
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
    const invite = async ({
        clientAddress,
        link,
    }: {
        clientAddress: string;
        link: SafeLink;
    }): Promise<JSX.Element> => {
    
        // TODO: replace with client fetch
    
        switch (link.kind) {
            case LinkKind.Alias:
                return (
                    <RoomPreviewWithTopic
                        room={
    
                            await getRoomFromAlias(clientAddress, link.identifier)
    
                        }
                    />
                );
    
            case LinkKind.RoomId:
                return (
                    <RoomPreviewWithTopic
    
                        room={await getRoomFromId(clientAddress, link.identifier)}
    
                    />
                );
    
            case LinkKind.UserId:
                return (
                    <UserPreview
    
                        user={await getUser(clientAddress, link.identifier)}
    
                        userId={link.identifier}
                    />
                );
    
            case LinkKind.Permalink:
                return (
                    <EventPreview
    
                        room={await getRoomFromPermalink(clientAddress, link)}
    
                                await client(clientAddress),
    
            case LinkKind.GroupId:
                return (
                    <GroupPreview
                        group={await getGroup(clientAddress, link.identifier)}
    
                        groupId={link.identifier}
    
            default:
                // Todo Implement events
                return <></>;
        }
    };
    
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
    interface PreviewProps extends IProps {
        client: string;
    }
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
    const Preview: React.FC<PreviewProps> = ({ link, client }: PreviewProps) => {
        const [content, setContent] = useState(<DefaultPreview link={link} />);
    
        // TODO: support multiple clients with vias
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
            (async (): Promise<void> =>
                setContent(
                    await invite({
                        clientAddress: client,
                        link,
                    })
                ))();
        }, [link, client]);
    
        return content;
    };
    
    const LinkPreview: React.FC<IProps> = ({ link }: IProps) => {
        let content: JSX.Element;
        const [showHSOptions, setShowHSOPtions] = useState(false);
    
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
        const hses = useHSs({ link });
    
        if (!hses.length) {
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
            content = (
                <>
                    <DefaultPreview link={link} />
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
                        checked={showHSOptions}
                        onChange={(): void => setShowHSOPtions(!showHSOptions)}
                    >
    
                        <span>
                            About&nbsp;
                            <span className="matrixIdentifier">
                                {link.identifier}
                            </span>
                        </span>
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
                </>
            );
            if (showHSOptions) {
                content = (
                    <>
                        {content}
    
                        <HomeserverOptions link={link} />
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
                    </>
                );
            }
        } else {
    
            content = <Preview link={link} client={hses[0]} />;
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
        }
    
        const [{ clientId }] = useContext(ClientContext);
    
    
        // Select which client to link to
    
        const displayClientId = clientId
            ? clientId
            : link.arguments.client
            ? link.arguments.client
            : null;
    
    
        const client = displayClientId ? clientMap[displayClientId] : null;
    
    
        const sharer = link.arguments.sharer ? (
            <WrappedInviterPreview
                link={{
                    kind: LinkKind.UserId,
                    identifier: link.arguments.sharer,
    
    Jorik Schellekens's avatar
    Jorik Schellekens committed
                    arguments: { vias: [], originalParams: new URLSearchParams() },
    
        ) : (
            <p style={{ margin: '0 0 10px 0' }}>You're invited to join</p>
        );
    
            <InviteTile client={client} link={link}>
    
                {content}
            </InviteTile>
        );
    };
    
    export default LinkPreview;