Skip to content
Snippets Groups Projects
Commit 74b79092 authored by Jorik Schellekens's avatar Jorik Schellekens
Browse files

Show sharer preview for matrix.to links

parent 85fab363
No related branches found
No related tags found
No related merge requests found
...@@ -19,4 +19,8 @@ limitations under the License. ...@@ -19,4 +19,8 @@ limitations under the License.
border-radius: 0; border-radius: 0;
border: 0; border: 0;
} }
h1 {
word-break: break-all;
}
} }
...@@ -20,10 +20,11 @@ import { getEvent, client } from 'matrix-cypher'; ...@@ -20,10 +20,11 @@ import { getEvent, client } from 'matrix-cypher';
import { RoomPreviewWithTopic } from './RoomPreview'; import { RoomPreviewWithTopic } from './RoomPreview';
import InviteTile from './InviteTile'; import InviteTile from './InviteTile';
import { SafeLink, LinkKind } from '../parser/types'; import { SafeLink, LinkKind } from '../parser/types';
import UserPreview from './UserPreview'; import UserPreview, { WrappedInviterPreview } from './UserPreview';
import EventPreview from './EventPreview'; import EventPreview from './EventPreview';
import HomeserverOptions from './HomeserverOptions'; import HomeserverOptions from './HomeserverOptions';
import DefaultPreview from './DefaultPreview'; import DefaultPreview from './DefaultPreview';
import Toggle from './Toggle';
import { clientMap } from '../clients'; import { clientMap } from '../clients';
import { import {
getRoomFromId, getRoomFromId,
...@@ -32,12 +33,7 @@ import { ...@@ -32,12 +33,7 @@ import {
getUser, getUser,
} from '../utils/cypher-wrapper'; } from '../utils/cypher-wrapper';
import { ClientContext } from '../contexts/ClientContext'; import { ClientContext } from '../contexts/ClientContext';
import HSContext, { import useHSs from '../utils/getHS';
TempHSContext,
HSOptions,
State as HSState,
} from '../contexts/HSContext';
import Toggle from './Toggle';
interface IProps { interface IProps {
link: SafeLink; link: SafeLink;
...@@ -118,32 +114,14 @@ const Preview: React.FC<PreviewProps> = ({ link, client }: PreviewProps) => { ...@@ -118,32 +114,14 @@ const Preview: React.FC<PreviewProps> = ({ link, client }: PreviewProps) => {
return content; return content;
}; };
function selectedClient(link: SafeLink, hsOptions: HSState): string[] {
switch (hsOptions.option) {
case HSOptions.Unset:
return [];
case HSOptions.None:
return [];
case HSOptions.TrustedHSOnly:
return [hsOptions.hs];
case HSOptions.Any:
return [
'https://' + link.identifier.split(':')[1],
...link.arguments.vias,
];
}
}
const LinkPreview: React.FC<IProps> = ({ link }: IProps) => { const LinkPreview: React.FC<IProps> = ({ link }: IProps) => {
let content: JSX.Element; let content: JSX.Element;
const [showHSOptions, setShowHSOPtions] = useState(false); const [showHSOptions, setShowHSOPtions] = useState(false);
const [hsOptions] = useContext(HSContext);
const [tempHSState] = useContext(TempHSContext);
if ( const hses = useHSs(link);
hsOptions.option === HSOptions.Unset && console.log(hses);
tempHSState.option === HSOptions.Unset
) { if (!hses) {
content = ( content = (
<> <>
<DefaultPreview link={link} /> <DefaultPreview link={link} />
...@@ -164,11 +142,7 @@ const LinkPreview: React.FC<IProps> = ({ link }: IProps) => { ...@@ -164,11 +142,7 @@ const LinkPreview: React.FC<IProps> = ({ link }: IProps) => {
); );
} }
} else { } else {
const clients = content = <Preview link={link} client={hses[0]} />;
tempHSState.option !== HSOptions.Unset
? selectedClient(link, tempHSState)
: selectedClient(link, hsOptions);
content = <Preview link={link} client={clients[0]} />;
} }
const [{ clientId }] = useContext(ClientContext); const [{ clientId }] = useContext(ClientContext);
...@@ -182,8 +156,20 @@ const LinkPreview: React.FC<IProps> = ({ link }: IProps) => { ...@@ -182,8 +156,20 @@ const LinkPreview: React.FC<IProps> = ({ link }: IProps) => {
const client = displayClientId ? clientMap[displayClientId] : null; const client = displayClientId ? clientMap[displayClientId] : null;
const sharer = link.arguments.sharer ? (
<WrappedInviterPreview
link={{
kind: LinkKind.UserId,
identifier: link.arguments.sharer,
arguments: { vias: [] },
originalLink: '',
}}
/>
) : null;
return ( return (
<InviteTile client={client} link={link}> <InviteTile client={client} link={link}>
{sharer}
{content} {content}
</InviteTile> </InviteTile>
); );
......
...@@ -14,10 +14,13 @@ See the License for the specific language governing permissions and ...@@ -14,10 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React from 'react'; import React, { useState, useEffect } from 'react';
import { User } from 'matrix-cypher'; import { client, User, getUserDetails } from 'matrix-cypher';
import icon from '../imgs/chat-icon.svg';
import { UserAvatar } from './Avatar'; import Avatar, { UserAvatar } from './Avatar';
import useHSs from '../utils/getHS';
import { UserId } from '../parser/types';
import './UserPreview.scss'; import './UserPreview.scss';
...@@ -37,14 +40,49 @@ const UserPreview: React.FC<IProps> = ({ user, userId }: IProps) => ( ...@@ -37,14 +40,49 @@ const UserPreview: React.FC<IProps> = ({ user, userId }: IProps) => (
export default UserPreview; export default UserPreview;
export const InviterPreview: React.FC<IProps> = ({ user, userId }: IProps) => ( interface InviterPreviewProps {
<div className="miniUserPreview"> user?: User;
<div> userId: string;
<h1> }
Invited by <b>{user.displayname}</b>
</h1> export const InviterPreview: React.FC<InviterPreviewProps> = ({
<p>{userId}</p> user,
</div> userId,
}: InviterPreviewProps) => {
const avatar = user ? (
<UserAvatar user={user} userId={userId} /> <UserAvatar user={user} userId={userId} />
</div> ) : (
); <Avatar label={`Placeholder icon for ${userId}`} avatarUrl={icon} />
);
return (
<div className="miniUserPreview">
<div>
<h1>
Invited by <b>{user ? user.displayname : userId}</b>
</h1>
{user ? <p>{userId}</p> : null}
</div>
{avatar}
</div>
);
};
interface WrappedInviterProps {
link: UserId;
}
export const WrappedInviterPreview: React.FC<WrappedInviterProps> = ({
link,
}: WrappedInviterProps) => {
const [user, setUser] = useState<User | undefined>(undefined);
const hss = useHSs(link);
useEffect(() => {
if (hss) {
client(hss[0])
.then((c) => getUserDetails(c, link.identifier))
.then(setUser)
.catch((x) => console.log("couldn't fetch user preview", x));
}
}, [hss, link]);
return <InviterPreview user={user} userId={link.identifier} />;
};
...@@ -29,17 +29,12 @@ export enum HSOptions { ...@@ -29,17 +29,12 @@ export enum HSOptions {
TrustedHSOnly = 'TRUSTED_CLIENT_ONLY', TrustedHSOnly = 'TRUSTED_CLIENT_ONLY',
// Matrix.to may contact any homeserver it requires // Matrix.to may contact any homeserver it requires
Any = 'ANY', Any = 'ANY',
// Matrix.to may not contact any homeservers
None = 'NONE',
} }
const STATE_SCHEMA = union([ const STATE_SCHEMA = union([
object({ object({
option: literal(HSOptions.Unset), option: literal(HSOptions.Unset),
}), }),
object({
option: literal(HSOptions.None),
}),
object({ object({
option: literal(HSOptions.Any), option: literal(HSOptions.Any),
}), }),
...@@ -55,7 +50,6 @@ export type State = TypeOf<typeof STATE_SCHEMA>; ...@@ -55,7 +50,6 @@ export type State = TypeOf<typeof STATE_SCHEMA>;
export enum ActionType { export enum ActionType {
SetHS = 'SET_HS', SetHS = 'SET_HS',
SetAny = 'SET_ANY', SetAny = 'SET_ANY',
SetNone = 'SET_NONE',
} }
export interface SetHS { export interface SetHS {
...@@ -67,11 +61,7 @@ export interface SetAny { ...@@ -67,11 +61,7 @@ export interface SetAny {
action: ActionType.SetAny; action: ActionType.SetAny;
} }
export interface SetNone { export type Action = SetHS | SetAny;
action: ActionType.SetNone;
}
export type Action = SetHS | SetAny | SetNone;
export const INITIAL_STATE: State = { export const INITIAL_STATE: State = {
option: HSOptions.Unset, option: HSOptions.Unset,
...@@ -81,10 +71,6 @@ export const unpersistedReducer = (state: State, action: Action): State => { ...@@ -81,10 +71,6 @@ export const unpersistedReducer = (state: State, action: Action): State => {
console.log('reducing'); console.log('reducing');
console.log(action); console.log(action);
switch (action.action) { switch (action.action) {
case ActionType.SetNone:
return {
option: HSOptions.None,
};
case ActionType.SetAny: case ActionType.SetAny:
return { return {
option: HSOptions.Any, option: HSOptions.Any,
......
/*
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 { useContext } from 'react';
import HSContext, {
TempHSContext,
State,
HSOptions,
} from '../contexts/HSContext';
import { SafeLink } from '../parser/types';
function selectedClient(link: SafeLink, hsOptions: State): string[] {
switch (hsOptions.option) {
case HSOptions.Unset:
return [];
case HSOptions.TrustedHSOnly:
return [hsOptions.hs];
case HSOptions.Any:
return [
...link.identifier
.split('/')
.map((i) => 'https://' + i.split(':')[1]),
...link.arguments.vias,
];
}
}
export default function useHSs(link: SafeLink): string[] {
const [HSState] = useContext(HSContext);
const [TempHSState] = useContext(TempHSContext);
if (HSState.option !== HSOptions.Unset) {
return selectedClient(link, HSState);
} else if (TempHSState.option !== HSOptions.Unset) {
return selectedClient(link, TempHSState);
} else {
return [];
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment