From d4f3fc650af8bf995744ff6a41532d10498395ad Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 24 Feb 2022 03:06:43 -0500 Subject: [PATCH] coming together.. --- .../tts_configs/TtsConfigsEditRulePage.tsx | 184 ++---------------- .../EventMatchPredicateBuilderComponent.tsx | 124 ++++++------ .../EventResponseComponent.tsx | 27 +-- 3 files changed, 76 insertions(+), 259 deletions(-) diff --git a/packages/storyteller/src/pages/tts_configs/TtsConfigsEditRulePage.tsx b/packages/storyteller/src/pages/tts_configs/TtsConfigsEditRulePage.tsx index 2e208b2fd1..038ec1086e 100644 --- a/packages/storyteller/src/pages/tts_configs/TtsConfigsEditRulePage.tsx +++ b/packages/storyteller/src/pages/tts_configs/TtsConfigsEditRulePage.tsx @@ -9,11 +9,7 @@ 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 './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 { 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'; @@ -32,18 +28,21 @@ function TtsConfigsEditRulePage(props: Props) { const history = useHistory(); - // Initial request + // ========== Initial Load of Server State ========== + const [twitchEventRule, setTwitchEventRule] = useState(undefined); - // The event category cannot be changed ! - const [twitchEventCategory, setTwitchEventCategory] = useState(TwitchEventCategory.Bits); + // ========== Values passed to subcomponents for editing ========== - // The rule types differ per category and the user can change them - const [bitsRuleType, setBitsRuleType] = useState(BitsRuleType.BitsCheermoteNameExactMatch); - //const [channelPointsRuleType, setChannelPointsRuleType] = useState(ChannelPointsRuleType.ChannelPointsRewardNameExactMatch); + const [newEventMatchPredicate, setNewEventMatchPredicate] = useState({}); + const [newEventResponse, setNewEventResponse] = useState({}); + // ========== ??? ========== + + /// TODO GET RID OF THIS const [eventResponseType, setEventResponseType] = useState(EventResponseType.TtsSingleVoice); + // ===== Predicate Field values (editing) ===== // Used in: @@ -77,11 +76,14 @@ function TtsConfigsEditRulePage(props: Props) { if (GetTwitchEventRuleIsOk(response)) { setTwitchEventRule(response.twitch_event_rule); - setTwitchEventCategory(response.twitch_event_rule.event_category); setEventMatchPredicate(response.twitch_event_rule.event_match_predicate); setEventResponse(response.twitch_event_rule.event_response); setRuleIsDisabled(response.twitch_event_rule.rule_is_disabled); + // TODO + setNewEventMatchPredicate(response.twitch_event_rule.event_match_predicate); + setNewEventResponse(response.twitch_event_rule.event_response); + let serverBitsRuleType = BitsRuleType.BitsCheermoteNameExactMatch; switch (response.twitch_event_rule.event_category) { @@ -106,8 +108,6 @@ function TtsConfigsEditRulePage(props: Props) { break; } - setBitsRuleType(serverBitsRuleType); - if (!!response.twitch_event_rule.event_response.tts_single_voice) { setEventResponseType(EventResponseType.TtsSingleVoice); setTtsModelToken(response.twitch_event_rule.event_response.tts_single_voice.tts_model_token) @@ -125,93 +125,6 @@ function TtsConfigsEditRulePage(props: Props) { getTwitchEventRule(token); }, [getTwitchEventRule, token]); -// const updateBitsRuleType = (ev: React.FormEvent) : 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; -// } - -// 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 updateTtsModelToken = (token: string) => { let response : EventResponse = {}; @@ -231,6 +144,10 @@ function TtsConfigsEditRulePage(props: Props) { setEventResponse(response); } + const updateEventMatchPredicate = (predicate: EventMatchPredicate) => { + setNewEventMatchPredicate(predicate); + } + const handleFormSubmit = async (ev: React.FormEvent) : Promise => { ev.preventDefault(); @@ -252,7 +169,6 @@ function TtsConfigsEditRulePage(props: Props) { return false; } - if (!props.sessionWrapper.isLoggedIn()) { return

Must Log In

; } @@ -261,39 +177,6 @@ function TtsConfigsEditRulePage(props: Props) { return

Loading...

; } -// let ruleTypeForm = <> -// -// if (twitchEventCategory === TwitchEventCategory.Bits) { -// switch (bitsRuleType) { -// case BitsRuleType.BitsCheermoteNameExactMatch: -// ruleTypeForm = ; -// break; -// case BitsRuleType.BitsCheermotePrefixSpendThreshold: -// ruleTypeForm = -// break; -// case BitsRuleType.BitsSpendThreshold: -// ruleTypeForm = ; -// break; -// } -// -// } else if (twitchEventCategory === TwitchEventCategory.ChannelPoints) { -// ruleTypeForm = ; -// } - // NB: This is a hypothetical version of what we'll update to let renderRule : TwitchEventRule = { // Unchanged @@ -304,7 +187,7 @@ function TtsConfigsEditRulePage(props: Props) { updated_at: twitchEventRule.updated_at, // Updated in UI - event_match_predicate: eventMatchPredicate, + event_match_predicate: newEventMatchPredicate, event_response: eventResponse, rule_is_disabled: ruleIsDisabled, }; @@ -320,37 +203,10 @@ function TtsConfigsEditRulePage(props: Props) {
-{/* -

1) Pick what to match on

- -
- -
-
- -
-
-
- -
-
- -

2) Configure the matching

- - {ruleTypeForm} - -
-
-*/} - void, // FakeYou voices allTtsModels: TtsModelListItem[], @@ -43,82 +45,74 @@ function EventMatchPredicateBuilderComponent(props: EventMatchPredicateBuilderCo // ChannelPointsRewardNameExactMatch const [rewardName, setRewardName] = useState(''); - // Used in: - // TtsSingleVoice - const [ttsModelToken, setTtsModelToken] = useState(''); + // NB: useState is not always setting from props correctly (after several re-renders) + // The following answers suggests using useEffect: + // https://stackoverflow.com/a/54866051 (less clear by also using useState(), but good comments) + // https://stackoverflow.com/a/62982753 + useEffect(() => { + let newBitsRuleType = BitsRuleType.BitsCheermoteNameExactMatch; + let newChannelPointsRuleType = ChannelPointsRuleType.ChannelPointsRewardNameExactMatch; + + switch (props.twitchEventCategory) { + case TwitchEventCategory.Bits: + if (!!props.eventMatchPredicate.bits_cheermote_name_exact_match) { + //serverBitsRuleType = BitsRuleType.BitsCheermoteNameExactMatch; + newBitsRuleType = BitsRuleType.BitsCheermoteNameExactMatch; + } else if (!!props.eventMatchPredicate.bits_cheermote_prefix_spend_threshold) { + //serverBitsRuleType = BitsRuleType.BitsCheermotePrefixSpendThreshold; + //setMinimumBitsSpent(response.twitch_event_rule.event_match_predicate.bits_cheermote_prefix_spend_threshold.minimum_bits_spent); + newBitsRuleType = BitsRuleType.BitsCheermotePrefixSpendThreshold; + } else if (!!props.eventMatchPredicate.bits_spend_threshold) { + //serverBitsRuleType = BitsRuleType.BitsSpendThreshold; + //setMinimumBitsSpent(response.twitch_event_rule.event_match_predicate.bits_spend_threshold.minimum_bits_spent); + newBitsRuleType = BitsRuleType.BitsSpendThreshold; + } + break; + case TwitchEventCategory.ChannelPoints: // NB: Only one rule type + if (!!props.eventMatchPredicate.channel_points_reward_name_exact_match) { + //setRewardName(response.twitch_event_rule.event_match_predicate.channel_points_reward_name_exact_match.reward_name); + newChannelPointsRuleType = ChannelPointsRuleType.ChannelPointsRewardNameExactMatch; + } + break; + case TwitchEventCategory.ChatCommand: // TODO: Not yet supported + default: + break; + } + + setBitsRuleType(newBitsRuleType); + setChannelPointsRuleType(newChannelPointsRuleType); + + }, [props.twitchEventCategory, props.eventMatchPredicate]); const handleChangedBitsRuleType = (ev: React.FormEvent) : 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 handleChangedChannelPointsRuleType = (ev: React.FormEvent) : boolean => { const value = (ev.target as HTMLSelectElement).value; const ruleType = value as ChannelPointsRuleType; - - // TODO: - let predicate : EventMatchPredicate = {}; - setChannelPointsRuleType(ruleType); 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); + backPropagateEventMatchPredicate(); } const updateMinimumBitsSpent = (minimumSpent: number) => { + setMinimumBitsSpent(minimumSpent); + backPropagateEventMatchPredicate(); + } + + const updateRewardName = (name: string) => { + setRewardName(name); + } + + const backPropagateEventMatchPredicate = () => { let predicate : EventMatchPredicate = {}; switch (bitsRuleType) { @@ -130,23 +124,17 @@ function EventMatchPredicateBuilderComponent(props: EventMatchPredicateBuilderCo case BitsRuleType.BitsCheermotePrefixSpendThreshold: predicate.bits_cheermote_prefix_spend_threshold = { cheermote_prefix: cheerNameOrPrefix, - minimum_bits_spent: minimumSpent, + minimum_bits_spent: minimumBitsSpent, } break; case BitsRuleType.BitsSpendThreshold: predicate.bits_spend_threshold = { - minimum_bits_spent: minimumSpent, + minimum_bits_spent: minimumBitsSpent, } break; } - setMinimumBitsSpent(minimumSpent); - // TODO - //setEventMatchPredicate(predicate); - } - - const updateRewardName = (name: string) => { - setRewardName(name); + props.updateEventMatchPredicate(predicate); } @@ -214,14 +202,12 @@ function EventMatchPredicateBuilderComponent(props: EventMatchPredicateBuilderCo />; } - console.log(matchingRulesForm); - return ( <>

1) Pick what to match on

- + {/**/}
{ruleTypeSelect} diff --git a/packages/storyteller/src/pages/tts_configs/event_response_builder/EventResponseComponent.tsx b/packages/storyteller/src/pages/tts_configs/event_response_builder/EventResponseComponent.tsx index ad4f1e0657..9d418cb53e 100644 --- a/packages/storyteller/src/pages/tts_configs/event_response_builder/EventResponseComponent.tsx +++ b/packages/storyteller/src/pages/tts_configs/event_response_builder/EventResponseComponent.tsx @@ -5,7 +5,7 @@ import { TtsSingleVoiceForm } from './TtsSingleVoiceForm'; import { EventResponseType } from './EventResponseType'; interface EventResponseComponentProps { - // Storyteller TTS configs + // Form state communicated upstream ttsModelToken: string, setTtsModelToken: (token: string) => void, @@ -20,32 +20,7 @@ function EventResponseComponent(props: EventResponseComponentProps) { const handleChangedEventResponseType = (ev: React.FormEvent) : 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 (