Add client options and styling for client tiles

This commit is contained in:
Jorik Schellekens 2020-09-01 10:41:17 +02:00
parent 6e7a119831
commit 74d223e475
6 changed files with 346 additions and 0 deletions

View file

@ -0,0 +1,22 @@
/*
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.
*/
.clientList {
display: grid;
row-gap: 20px;
list-style-type: none;
padding-inline-start: 0;
}

View file

@ -0,0 +1,91 @@
/*
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, { useContext } from 'react';
import { UAContext } from '@quentin-sommer/react-useragent';
import { SafeLink } from '../parser/types';
import { ActionType, ClientContext } from '../contexts/ClientContext';
import Clients from '../clients';
import { Client, Platform } from '../clients/types';
import ClientTile from './ClientTile';
import './ClientList.scss';
interface IProps {
link: SafeLink;
}
const ClientList: React.FC<IProps> = ({ link }: IProps) => {
const [
{ rememberSelection, showOnlyDeviceClients, showExperimentalClients },
clientDispatcher,
] = useContext(ClientContext);
const { uaResults } = useContext(UAContext);
/*
* Function to decide whether a client is shown
*/
const showClient = (client: Client): boolean => {
let showClient = false;
if (!showOnlyDeviceClients || uaResults === {}) {
showClient = true;
}
switch (client.platform) {
case Platform.Desktop:
showClient = showClient || !(uaResults as any).mobile;
break;
case Platform.iOS:
showClient = showClient || (uaResults as any).ios;
break;
case Platform.Android:
showClient = showClient || (uaResults as any).android;
break;
}
if (!showExperimentalClients && client.experimental) {
showClient = false;
}
return showClient;
};
const clientLi = (client: Client): JSX.Element => (
<li
key={client.clientId}
onClick={(): void =>
rememberSelection
? clientDispatcher({
action: ActionType.SetClient,
clientId: client.clientId,
})
: undefined
}
>
<ClientTile client={client} link={link} />
</li>
);
return (
<ul className="clientList">
{Clients.filter(showClient).map(clientLi)}
</ul>
);
};
export default ClientList;

View file

@ -0,0 +1,30 @@
/*
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.
*/
.advanced {
margin: 0 5%;
.advancedOptions {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.clientList {
margin-top: 20px;
}
}

View file

@ -0,0 +1,79 @@
/*
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, { useContext } from 'react';
import './ClientSelection.scss';
import { ActionType, ClientContext } from '../contexts/ClientContext';
import ClientList from './ClientList';
import { SafeLink } from '../parser/types';
interface IProps {
link: SafeLink;
}
const ClientSelection: React.FC<IProps> = ({ link }: IProps) => {
const [clientState, clientStateDispatch] = useContext(ClientContext);
const options = (
<div className="advancedOptions">
<label>
<input
type="checkbox"
onChange={(): void => {
clientStateDispatch({
action: ActionType.ToggleRememberSelection,
});
}}
checked={clientState.rememberSelection}
/>
Remember my selection for future invites in this browser
</label>
<label>
<input
type="checkbox"
onChange={(): void => {
clientStateDispatch({
action: ActionType.ToggleShowOnlyDeviceClients,
});
}}
checked={clientState.showOnlyDeviceClients}
/>
Show only clients suggested for this device
</label>
<label>
<input
type="checkbox"
onChange={(): void => {
clientStateDispatch({
action: ActionType.ToggleShowExperimentalClients,
});
}}
checked={clientState.showExperimentalClients}
/>
Show experimental clients
</label>
</div>
);
return (
<div className="advanced">
{options}
<ClientList link={link} />
</div>
);
};
export default ClientSelection;

View file

@ -0,0 +1,66 @@
/*
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';
.clientTile {
display: flex;
flex-direction: row;
height: 155px;
width: 100%;
color: $foreground;
> img {
flex-shrink: 0;
height: 100%;
}
h1 {
text-align: left;
font-size: 14px;
line-height: 24px;
}
p {
margin-right: 20px;
margin-top: 20px;
text-align: left;
}
border: 1px solid $borders;
border-radius: 8px;
padding: 8px;
// For the chevron
position: relative;
}
.clientTileLink {
position: relative;
width: 100%;
&::after {
// TODO: add chevron top right
position: absolute;
right: 10px;
top: 5px;
content: '>';
}
}

View file

@ -0,0 +1,58 @@
/*
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 { Client, ClientKind } from '../clients/types';
import { SafeLink } from '../parser/types';
import Tile from './Tile';
import './ClientTile.scss';
interface IProps {
client: Client;
link: SafeLink;
}
const ClientTile: React.FC<IProps> = ({ client, link }: IProps) => {
const inviteLine =
client.kind === ClientKind.TEXT_CLIENT ? (
<p>{client.toInviteString(link)}</p>
) : null;
const className = classNames('clientTile', {
clientTileLink: client.kind === ClientKind.LINKED_CLIENT,
});
let clientTile = (
<Tile className={className}>
<img src={client.logo} alt={client.name + ' logo'} />
<div>
<h1>{client.name}</h1>
<p>{client.description}</p>
{inviteLine}
</div>
</Tile>
);
if (client.kind === ClientKind.LINKED_CLIENT) {
clientTile = <a href={client.toUrl(link).toString()}>{clientTile}</a>;
}
return clientTile;
};
export default ClientTile;