Files
CipherStreamWeb/src/components/ciphers/polysubstitution/railfence/RailFenceInputs.tsx
2026-08-15 17:28:19 -04:00

144 lines
4.2 KiB
TypeScript

import CopyOutputButton from "@/components/button/CopyOutputButton";
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
import InputMessage from "@/components/input/InputMessage";
import NumberSelector from "@/components/input/NumberSelector";
import OutputMessage from "@/components/input/OutputMessage";
import PreservationSliders from "@/components/input/PreservationSliders";
import { useDecodeRailFence, useEncodeRailFence } from "@/hooks/polysubstitution/RailFenceHooks";
import { useToaster } from "mattrixwv-components";
import { useEffect, useState } from "react";
import { useDebouncedCallback } from "use-debounce";
export default function RaidFenceInputs(){
const [ capitals, setCapitals ] = useState(true);
const [ symbols, setSymbols ] = useState(true);
const [ whitespace, setWhitespace ] = useState(true);
const [ encoding, setEncoding ] = useState(true);
const [ rails, setRails ] = useState(2);
const [ input, setInput ] = useState("");
const [ output, setOutput ] = useState("");
const { addDanger } = useToaster();
const encodeRailFenceMutation = useEncodeRailFence();
const decodeRailFenceMutation = useDecodeRailFence();
//Do coding with a delay
const performCoding = useDebouncedCallback(() => {
if(input === ""){
// eslint-disable-next-line @eslint-react/set-state-in-effect
setOutput("");
return;
}
if(encoding){
encodeRailFenceMutation.mutate({
encoding,
preserveSymbols: symbols,
preserveWhitespace: whitespace,
preserveCapitals: capitals,
rails,
inputString: input
});
}
else{
decodeRailFenceMutation.mutate({
encoding,
preserveSymbols: symbols,
preserveWhitespace: whitespace,
preserveCapitals: capitals,
rails,
inputString: input
});
}
}, 1000);
//Code when input changes
useEffect(() => {
performCoding();
}, [capitals, encoding, rails, input, performCoding, symbols, whitespace]);
//When the mutation is successful set the new output
useEffect(() => {
if(decodeRailFenceMutation.isSuccess){
// eslint-disable-next-line @eslint-react/set-state-in-effect,react-hooks/set-state-in-effect
setOutput(decodeRailFenceMutation.data.outputString ?? "");
decodeRailFenceMutation.reset();
}
if(encodeRailFenceMutation.isSuccess){
// eslint-disable-next-line @eslint-react/set-state-in-effect
setOutput(encodeRailFenceMutation.data.outputString ?? "");
encodeRailFenceMutation.reset();
}
// eslint-disable-next-line @eslint-react/exhaustive-deps,react-hooks/exhaustive-deps
}, [ decodeRailFenceMutation.isSuccess, encodeRailFenceMutation.isSuccess, decodeRailFenceMutation.data, encodeRailFenceMutation.data ]);
//When the mutation has an error, display the message
useEffect(() => {
if(decodeRailFenceMutation.isError){
addDanger(decodeRailFenceMutation.error.message);
decodeRailFenceMutation.reset();
}
if(encodeRailFenceMutation.isError){
addDanger(encodeRailFenceMutation.error.message);
encodeRailFenceMutation.reset();
}
// eslint-disable-next-line @eslint-react/exhaustive-deps,react-hooks/exhaustive-deps
}, [ decodeRailFenceMutation.isError, encodeRailFenceMutation.isError ]);
return (
<div
className="flex flex-col items-center justify-center gap-y-4"
>
<div
className="flex flex-row items-center justify-center gap-x-8"
>
<PreservationSliders
capitals={capitals}
setCapitals={setCapitals}
symbols={symbols}
setSymbols={setSymbols}
whitespace={whitespace}
setWhitespace={setWhitespace}
/>
</div>
<div
className="flex flex-col items-center justify-center"
>
<EncodingDecodingButton
encoding={encoding}
setEncoding={setEncoding}
/>
</div>
<div
className="flex flex-col items-center justify-center gap-y-8"
>
<div
className="flex flex-col items-center justify-center gap-y-2"
>
<NumberSelector
label="Rails"
value={rails}
onChange={setRails}
minValue={2}
maxValue={100}
/>
</div>
<InputMessage
value={input}
onChange={setInput}
/>
<OutputMessage
value={output}
onChange={setOutput}
/>
<CopyOutputButton
value={output}
/>
</div>
</div>
);
}