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.
68 lines
2.5 KiB
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>
|
|
}
|
|
|