import React, { useMemo } from 'react'; import { Just, Nothing } from 'folktale/maybe'; import ob from 'urbit-ob'; import BN from 'bn.js'; import 'style/anim.css'; import * as need from 'lib/need'; import { chunkStr, Matrix, walk, rand } from 'lib/card'; import usePermissionsForPoint from 'lib/usePermissionsForPoint'; import { useSyncOwnedPoints } from 'lib/useSyncPoints'; import { buildKeyType } from 'lib/point'; import { useWallet } from 'store/wallet'; import { sigil, reactRenderer } from 'urbit-sigil-js'; function makeSigil(size, patp, colors) { const config = { patp: patp, colors: colors, margin: 0, renderer: reactRenderer, }; // Planet if (patp.length === 14) { return sigil({ patp: patp, size: size, ...config, }); } // Star if (patp.length === 7) { return sigil({ patp: patp, width: size * 2, height: size, full: true, ...config, }); } // Galaxy if (patp.length === 4) { return sigil({ patp: patp, size: size, full: true, ...config, }); } } const symbols = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; /** * Address is Maybe * point is Maybe * animationMode is 'slide' | 'step' | 'none' * */ function Passport({ address, point, inverted, animationMode = 'none', keyType, }) { const [cols, rows, tile] = [35, 12, 12]; const loading = Nothing.hasInstance(address) || Nothing.hasInstance(point); const defaultMatrix = () => { return Matrix.new(rows, cols); }; const patp = ob.patp(point.value); const makeMatrix = addr => { // remove the 0x const onlyTheNumberPart = addr.substring(2); // make bigNum from hex const int = new BN(onlyTheNumberPart, 16); // make a bigger number const big = int.pow(new BN(10)); // parse that to a string and pad const b10 = big.toString(10).padStart(32, '0'); // split the big number into parts const chunkSize = Math.ceil(b10.length / 8); const chunks = chunkStr(b10, chunkSize).map(c => new BN(c)); // generate an empty matrix const startMatrix = Matrix.new(rows, cols); // do a few random walks starting at diff coordinates const [, matrix] = chunks.reduce((acc, chunk) => { return walk(chunk, acc[1]); // start with the 'random' points (not actually random, they are deterministic) }, rand(big, startMatrix)); return matrix; }; const matrix = address.matchWith({ Just: ({ value }) => makeMatrix(value), Nothing: defaultMatrix, }); const bgColor = inverted ? 'white' : 'black'; const fgColor = inverted ? 'black' : 'white'; const sigil = useMemo( () => Just.hasInstance(point) && makeSigil(64, patp, [bgColor, fgColor]), [patp, point, bgColor, fgColor] ); return (
{sigil}
{Just.hasInstance(point) && patp}
{keyType !== '' ? (
{keyType}
) : (
)}
{matrix.map((row, _row) => { return (
{row.map((v, _col) => { return ( ); })}
); })}
); } const Cell = props => { return (
); }; /** * point is number * */ function MiniPassport({ point, inverted, ...rest }) { useSyncOwnedPoints([point]); const { wallet } = useWallet(); const address = need.addressFromWallet(wallet); const patp = ob.patp(point); const permissions = usePermissionsForPoint(address, point); const keyType = buildKeyType(permissions); const sigil = useMemo( () => makeSigil(44, patp, inverted ? ['white', 'black'] : ['black', 'white']), [inverted, patp] ); return (
{sigil}
{patp}
{keyType !== '' ? (
{keyType}
) : (
)}
); } Passport.Mini = MiniPassport; export default Passport;