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.
79 lines
2.6 KiB
79 lines
2.6 KiB
import {
|
|
reconstituteTable,
|
|
TableEmoji,
|
|
type TableFullProps,
|
|
TableHeaderDataset,
|
|
tableIdentifier,
|
|
TableTitle
|
|
} from './TableHeader';
|
|
import {
|
|
reconstituteResponseElement,
|
|
ResponseElement,
|
|
type ResponseElementProps, responseIdPrefix
|
|
} from './ResponseElement';
|
|
import { useCallback } from 'preact/hooks';
|
|
|
|
export interface ResponseTypeProps {
|
|
table: TableFullProps,
|
|
selectedMappingId: number | null,
|
|
contents: Omit<ResponseElementProps, 'selected'>[],
|
|
}
|
|
|
|
export interface PartialResponseTypeProps {
|
|
table?: Partial<TableFullProps>;
|
|
selectedMappingId?: number | null;
|
|
contents?: Omit<ResponseElementProps, 'selected'>[];
|
|
}
|
|
|
|
export function reconstituteResponseType(element: HTMLLIElement, partial?: PartialResponseTypeProps): ResponseTypeProps {
|
|
const table = reconstituteTable(element.querySelector('.tableHeader')!, partial?.table) as TableFullProps;
|
|
let selected: number | null | undefined = partial?.selectedMappingId ?? null,
|
|
contents: Omit<ResponseElementProps, 'selected'>[] | undefined = partial?.contents;
|
|
if (!contents) {
|
|
contents = [];
|
|
for (const child of Array.from(element.querySelector('.responseTypeList')!.children) as HTMLLIElement[]) {
|
|
const childContents = reconstituteResponseElement(child);
|
|
if (typeof selected === 'undefined' && childContents.selected) {
|
|
selected = childContents.result.mappingId;
|
|
}
|
|
contents.push(childContents);
|
|
}
|
|
if (typeof selected === 'undefined') {
|
|
selected = null;
|
|
}
|
|
} else if (typeof selected === 'undefined') {
|
|
const active = element.querySelector('.response.active');
|
|
selected = active ? parseInt(active.id.substring(responseIdPrefix.length)) : null;
|
|
}
|
|
return {
|
|
table,
|
|
selectedMappingId: selected,
|
|
contents
|
|
};
|
|
}
|
|
|
|
export interface ResponseTypeEvents {
|
|
onSelectResponse?: (tableId: number, mappingId: number) => void
|
|
}
|
|
|
|
export const responseListIdPrefix = 'responses-';
|
|
|
|
export function ResponseType({ table, selectedMappingId, contents, onSelectResponse }: ResponseTypeProps & ResponseTypeEvents) {
|
|
const onSelectChild = useCallback((mappingId: number) => {
|
|
if (onSelectResponse) {
|
|
onSelectResponse(table.id, mappingId)
|
|
}
|
|
}, [onSelectResponse]);
|
|
return <li id={responseListIdPrefix + tableIdentifier(table)} class="responseType window readable">
|
|
<h2 class="responseTypeHead tableHeader" {...TableHeaderDataset(table)}>
|
|
<TableEmoji emoji={table.emoji} />{' '}<TableTitle title={table.title} />
|
|
</h2>
|
|
<ul class="responseTypeList">
|
|
{contents.map(result =>
|
|
<ResponseElement key={result.result.mappingId}
|
|
selected={result.result.mappingId === selectedMappingId}
|
|
onSelected={onSelectChild}
|
|
{...result} />)}
|
|
</ul>
|
|
</li>;
|
|
}
|
|
|