React Native identicon (#173)

* React Native identicon

* Simplify using generate interface

* Remove unknown RN props

* Update packages/reactnative-identicon/src/icons/Polkadot.tsx

Co-Authored-By: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com>

* Linting, deps move

* Default component with themes
This commit is contained in:
Jaco Greeff
2019-08-02 10:15:47 +02:00
committed by GitHub
parent 3dd5981ba7
commit 004a4398dd
14 changed files with 1762 additions and 68 deletions
@@ -0,0 +1,81 @@
// Copyright 2017-2019 @polkadot/react-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Prefix } from '@polkadot/util-crypto/address/types';
import { Props as ComponentProps } from './types';
import React from 'react';
import { isHex, isU8a, u8aToHex } from '@polkadot/util';
import { decodeAddress, encodeAddress } from '@polkadot/util-crypto';
import { Empty, Polkadot } from './icons';
const Fallback = Polkadot;
interface Props {
prefix?: Prefix;
size?: number;
theme?: 'polkadot';
value?: string | Uint8Array | null;
}
interface State {
address: string;
publicKey: string;
}
const DEFAULT_SIZE = 64;
const DEFAULT_THEME = 'polkadot';
const Components: Record<string, React.ComponentType<ComponentProps>> = {
polkadot: Polkadot
};
export default class IdentityIcon extends React.PureComponent<Props, State> {
public state: State = {
address: '',
publicKey: '0x'
};
private static prefix?: Prefix = undefined;
public static setDefaultPrefix (prefix: Prefix): void {
IdentityIcon.prefix = prefix;
}
public static getDerivedStateFromProps ({ prefix = IdentityIcon.prefix, value }: Props, prevState: State): State | null {
try {
const address = isU8a(value) || isHex(value)
? encodeAddress(value, prefix)
: (value || '');
const publicKey = u8aToHex(decodeAddress(address, true, prefix));
return address === prevState.address
? null
: { address, publicKey };
} catch (error) {
return {
address: '',
publicKey: '0x'
};
}
}
public render (): React.ReactNode {
const { theme = DEFAULT_THEME, size = DEFAULT_SIZE } = this.props;
const { address, publicKey } = this.state;
const Component = !address
? Empty
: Components[theme] || Fallback;
return (
<Component
address={address}
publicKey={publicKey}
size={size}
/>
);
}
}
@@ -0,0 +1,25 @@
// Copyright 2017-2019 @polkadot/react-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Props } from '../types';
import React from 'react';
import { View } from 'react-native';
import Svg from 'react-native-svg';
export default class Empty extends React.PureComponent<Props> {
public render (): React.ReactNode {
const { size } = this.props;
return (
<View>
<Svg
height={size}
viewBox='0 0 64 64'
width={size}
/>
</View>
);
}
}
@@ -0,0 +1,45 @@
// Copyright 2018 @polkadot/react-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Props as BaseProps } from '../types';
import React from 'react';
import { View } from 'react-native';
import Svg, { Circle as SvgCircle } from 'react-native-svg';
import generateIcon, { Circle as CircleType } from '@polkadot/ui-shared/polkadotIcon';
interface Props extends BaseProps {
sixPoint?: boolean;
}
export default class Identicon extends React.PureComponent<Props> {
public render (): React.ReactNode {
const { address, sixPoint, size } = this.props;
return (
<View>
<Svg
height={size}
id={address}
width={size}
viewBox='0 0 64 64'
>
{generateIcon(address, sixPoint).map(this.renderCircle)}
</Svg>
</View>
);
}
private renderCircle = ({ cx, cy, r, fill }: CircleType, key: number): React.ReactNode => {
return (
<SvgCircle
key={key}
cx={cx}
cy={cy}
r={r}
fill={fill}
/>
);
}
}
@@ -0,0 +1,6 @@
// Copyright 2017-2019 @polkadot/react-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export { default as Empty } from './Empty';
export { default as Polkadot } from './Polkadot';
@@ -0,0 +1,8 @@
// Copyright 2017-2019 @polkadot/react-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Identicon from './Identicon';
export * from './icons';
export default Identicon;
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2018 @polkadot/react-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// NOTE This is not clean since we miss the proper RN typings. However it does
// conflict with everything else, so... well, stick with the minimum here
declare module 'react-native' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface GestureResponderHandlers {}
type ImageProperties = Record<string, string>;
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface ViewProperties {}
export const View: React.ComponentClass;
}
@@ -0,0 +1,9 @@
// Copyright 2018 @polkadot/react-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export interface Props {
address: string;
publicKey: string;
size: number;
}