mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 09:28:11 +00:00
coming together..
This commit is contained in:
1 parent
0daf419e55
commit
d4f3fc650a
3 files changed
+76
-259
No files matched your search
@@ -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<TwitchEventRule|undefined>(undefined);
|
||||
|
||||
// The event category cannot be changed !
|
||||
const [twitchEventCategory, setTwitchEventCategory] = useState<TwitchEventCategory>(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>(BitsRuleType.BitsCheermoteNameExactMatch);
|
||||
//const [channelPointsRuleType, setChannelPointsRuleType] = useState<ChannelPointsRuleType>(ChannelPointsRuleType.ChannelPointsRewardNameExactMatch);
|
||||
const [newEventMatchPredicate, setNewEventMatchPredicate] = useState<EventMatchPredicate>({});
|
||||
const [newEventResponse, setNewEventResponse] = useState<EventResponse>({});
|
||||
|
||||
// ========== ??? ==========
|
||||
|
||||
/// TODO GET RID OF THIS
|
||||
const [eventResponseType, setEventResponseType] = useState<EventResponseType>(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<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;
|
||||
// }
|
||||
|
||||
// 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<HTMLFormElement>) : Promise<boolean> => {
|
||||
ev.preventDefault();
|
||||
|
||||
@@ -252,7 +169,6 @@ function TtsConfigsEditRulePage(props: Props) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!props.sessionWrapper.isLoggedIn()) {
|
||||
return <h1>Must Log In</h1>;
|
||||
}
|
||||
@@ -261,39 +177,6 @@ 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}
|
||||
// />;
|
||||
// }
|
||||
|
||||
// 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) {
|
||||
|
||||
<form onSubmit={handleFormSubmit}>
|
||||
|
||||
{/*
|
||||
<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={updateBitsRuleType}>
|
||||
<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}
|
||||
|
||||
<br />
|
||||
<br />
|
||||
*/}
|
||||
|
||||
<EventMatchPredicateBuilderComponent
|
||||
twitchEventCategory={twitchEventRule.event_category}
|
||||
eventMatchPredicate={newEventMatchPredicate}
|
||||
updateEventMatchPredicate={updateEventMatchPredicate}
|
||||
allTtsModels={props.allTtsModels}
|
||||
allTtsModelsByToken={props.allTtsModelsByToken}
|
||||
|
||||
|
||||
+55
-69
@@ -14,7 +14,9 @@ interface EventMatchPredicateBuilderComponentProps {
|
||||
// CANNOT BE CHANGED AFTER CREATION
|
||||
twitchEventCategory: TwitchEventCategory,
|
||||
|
||||
// Storyteller TTS configs
|
||||
// Updates sent back up the tree
|
||||
eventMatchPredicate: EventMatchPredicate,
|
||||
updateEventMatchPredicate: (predicate: EventMatchPredicate) => 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<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 handleChangedChannelPointsRuleType = (ev: React.FormEvent<HTMLSelectElement>) : 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 (
|
||||
<>
|
||||
<h2 className="title is-4">1) Pick what to match on</h2>
|
||||
|
||||
<div className="field">
|
||||
<label className="label">Rule Type</label>
|
||||
{/*<label className="label">Rule Type</label>*/}
|
||||
<div className="control">
|
||||
<div className="select is-medium is-fullwidth">
|
||||
{ruleTypeSelect}
|
||||
|
||||
+1
-26
@@ -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<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 (
|
||||
|
||||
Reference in new issue
Block a user