import debug from 'debug'; import { isNil, lensPath, set, splitEvery, update } from 'ramda'; import { FC, useEffect, useMemo, useState } from 'react'; import tw, { css, styled } from 'twin.macro'; import { Borders, borders } from '../../constants/border'; import { useLedCount } from '../contents/led-count'; import { DisplayConfig, LedStripConfigOfBorders } from '../models/display-config'; import { LedStripConfig } from '../models/led-strip-config'; import { PixelRgb } from '../models/pixel-rgb'; import { ScreenshotDto } from '../models/screenshot.dto'; import { DraggableStrip } from './draggable-strip'; import { StyledPixel } from './styled-pixel'; export const logger = debug('app:completed-led-strip'); interface CompletedLedStripProps { screenshots: ScreenshotDto[]; onDisplayConfigChange?: (value: DisplayConfig) => void; } type BorderLedStrip = { pixels: PixelRgb[]; config: LedStripConfig | null; }; const StyledContainer = styled.section( ({ rows, columns }: { rows: number; columns: number }) => [ tw`grid m-4 pb-2 items-center justify-items-center select-none`, css` grid-template-columns: repeat(${columns}, 1fr); grid-template-rows: auto repeat(${rows}, 1fr); `, ], ); const StyledCompletedContainer = styled.section( tw`dark:bg-transparent shadow-xl border-gray-500 border rounded-full flex flex-wrap justify-around items-center mb-2`, css` grid-column: 1 / -1; justify-self: stretch; `, ); export const CompletedLedStrip: FC = ({ screenshots, onDisplayConfigChange, }) => { const borderLedStrips: BorderLedStrip[] = useMemo(() => { return screenshots.flatMap((ss) => borders.map((b) => ({ pixels: splitEvery(3, Array.from(ss.colors[b])) as PixelRgb[], config: ss.config.led_strip_of_borders[b], })), ); }, [screenshots]); const ledCount = useMemo( () => borderLedStrips.reduce((prev, curr) => prev + curr.pixels.length, 0), [borderLedStrips], ); const { setLedCount } = useLedCount(); // setLedCount for context useEffect(() => { setLedCount(ledCount); }, [ledCount, setLedCount]); const [overrideBorderLedStrips, setOverrideBorderLedStrips] = useState(); const completedPixels = useMemo(() => { const completed: PixelRgb[] = new Array(ledCount).fill([0, 0, 0]); (overrideBorderLedStrips ?? borderLedStrips).forEach(({ pixels, config }) => { if (isNil(config)) { return; } if (config.global_start_position <= config.global_end_position) { pixels.forEach((color, i) => { completed[config.global_start_position + i] = color; }); } else { pixels.forEach((color, i) => { completed[config.global_start_position - i] = color; }); } }); return completed.map((color, i) => ); }, [ledCount, borderLedStrips, overrideBorderLedStrips]); const strips = useMemo(() => { return borderLedStrips.map(({ config, pixels }, index) => config ? ( { setOverrideBorderLedStrips( update(index, { config: c, pixels }, borderLedStrips), ); }} onConfigFinish={(c) => { const indexOfDisplay = Math.floor(index / borders.length); const xLens = lensPath([ borders[index % borders.length], ]); const displayConfig: DisplayConfig = { ...screenshots[indexOfDisplay].config, led_strip_of_borders: set( xLens, c, screenshots[indexOfDisplay].config.led_strip_of_borders, ), }; onDisplayConfigChange?.(displayConfig); }} /> ) : (
), ); }, [borderLedStrips, screenshots]); useEffect(() => { setOverrideBorderLedStrips(undefined); }, [borderLedStrips]); return ( {completedPixels} {strips} ); };