diff --git a/src/components/ClientList.scss b/src/components/ClientList.scss new file mode 100644 index 0000000..24c8823 --- /dev/null +++ b/src/components/ClientList.scss @@ -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; +} diff --git a/src/components/ClientList.tsx b/src/components/ClientList.tsx new file mode 100644 index 0000000..3fdb745 --- /dev/null +++ b/src/components/ClientList.tsx @@ -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 = ({ 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 => ( +
  • + rememberSelection + ? clientDispatcher({ + action: ActionType.SetClient, + clientId: client.clientId, + }) + : undefined + } + > + +
  • + ); + + return ( + + ); +}; + +export default ClientList; diff --git a/src/components/ClientSelection.scss b/src/components/ClientSelection.scss new file mode 100644 index 0000000..3900f77 --- /dev/null +++ b/src/components/ClientSelection.scss @@ -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; + } +} diff --git a/src/components/ClientSelection.tsx b/src/components/ClientSelection.tsx new file mode 100644 index 0000000..6a15ad4 --- /dev/null +++ b/src/components/ClientSelection.tsx @@ -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 = ({ link }: IProps) => { + const [clientState, clientStateDispatch] = useContext(ClientContext); + const options = ( +
    + + + +
    + ); + + return ( +
    + {options} + +
    + ); +}; + +export default ClientSelection; diff --git a/src/components/ClientTile.scss b/src/components/ClientTile.scss new file mode 100644 index 0000000..18a8be0 --- /dev/null +++ b/src/components/ClientTile.scss @@ -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: '>'; + } +} diff --git a/src/components/ClientTile.tsx b/src/components/ClientTile.tsx new file mode 100644 index 0000000..6367b72 --- /dev/null +++ b/src/components/ClientTile.tsx @@ -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 = ({ client, link }: IProps) => { + const inviteLine = + client.kind === ClientKind.TEXT_CLIENT ? ( +

    {client.toInviteString(link)}

    + ) : null; + + const className = classNames('clientTile', { + clientTileLink: client.kind === ClientKind.LINKED_CLIENT, + }); + let clientTile = ( + + {client.name +
    +

    {client.name}

    +

    {client.description}

    + {inviteLine} +
    +
    + ); + + if (client.kind === ClientKind.LINKED_CLIENT) { + clientTile = {clientTile}; + } + + return clientTile; +}; + +export default ClientTile;