174 lines
6.8 KiB
TypeScript
174 lines
6.8 KiB
TypeScript
"use client";
|
|
|
|
import axios from "axios";
|
|
import * as React from 'react';
|
|
import { useEffect, useState } from "react";
|
|
import { useSession } from "next-auth/react";
|
|
import RedeemptionAction from "@/components/elements/redeemable-action";
|
|
import OBSRedemption from "@/components/elements/redemption";
|
|
import { ActionType } from "@prisma/client";
|
|
import InfoNotice from "@/components/elements/info-notice";
|
|
|
|
const obsTransformations = [
|
|
{ label: "scene_name", description: "", placeholder: "Name of the OBS scene" },
|
|
{ label: "scene_item_name", description: "", placeholder: "Name of the OBS scene item / source" },
|
|
{ label: "rotation", description: "", placeholder: "An expression using x as the previous value" },
|
|
{ label: "position_x", description: "", placeholder: "An expression using x as the previous value" },
|
|
{ label: "position_y", description: "", placeholder: "An expression using x as the previous value" },
|
|
]
|
|
|
|
const customTwitchRedemptions = [
|
|
{
|
|
id: 'adbreak',
|
|
title: 'Adbreak (TTS redemption)'
|
|
},
|
|
{
|
|
id: 'follow',
|
|
title: 'New Follower (TTS redemption)'
|
|
},
|
|
{
|
|
id: 'subscription',
|
|
title: 'Subscription (TTS redemption)'
|
|
},
|
|
{
|
|
id: 'subscription.gift',
|
|
title: 'Subscription Gifted (TTS redemption)'
|
|
},
|
|
]
|
|
|
|
const RedemptionsPage = () => {
|
|
const { data: session, status } = useSession();
|
|
const [actions, setActions] = useState<{ name: string, type: string, data: any }[]>([])
|
|
const [twitchRedemptions, setTwitchRedemptions] = useState<{ id: string, title: string }[]>([])
|
|
const [connections, setConnections] = useState<{ name: string, clientId: string, type: string, scope: string, expiresAt: Date }[]>([])
|
|
const [redemptions, setRedemptions] = useState<{ id: string, redemptionId: string, actionName: string, order: number }[]>([])
|
|
|
|
function addAction(name: string, type: ActionType, data: { [key: string]: string }) {
|
|
setActions([...actions, { name, type, data }])
|
|
}
|
|
|
|
function removeAction(action: { name: string, type: string, data: any }) {
|
|
setActions(actions.filter(a => a.name != action.name))
|
|
}
|
|
|
|
function addRedemption(id: string, actionName: string, redemptionId: string, order: number) {
|
|
setRedemptions([...redemptions, { id, redemptionId, actionName, order }])
|
|
}
|
|
|
|
function removeRedemption(redemption: { id: string, redemptionId: string, actionName: string, order: number }) {
|
|
setRedemptions(redemptions.filter(r => r.id != redemption.id))
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (status !== "authenticated")
|
|
return
|
|
|
|
axios.get('/api/connection')
|
|
.then(d => {
|
|
setConnections(d.data.data)
|
|
})
|
|
|
|
axios.get("/api/settings/redemptions/actions")
|
|
.then(d => {
|
|
setActions(d.data)
|
|
})
|
|
|
|
axios.get("/api/account/redemptions")
|
|
.then(d => {
|
|
let res : { id: string, title: string }[] = d.data?.data ?? []
|
|
res = [ ...res, ...customTwitchRedemptions ]
|
|
setTwitchRedemptions(res.sort((a, b) => {
|
|
if (a.title < b.title)
|
|
return -1
|
|
else if (a.title > b.title)
|
|
return 1
|
|
return 0
|
|
}))
|
|
|
|
axios.get("/api/settings/redemptions")
|
|
.then(d => {
|
|
setRedemptions(d.data)
|
|
})
|
|
})
|
|
}, [session])
|
|
|
|
return (
|
|
<div>
|
|
<div className="text-2xl text-center pt-[50px]">Redemption Actions</div>
|
|
<InfoNotice
|
|
message="Redemption actions are activated when specific Twitch channel point redeems have been activated. Aforementioned redeem need to be linked in the redemption part, together with the action, for the action to activate."
|
|
hidden={false} />
|
|
{actions.map(action =>
|
|
<div
|
|
className="px-10 py-3 w-full h-full flex-grow inset-y-1/2"
|
|
key={action.name}>
|
|
<RedeemptionAction
|
|
name={action.name}
|
|
type={action.type}
|
|
data={action.data}
|
|
edit={false}
|
|
showEdit={true}
|
|
isNew={false}
|
|
obsTransformations={obsTransformations}
|
|
connections={connections}
|
|
adder={addAction}
|
|
remover={removeAction} />
|
|
</div>
|
|
)}
|
|
<div
|
|
className="px-10 py-3 w-full h-full flex-grow inset-y-1/2">
|
|
<RedeemptionAction
|
|
name=""
|
|
type={undefined}
|
|
data={{}}
|
|
edit={true}
|
|
showEdit={false}
|
|
isNew={true}
|
|
obsTransformations={obsTransformations}
|
|
connections={connections}
|
|
adder={addAction}
|
|
remover={removeAction} />
|
|
</div>
|
|
|
|
<div className="text-2xl text-center pt-[50px]">Redemptions</div>
|
|
<InfoNotice
|
|
message="Redemptions are just a way to link specific actions to actual Twitch channel point redeems."
|
|
hidden={false} />
|
|
{redemptions.map(redemption =>
|
|
<div
|
|
className="px-10 py-3 w-full h-full flex-grow inset-y-1/2"
|
|
key={redemption.id}>
|
|
<OBSRedemption
|
|
id={redemption.id}
|
|
redemptionId={redemption.redemptionId}
|
|
actionName={redemption.actionName}
|
|
numbering={redemption.order}
|
|
edit={false}
|
|
showEdit={true}
|
|
isNew={false}
|
|
actions={actions.map(a => a.name)}
|
|
twitchRedemptions={twitchRedemptions}
|
|
adder={addRedemption}
|
|
remover={removeRedemption} />
|
|
</div>
|
|
)}
|
|
<div
|
|
className="px-10 py-3 w-full h-full flex-grow inset-y-1/2">
|
|
<OBSRedemption
|
|
id={undefined}
|
|
redemptionId={undefined}
|
|
actionName=""
|
|
numbering={0}
|
|
edit={true}
|
|
showEdit={false}
|
|
isNew={true}
|
|
actions={actions.map(a => a.name)}
|
|
twitchRedemptions={twitchRedemptions}
|
|
adder={addRedemption}
|
|
remover={removeRedemption} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default RedemptionsPage; |