Add gdpr options
This commit is contained in:
@@ -21,6 +21,7 @@ import { ActionType, ClientContext } from '../contexts/ClientContext';
|
||||
import ClientList from './ClientList';
|
||||
import { SafeLink } from '../parser/types';
|
||||
import Button from './Button';
|
||||
import StyledCheckbox from './StyledCheckbox';
|
||||
|
||||
interface IProps {
|
||||
link: SafeLink;
|
||||
@@ -31,40 +32,34 @@ const ClientSelection: React.FC<IProps> = ({ link }: IProps) => {
|
||||
const [rememberSelection, setRememberSelection] = useState(false);
|
||||
const options = (
|
||||
<div className="advancedOptions">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
onChange={(): void => {
|
||||
setRememberSelection(!rememberSelection);
|
||||
}}
|
||||
checked={rememberSelection}
|
||||
/>
|
||||
<StyledCheckbox
|
||||
onChange={(): void => {
|
||||
setRememberSelection(!rememberSelection);
|
||||
}}
|
||||
checked={rememberSelection}
|
||||
>
|
||||
Remember my selection for future invites in this browser
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
onChange={(): void => {
|
||||
clientStateDispatch({
|
||||
action: ActionType.ToggleShowOnlyDeviceClients,
|
||||
});
|
||||
}}
|
||||
checked={clientState.showOnlyDeviceClients}
|
||||
/>
|
||||
</StyledCheckbox>
|
||||
<StyledCheckbox
|
||||
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}
|
||||
/>
|
||||
</StyledCheckbox>
|
||||
<StyledCheckbox
|
||||
onChange={(): void => {
|
||||
clientStateDispatch({
|
||||
action: ActionType.ToggleShowExperimentalClients,
|
||||
});
|
||||
}}
|
||||
checked={clientState.showExperimentalClients}
|
||||
>
|
||||
Show experimental clients
|
||||
</label>
|
||||
</StyledCheckbox>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
.defaultPreview {
|
||||
.avatar {
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
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 { SafeLink } from '../parser/types';
|
||||
import Avatar from './Avatar';
|
||||
|
||||
import './DefaultPreview.scss';
|
||||
|
||||
import genericRoomPreview from '../imgs/chat-icon.svg';
|
||||
|
||||
interface IProps {
|
||||
link: SafeLink;
|
||||
}
|
||||
|
||||
const DefaultPreview: React.FC<IProps> = ({ link }: IProps) => {
|
||||
return (
|
||||
<div className="defaultPreview">
|
||||
<Avatar
|
||||
avatarUrl={genericRoomPreview}
|
||||
label={`Generic icon representing ${link.identifier}`}
|
||||
/>
|
||||
<h1>{link.identifier}</h1>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DefaultPreview;
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
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';
|
||||
|
||||
.homeserverOptions {
|
||||
display: grid;
|
||||
row-gap: 20px;
|
||||
|
||||
background: $app-background;
|
||||
text-align: left;
|
||||
|
||||
> * {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.homeserverOptionsDescription {
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
> p {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
> img {
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
background-color: $background;
|
||||
height: 62px;
|
||||
width: 62px;
|
||||
padding: 11px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
display: grid;
|
||||
row-gap: 25px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
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 HomeserverOptions from './HomeserverOptions';
|
||||
|
||||
export default {
|
||||
title: 'HomeserverOptions',
|
||||
parameters: {
|
||||
design: {
|
||||
type: 'figma',
|
||||
url:
|
||||
'https://figma.com/file/WSXjCGc1k6FVI093qhlzOP/04-Recieving-share-link?node-id=143%3A5853',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Default: React.FC = () => <HomeserverOptions />;
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
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, useState } from 'react';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { string } from 'zod';
|
||||
|
||||
import Tile from './Tile';
|
||||
import HSContext, { TempHSContext, ActionType } from '../contexts/HSContext';
|
||||
import icon from '../imgs/telecom-mast.svg';
|
||||
import Button from './Button';
|
||||
import Input from './Input';
|
||||
import Toggle from './Toggle';
|
||||
import StyledCheckbox from './StyledCheckbox';
|
||||
|
||||
import './HomeserverOptions.scss';
|
||||
|
||||
interface IProps {}
|
||||
|
||||
interface FormValues {
|
||||
HSUrl: string;
|
||||
}
|
||||
|
||||
function validateURL(values: FormValues): Partial<FormValues> {
|
||||
const errors: Partial<FormValues> = {};
|
||||
try {
|
||||
string().url().parse(values.HSUrl);
|
||||
} catch {
|
||||
errors.HSUrl = 'This must be a valid url';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
const HomeserverOptions: React.FC<IProps> = () => {
|
||||
const HSStateDispatcher = useContext(HSContext)[1];
|
||||
const TempHSStateDispatcher = useContext(TempHSContext)[1];
|
||||
const [rememberSelection, setRemeberSelection] = useState(false);
|
||||
const [usePrefered, setUsePrefered] = useState(false);
|
||||
const dispatcher = rememberSelection
|
||||
? HSStateDispatcher
|
||||
: TempHSStateDispatcher;
|
||||
|
||||
const hsInput = usePrefered ? (
|
||||
<Formik
|
||||
initialValues={{
|
||||
HSUrl: '',
|
||||
}}
|
||||
validate={validateURL}
|
||||
onSubmit={({ HSUrl }): void =>
|
||||
dispatcher({ action: ActionType.SetHS, HSURL: HSUrl })
|
||||
}
|
||||
>
|
||||
<Form>
|
||||
<Input
|
||||
type="text"
|
||||
name="HSUrl"
|
||||
placeholder="https://example.com"
|
||||
/>
|
||||
<Button type="submit">Set HS</Button>
|
||||
</Form>
|
||||
</Formik>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<Tile className="homeserverOptions">
|
||||
<div className="homeserverOptionsDescription">
|
||||
<div>
|
||||
<p>
|
||||
Let's locate a homeserver to show you more information.
|
||||
</p>
|
||||
</div>
|
||||
<img
|
||||
src={icon}
|
||||
alt="Icon making it clear that connections may be made with external services"
|
||||
/>
|
||||
</div>
|
||||
<StyledCheckbox
|
||||
checked={rememberSelection}
|
||||
onChange={(e): void => setRemeberSelection(e.target.checked)}
|
||||
>
|
||||
Remember my choice.
|
||||
</StyledCheckbox>
|
||||
<Button
|
||||
onClick={(): void => {
|
||||
dispatcher({ action: ActionType.SetAny });
|
||||
}}
|
||||
>
|
||||
Use any homeserver
|
||||
</Button>
|
||||
<Toggle
|
||||
checked={usePrefered}
|
||||
onChange={(): void => setUsePrefered(!usePrefered)}
|
||||
>
|
||||
Use my prefered homeserver only
|
||||
</Toggle>
|
||||
{hsInput}
|
||||
</Tile>
|
||||
);
|
||||
};
|
||||
|
||||
export default HomeserverOptions;
|
||||
@@ -22,6 +22,8 @@ import InviteTile from './InviteTile';
|
||||
import { SafeLink, LinkKind } from '../parser/types';
|
||||
import UserPreview from './UserPreview';
|
||||
import EventPreview from './EventPreview';
|
||||
import HomeserverOptions from './HomeserverOptions';
|
||||
import DefaultPreview from './DefaultPreview';
|
||||
import { clientMap } from '../clients';
|
||||
import {
|
||||
getRoomFromId,
|
||||
@@ -30,16 +32,26 @@ import {
|
||||
getUser,
|
||||
} from '../utils/cypher-wrapper';
|
||||
import { ClientContext } from '../contexts/ClientContext';
|
||||
import HSContext, {
|
||||
TempHSContext,
|
||||
HSOptions,
|
||||
State as HSState,
|
||||
} from '../contexts/HSContext';
|
||||
import Toggle from './Toggle';
|
||||
|
||||
interface IProps {
|
||||
link: SafeLink;
|
||||
}
|
||||
|
||||
const LOADING: JSX.Element = <>Generating invite</>;
|
||||
|
||||
const invite = async ({ link }: { link: SafeLink }): Promise<JSX.Element> => {
|
||||
const invite = async ({
|
||||
clientAddress,
|
||||
link,
|
||||
}: {
|
||||
clientAddress: string;
|
||||
link: SafeLink;
|
||||
}): Promise<JSX.Element> => {
|
||||
// TODO: replace with client fetch
|
||||
const defaultClient = await client('https://matrix.org');
|
||||
const defaultClient = await client(clientAddress);
|
||||
switch (link.kind) {
|
||||
case LinkKind.Alias:
|
||||
return (
|
||||
@@ -85,12 +97,79 @@ const invite = async ({ link }: { link: SafeLink }): Promise<JSX.Element> => {
|
||||
}
|
||||
};
|
||||
|
||||
const LinkPreview: React.FC<IProps> = ({ link }: IProps) => {
|
||||
const [content, setContent] = useState(LOADING);
|
||||
interface PreviewProps extends IProps {
|
||||
client: string;
|
||||
}
|
||||
|
||||
const Preview: React.FC<PreviewProps> = ({ link, client }: PreviewProps) => {
|
||||
const [content, setContent] = useState(<DefaultPreview link={link} />);
|
||||
|
||||
// TODO: support multiple clients with vias
|
||||
useEffect(() => {
|
||||
(async (): Promise<void> => setContent(await invite({ link })))();
|
||||
}, [link]);
|
||||
(async (): Promise<void> =>
|
||||
setContent(
|
||||
await invite({
|
||||
clientAddress: client,
|
||||
link,
|
||||
})
|
||||
))();
|
||||
}, [link, client]);
|
||||
|
||||
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) => {
|
||||
let content: JSX.Element;
|
||||
const [showHSOptions, setShowHSOPtions] = useState(false);
|
||||
const [hsOptions] = useContext(HSContext);
|
||||
const [tempHSState] = useContext(TempHSContext);
|
||||
|
||||
if (
|
||||
hsOptions.option === HSOptions.Unset &&
|
||||
tempHSState.option === HSOptions.Unset
|
||||
) {
|
||||
content = (
|
||||
<>
|
||||
<DefaultPreview link={link} />
|
||||
<Toggle
|
||||
checked={showHSOptions}
|
||||
onChange={(): void => setShowHSOPtions(!showHSOptions)}
|
||||
>
|
||||
Show more information
|
||||
</Toggle>
|
||||
</>
|
||||
);
|
||||
if (showHSOptions) {
|
||||
content = (
|
||||
<>
|
||||
{content}
|
||||
<HomeserverOptions />
|
||||
</>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const clients =
|
||||
tempHSState.option !== HSOptions.Unset
|
||||
? selectedClient(link, tempHSState)
|
||||
: selectedClient(link, hsOptions);
|
||||
content = <Preview link={link} client={clients[0]} />;
|
||||
}
|
||||
|
||||
const [{ clientId }] = useContext(ClientContext);
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
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';
|
||||
@import '../mixins';
|
||||
|
||||
.styledCheckbox {
|
||||
display: flex;
|
||||
|
||||
align-items: center;
|
||||
|
||||
input[type='checkbox'] {
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&:checked + div {
|
||||
background: $foreground;
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&.focus-visible {
|
||||
& + div {
|
||||
@include unreal-focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.styledCheckboxWrapper {
|
||||
display: flex;
|
||||
|
||||
margin-right: 5px;
|
||||
border: 2px solid $foreground;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Stolen from the matrix-react-sdk
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import tick from '../imgs/tick.svg';
|
||||
|
||||
import './StyledCheckbox.scss';
|
||||
|
||||
interface IProps extends React.InputHTMLAttributes<HTMLInputElement> {}
|
||||
|
||||
const StyledCheckbox: React.FC<IProps> = ({
|
||||
children,
|
||||
className,
|
||||
...otherProps
|
||||
}: IProps) => (
|
||||
<label className="styledCheckbox">
|
||||
<input {...otherProps} type="checkbox" />
|
||||
{/* Using the div to center the image */}
|
||||
<div className="styledCheckboxWrapper">
|
||||
<img src={tick} />
|
||||
</div>
|
||||
{children}
|
||||
</label>
|
||||
);
|
||||
|
||||
export default StyledCheckbox;
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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 '../mixins';
|
||||
|
||||
.toggle {
|
||||
display: flex;
|
||||
|
||||
> input[type='checkbox'] {
|
||||
// Remove the OS's representation
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
appearance: none;
|
||||
|
||||
&.focus-visible {
|
||||
& + img {
|
||||
@include unreal-focus;
|
||||
}
|
||||
}
|
||||
|
||||
&:checked {
|
||||
& + img {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
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 chevron from '../imgs/chevron-down.svg';
|
||||
|
||||
import './Toggle.scss';
|
||||
|
||||
interface IProps extends React.InputHTMLAttributes<Element> {
|
||||
children?: React.ReactChild;
|
||||
}
|
||||
|
||||
const Toggle: React.FC<IProps> = ({ children, ...props }: IProps) => (
|
||||
<label className="toggle">
|
||||
{children}
|
||||
<input type="checkbox" {...props} />
|
||||
<img src={chevron} />
|
||||
</label>
|
||||
);
|
||||
|
||||
export default Toggle;
|
||||
Reference in New Issue
Block a user