From a9ca5fbcf9f11d1281e80f3c2a6ffbd810d834bb Mon Sep 17 00:00:00 2001 From: Layne <laynebalsters@gmail.com> Date: Tue, 29 Jun 2021 09:15:31 -0400 Subject: [PATCH 1/4] wired custom ui boxes --- .../images/wired/card-action-corners.png | Bin 0 -> 1827 bytes src/views/wired/WiredView.scss | 122 ++++++++++++++++++ src/views/wired/views/base/WiredBaseView.tsx | 15 ++- 3 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 src/assets/images/wired/card-action-corners.png diff --git a/src/assets/images/wired/card-action-corners.png b/src/assets/images/wired/card-action-corners.png new file mode 100644 index 0000000000000000000000000000000000000000..faec2349dc752a8e3ab656e8470bd5ab3bdd548c GIT binary patch literal 1827 zcmcIlPl()97>|ghwpJ=46%P_p!L9lxe<uH4?6l0zY~2B~uDfI176o5kUS`53c`?cC z%q|K=7Q{mjiWj9Gym}C!;-M;nH*ey_vpu*+^(ct=z4_NF+hr~WlDs6p_xpa|@B8xJ zd+Td2oI3Hu2}zPpbynLOaDPag$B)7F^5C@txILJ!UMVH%<fG!ePx|=A<C1hNiMw0X zmj9whd0HbO4_IxK=75%@^A|@sq1&vI1J;YPhVt9j-zjn&Hk4N_U-R=8>&L5m1>4+P z>(ae#ibLh%1^N8Q1A>%QL>{F{R(hj`GUoMQEMBXMJcd-;4W%gp%3J=r+~Nh3t(uLf zZo0CAYr1V}b^AHl&~&V7uBz9OrhA(0S&lqC6o^)Yk+;#lG>rvM4W(aIxu>eb;jlKW z*LcxWb&P?-Pz?hC0+qX2MMfwq&(0XytfWPpS253I!AJr=s2U0=ourWFbK0z&+60EF zBa*9nO%o~2fWCh;G)?E|vRc`JC{w+M5|`cGoT(eE<b#5;l^vE<XJ^6kKCgJ$=l9Sy z|NJk7A)N=z2SqZrC!{J%SPI-FVD+)S+-nt#RJ`bNp3DlhK8q+DkhQ$z6B=hi!#Sa8 zI)$}K#TtsC89LHzWZ<smdY0~42GUGV(<V?KIw2$#Sq#j>INDtV>ib?ND=U&w)@e5s z5LJug&@)|PGM!>%Vw1wfVkmG3MV1@kFmfUbo8ed&%x`l#5MGG+lg14>1&+C&9;=%s zqmUbM%mBHXsUcTqAqw0&wQ!(EIKnfwmx>tv9g^J5DpZBQ=ui#U%`iZYfg@zvc7Os) zbCE+_TBn%Uj^QZsowzNY@WSUIxLa4`ka`g>QUV<mr=-W!JnM;m26o6|H7=oeyVE~p zlf5||C9yniJC9J&?G1&BGBe12@;W}my~T7+<`4S}NRKG~1Xl8>8j^xFd*Ji}?WNvJ zeo1zY7Qa~O|5x!-YiXZkJqF9Cs)%${vCvEkqyD#McWOTCn<jL$sAxGgVwv>jmRvZz zO(`*K!!=E$8Q4KVWMUNP1S1kT77HSa={T6ENaC5E39Wi`{IT-8mdx2?Sck=Mz5&3) zd<$V2BwoM<v3z~dht1{nPP^G%djFG+=EK*d<G0yc-#`6lerx|`@$B<CxpsU1De1>E zH?A%zAAa<}N$<=fzrMUrS_fB8KN)m>|EzWT(jVb7E!Fzv^55^0Z-2UF{_yk7558HG juYB=o`Pi3lU%&sW+F!419-NEBHr82LYk$7{#ykH20l7o+ literal 0 HcmV?d00001 diff --git a/src/views/wired/WiredView.scss b/src/views/wired/WiredView.scss index bab60efb..ce1bc799 100644 --- a/src/views/wired/WiredView.scss +++ b/src/views/wired/WiredView.scss @@ -1,5 +1,6 @@ .nitro-wired { width: 300px; + padding:7px; .icon { width: 16px; @@ -35,4 +36,125 @@ background-image: url('../../assets/images/wired/icon_wired_rotate_counter_clockwise.png'); } } + + .nitro-wired-header { + color: #000; + margin-bottom:3px; + + .nitro-wired-title, .nitro-wired-close { + border:1px solid rgba($black,.8); + background-image: linear-gradient(45deg, #00d9cb 25%, #00bdb0 25%, #00bdb0 50%, #00d9cb 50%, #00d9cb 75%, #00bdb0 75%, #00bdb0 100%); + background-size: 197.99px 197.99px; + animation: wiredSlider 3s linear infinite; + text-align: center; + box-shadow:inset 0 0 0 2px rgba($white,.6), 0 2px rgba($black,.4); + } + + .nitro-wired-title { + margin-right:3px; + } + + .nitro-wired-close { + min-width: 23px; + } + } + + &.nitro-wired-trigger { + background-color: #3b2516 !important; + border: 1px solid #000 !important; + box-shadow: inset 0px -2px #50321f, + inset 0px -3px #86583b, + inset 0 0 0 1px #86583b, + inset 0 0 0 3px #644029, + inset 0 0 0 4px rgba($black,.4) !important; + + .bg-light,.bg-primary { + background-color: transparent !important; + } + + .bg-dark { + background-color: #000 !important; + } + } + + &.nitro-wired-action { + background-color: #686868 !important; + border: 1px solid #000 !important; + box-shadow: inset 0px -2px #9d9d9d, + inset 0px -3px #c5c5c5, + inset 0 0 0 1px #c5c5c5, + inset 0 0 0 3px #9d9d9d, + inset 0 0 0 4px rgba($black,.4) !important; + + .bg-light,.bg-primary { + background-color: transparent !important; + } + + .bg-dark { + background-color: #000 !important; + } + + &::before, + &::after, + .content-area::before, + .content-area::after { + content: ''; + height: 6px; + width: 6px; + position: absolute; + background-image: url('../../assets/images/wired/card-action-corners.png'); + } + + &::before { + background-position: 0 0; + top: 0; + left: 0; + } + + &::after { + background-position: 6px 0; + top: 0; + right: 0; + } + + .content-area { + &::before { + background-position: 0 6px; + bottom: 0; + left: 0; + } + + &::after { + background-position: 6px 6px; + bottom: 0; + right: 0; + } + } + } + + &.nitro-wired-condition { + background-color: #cfd2dd !important; + border: 1px solid #000 !important; + box-shadow: inset 0 0 0 3px #efefef, inset 4px 4px #abaeb9 !important; + color: #000; + + .bg-light,.bg-primary { + background-color: transparent !important; + } + + .bg-dark { + background-color: #000 !important; + } + } +} + + +@keyframes wiredSlider { + 0% { + background-position: 0 0; + } + + 100% { + background-position: 0 -197.99px; + } } diff --git a/src/views/wired/views/base/WiredBaseView.tsx b/src/views/wired/views/base/WiredBaseView.tsx index 3bbc1c85..44fc0106 100644 --- a/src/views/wired/views/base/WiredBaseView.tsx +++ b/src/views/wired/views/base/WiredBaseView.tsx @@ -2,7 +2,7 @@ import { FC, useCallback, useEffect, useState } from 'react'; import { GetSessionDataManager } from '../../../../api'; import { WiredEvent } from '../../../../events'; import { dispatchUiEvent } from '../../../../hooks/events'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { NitroCardContentView, NitroCardView } from '../../../../layout'; import { LocalizeText } from '../../../../utils/LocalizeText'; import { useWiredContext } from '../../context/WiredContext'; import { WiredFurniType } from '../../WiredView.types'; @@ -52,9 +52,12 @@ export const WiredBaseView: FC<WiredBaseViewProps> = props => }, [ setTrigger ]); return ( - <NitroCardView className="nitro-wired" simple={ true }> - <NitroCardHeaderView headerText={ LocalizeText('wiredfurni.title') } onCloseClick={ close } /> - <NitroCardContentView className="text-black"> + <NitroCardView className={`nitro-wired nitro-wired-${wiredType} ` + (wiredType == 'trigger' ? 'rounded-0' : 'rounded-2')}> + <div className="nitro-wired-header d-flex"> + <div className="nitro-wired-title rounded-start w-100 drag-handler">{LocalizeText('wiredfurni.title')}</div> + <div className="nitro-wired-close rounded-end flex-shrink-0" onClick={ close }><i className="fas fa-times" /></div> + </div> + <NitroCardContentView> <div className="d-flex align-items-center"> <i className={ `me-2 icon icon-wired-${ wiredType }` } /> <div className="fw-bold">{ wiredName }</div> @@ -73,8 +76,8 @@ export const WiredBaseView: FC<WiredBaseViewProps> = props => <div>{ LocalizeText('wiredfurni.pickfurnis.desc') }</div> </> } <div className="d-flex mt-3"> - <button className="btn btn-success me-2 w-100" onClick={ onSave }>{ LocalizeText('wiredfurni.ready') }</button> - <button className="btn btn-secondary w-100" onClick={ close }>{ LocalizeText('cancel') }</button> + <button className="btn btn-sm btn-success me-2 w-100" onClick={ onSave }>{ LocalizeText('wiredfurni.ready') }</button> + <button className="btn btn-sm btn-secondary w-100" onClick={ close }>{ LocalizeText('cancel') }</button> </div> </NitroCardContentView> </NitroCardView> From 6de6540a03682fe8008afc759e37eb9be16e8130 Mon Sep 17 00:00:00 2001 From: MyNameIsBatman <montevechiol@gmail.com> Date: Tue, 29 Jun 2021 17:38:03 -0300 Subject: [PATCH 2/4] Give Reward Action --- .../wired/common/GetWiredActionLayout.tsx | 3 + .../WiredActionBotGiveHandItemView.tsx | 2 +- .../give-reward/WiredActionGiveRewardView.tsx | 173 ++++++++++++++++++ .../WiredConditionActorHasHandItem.tsx | 2 +- 4 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 src/views/wired/views/actions/give-reward/WiredActionGiveRewardView.tsx diff --git a/src/views/wired/common/GetWiredActionLayout.tsx b/src/views/wired/common/GetWiredActionLayout.tsx index fe1ca34f..9c698937 100644 --- a/src/views/wired/common/GetWiredActionLayout.tsx +++ b/src/views/wired/common/GetWiredActionLayout.tsx @@ -9,6 +9,7 @@ import { WiredActionCallAnotherStackView } from '../views/actions/call-another-s import { WiredActionChaseView } from '../views/actions/chase/WiredActionChaseView'; import { WiredActionChatView } from '../views/actions/chat/WiredActionChatView'; import { WiredActionFleeView } from '../views/actions/flee/WiredActionFleeView'; +import { WiredActionGiveRewardView } from '../views/actions/give-reward/WiredActionGiveRewardView'; import { WiredActionGiveScoreToPredefinedTeamView } from '../views/actions/give-score-to-predefined-team/WiredActionGiveScoreToPredefinedTeamView'; import { WiredActionGiveScoreView } from '../views/actions/give-score/WiredActionGiveScoreView'; import { WiredActionJoinTeamView } from '../views/actions/join-team/WiredActionJoinTeamView'; @@ -50,6 +51,8 @@ export function GetWiredActionLayout(code: number): JSX.Element return <WiredActionChatView />; case WiredActionLayout.FLEE: return <WiredActionFleeView />; + case WiredActionLayout.GIVE_REWARD: + return <WiredActionGiveRewardView />; case WiredActionLayout.GIVE_SCORE: return <WiredActionGiveScoreView />; case WiredActionLayout.GIVE_SCORE_TO_PREDEFINED_TEAM: diff --git a/src/views/wired/views/actions/bot-give-hand-item/WiredActionBotGiveHandItemView.tsx b/src/views/wired/views/actions/bot-give-hand-item/WiredActionBotGiveHandItemView.tsx index 75c0db17..2b3f8d6f 100644 --- a/src/views/wired/views/actions/bot-give-hand-item/WiredActionBotGiveHandItemView.tsx +++ b/src/views/wired/views/actions/bot-give-hand-item/WiredActionBotGiveHandItemView.tsx @@ -31,7 +31,7 @@ export const WiredActionBotGiveHandItemView: FC<{}> = props => <input type="text" className="form-control form-control-sm" maxLength={ 32 } value={ botName } onChange={ event => setBotName(event.target.value) } /> </div> <div className="fw-bold">{ LocalizeText('wiredfurni.params.handitem') }</div> - <select className="form-select" value={ handItemId } onChange={ (e) => setHandItemId(Number(e.target.value)) }> + <select className="form-select form-select-sm" value={ handItemId } onChange={ (e) => setHandItemId(Number(e.target.value)) }> <option value="0">------</option> {allowedHanditemIds && allowedHanditemIds.map(value => { diff --git a/src/views/wired/views/actions/give-reward/WiredActionGiveRewardView.tsx b/src/views/wired/views/actions/give-reward/WiredActionGiveRewardView.tsx new file mode 100644 index 00000000..0d857a67 --- /dev/null +++ b/src/views/wired/views/actions/give-reward/WiredActionGiveRewardView.tsx @@ -0,0 +1,173 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionGiveRewardView: FC<{}> = props => +{ + const [ limitEnabled, setLimitEnabled ] = useState(false); + const [ rewardTime, setRewardTime ] = useState(1); + const [ uniqueRewards, setUniqueRewards ] = useState(false); + const [ rewardsLimit, setRewardsLimit ] = useState(1); + const [ limitationInterval, setLimitationInterval ] = useState(1); + const [ rewards, setRewards ] = useState<{ isBadge: boolean, itemCode: string, probability: number }[]>([]); + + const { trigger = null, setIntParams = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setRewardTime(trigger.intData.length > 0 ? trigger.intData[0] : 0); + setUniqueRewards(trigger.intData.length > 1 ? trigger.intData[1] === 1 : false); + setRewardsLimit(trigger.intData.length > 2 ? trigger.intData[2] : 0); + setLimitationInterval(trigger.intData.length > 3 ? trigger.intData[3] : 0); + setLimitEnabled(trigger.intData.length > 3 ? trigger.intData[3] > 0 : false); + + const readRewards: { isBadge: boolean, itemCode: string, probability: number }[] = []; + + if(trigger.stringData.length > 0 && trigger.stringData.includes(';')) + { + const splittedRewards = trigger.stringData.split(';'); + + for(const rawReward of splittedRewards) + { + const reward = rawReward.split(','); + + if(reward.length !== 3) continue; + + readRewards.push({ isBadge: reward[0] === '0', itemCode: reward[1], probability: Number(reward[2]) }); + } + } + + if(readRewards.length === 0) + { + readRewards.push({ isBadge: false, itemCode: '', probability: null }); + } + + setRewards(readRewards); + }, [ trigger ]); + + const addReward = useCallback(() => + { + setRewards(rewards => [...rewards, { isBadge: false, itemCode: '', probability: null }]); + }, [ setRewards ]); + + const removeReward = useCallback((index: number) => + { + const rewardsClone = Array.from(rewards); + rewardsClone.splice(index, 1); + + setRewards(rewardsClone); + }, [ rewards, setRewards ]); + + const updateReward = useCallback((index: number, isBadge: boolean, itemCode: string, probability: number) => + { + const rewardsClone = Array.from(rewards); + const reward = rewardsClone[index]; + + if(!reward) return; + + reward.isBadge = isBadge; + reward.itemCode = itemCode; + reward.probability = probability; + + setRewards(rewardsClone); + }, [ rewards, setRewards ]); + + const save = useCallback(() => + { + let stringRewards = []; + + for(const reward of rewards) + { + if(!reward.itemCode) continue; + + const rewardsString = [reward.isBadge ? '0' : '1', reward.itemCode, reward.probability.toString()]; + stringRewards.push(rewardsString.join(',')); + } + + if(stringRewards.length > 0) + { + setStringParam(stringRewards.join(';')); + setIntParams([rewardTime, uniqueRewards ? 1 : 0, rewardsLimit, limitationInterval]); + } + }, [ rewardTime, uniqueRewards, rewardsLimit, limitationInterval, rewards, setIntParams, setStringParam ]); + + return ( + <WiredActionBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }> + <div className="form-check"> + <input className="form-check-input" type="checkbox" id="limitEnabled" onChange={(e) => setLimitEnabled(e.target.checked)} /> + <label className="form-check-label" htmlFor="uniqueRewards"> + { LocalizeText('wiredfurni.params.prizelimit', ['amount'], [limitEnabled ? rewardsLimit.toString() : '']) } + </label> + </div> + { !limitEnabled && <div className="bg-muted rounded small text-black p-1 text-center"> + Reward limit not set. Make sure rewards are badges or non-tradeable items. + </div> } + { limitEnabled && <Slider + defaultValue={ rewardsLimit } + dots={ true } + min={ 1 } + max={ 1000 } + step={ 1 } + onChange={ event => setRewardsLimit(event) } + /> } + <hr className="my-1 mb-2 bg-dark" /> + <div className="fw-bold">How ofter can a user be rewarded?</div> + <div className="d-flex"> + <select className="form-select form-select-sm w-100" value={ rewardTime } onChange={ (e) => setRewardTime(Number(e.target.value)) }> + <option value="0">Once</option> + <option value="3">Once every { limitationInterval } minutes</option> + <option value="2">Once every { limitationInterval } hours</option> + <option value="1">Once every { limitationInterval } days</option> + </select> + { rewardTime > 0 && <input type="number" className="ms-2 form-control form-control-sm" value={ limitationInterval } onChange={ event => setLimitationInterval(Number(event.target.value)) } /> } + </div> + <hr className="my-1 mb-2 bg-dark" /> + <div className="form-check"> + <input className="form-check-input" type="checkbox" id="uniqueRewards" checked={ uniqueRewards } onChange={(e) => setUniqueRewards(e.target.checked)} /> + <label className="form-check-label" htmlFor="uniqueRewards"> + Unique rewards + </label> + </div> + <div className="bg-muted rounded small text-black p-1 text-center">If checked each reward will be given once to each user. This will disable the probabilities option.</div> + <hr className="my-1 mb-2 bg-dark" /> + <div className="d-flex justify-content-between align-items-center"> + <div className="fw-bold">Rewards</div> + <div className="btn btn-sm btn-success" onClick={ addReward }><i className="fas fa-plus" /></div> + </div> + <table className="table-sm"> + <thead> + <tr> + <td>Badge?</td> + <td>Item Code</td> + <td>Probability</td> + <td></td> + </tr> + </thead> + <tbody> + { rewards && rewards.map((reward, index) => + { + return ( + <tr key={ index }> + <td className="d-flex align-items-center justify-content-center"> + <input className="form-check-input" type="checkbox" checked={ reward.isBadge } onChange={(e) => updateReward(index, e.target.checked, reward.itemCode, reward.probability)} /> + </td> + <td> + <input type="text" className="form-control form-control-sm" value={ reward.itemCode } onChange={ e => updateReward(index, reward.isBadge, e.target.value, reward.probability) } /> + </td> + <td> + <input type="number" className="form-control form-control-sm" value={ reward.probability } onChange={ e => updateReward(index, reward.isBadge, reward.itemCode, Number(e.target.value)) } /> + </td> + <td> + { index > 0 && <button className="btn btn-sm btn-danger" onClick={() => removeReward(index) }><i className="fas fa-trash" /></button> } + </td> + </tr> + ) + }) } + </tbody> + </table> + </WiredActionBaseView> + ); +} diff --git a/src/views/wired/views/conditions/actor-has-hand-item/WiredConditionActorHasHandItem.tsx b/src/views/wired/views/conditions/actor-has-hand-item/WiredConditionActorHasHandItem.tsx index fe746924..5a4fb4c5 100644 --- a/src/views/wired/views/conditions/actor-has-hand-item/WiredConditionActorHasHandItem.tsx +++ b/src/views/wired/views/conditions/actor-has-hand-item/WiredConditionActorHasHandItem.tsx @@ -24,7 +24,7 @@ export const WiredConditionActorHasHandItemView: FC<{}> = props => return ( <WiredConditionBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }> <div className="fw-bold">{ LocalizeText('wiredfurni.params.handitem') }</div> - <select className="form-select" value={ handItemId } onChange={ (e) => setHandItemId(Number(e.target.value)) }> + <select className="form-select form-select-sm" value={ handItemId } onChange={ (e) => setHandItemId(Number(e.target.value)) }> {allowedHanditemIds && allowedHanditemIds.map(value => { return <option value={ value }>{ LocalizeText('handitem' + value) }</option> From a0098d8048281028622edc2657d470539c678a42 Mon Sep 17 00:00:00 2001 From: MyNameIsBatman <montevechiol@gmail.com> Date: Tue, 29 Jun 2021 17:46:08 -0300 Subject: [PATCH 3/4] Fix cols --- .../move-and-rotate-furni/WiredActionMoveAndRotateFurniView.tsx | 2 +- .../wired/views/actions/move-furni/WiredActionMoveFurniView.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/wired/views/actions/move-and-rotate-furni/WiredActionMoveAndRotateFurniView.tsx b/src/views/wired/views/actions/move-and-rotate-furni/WiredActionMoveAndRotateFurniView.tsx index 24d9cd22..b12707f0 100644 --- a/src/views/wired/views/actions/move-and-rotate-furni/WiredActionMoveAndRotateFurniView.tsx +++ b/src/views/wired/views/actions/move-and-rotate-furni/WiredActionMoveAndRotateFurniView.tsx @@ -48,7 +48,7 @@ export const WiredActionMoveAndRotateFurniView: FC<{}> = props => return ( <WiredActionBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ save }> <div className="fw-bold">{ LocalizeText('wiredfurni.params.startdir') }</div> - <div className="row row-cold-4"> + <div className="row row-cols-4"> { directionOptions.map(option => { return ( diff --git a/src/views/wired/views/actions/move-furni/WiredActionMoveFurniView.tsx b/src/views/wired/views/actions/move-furni/WiredActionMoveFurniView.tsx index 8bd53a9e..1038ba62 100644 --- a/src/views/wired/views/actions/move-furni/WiredActionMoveFurniView.tsx +++ b/src/views/wired/views/actions/move-furni/WiredActionMoveFurniView.tsx @@ -66,7 +66,7 @@ export const WiredActionMoveFurniView: FC<{}> = props => { LocalizeText('wiredfurni.params.movefurni.0') } </label> </div> - <div className="row row-cold-4"> + <div className="row row-cols-4"> { directionOptions.map(option => { return ( From 35c542f7db29416ac80fc04803bca8eb6f1c063c Mon Sep 17 00:00:00 2001 From: MyNameIsBatman <montevechiol@gmail.com> Date: Tue, 29 Jun 2021 21:43:49 -0300 Subject: [PATCH 4/4] Date Condition --- .../wired/common/GetWiredConditionLayout.tsx | 3 + .../WiredConditionDateRangeView.tsx | 62 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/views/wired/views/conditions/date-range/WiredConditionDateRangeView.tsx diff --git a/src/views/wired/common/GetWiredConditionLayout.tsx b/src/views/wired/common/GetWiredConditionLayout.tsx index ac6dc69a..068ec848 100644 --- a/src/views/wired/common/GetWiredConditionLayout.tsx +++ b/src/views/wired/common/GetWiredConditionLayout.tsx @@ -4,6 +4,7 @@ import { WiredConditionActorIsOnFurniView } from '../views/conditions/actor-is-o import { WiredConditionActorIsTeamMemberView } from '../views/conditions/actor-is-team-member/WiredConditionActorIsTeamMemberView'; import { WiredConditionActorIsWearingBadgeView } from '../views/conditions/actor-is-wearing-badge/WiredConditionActorIsWearingBadgeView'; import { WiredConditionActorIsWearingEffectView } from '../views/conditions/actor-is-wearing-effect/WiredConditionActorIsWearingEffectView'; +import { WiredConditionDateRangeView } from '../views/conditions/date-range/WiredConditionDateRangeView'; import { WiredConditionFurniHasAvatarOnView } from '../views/conditions/furni-has-avatar-on/WiredConditionFurniHasAvatarOnView'; import { WiredConditionFurniHasFurniOnView } from '../views/conditions/furni-has-furni-on/WiredConditionFurniHasFurniOnView'; import { WiredConditionFurniHasNotFurniOnView } from '../views/conditions/furni-has-not-furni-on/WiredConditionFurniHasNotFurniOnView'; @@ -35,6 +36,8 @@ export function GetWiredConditionLayout(code: number): JSX.Element case WiredConditionlayout.ACTOR_IS_WEARING_EFFECT: case WiredConditionlayout.NOT_ACTOR_WEARING_EFFECT: return <WiredConditionActorIsWearingEffectView />; + case WiredConditionlayout.DATE_RANGE_ACTIVE: + return <WiredConditionDateRangeView />; case WiredConditionlayout.FURNIS_HAVE_AVATARS: case WiredConditionlayout.FURNI_NOT_HAVE_HABBO: return <WiredConditionFurniHasAvatarOnView />; diff --git a/src/views/wired/views/conditions/date-range/WiredConditionDateRangeView.tsx b/src/views/wired/views/conditions/date-range/WiredConditionDateRangeView.tsx new file mode 100644 index 00000000..a0d3c0dd --- /dev/null +++ b/src/views/wired/views/conditions/date-range/WiredConditionDateRangeView.tsx @@ -0,0 +1,62 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionDateRangeView: FC<{}> = props => +{ + const [ startDate, setStartDate ] = useState(''); + const [ endDate, setEndDate ] = useState(''); + const { trigger = null, setIntParams = null } = useWiredContext(); + + const dateToString = useCallback((date: Date) => + { + return `${date.getFullYear()}/${('0' + (date.getMonth() + 1)).slice(-2)}/${('0' + date.getDate()).slice(-2)} ` + `${('0' + date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}`; + }, []); + + useEffect(() => + { + if(trigger.intData.length >= 2) + { + let startDate = new Date(); + let endDate = new Date(); + + if(trigger.intData[0] > 0) + startDate = new Date((trigger.intData[0] * 1000)); + + if(trigger.intData[1] > 0) + endDate = new Date((trigger.intData[1] * 1000)); + + setStartDate(dateToString(startDate)); + setEndDate(dateToString(endDate)); + } + }, [ trigger ]); + + const save = useCallback(() => + { + let startDateMili = 0; + let endDateMili = 0; + + const startDateInstance = new Date(startDate); + const endDateInstance = new Date(endDate); + + if(startDateInstance && endDateInstance) + { + startDateMili = startDateInstance.getTime() / 1000; + endDateMili = endDateInstance.getTime() / 1000; + } + + setIntParams([startDateMili, endDateMili]); + }, [ startDate, endDate, setIntParams ]); + + return ( + <WiredConditionBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }> + <div className="fw-bold">{ LocalizeText('wiredfurni.params.startdate') }</div> + <input type="text" className="form-control form-control-sm" value={ startDate } onChange={ (e) => setStartDate(e.target.value) } /> + <hr className="my-1 mb-2 bg-dark" /> + <div className="fw-bold">{ LocalizeText('wiredfurni.params.enddate') }</div> + <input type="text" className="form-control form-control-sm" value={ endDate } onChange={ (e) => setEndDate(e.target.value) } /> + </WiredConditionBaseView> + ); +}