Scenario generator for vore roleplay and story ideas. https://scenario-generator.deliciousreya.net/responses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
vore-scenario-generator/src/common/client/ResponseElement.tsx

68 lines
2.5 KiB

import { reconstituteResultText, ResultText, type ResultTextPropsFull } from './ResultText';
import {
Attribution,
type AttributionPropsFull,
type PartialAttributionPropsFull, reconstituteAttribution
} from './Attribution';
import { FormButton } from './Button';
import { IncludesGenerator } from './GeneratorPage';
import { useCallback, useContext, useEffect, useState } from 'preact/hooks';
import { type Context, createContext, createRef } from 'preact';
import { pulseElement } from './pulseElement';
export const CurrentSelectedResponse: Context<number|null> = createContext<number|null>(null)
export interface ResponseElementProps {
attribution: AttributionPropsFull
result: ResultTextPropsFull
selected: boolean
}
export interface ResponseElementEvents {
onSelected?: (mappingId: number) => void
}
export interface PartialResponseElementProps {
attribution?: PartialAttributionPropsFull
result?: Partial<ResultTextPropsFull>
selected?: boolean
}
export function reconstituteResponseElement(element: HTMLLIElement, partial?: PartialResponseElementProps): ResponseElementProps {
const result = reconstituteResultText(element.querySelector<HTMLButtonElement>(".resultText")!, partial?.result)
const attribution = reconstituteAttribution(element.querySelector<HTMLDivElement>(".attribution")!, partial?.attribution)
return {
result: result as ResultTextPropsFull,
attribution: attribution as AttributionPropsFull,
selected: partial?.selected ?? element.classList.contains("active")
}
}
export const responseIdPrefix="response-"
export function ResponseElement({attribution, result, selected, onSelected}: ResponseElementProps & ResponseElementEvents) {
const includesGenerator = useContext(IncludesGenerator);
const [lastSelected, setLastSelected] = useState(selected)
const onSelect = useCallback(() => {
if (onSelected) {
onSelected(result.mappingId)
}
}, [attribution, result, onSelected])
const ref = createRef<HTMLLIElement>()
useEffect(() => {
if (lastSelected !== selected) {
setLastSelected(selected)
if (ref.current) {
pulseElement(ref.current)
}
}
}, [selected, lastSelected, setLastSelected, ref]);
return <li ref={ref} id={responseIdPrefix + result.mappingId} class={`response attributed${selected ? " active" : ""}`}>
<ResultText {...result} />
<Attribution {...attribution}>
{includesGenerator
? <FormButton type={"button"} class="makeResponseActive requiresJs" onClick={onSelect}>Set in Generated Scenario</FormButton>
: null}
</Attribution>
</li>
}