Skip to content

Commit

Permalink
fix: move circle logic to its own component
Browse files Browse the repository at this point in the history
  • Loading branch information
Aerilym committed Nov 5, 2024
1 parent 14fa6f6 commit f78983b
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 105 deletions.
27 changes: 9 additions & 18 deletions apps/staking/components/Form/StakeAmountField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { formatSENTBigInt } from '@session/contracts/hooks/SENT';
import { Button } from '@session/ui/ui/button';
import { ButtonDataTestId } from '@/testing/data-test-ids';
import { Input } from '@session/ui/ui/input';
import { Slider } from '@session/ui/ui/slider';
import { Circle } from '@session/ui/motion/shapes/circle';
import { Slider, SliderLineCircle } from '@session/ui/ui/slider';
import * as React from 'react';
import type { DecimalDelimiter } from '@/lib/locale-client';
import { useTranslations } from 'next-intl';
Expand Down Expand Up @@ -252,28 +251,20 @@ export default function StakeAmountField({
return onChange(val.toString());
}}
>
<svg
height={10}
width={10}
xmlns="http://www.w3.org/2000/svg"
className="absolute cursor-pointer"
<SliderLineCircle
variant="blue"
strokeVariant="blue"
style={{
left: `calc(${(bigIntToNumber(maxStake, SENT_DECIMALS) / bigIntToNumber(fullStake, SENT_DECIMALS)) * 100}% - 8px)`,
}}
>
<Circle cx="50%" cy="50%" r={4} variant="blue" strokeVariant="blue" />
</svg>
<svg
height={10}
width={10}
xmlns="http://www.w3.org/2000/svg"
className="absolute cursor-pointer"
/>
<SliderLineCircle
variant="blue"
strokeVariant="blue"
style={{
left: `calc(${(bigIntToNumber(minStake, SENT_DECIMALS) / bigIntToNumber(fullStake, SENT_DECIMALS)) * 100}%)`,
}}
>
<Circle cx="50%" cy="50%" r={4} variant="blue" strokeVariant="blue" />
</svg>
/>
</Slider>
</div>
</FormControl>
Expand Down
1 change: 1 addition & 0 deletions apps/staking/tests/maths.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ function getRandomBigInt(min: bigint, max: bigint): bigint {

const getRandomOperatorContributorAmount = (): bigint =>
getRandomBigInt(5000000000000n, 20000000000000n);

const getRandomContributorAmount = (min: bigint, max: bigint): bigint => getRandomBigInt(min, max);

function createRandomContributorArray() {
Expand Down
16 changes: 12 additions & 4 deletions packages/contracts/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,29 @@ export const HEX_BYTES = {
ED_25519_SIG_BYTES: 128,
};

const bytes64 = 64;

/**
* Encodes a hex string to an array of BigInt chunks.
* @param hex - The hex string to encode.
* @param hexBytes - The number of bytes in the hex string.
* @returns An array of BigInt chunks.
*/
export function encodeHexToBigIntChunks(hex: string, hexBytes: number): Array<bigint> {
if (hexBytes < 64 || hexBytes % 64 !== 0) {
throw new Error(`hexBytes must be divisible by 2. hexBits: ${hexBytes}`);
if (hexBytes < bytes64 || hexBytes % bytes64 !== 0) {
throw new Error(`hexBytes must be divisible by ${bytes64}. hexBits: ${hexBytes}`);
}

if (hex.length !== hexBytes) {
throw new Error(`Hex length is invalid, it must be a ${hexBytes} byte string`);
}

const numberOfChunks = hexBytes / 64;
const numberOfChunks = hexBytes / bytes64;

const chunks = [];

for (let i = 0; i < numberOfChunks; i++) {
chunks.push(hex.slice(i * 64, (i + 1) * 64));
chunks.push(hex.slice(i * bytes64, (i + 1) * bytes64));
}

return chunks.map((hexChunk) => BigInt(`0x${hexChunk}`));
Expand Down
154 changes: 71 additions & 83 deletions packages/ui/components/ui/slider.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
'use client';

import * as React from 'react';
import { useState } from 'react';
import {
type ComponentPropsWithoutRef,
type CSSProperties,
type ElementRef,
forwardRef,
useState,
} from 'react';
import * as SliderPrimitive from '@radix-ui/react-slider';
import { cn } from '../../lib/utils';
import { Circle } from '../motion/shapes/circle';
import { Circle, type CircleVariantProps } from '../motion/shapes/circle';

const circleRadius = 6;
const extraRad = 1.875;
const height = (circleRadius + extraRad) * 2 + 2;
const width = height;
const circleVariant = 'green';
const thumbSize = (circleRadius + extraRad) * 2 + 2;

const Slider = React.forwardRef<
React.ElementRef<typeof SliderPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
export const SliderLineCircle = forwardRef<
SVGSVGElement,
CircleVariantProps & { style?: CSSProperties; className?: string }
>(({ className, variant, strokeVariant, ...props }, ref) => (
<svg
height={10}
width={10}
xmlns="http://www.w3.org/2000/svg"
className={cn('absolute cursor-pointer', className)}
{...props}
ref={ref}
>
<Circle cx="50%" cy="50%" r={4} variant={variant} strokeVariant={strokeVariant} />
</svg>
));

const Slider = forwardRef<
ElementRef<typeof SliderPrimitive.Root>,
ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
>(({ value, max, className, children, ...props }, ref) => {
const [showPercent, setShowPercent] = useState<boolean>(false);
const decimalPercent =
Expand All @@ -27,96 +46,65 @@ const Slider = React.forwardRef<
max={max}
{...props}
>
<SliderPrimitive.Track className="bg-indicator-grey relative mx-1 h-0.5 w-full grow rounded-full">
<SliderPrimitive.Track className="bg-gray-lighter relative mx-1 h-0.5 w-full grow rounded-full">
<SliderPrimitive.Range className="bg-session-green absolute h-full" />
<div className="absolute left-0 right-0 flex h-full items-center justify-center">
<svg
height={10}
width={10}
xmlns="http://www.w3.org/2000/svg"
className="absolute -left-0.5 cursor-pointer"
>
<Circle cx="50%" cy="50%" r={4} variant="green" strokeVariant="green" />
</svg>
<svg
height={10}
width={10}
xmlns="http://www.w3.org/2000/svg"
className="absolute -right-0.5 cursor-pointer"
>
<Circle cx="50%" cy="50%" r={4} variant="grey" strokeVariant="grey" />
</svg>
<svg
height={10}
width={10}
xmlns="http://www.w3.org/2000/svg"
className="absolute cursor-pointer"
style={{
left: `calc(${25}%)`,
}}
>
<Circle
cx="50%"
cy="50%"
r={4}
variant={decimalPercent > 0.25 ? 'green' : 'grey'}
strokeVariant={decimalPercent > 0.25 ? 'green' : 'grey'}
/>
</svg>
<svg
height={10}
width={10}
xmlns="http://www.w3.org/2000/svg"
className="absolute cursor-pointer"
style={{
left: `calc(${50}% - 8px)`,
}}
>
<Circle
cx="50%"
cy="50%"
r={4}
variant={decimalPercent > 0.5 ? 'green' : 'grey'}
strokeVariant={decimalPercent > 0.5 ? 'green' : 'grey'}
/>
</svg>
<svg
height={10}
width={10}
xmlns="http://www.w3.org/2000/svg"
className="absolute cursor-pointer"
style={{
left: `calc(${75}% - 8px)`,
}}
>
<Circle
cx="50%"
cy="50%"
r={4}
variant={decimalPercent > 0.75 ? 'green' : 'grey'}
strokeVariant={decimalPercent > 0.75 ? 'green' : 'grey'}
/>
</svg>
<SliderLineCircle className="-left-0.5" variant="green" strokeVariant="green" />
<SliderLineCircle
className="-right-0.5"
variant="grey-lighter"
strokeVariant="grey-lighter"
/>
<SliderLineCircle
className="-right-0.5"
variant="grey-lighter"
strokeVariant="grey-lighter"
/>
<SliderLineCircle
variant={decimalPercent > 0.25 ? 'green' : 'grey-lighter'}
strokeVariant={decimalPercent > 0.25 ? 'green' : 'grey-lighter'}
style={{ left: `calc(${25}%)` }}
/>
<SliderLineCircle
variant={decimalPercent > 0.5 ? 'green' : 'grey-lighter'}
strokeVariant={decimalPercent > 0.5 ? 'green' : 'grey-lighter'}
style={{ left: `calc(${50}% - 8px)` }}
/>
<SliderLineCircle
variant={decimalPercent > 0.75 ? 'green' : 'grey-lighter'}
strokeVariant={decimalPercent > 0.75 ? 'green' : 'grey-lighter'}
style={{ left: `calc(${75}% - 8px)` }}
/>
{children}
</div>
</SliderPrimitive.Track>
<SliderPrimitive.Thumb
onMouseEnter={() => setShowPercent(true)}
onMouseLeave={() => setShowPercent(false)}
style={{ width, height }}
style={{ width: thumbSize, height: thumbSize }}
className="relative block cursor-pointer rounded-full focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-offset-1 disabled:pointer-events-none disabled:opacity-50"
>
<svg height={height} width={width} xmlns="http://www.w3.org/2000/svg" className="absolute">
<Circle cx="50%" cy="50%" r={circleRadius + extraRad} variant={circleVariant} />
<svg
height={thumbSize}
width={thumbSize}
xmlns="http://www.w3.org/2000/svg"
className="absolute"
>
<Circle cx="50%" cy="50%" r={circleRadius + extraRad} variant="green" />
</svg>
<svg height={height} width={width} xmlns="http://www.w3.org/2000/svg" className="absolute">
<Circle cx="50%" cy="50%" r={circleRadius} strokeWidth={1.125} variant={circleVariant} />
<svg
height={thumbSize}
width={thumbSize}
xmlns="http://www.w3.org/2000/svg"
className="absolute"
>
<Circle cx="50%" cy="50%" r={circleRadius} strokeWidth={1.125} variant="green" />
</svg>
{showPercent ? (
<span
className={cn(
'absolute -top-8',
'text-session-white animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 bg-session-black border-px z-50 max-w-[90svw] flex-wrap overflow-hidden text-wrap rounded-lg border border-[#1C2624] bg-opacity-50 px-1.5 py-1 text-xs shadow-xl outline-none md:max-w-xl'
'text-session-white animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 bg-session-black border-px z-50 max-w-[90svw] flex-wrap overflow-hidden text-wrap rounded-lg border border-gray-800 bg-opacity-50 px-1.5 py-1 text-xs shadow-xl outline-none md:max-w-xl'
)}
style={{ left: -circleRadius - extraRad }}
>
Expand Down
1 change: 1 addition & 0 deletions packages/ui/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@

--indicator-black: var(--session-black);
--indicator-grey: rgb(74, 74, 74);
--indicator-grey-lighter: var(--session-gray-lighter);
--indicator-green: var(--session-green);
--indicator-blue: rgb(0, 163, 247);
--indicator-yellow: rgb(247, 222, 0);
Expand Down
1 change: 1 addition & 0 deletions packages/ui/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default {
indicator: {
black: 'var(--indicator-black)',
grey: 'var(--indicator-grey)',
'grey-lighter': 'var(--indicator-grey-lighter)',
green: 'var(--indicator-green)',
blue: 'var(--indicator-blue)',
yellow: 'var(--indicator-yellow)',
Expand Down

0 comments on commit f78983b

Please sign in to comment.