Merge branch 'account_deletion' into master

This commit is contained in:
ErickSkrauch
2020-11-19 15:40:08 +01:00
90 changed files with 3929 additions and 2769 deletions

View File

@@ -0,0 +1,27 @@
import React, { ComponentType } from 'react';
import clsx from 'clsx';
import styles from './pseudoAvatar.scss';
interface Props {
index?: number;
deleted?: boolean;
className?: string;
}
const PseudoAvatar: ComponentType<Props> = ({ index = 0, deleted, className }) => (
<div
className={clsx(
styles.pseudoAvatarWrapper,
{
[styles.deletedPseudoAvatar]: deleted,
},
className,
)}
>
<div className={clsx(styles.pseudoAvatar, styles[`pseudoAvatar${index % 7}`])} />
{deleted ? <div className={styles.deletedIcon} /> : ''}
</div>
);
export default PseudoAvatar;

View File

@@ -1,7 +1,8 @@
import React, { InputHTMLAttributes, MouseEventHandler } from 'react';
import ReactDOM from 'react-dom';
import { MessageDescriptor } from 'react-intl';
import ClickAwayListener from 'react-click-away-listener';
import clsx from 'clsx';
import { COLOR_GREEN, Color } from 'app/components/ui';
import styles from './dropdown.scss';
@@ -12,7 +13,7 @@ type ItemLabel = I18nString | React.ReactElement;
interface Props extends InputHTMLAttributes<HTMLInputElement> {
label: I18nString;
items: { [value: string]: ItemLabel };
items: Record<string, ItemLabel>;
block?: boolean;
color: Color;
}
@@ -37,18 +38,6 @@ export default class Dropdown extends FormInputComponent<Props, State> {
activeItem: null,
};
componentDidMount() {
// listen to capturing phase to ensure, that our event handler will be
// called before all other
// @ts-ignore
document.addEventListener('click', this.onBodyClick, true);
}
componentWillUnmount() {
// @ts-ignore
document.removeEventListener('click', this.onBodyClick);
}
render() {
const { color, block, items, ...restProps } = this.props;
const { isActive } = this.state;
@@ -59,7 +48,7 @@ export default class Dropdown extends FormInputComponent<Props, State> {
const label = React.isValidElement(activeItem.label) ? activeItem.label : this.formatMessage(activeItem.label);
return (
<div>
<ClickAwayListener onClickAway={this.onCloseClick}>
<div
className={clsx(styles[color], {
[styles.block]: block,
@@ -84,7 +73,7 @@ export default class Dropdown extends FormInputComponent<Props, State> {
</div>
{this.renderError()}
</div>
</ClickAwayListener>
);
}
@@ -137,17 +126,9 @@ export default class Dropdown extends FormInputComponent<Props, State> {
this.toggle();
};
onBodyClick: MouseEventHandler = (event) => {
onCloseClick = () => {
if (this.state.isActive) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const el = ReactDOM.findDOMNode(this)!;
if (!el.contains(event.target as HTMLElement) && el !== event.target) {
event.preventDefault();
event.stopPropagation();
this.toggle();
}
this.toggle();
}
};
}

View File

@@ -30,3 +30,4 @@ export const SKIN_LIGHT: Skin = 'light';
export const skins: Array<Skin> = [SKIN_DARK, SKIN_LIGHT];
export { default as RelativeTime } from './RelativeTime';
export { default as PseudoAvatar } from './PseudoAvatar';

View File

@@ -9,10 +9,11 @@ import styles from './componentLoader.scss';
interface Props {
skin?: Skin;
className?: string;
}
const ComponentLoader: ComponentType<Props> = ({ skin = 'dark' }) => (
<div className={clsx(styles.componentLoader, styles[`${skin}ComponentLoader`])}>
const ComponentLoader: ComponentType<Props> = ({ skin = 'dark', className }) => (
<div className={clsx(styles.componentLoader, styles[`${skin}ComponentLoader`], className)}>
<div className={styles.spins}>
{new Array(5).fill(0).map((_, index) => (
<div className={clsx(styles.spin, styles[`spin${index}`])} key={index} />

View File

@@ -1,41 +1,31 @@
@import '~app/components/ui/colors.scss';
.componentLoader {
width: 100%;
text-align: center;
font-size: 20px;
}
.spins {
height: 40px;
height: 2em;
display: flex;
flex-shrink: 1;
flex-basis: 0;
flex-direction: row;
}
.spin {
height: 20px;
width: 20px;
height: 1em;
width: 1em;
display: inline-block;
margin: 10px 2px;
margin: 0.5em 0.1em;
opacity: 0;
animation: loaderAnimation 1s infinite;
}
.spin1 {
animation-delay: 0s;
}
.spin2 {
animation-delay: 0.1s;
}
.spin3 {
animation-delay: 0.2s;
}
.spin4 {
animation-delay: 0.3s;
}
.spin5 {
animation-delay: 0.4s;
@for $i from 0 to 5 {
.spin#{$i} {
animation-delay: 0.1s * $i;
}
}
/**

View File

@@ -0,0 +1,53 @@
@import '~app/components/ui/colors.scss';
.pseudoAvatarWrapper {
position: relative;
display: inline-flex; // Needed to get right position of the cross icon
}
.pseudoAvatar {
composes: minecraft-character from '~app/components/ui/icons.scss';
font-size: 1em;
&0 {
color: $green;
}
&1 {
color: $blue;
}
&2 {
color: $violet;
}
&3 {
color: $orange;
}
&4 {
color: $dark_blue;
}
&5 {
color: $light_violet;
}
&6 {
color: $red;
}
.deletedPseudoAvatar & {
color: #ccc;
}
}
.deletedIcon {
composes: close from '~app/components/ui/icons.scss';
position: absolute;
top: 0.16em;
left: -0.145em;
font-size: 0.7em;
color: rgba($red, 0.75);
}