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.
134 lines
7.0 KiB
134 lines
7.0 KiB
import {
|
|
type RollTable,
|
|
type RollTableDetails,
|
|
type RollTableDetailsAndResults,
|
|
type RollTableResult
|
|
} from './rolltable';
|
|
|
|
// TODO: port the rest of these to preact
|
|
|
|
export function buildGeneratorPage<T, BuilderT extends TemplateBuilder<T>>(
|
|
{ results, generatorTargetUrl, clientId, creditsUrl, editable, selected, includesResponses, builder }:
|
|
{ readonly results: ReadonlyMap<RollTable, RollTableResult>,
|
|
readonly generatorTargetUrl: string,
|
|
readonly clientId: string,
|
|
readonly creditsUrl: string,
|
|
readonly editable: boolean,
|
|
readonly selected: ReadonlySet<RollTable>,
|
|
readonly includesResponses: boolean,
|
|
readonly builder: BuilderT}): ReturnType<BuilderT["makeDiv"]> {
|
|
return builder.makeDiv(
|
|
{id: "generator", classes: "page"},
|
|
builder.makeForm({method: FormMethod.Post, action: generatorTargetUrl, id: "generatorWindow", classes: ["window", "readable"]},
|
|
builder.makeHeading2({id: "generatorHead"}, builder.makeText("Your generated scenario")),
|
|
builder.makeUnorderedList({id: "generatedScenario"},
|
|
...Array.from(results.values()).map(result =>
|
|
buildGeneratedElement({
|
|
result,
|
|
selected: (editable && includesResponses && result.table.full === 'results') ? selected.has(result.table) : null,
|
|
includesResponses,
|
|
builder}))),
|
|
builder.makeDiv({id: "generatorControls"},
|
|
builder.makeDiv({id: "copyButtons", classes: ["buttons", "requiresJs", "jsPopupHost"]},
|
|
builder.makeButton({id: "copyMD"}, builder.makeText("Markdown")),
|
|
builder.makeButton({id: "copyBB"}, builder.makeText("BBCode")),
|
|
builder.makeButton({id: "copyEmojiText"}, builder.makeText("Text + Emoji")),
|
|
builder.makeButton({id: "copyText"}, builder.makeText("Text Only")),
|
|
),
|
|
...(editable ? [builder.makeDiv({id: "rollButtons", classes: ["buttons"]},
|
|
builder.makeButton({type: ButtonType.Submit, id: "reroll", name: "submit", value: "reroll"}, builder.makeText("Reroll Selected")),
|
|
builder.makeButton({id: "selectAll", classes: "requiresJs"}, builder.makeText("Select All")),
|
|
builder.makeButton({id: "selectNone", classes: "requiresJs"}, builder.makeText("Select None")),
|
|
)] : []),
|
|
builder.makeDiv({id: "scenarioButtons", classes: ["buttons"]},
|
|
...(editable ? [
|
|
builder.makeHyperlink({id: "rerollAll", url: generatorTargetUrl, destination: HyperlinkDestination.Internal, asButton: true}, builder.makeText("New Scenario")),
|
|
builder.makeButton({type: ButtonType.Submit, id: "saveScenario", name: "submit", value: "saveScenario"}, builder.makeText("Get Scenario Link"))
|
|
] : [
|
|
builder.makeHyperlink({url: generatorTargetUrl, destination: HyperlinkDestination.Internal, asButton: true}, builder.makeText("Open in Generator"))
|
|
])
|
|
),
|
|
...(clientId !== '' || includesResponses ? [builder.makeDiv({id: "generatorLinks", classes: ["buttons"]},
|
|
...(clientId !== '' ? [builder.makeHyperlink(
|
|
{
|
|
url: `https://discord.com/api/oauth2/authorize?client_id=${
|
|
encodeURIComponent(clientId)}&permissions=0&scope=applications.commands`,
|
|
destination: HyperlinkDestination.External,
|
|
asButton: true},
|
|
builder.makeText("Add to Discord"))] : []),
|
|
...(includesResponses ? [builder.makeHyperlink(
|
|
{
|
|
url: `#responses`,
|
|
destination: HyperlinkDestination.Internal,
|
|
asButton: true},
|
|
builder.makeText("View Possible Responses"))] : []),
|
|
)] : [])
|
|
)
|
|
),
|
|
buildFooter({includesResponses, includesGenerator: true, creditsUrl, builder})
|
|
) as ReturnType<BuilderT["makeDiv"]>
|
|
}
|
|
|
|
export function buildResponseTypeButton<T, BuilderT extends TemplateBuilder<T>>({table, builder}: {readonly table: RollTableDetails, readonly builder: BuilderT}): ReturnType<BuilderT["makeHyperlink"]> {
|
|
return builder.makeHyperlink({
|
|
url: `#responses-${htmlTableIdentifier(table)}`,
|
|
destination: HyperlinkDestination.Internal,
|
|
asButton: true,
|
|
}, builder.makeText(`${table.emoji} ${table.name}`)) as ReturnType<BuilderT["makeHyperlink"]>
|
|
}
|
|
|
|
export function buildResponse<T, BuilderT extends TemplateBuilder<T>>({result, active, includesGenerator, builder}: {readonly result: RollTableResult, readonly active: boolean, readonly includesGenerator: boolean, readonly builder: BuilderT}): ReturnType<BuilderT["makeListItem"]> {
|
|
return builder.makeListItem(
|
|
{
|
|
id: result.full ? `response-${result.mappingId}` : undefined,
|
|
classes: ["response", "jsPopupHost", ...(active ? ["active"] : []), ...(result.full ? ["attributed"] : [])],
|
|
},
|
|
builder.makeButton({classes: "resultText", data: buildResultData(result)}, builder.makeText(result.text)),
|
|
buildResultAttribution({
|
|
result,
|
|
button: result.full && includesGenerator ? builder.makeButton({classes: ["makeResponseActive", "requiresJs"]}, builder.makeText("Set in Generated Scenario")) : undefined,
|
|
builder})) as ReturnType<BuilderT["makeListItem"]>
|
|
}
|
|
|
|
export function buildResponseList<T, BuilderT extends TemplateBuilder<T>>({table, activeResult, includesGenerator, builder}: {readonly table: RollTableDetailsAndResults, readonly activeResult?: RollTableResult, readonly includesGenerator: boolean, readonly builder: BuilderT}): ReturnType<BuilderT["makeListItem"]> {
|
|
return builder.makeListItem(
|
|
{
|
|
classes: ["responseType", "window", "readable"],
|
|
id: `responses-${htmlTableIdentifier(table)}`
|
|
},
|
|
builder.makeHeading2(
|
|
{
|
|
classes: ["responseTypeHead", "tableHeader"],
|
|
data: buildTableData(table)
|
|
},
|
|
builder.makeSpan({classes: "tableEmoji"}, builder.makeText(table.emoji)),
|
|
builder.makeText(' '),
|
|
builder.makeSpan({classes: "tableTitle"}, builder.makeText(table.title)),
|
|
),
|
|
builder.makeUnorderedList({}, ...Array.from(table.resultsById.values())
|
|
.map(result =>
|
|
buildResponse({result, active: result === activeResult, includesGenerator, builder})))
|
|
) as ReturnType<BuilderT["makeListItem"]>
|
|
}
|
|
|
|
export function buildResponsesPage<T, BuilderT extends TemplateBuilder<T>>(
|
|
{ tables, results, creditsUrl, includesGenerator, builder }: {
|
|
readonly tables: Iterable<RollTableDetailsAndResults>,
|
|
readonly results?: ReadonlyMap<RollTable, RollTableResult>,
|
|
readonly creditsUrl: string,
|
|
readonly includesGenerator: boolean,
|
|
readonly builder: BuilderT}): ReturnType<BuilderT["makeDiv"]> {
|
|
return builder.makeDiv({id: "responses", classes: "page"},
|
|
builder.makeHeader({id: "responsesHeader", classes: "window"},
|
|
builder.makeHeading1({id: "responsesHead"}, builder.makeText("Possible Responses")),
|
|
builder.makeNav({id: "responsesHeaderNav", classes: "buttons"},
|
|
...Array.from(tables).map(table => buildResponseTypeButton({table, builder})),
|
|
builder.makeHyperlink({url: `#generator`, destination: HyperlinkDestination.Internal, asButton: true, id: "returnToGenerator"}, builder.makeText("Return to Generator"))
|
|
),
|
|
),
|
|
builder.makeUnorderedList({id: "responseLists"},
|
|
...Array.from(tables).map(table =>
|
|
buildResponseList({table, activeResult: results?.get(table), includesGenerator, builder}))),
|
|
buildFooter({builder, creditsUrl, includesResponses: true, includesGenerator}),
|
|
) as ReturnType<BuilderT["makeDiv"]>
|
|
}
|
|
|