Add client options and styling for client tiles
This commit is contained in:
parent
6e7a119831
commit
74d223e475
6 changed files with 346 additions and 0 deletions
22
src/components/ClientList.scss
Normal file
22
src/components/ClientList.scss
Normal 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;
|
||||||
|
}
|
91
src/components/ClientList.tsx
Normal file
91
src/components/ClientList.tsx
Normal 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;
|
30
src/components/ClientSelection.scss
Normal file
30
src/components/ClientSelection.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
79
src/components/ClientSelection.tsx
Normal file
79
src/components/ClientSelection.tsx
Normal 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;
|
66
src/components/ClientTile.scss
Normal file
66
src/components/ClientTile.scss
Normal 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: '>';
|
||||||
|
}
|
||||||
|
}
|
58
src/components/ClientTile.tsx
Normal file
58
src/components/ClientTile.tsx
Normal 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;
|
Loading…
Reference in a new issue