Add preview components
This commit is contained in:
parent
eeb119ecb3
commit
ba90c5558d
20 changed files with 716 additions and 8 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -23,3 +23,5 @@ yarn-debug.log*
|
|||
yarn-error.log*
|
||||
|
||||
.vercel
|
||||
|
||||
storybook-static
|
||||
|
|
|
@ -5,13 +5,15 @@ import { withKnobs } from '@storybook/addon-knobs';
|
|||
import { withDesign } from 'storybook-addon-designs'
|
||||
import { addParameters } from '@storybook/react';
|
||||
|
||||
import SingleColumn from '../src/layouts/SingleColumn';
|
||||
|
||||
|
||||
|
||||
// Default styles
|
||||
import "../src/index.scss";
|
||||
|
||||
addDecorator(
|
||||
storyFn => <div style={{ textAlign: 'center' }}>{storyFn()}</div>
|
||||
storyFn => <SingleColumn>{storyFn()}</SingleColumn>
|
||||
);
|
||||
|
||||
addDecorator(withA11y);
|
||||
|
@ -22,7 +24,7 @@ addDecorator(withDesign);
|
|||
|
||||
addParameters({
|
||||
backgrounds: [
|
||||
{name: 'light', value: '#F4F4F4'},
|
||||
{name: 'white', value: '#FFFFFF', default: true},
|
||||
{name: 'light', value: '#F4F4F4', default: true},
|
||||
{name: 'white', value: '#FFFFFF'},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -44,3 +44,6 @@ You can discuss matrix.to in
|
|||
[`#matrix.to:matrix.org`](https://matrix.to/#/#matrix.to:matrix.org)
|
||||
|
||||
A development build of matrix-two can be found at https://matrix-to.vercel.app
|
||||
|
||||
A preview of all components can be found at
|
||||
https://matrix-to-storybook.vercel.app
|
||||
|
|
|
@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
@import "./color-scheme";
|
||||
|
||||
#root {
|
||||
background-color: $app-background;
|
||||
}
|
||||
|
|
|
@ -22,3 +22,4 @@ $grey: #666666;
|
|||
$accent: #0098d4;
|
||||
$error: #d6001c;
|
||||
$link: #0098d4;
|
||||
$borders: #f4f4f4;
|
||||
|
|
24
src/components/Avatar.scss
Normal file
24
src/components/Avatar.scss
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
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 "../color-scheme";
|
||||
|
||||
.avatar {
|
||||
border-radius: 100%;
|
||||
border: 1px solid $borders;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
39
src/components/Avatar.stories.tsx
Normal file
39
src/components/Avatar.stories.tsx
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
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 { UserAvatar } from "./Avatar";
|
||||
|
||||
export default {
|
||||
title: "Avatar",
|
||||
parameters: {
|
||||
design: {
|
||||
type: "figma",
|
||||
url:
|
||||
"https://www.figma.com/file/WSXjCGc1k6FVI093qhlzOP/04-Recieving-share-link?node-id=143%3A5853",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Default: React.FC<{}> = () => (
|
||||
<UserAvatar
|
||||
user={{
|
||||
avatar_url: "mxc://matrix.org/EqMZYbAYhREvHXvYFyfxOlkf",
|
||||
displayname: "Jorik Schellekens",
|
||||
}}
|
||||
/>
|
||||
);
|
86
src/components/Avatar.tsx
Normal file
86
src/components/Avatar.tsx
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
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, { 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 logo from "../imgs/matrix-logo.svg";
|
||||
|
||||
import "./Avatar.scss";
|
||||
|
||||
interface IProps {
|
||||
className?: string;
|
||||
avatarUrl: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const Avatar: React.FC<IProps> = ({ className, avatarUrl, label }: IProps) => {
|
||||
const [src, setSrc] = useState(avatarUrl);
|
||||
useEffect(() => {
|
||||
setSrc(avatarUrl);
|
||||
}, [avatarUrl]);
|
||||
|
||||
return (
|
||||
<img
|
||||
src={src}
|
||||
onError={(_) => setSrc(logo)}
|
||||
alt={label}
|
||||
className={classNames("avatar", className)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
interface IPropsUserAvatar {
|
||||
user: User;
|
||||
}
|
||||
|
||||
export const UserAvatar: React.FC<IPropsUserAvatar> = ({
|
||||
user,
|
||||
}: IPropsUserAvatar) => (
|
||||
<Avatar
|
||||
avatarUrl={convertMXCtoMediaQuery(
|
||||
// TODO: replace with correct client
|
||||
"matrix.org",
|
||||
user.avatar_url
|
||||
)}
|
||||
label={user.displayname}
|
||||
/>
|
||||
);
|
||||
|
||||
interface IPropsRoomAvatar {
|
||||
room: Room;
|
||||
}
|
||||
|
||||
export const RoomAvatar: React.FC<IPropsRoomAvatar> = ({
|
||||
room,
|
||||
}: IPropsRoomAvatar) => (
|
||||
<Avatar
|
||||
avatarUrl={
|
||||
room.avatar_url
|
||||
? convertMXCtoMediaQuery(
|
||||
// TODO: replace with correct client
|
||||
"matrix.org",
|
||||
room.avatar_url
|
||||
)
|
||||
: ""
|
||||
}
|
||||
label={room.name || room.room_id}
|
||||
/>
|
||||
);
|
||||
|
||||
export default Avatar;
|
36
src/components/EventPreview.tsx
Normal file
36
src/components/EventPreview.tsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
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 { Room } from "cypher/src/schemas/PublicRoomsSchema";
|
||||
import { Event } from "cypher/src/schemas/EventSchema";
|
||||
|
||||
import RoomPreview from "./RoomPreview";
|
||||
|
||||
interface IProps {
|
||||
room: Room;
|
||||
event: Event;
|
||||
}
|
||||
|
||||
const EventPreview: React.FC<IProps> = ({ room, event }: IProps) => (
|
||||
<>
|
||||
<RoomPreview room={room} />
|
||||
<p>"{event.content}"</p>
|
||||
<p>{event.sender}</p>
|
||||
</>
|
||||
);
|
||||
|
||||
export default EventPreview;
|
25
src/components/InviteTile.scss
Normal file
25
src/components/InviteTile.scss
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
.inviteTile {
|
||||
.button {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
> .textButton {
|
||||
margin-top: 28px;
|
||||
}
|
||||
}
|
122
src/components/InviteTile.stories.tsx
Normal file
122
src/components/InviteTile.stories.tsx
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
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 InviteTile from "./InviteTile";
|
||||
import UserPreview, { InviterPreview } from "./UserPreview";
|
||||
import RoomPreview, { RoomPreviewWithTopic } from "./RoomPreview";
|
||||
|
||||
export default {
|
||||
title: "InviteTile",
|
||||
parameters: {
|
||||
design: {
|
||||
type: "figma",
|
||||
url:
|
||||
"https://figma.com/file/WSXjCGc1k6FVI093qhlzOP/04-Recieving-share-link?node-id=59%3A334",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const withLink: React.FC<{}> = () => (
|
||||
<InviteTile
|
||||
inviteAction={{
|
||||
type: "link",
|
||||
link: "https://app.element.io/#/room/#asdfasf:matrix.org",
|
||||
}}
|
||||
>
|
||||
This is an invite with a link
|
||||
</InviteTile>
|
||||
);
|
||||
|
||||
export const withInstruction: React.FC<{}> = () => (
|
||||
<InviteTile
|
||||
inviteAction={{
|
||||
type: "instruction",
|
||||
text: "Type /join #asdfasf:matrix.org",
|
||||
}}
|
||||
>
|
||||
This is an invite with an instruction
|
||||
</InviteTile>
|
||||
);
|
||||
|
||||
export const withUserPreview: React.FC<{}> = () => (
|
||||
<InviteTile
|
||||
inviteAction={{
|
||||
type: "link",
|
||||
link: "https://app.element.io/#/room/#asdfasf:matrix.org",
|
||||
}}
|
||||
>
|
||||
<UserPreview
|
||||
user={{
|
||||
avatar_url: "mxc://matrix.org/EqMZYbAYhREvHXvYFyfxOlkf",
|
||||
displayname: "Nicholas Briteli",
|
||||
}}
|
||||
userId="@nicholasbritelli:matrix.org"
|
||||
/>
|
||||
</InviteTile>
|
||||
);
|
||||
|
||||
export const withRoomPreviewAndRoomTopic: React.FC<{}> = () => (
|
||||
<InviteTile
|
||||
inviteAction={{
|
||||
type: "link",
|
||||
link: "https://app.element.io/#/room/#asdfasf:matrix.org",
|
||||
}}
|
||||
>
|
||||
<RoomPreviewWithTopic
|
||||
room={{
|
||||
aliases: ["#murrays:cheese.bar"],
|
||||
avatar_url: "mxc://bleeker.street/CHEDDARandBRIE",
|
||||
guest_can_join: false,
|
||||
name: "CHEESE",
|
||||
num_joined_members: 37,
|
||||
room_id: "!ol19s:bleecker.street",
|
||||
topic: "Tasty tasty cheese",
|
||||
world_readable: true,
|
||||
}}
|
||||
/>
|
||||
</InviteTile>
|
||||
);
|
||||
|
||||
export const withRoomPreviewAndInviter: React.FC<{}> = () => (
|
||||
<InviteTile
|
||||
inviteAction={{
|
||||
type: "link",
|
||||
link: "https://app.element.io/#/room/#asdfasf:matrix.org",
|
||||
}}
|
||||
>
|
||||
<InviterPreview
|
||||
user={{
|
||||
avatar_url: "mxc://matrix.org/EqMZYbAYhREvHXvYFyfxOlkf",
|
||||
displayname: "Nicholas Briteli",
|
||||
}}
|
||||
userId="@nicholasbritelli:matrix.org"
|
||||
/>
|
||||
<RoomPreview
|
||||
room={{
|
||||
aliases: ["#murrays:cheese.bar"],
|
||||
avatar_url: "mxc://bleeker.street/CHEDDARandBRIE",
|
||||
guest_can_join: false,
|
||||
name: "CHEESE",
|
||||
num_joined_members: 37,
|
||||
room_id: "!ol19s:bleecker.street",
|
||||
topic: "Tasty tasty cheese",
|
||||
world_readable: true,
|
||||
}}
|
||||
/>
|
||||
</InviteTile>
|
||||
);
|
64
src/components/InviteTile.tsx
Normal file
64
src/components/InviteTile.tsx
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
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 "./Tile";
|
||||
import LinkButton from "./LinkButton";
|
||||
import TextButton from "./TextButton";
|
||||
|
||||
import "./InviteTile.scss";
|
||||
|
||||
export interface InviteLink {
|
||||
type: "link";
|
||||
link: string;
|
||||
}
|
||||
|
||||
export interface InviteInstruction {
|
||||
type: "instruction";
|
||||
text: string;
|
||||
}
|
||||
|
||||
type InviteAction = InviteLink | InviteInstruction;
|
||||
|
||||
interface IProps {
|
||||
children?: React.ReactNode;
|
||||
inviteAction: InviteAction;
|
||||
}
|
||||
|
||||
const InviteTile: React.FC<IProps> = ({ children, inviteAction }: IProps) => {
|
||||
let invite: React.ReactNode;
|
||||
switch (inviteAction.type) {
|
||||
case "link":
|
||||
invite = (
|
||||
<LinkButton href={inviteAction.link}>Accept invite</LinkButton>
|
||||
);
|
||||
break;
|
||||
case "instruction":
|
||||
invite = <p>{inviteAction.text}</p>;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tile className="inviteTile">
|
||||
{children}
|
||||
{invite}
|
||||
<TextButton>Advanced options</TextButton>
|
||||
</Tile>
|
||||
);
|
||||
};
|
||||
|
||||
export default InviteTile;
|
28
src/components/LinkButton.tsx
Normal file
28
src/components/LinkButton.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
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 classnames from "classnames";
|
||||
|
||||
import "./Button.scss";
|
||||
|
||||
interface IProps extends React.LinkHTMLAttributes<HTMLElement> {}
|
||||
|
||||
const LinkButton: React.FC<IProps> = ({ className, ...props }: IProps) => (
|
||||
<a className={classnames("button", className)} {...props} />
|
||||
);
|
||||
|
||||
export default LinkButton;
|
|
@ -26,8 +26,8 @@ const MatrixTile: React.FC = () => {
|
|||
<Tile className="matrixTile">
|
||||
<img src={logo} alt="matrix-logo" />
|
||||
<div>
|
||||
Matrix.to is a stateless URL redirecting service for the{" "}
|
||||
<a href="https://matrix.org">Matrix</a> ecosystem.
|
||||
This invite uses <a href="https://matrix.org">Matrix</a>, an
|
||||
open network for secure, decentralized communication.
|
||||
</div>
|
||||
</Tile>
|
||||
);
|
||||
|
|
31
src/components/RoomPreview.scss
Normal file
31
src/components/RoomPreview.scss
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
.roomPreview {
|
||||
> .avatar {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
> h1 {
|
||||
font-size: 20px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.roomTopic {
|
||||
padding-top: 32px;
|
||||
}
|
50
src/components/RoomPreview.tsx
Normal file
50
src/components/RoomPreview.tsx
Normal file
|
@ -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 { Room } from "cypher/src/schemas/PublicRoomsSchema";
|
||||
|
||||
import { RoomAvatar } from "./Avatar";
|
||||
|
||||
import "./RoomPreview.scss";
|
||||
|
||||
interface IProps {
|
||||
room: Room;
|
||||
}
|
||||
|
||||
const RoomPreview: React.FC<IProps> = ({ room }: IProps) => {
|
||||
const roomAlias = room.aliases ? room.aliases[0] : room.room_id;
|
||||
return (
|
||||
<div className="roomPreview">
|
||||
<RoomAvatar room={room} />
|
||||
<h1>{room.name}</h1>
|
||||
<p>{room.num_joined_members.toLocaleString()} members</p>
|
||||
<p>{roomAlias}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const RoomPreviewWithTopic: React.FC<IProps> = ({ room }: IProps) => {
|
||||
const topic = room.topic ? <p className="roomTopic">{room.topic}</p> : null;
|
||||
return (
|
||||
<>
|
||||
<RoomPreview room={room} />
|
||||
{topic}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default RoomPreview;
|
|
@ -19,11 +19,15 @@ limitations under the License.
|
|||
.tile {
|
||||
background-color: $background;
|
||||
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
color: $grey;
|
||||
}
|
||||
}
|
||||
|
|
74
src/components/UserPreview.scss
Normal file
74
src/components/UserPreview.scss
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
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 "../color-scheme";
|
||||
|
||||
.userPreview {
|
||||
width: 100%;
|
||||
|
||||
> .avatar {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.miniUserPreview {
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
border: 1px solid $app-background;
|
||||
border-radius: 16px;
|
||||
padding: 6px 16px;
|
||||
|
||||
> div {
|
||||
flex-grow: 1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
50
src/components/UserPreview.tsx
Normal file
50
src/components/UserPreview.tsx
Normal file
|
@ -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 { User } from "cypher/src/schemas/UserSchema";
|
||||
|
||||
import { UserAvatar } from "./Avatar";
|
||||
|
||||
import "./UserPreview.scss";
|
||||
|
||||
interface IProps {
|
||||
user: User;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
const UserPreview: React.FC<IProps> = ({ user, userId }: IProps) => (
|
||||
<div className="userPreview">
|
||||
<UserAvatar user={user} />
|
||||
<h1>{user.displayname} invites you to connect</h1>
|
||||
<p>{userId}</p>
|
||||
<hr />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default UserPreview;
|
||||
|
||||
export const InviterPreview: React.FC<IProps> = ({ user, userId }: IProps) => (
|
||||
<div className="miniUserPreview">
|
||||
<div>
|
||||
<h1>
|
||||
Invited by <b>{user.displayname}</b>
|
||||
</h1>
|
||||
<p>{userId}</p>
|
||||
</div>
|
||||
<UserAvatar user={user} />
|
||||
</div>
|
||||
);
|
65
src/contexts/ClientContext.ts
Normal file
65
src/contexts/ClientContext.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
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 { Client, discoverServer } from "cypher";
|
||||
import { prefixFetch } from "cypher/src/utils/fetch";
|
||||
|
||||
type State = {
|
||||
clientURL: string;
|
||||
client: Client;
|
||||
}[];
|
||||
|
||||
// Actions are a discriminated union.
|
||||
export enum ActionTypes {
|
||||
AddClient = "ADD_CLIENT",
|
||||
RemoveClient = "REMOVE_CLIENT",
|
||||
}
|
||||
|
||||
export interface AddClient {
|
||||
action: ActionTypes.AddClient;
|
||||
clientURL: string;
|
||||
}
|
||||
|
||||
export interface RemoveClient {
|
||||
action: ActionTypes.RemoveClient;
|
||||
clientURL: string;
|
||||
}
|
||||
|
||||
export type Action = AddClient | RemoveClient;
|
||||
|
||||
export const INITIAL_STATE: State = [];
|
||||
export const reducer = async (state: State, action: Action): Promise<State> => {
|
||||
switch (action.action) {
|
||||
case ActionTypes.AddClient:
|
||||
return state.filter((x) => x.clientURL !== action.clientURL);
|
||||
|
||||
case ActionTypes.RemoveClient:
|
||||
if (!state.filter((x) => x.clientURL === action.clientURL)) {
|
||||
const resolvedURL = await discoverServer(action.clientURL);
|
||||
state.push({
|
||||
clientURL: resolvedURL,
|
||||
client: prefixFetch(resolvedURL),
|
||||
});
|
||||
}
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
// The null is a hack to make the type checker happy
|
||||
// create context does not need an argument
|
||||
export default React.createContext<typeof reducer | null>(null);
|
Loading…
Reference in a new issue