import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "react"; import { Grid, IconButton, List, ListItem, ListItemText, ListSubheader, Paper, Table, TableBody, TableCell, TableContainer, TableRow, Typography } from "@material-ui/core"; import { makeStyles } from "@material-ui/core/styles"; import { useBloc } from "./state/state"; import BlocsCubit from "./state/BlocsCubit"; import BlocBase from "../../src/lib/BlocBase"; import { Alert } from "@material-ui/lab"; import { ChangeEvent } from "../../src/lib/types"; import clsx from "clsx"; import Bug from "@material-ui/icons/BugReport"; const useStyles = makeStyles((theme) => ({ root: { position: "fixed", background: "#333", zIndex: 9999, borderTop: "2px solid #000", display: "flex", flexDirection: "column", right: 0, bottom: 0, left: 0, height: '500px', transform: 'translateY(100%)', transition: 'transform 0.3s ease-in-out', }, showRoot: { transform: 'translateY(0)', } , showButton: { position: "absolute", bottom: '100%', right: 0, }, content: { flex: "1", display: "flex", height: "0" }, blocItems: { overflow: "auto", width: "230px" }, listHeader: { background: "#333", borderBottom: "1px solid #555" } })); const useItemStyles = makeStyles((theme) => ({ item: { width: "100%", justifyContent: "flex-start", "& span": { textTransform: "none" } }, itemWrap: { position: "relative" }, "@keyframes move": { "0%": { left: "100%", opacity: 1 }, "100%": { left: "0%", opacity: 0 } }, event: { width: "4px", pointerEvents: "none", background: "#f99", position: "absolute", left: "100%", top: 0, bottom: 0, opacity: 0, animation: `$move 600ms linear` } })); const useDetailStyles = makeStyles((theme) => ({ details: { flex: "1", overflow: "auto", borderLeft: "1px solid #000", padding: "20px" }, value: { padding: "15px 20px", marginBottom: "20px" }, code: { margin: "10px 0", background: "#111", padding: "6px 20px", borderRadius: "5px", color: "white" } })); const BlocItem: FC<{ bloc: BlocBase, onSelect: (selected: BlocBase, event?: ChangeEvent) => void, selected: boolean, }> = ( { bloc, onSelect, selected }) => { const classes = useItemStyles(); const container = useRef(null); const [event, setEvent] = useState | undefined>(undefined); const addChange = useCallback((e: ChangeEvent) => { setEvent(e); const el = document.createElement("div"); el.classList.add(classes.event); container.current?.appendChild(el); setTimeout(() => { container.current?.removeChild(el); }, 1000); }, [bloc, container]); useEffect(() => { return bloc.addChangeListener(addChange); }, [bloc]); return
onSelect(bloc, event)} selected={selected} > {bloc.constructor.name}
; }; const BlocDetails: FC<{ bloc?: BlocBase, lastEvent?: ChangeEvent }> = ( { bloc, lastEvent } ) => { const classes = useDetailStyles(); const selected = bloc; const [event, setEvent] = useState | undefined>(lastEvent); const addChange = useCallback((event?: ChangeEvent) => { setEvent(event); }, [bloc]); useEffect(() => { return bloc?.addChangeListener(addChange); }, [bloc]); return
{selected &&
Value
{JSON.stringify(selected.state, null, 2)}
Most recent change {!event && No events captured} {event && From
{JSON.stringify(event?.currentState, null, 2)}
To
{JSON.stringify(event?.nextState, null, 2)}
}
Details Created At {selected.createdAt.toISOString()} ID {selected.id} Register Listeners {selected.registerListeners.length} Change Listeners (2 are from the debug tools) {selected.changeListeners.length} Value Change Listeners {selected.valueChangeListeners.length}
} {!selected &&
Select a BLoC to see details
}
; }; const Content: FC = () => { const classes = useStyles(); // const [tab, setTab] = useState(0); const [selected, setSelected] = useState<[BlocBase | undefined, ChangeEvent | undefined]>([undefined, undefined]); const [blocs] = useBloc(BlocsCubit); const [show, setShow] = useState(false); // const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => { // setTab(newValue); // }; // const [change, setChange] = useState>>({}); // // const addChange = useCallback((id: string, event: ChangeEvent) => { // setChange({ // ...change, // [id]: event // }); // console.log({...change}); // }, [change]) // // useEffect(() => { // const removers: Array<() => void> = []; // blocs.blocs.forEach(b => { // const rm = b.addChangeListener((event) => { // addChange(b.id, event); // }); // removers.push(rm); // }); // // return () => { // removers.forEach(rm => rm()); // }; // }, []); const globalBlocs = useMemo(() => blocs.blocs.filter(b => b.meta.scope === "global"), [blocs]); const localBlocs = useMemo(() => blocs.blocs.filter(b => b.meta.scope === "local"), [blocs]); return
{/**/} {/* */} {/* */} {/* */} {/**/} setShow(!show)} className={classes.showButton}>
Global BLoCs ({globalBlocs.length}) {globalBlocs.map(bloc => setSelected([b, e])} selected={bloc === selected[0]} />)} Local BLoCs ({localBlocs.length}) {localBlocs.map(bloc => setSelected([b, e])} selected={bloc === selected[0]} />)}
; }; export default Content;