MASSIVE REFACTOR WIP - TOTALLY BROKEN

This commit is contained in:
Brandon Thomas committed 2022-02-24 01:47:45 -05:00
1 parent 40db488b40
commit 42f4f82ccd
9 files changed
+435 -137

No files matched your search

@@ -9,14 +9,15 @@ import { faAngleLeft, faSave } from '@fortawesome/free-solid-svg-icons';
import { EventMatchPredicate } from '@storyteller/components/src/api/storyteller/twitch_event_rules/shared/EventMatchPredicate';
import { EventResponse } from '@storyteller/components/src/api/storyteller/twitch_event_rules/shared/EventResponse';
import { TtsModelListItem } from '@storyteller/components/src/api/tts/ListTtsModels';
import { BitsCheermoteNameExactMatchForm } from './components/BitsCheermoteNameExactMatchForm';
import { BitsSpendThresholdForm } from './components/BitsSpendThresholdForm';
import { BitsCheermotePrefixSpendThresholdForm } from './components/BitsCheermotePrefixSpendThresholdForm';
import { BitsCheermoteNameExactMatchForm } from './event_match_predicate_builder/subforms/BitsCheermoteNameExactMatchForm';
import { BitsSpendThresholdForm } from './event_match_predicate_builder/subforms/BitsSpendThresholdForm';
import { BitsCheermotePrefixSpendThresholdForm } from './event_match_predicate_builder/subforms/BitsCheermotePrefixSpendThresholdForm';
import { TwitchEventCategory } from '@storyteller/components/src/api/storyteller/twitch_event_rules/shared/TwitchEventCategory';
import { BitsRuleType } from './components/RuleTypes';
import { ChannelPointsRewardNameExactMatchForm } from './components/ChannelPointsRewardNameExactMatchForm';
import { TtsSingleVoiceForm } from './event_response_builder/TtsSingleVoiceForm';
import { ChannelPointsRewardNameExactMatchForm } from './event_match_predicate_builder/subforms/ChannelPointsRewardNameExactMatchForm';
import { EventResponseType } from './event_response_builder/EventResponseType';
import { EventResponseComponent } from './event_response_builder/EventResponseComponent';
import { BitsRuleType } from './event_match_predicate_builder/types/BitsRuleType';
import { EventMatchPredicateBuilderComponent } from './event_match_predicate_builder/EventMatchPredicateBuilderComponent';
interface Props {
sessionWrapper: SessionWrapper,
@@ -124,92 +125,92 @@ function TtsConfigsEditRulePage(props: Props) {
getTwitchEventRule(token);
}, [getTwitchEventRule, token]);
const updateBitsRuleType = (ev: React.FormEvent<HTMLSelectElement>) : boolean => {
const value = (ev.target as HTMLSelectElement).value;
const ruleType = value as BitsRuleType;
// const updateBitsRuleType = (ev: React.FormEvent<HTMLSelectElement>) : boolean => {
// const value = (ev.target as HTMLSelectElement).value;
// const ruleType = value as BitsRuleType;
//
// let predicate : EventMatchPredicate = {};
//
// switch (ruleType) {
// case BitsRuleType.BitsCheermoteNameExactMatch:
// predicate.bits_cheermote_name_exact_match = {
// cheermote_name: cheerNameOrPrefix,
// }
// break;
// case BitsRuleType.BitsCheermotePrefixSpendThreshold:
// predicate.bits_cheermote_prefix_spend_threshold = {
// cheermote_prefix: cheerNameOrPrefix,
// minimum_bits_spent: minimumBitsSpent,
// }
// break;
// case BitsRuleType.BitsSpendThreshold:
// predicate.bits_spend_threshold = {
// minimum_bits_spent: minimumBitsSpent,
// }
// break;
// }
//
// setBitsRuleType(ruleType);
// setEventMatchPredicate(predicate);
//
// return true;
// }
let predicate : EventMatchPredicate = {};
// const updateCheerNameOrPrefix = (nameOrPrefix: string) => {
// let predicate : EventMatchPredicate = {};
//
// switch (bitsRuleType) {
// case BitsRuleType.BitsCheermoteNameExactMatch:
// predicate.bits_cheermote_name_exact_match = {
// cheermote_name: nameOrPrefix,
// }
// break;
// case BitsRuleType.BitsCheermotePrefixSpendThreshold:
// predicate.bits_cheermote_prefix_spend_threshold = {
// cheermote_prefix: nameOrPrefix,
// minimum_bits_spent: minimumBitsSpent,
// }
// break;
// case BitsRuleType.BitsSpendThreshold:
// predicate.bits_spend_threshold = {
// minimum_bits_spent: minimumBitsSpent,
// }
// break;
// }
//
// setCheerNameOrPrefix(nameOrPrefix);
// setEventMatchPredicate(predicate);
// }
switch (ruleType) {
case BitsRuleType.BitsCheermoteNameExactMatch:
predicate.bits_cheermote_name_exact_match = {
cheermote_name: cheerNameOrPrefix,
}
break;
case BitsRuleType.BitsCheermotePrefixSpendThreshold:
predicate.bits_cheermote_prefix_spend_threshold = {
cheermote_prefix: cheerNameOrPrefix,
minimum_bits_spent: minimumBitsSpent,
}
break;
case BitsRuleType.BitsSpendThreshold:
predicate.bits_spend_threshold = {
minimum_bits_spent: minimumBitsSpent,
}
break;
}
// const updateMinimumBitsSpent = (minimumSpent: number) => {
// let predicate : EventMatchPredicate = {};
//
// switch (bitsRuleType) {
// case BitsRuleType.BitsCheermoteNameExactMatch:
// predicate.bits_cheermote_name_exact_match = {
// cheermote_name: cheerNameOrPrefix,
// }
// break;
// case BitsRuleType.BitsCheermotePrefixSpendThreshold:
// predicate.bits_cheermote_prefix_spend_threshold = {
// cheermote_prefix: cheerNameOrPrefix,
// minimum_bits_spent: minimumSpent,
// }
// break;
// case BitsRuleType.BitsSpendThreshold:
// predicate.bits_spend_threshold = {
// minimum_bits_spent: minimumSpent,
// }
// break;
// }
//
// setMinimumBitsSpent(minimumSpent);
// setEventMatchPredicate(predicate);
// }
setBitsRuleType(ruleType);
setEventMatchPredicate(predicate);
return true;
}
const updateCheerNameOrPrefix = (nameOrPrefix: string) => {
let predicate : EventMatchPredicate = {};
switch (bitsRuleType) {
case BitsRuleType.BitsCheermoteNameExactMatch:
predicate.bits_cheermote_name_exact_match = {
cheermote_name: nameOrPrefix,
}
break;
case BitsRuleType.BitsCheermotePrefixSpendThreshold:
predicate.bits_cheermote_prefix_spend_threshold = {
cheermote_prefix: nameOrPrefix,
minimum_bits_spent: minimumBitsSpent,
}
break;
case BitsRuleType.BitsSpendThreshold:
predicate.bits_spend_threshold = {
minimum_bits_spent: minimumBitsSpent,
}
break;
}
setCheerNameOrPrefix(nameOrPrefix);
setEventMatchPredicate(predicate);
}
const updateMinimumBitsSpent = (minimumSpent: number) => {
let predicate : EventMatchPredicate = {};
switch (bitsRuleType) {
case BitsRuleType.BitsCheermoteNameExactMatch:
predicate.bits_cheermote_name_exact_match = {
cheermote_name: cheerNameOrPrefix,
}
break;
case BitsRuleType.BitsCheermotePrefixSpendThreshold:
predicate.bits_cheermote_prefix_spend_threshold = {
cheermote_prefix: cheerNameOrPrefix,
minimum_bits_spent: minimumSpent,
}
break;
case BitsRuleType.BitsSpendThreshold:
predicate.bits_spend_threshold = {
minimum_bits_spent: minimumSpent,
}
break;
}
setMinimumBitsSpent(minimumSpent);
setEventMatchPredicate(predicate);
}
const updateRewardName = (name: string) => {
setRewardName(name);
}
// const updateRewardName = (name: string) => {
// setRewardName(name);
// }
const updateTtsModelToken = (token: string) => {
let response : EventResponse = {};
@@ -260,38 +261,38 @@ function TtsConfigsEditRulePage(props: Props) {
return <h1>Loading...</h1>;
}
let ruleTypeForm = <></>
if (twitchEventCategory === TwitchEventCategory.Bits) {
switch (bitsRuleType) {
case BitsRuleType.BitsCheermoteNameExactMatch:
ruleTypeForm = <BitsCheermoteNameExactMatchForm
cheerName={cheerNameOrPrefix}
updateCheerNameOrPrefix={updateCheerNameOrPrefix}
/>;
break;
case BitsRuleType.BitsCheermotePrefixSpendThreshold:
ruleTypeForm = <BitsCheermotePrefixSpendThresholdForm
cheerPrefix={cheerNameOrPrefix}
updateCheerNameOrPrefix={updateCheerNameOrPrefix}
minimumBitsSpent={minimumBitsSpent}
updateMinimumBitsSpent={updateMinimumBitsSpent}
/>
break;
case BitsRuleType.BitsSpendThreshold:
ruleTypeForm = <BitsSpendThresholdForm
minimumBitsSpent={minimumBitsSpent}
updateMinimumBitsSpent={updateMinimumBitsSpent}
/>;
break;
}
} else if (twitchEventCategory === TwitchEventCategory.ChannelPoints) {
ruleTypeForm = <ChannelPointsRewardNameExactMatchForm
rewardName={rewardName}
updateRewardName={updateRewardName}
/>;
}
// let ruleTypeForm = <></>
//
// if (twitchEventCategory === TwitchEventCategory.Bits) {
// switch (bitsRuleType) {
// case BitsRuleType.BitsCheermoteNameExactMatch:
// ruleTypeForm = <BitsCheermoteNameExactMatchForm
// cheerName={cheerNameOrPrefix}
// updateCheerNameOrPrefix={updateCheerNameOrPrefix}
// />;
// break;
// case BitsRuleType.BitsCheermotePrefixSpendThreshold:
// ruleTypeForm = <BitsCheermotePrefixSpendThresholdForm
// cheerPrefix={cheerNameOrPrefix}
// updateCheerNameOrPrefix={updateCheerNameOrPrefix}
// minimumBitsSpent={minimumBitsSpent}
// updateMinimumBitsSpent={updateMinimumBitsSpent}
// />
// break;
// case BitsRuleType.BitsSpendThreshold:
// ruleTypeForm = <BitsSpendThresholdForm
// minimumBitsSpent={minimumBitsSpent}
// updateMinimumBitsSpent={updateMinimumBitsSpent}
// />;
// break;
// }
//
// } else if (twitchEventCategory === TwitchEventCategory.ChannelPoints) {
// ruleTypeForm = <ChannelPointsRewardNameExactMatchForm
// rewardName={rewardName}
// updateRewardName={updateRewardName}
// />;
// }
// NB: This is a hypothetical version of what we'll update to
let renderRule : TwitchEventRule = {
@@ -319,7 +320,8 @@ function TtsConfigsEditRulePage(props: Props) {
<form onSubmit={handleFormSubmit}>
<h2 className="title is-4">1) Pick a type of rule</h2>
{/*
<h2 className="title is-4">1) Pick what to match on</h2>
<div className="field">
<label className="label">Rule Type</label>
@@ -339,25 +341,28 @@ function TtsConfigsEditRulePage(props: Props) {
<br />
<br />
<h2 className="title is-4">2) Configure matching</h2>
<h2 className="title is-4">2) Configure the matching</h2>
{ruleTypeForm}
<br />
<br />
*/}
<h2 className="title is-4">3) Pick how to respond</h2>
<EventMatchPredicateBuilderComponent
twitchEventCategory={twitchEventRule.event_category}
allTtsModels={props.allTtsModels}
allTtsModelsByToken={props.allTtsModelsByToken}
<TtsSingleVoiceForm
/>
<EventResponseComponent
allTtsModels={props.allTtsModels}
allTtsModelsByToken={props.allTtsModelsByToken}
setTtsModelToken={updateTtsModelToken}
ttsModelToken={ttsModelToken}
/>
<br />
<br />
<h2 className="title is-4">This is the rule:</h2>
<div className="content">
@@ -0,0 +1,206 @@
import React, { useEffect, useState } from 'react';
import { TtsModelListItem } from '@storyteller/components/src/api/tts/ListTtsModels';
import { FakeYouExternalLink } from '@storyteller/components/src/elements/FakeYouExternalLink';
import { BitsRuleType } from './types/BitsRuleType';
import { TwitchEventCategory } from '@storyteller/components/src/api/storyteller/twitch_event_rules/shared/TwitchEventCategory';
import { EventMatchPredicate } from '@storyteller/components/src/api/storyteller/twitch_event_rules/shared/EventMatchPredicate';
import { BitsCheermoteNameExactMatchForm } from './subforms/BitsCheermoteNameExactMatchForm';
import { BitsCheermotePrefixSpendThresholdForm } from './subforms/BitsCheermotePrefixSpendThresholdForm';
import { BitsSpendThresholdForm } from './subforms/BitsSpendThresholdForm';
import { ChannelPointsRewardNameExactMatchForm } from './subforms/ChannelPointsRewardNameExactMatchForm';
interface EventMatchPredicateBuilderComponentProps {
// CANNOT BE CHANGED AFTER CREATION
twitchEventCategory: TwitchEventCategory,
// Storyteller TTS configs
// FakeYou voices
allTtsModels: TtsModelListItem[],
allTtsModelsByToken: Map<string, TtsModelListItem>,
};
function EventMatchPredicateBuilderComponent(props: EventMatchPredicateBuilderComponentProps) {
// ========== Core UI flow ==========
const [bitsRuleType, setBitsRuleType] = useState<BitsRuleType>(BitsRuleType.BitsCheermoteNameExactMatch);
// ========== Cached Values for Editing ==========
// Used in:
// BitsCheermoteNameExactMatch
// BitsCheermotePrefixSpendThreshold
const [cheerNameOrPrefix, setCheerNameOrPrefix] = useState('');
// Used in:
// BitsSpendThreshold
// BitsCheermotePrefixSpendThreshold
const [minimumBitsSpent, setMinimumBitsSpent] = useState(1);
// Used in:
// ChannelPointsRewardNameExactMatch
const [rewardName, setRewardName] = useState('');
// Used in:
// TtsSingleVoice
const [ttsModelToken, setTtsModelToken] = useState('');
const handleChangedBitsRuleType = (ev: React.FormEvent<HTMLSelectElement>) : boolean => {
const value = (ev.target as HTMLSelectElement).value;
const ruleType = value as BitsRuleType;
let predicate : EventMatchPredicate = {};
// TODO
//switch (ruleType) {
// case BitsRuleType.BitsCheermoteNameExactMatch:
// predicate.bits_cheermote_name_exact_match = {
// cheermote_name: cheerNameOrPrefix,
// }
// break;
// case BitsRuleType.BitsCheermotePrefixSpendThreshold:
// predicate.bits_cheermote_prefix_spend_threshold = {
// cheermote_prefix: cheerNameOrPrefix,
// minimum_bits_spent: minimumBitsSpent,
// }
// break;
// case BitsRuleType.BitsSpendThreshold:
// predicate.bits_spend_threshold = {
// minimum_bits_spent: minimumBitsSpent,
// }
// break;
//}
setBitsRuleType(ruleType);
// TODO
//setEventMatchPredicate(predicate);
return true;
}
const updateCheerNameOrPrefix = (nameOrPrefix: string) => {
let predicate : EventMatchPredicate = {};
switch (bitsRuleType) {
case BitsRuleType.BitsCheermoteNameExactMatch:
predicate.bits_cheermote_name_exact_match = {
cheermote_name: nameOrPrefix,
}
break;
case BitsRuleType.BitsCheermotePrefixSpendThreshold:
predicate.bits_cheermote_prefix_spend_threshold = {
cheermote_prefix: nameOrPrefix,
minimum_bits_spent: minimumBitsSpent,
}
break;
case BitsRuleType.BitsSpendThreshold:
predicate.bits_spend_threshold = {
minimum_bits_spent: minimumBitsSpent,
}
break;
}
setCheerNameOrPrefix(nameOrPrefix);
// TODO
//setEventMatchPredicate(predicate);
}
const updateMinimumBitsSpent = (minimumSpent: number) => {
let predicate : EventMatchPredicate = {};
switch (bitsRuleType) {
case BitsRuleType.BitsCheermoteNameExactMatch:
predicate.bits_cheermote_name_exact_match = {
cheermote_name: cheerNameOrPrefix,
}
break;
case BitsRuleType.BitsCheermotePrefixSpendThreshold:
predicate.bits_cheermote_prefix_spend_threshold = {
cheermote_prefix: cheerNameOrPrefix,
minimum_bits_spent: minimumSpent,
}
break;
case BitsRuleType.BitsSpendThreshold:
predicate.bits_spend_threshold = {
minimum_bits_spent: minimumSpent,
}
break;
}
setMinimumBitsSpent(minimumSpent);
// TODO
//setEventMatchPredicate(predicate);
}
const updateRewardName = (name: string) => {
setRewardName(name);
}
let ruleTypeForm = <></>
if (props.twitchEventCategory === TwitchEventCategory.Bits) {
switch (bitsRuleType) {
case BitsRuleType.BitsCheermoteNameExactMatch:
ruleTypeForm = <BitsCheermoteNameExactMatchForm
cheerName={cheerNameOrPrefix}
updateCheerNameOrPrefix={updateCheerNameOrPrefix}
/>;
break;
case BitsRuleType.BitsCheermotePrefixSpendThreshold:
ruleTypeForm = <BitsCheermotePrefixSpendThresholdForm
cheerPrefix={cheerNameOrPrefix}
updateCheerNameOrPrefix={updateCheerNameOrPrefix}
minimumBitsSpent={minimumBitsSpent}
updateMinimumBitsSpent={updateMinimumBitsSpent}
/>
break;
case BitsRuleType.BitsSpendThreshold:
ruleTypeForm = <BitsSpendThresholdForm
minimumBitsSpent={minimumBitsSpent}
updateMinimumBitsSpent={updateMinimumBitsSpent}
/>;
break;
}
} else if (props.twitchEventCategory === TwitchEventCategory.ChannelPoints) {
ruleTypeForm = <ChannelPointsRewardNameExactMatchForm
rewardName={rewardName}
updateRewardName={updateRewardName}
/>;
}
return (
<>
<h2 className="title is-4">1) Pick what to match on</h2>
<div className="field">
<label className="label">Rule Type</label>
<div className="control">
<div className="select is-medium is-fullwidth">
<select
value={bitsRuleType}
onChange={handleChangedBitsRuleType}>
<option value={BitsRuleType.BitsSpendThreshold}>Bits Spend Threshold</option>
<option value={BitsRuleType.BitsCheermoteNameExactMatch}>Cheermote Name (Exact Match)</option>
<option value={BitsRuleType.BitsCheermotePrefixSpendThreshold}>Cheermote Prefix and Bits Spend Threshold</option>
</select>
</div>
</div>
</div>
<br />
<br />
<h2 className="title is-4">2) Configure the matching</h2>
{ruleTypeForm}
</>
)
}
export { EventMatchPredicateBuilderComponent }
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faGem } from '@fortawesome/free-solid-svg-icons';
import { CHEER_BIT_LEVELS, CHEER_PREFIXES } from '../../../twitch/Cheers';
import { CHEER_BIT_LEVELS, CHEER_PREFIXES } from '../../../../twitch/Cheers';
interface BitsCheermoteNameExactMatchProps {
cheerName: string,
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faGem } from '@fortawesome/free-solid-svg-icons';
import { CHEER_BIT_LEVELS, CHEER_PREFIXES } from '../../../twitch/Cheers';
import { CHEER_BIT_LEVELS, CHEER_PREFIXES } from '../../../../twitch/Cheers';
interface BitsCheermotePrefixSpendThresholdProps {
cheerPrefix: string,
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faGem } from '@fortawesome/free-solid-svg-icons';
import { CHEER_BIT_LEVELS, CHEER_PREFIXES } from '../../../twitch/Cheers';
import { CHEER_BIT_LEVELS } from '../../../../twitch/Cheers';
interface BitsSpendThresholdFormProps {
minimumBitsSpent: number,
@@ -1,4 +1,3 @@
// Rule types for the different types of event types
// For bits / cheermotes
export enum BitsRuleType {
@@ -6,8 +5,3 @@ export enum BitsRuleType {
BitsCheermotePrefixSpendThreshold = "bits_cheermote_prefix_spend_threshold",
BitsSpendThreshold = "bits_spend_threshold",
}
// For channel points
export enum ChannelPointsRuleType {
ChannelPointsRewardNameExactMatch,
}
@@ -0,0 +1,5 @@
// For channel points
export enum ChannelPointsRuleType {
ChannelPointsRewardNameExactMatch,
}
@@ -0,0 +1,88 @@
import React, { useEffect, useState } from 'react';
import { TtsModelListItem } from '@storyteller/components/src/api/tts/ListTtsModels';
import { FakeYouExternalLink } from '@storyteller/components/src/elements/FakeYouExternalLink';
import { TtsSingleVoiceForm } from './TtsSingleVoiceForm';
import { EventResponseType } from './EventResponseType';
interface EventResponseComponentProps {
// Storyteller TTS configs
ttsModelToken: string,
setTtsModelToken: (token: string) => void,
// FakeYou voices
allTtsModels: TtsModelListItem[],
allTtsModelsByToken: Map<string, TtsModelListItem>,
};
function EventResponseComponent(props: EventResponseComponentProps) {
const [eventResponseType, setEventResponseType] = useState<EventResponseType>(EventResponseType.TtsSingleVoice);
const handleChangedEventResponseType = (ev: React.FormEvent<HTMLSelectElement>) : boolean => {
const value = (ev.target as HTMLSelectElement).value;
const responseType = value as EventResponseType;
// TODO:
//let predicate : EventMatchPredicate = {};
//switch (ruleType) {
// case BitsRuleType.BitsCheermoteNameExactMatch:
// predicate.bits_cheermote_name_exact_match = {
// cheermote_name: cheerNameOrPrefix,
// }
// break;
// case BitsRuleType.BitsCheermotePrefixSpendThreshold:
// predicate.bits_cheermote_prefix_spend_threshold = {
// cheermote_prefix: cheerNameOrPrefix,
// minimum_bits_spent: minimumBitsSpent,
// }
// break;
// case BitsRuleType.BitsSpendThreshold:
// predicate.bits_spend_threshold = {
// minimum_bits_spent: minimumBitsSpent,
// }
// break;
//}
setEventResponseType(responseType);
//setEventMatchPredicate(predicate);
return true;
}
return (
<>
<h2 className="title is-4">3) Pick how to respond</h2>
<div className="field">
<label className="label">Response Type</label>
<div className="control">
<div className="select is-medium is-fullwidth">
<select
value={eventResponseType}
onChange={handleChangedEventResponseType}>
<option value={EventResponseType.TtsSingleVoice}>Respond with a TTS voice</option>
<option value={EventResponseType.TtsRandomVoice}>Respond with a Random TTS voice from list</option>
</select>
</div>
</div>
</div>
<br />
<br />
<h2 className="title is-4">4) Configure the response</h2>
<TtsSingleVoiceForm
allTtsModels={props.allTtsModels}
allTtsModelsByToken={props.allTtsModelsByToken}
setTtsModelToken={props.setTtsModelToken}
ttsModelToken={props.ttsModelToken}
/>
<br />
<br />
</>
)
}
export { EventResponseComponent }