diff --git a/src/App.svelte b/src/App.svelte index 161c13b..39d1308 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -33,6 +33,14 @@ let chatMessage = ''; let chatBusy = false; let chatError = ''; + let showModeration = false; + let moderationAction: 'ban' | 'timeout' | 'unban' | 'delete_message' = 'timeout'; + let moderationUserId = ''; + let moderationMessageId = ''; + let moderationDuration = 600; + let moderationReason = ''; + let moderationBusy = false; + let moderationError = ''; let oauthLink = ''; let oauthIdentity: 'streamer' | 'bot' = 'streamer'; let oauthBusy = false; @@ -254,6 +262,26 @@ } } + async function applyModeration() { + moderationBusy = true; + moderationError = ''; + try { + const response = await fetch(`${serverAddress}/api/v1/twitch/moderation/action`, { + method: 'POST', + headers: { 'content-type': 'application/json', authorization: `Bearer ${sessionToken}` }, + body: JSON.stringify({ action: moderationAction, user_id: moderationUserId, duration_seconds: moderationDuration, reason: moderationReason, message_id: moderationMessageId }), + }); + if (!response.ok) throw new Error('The moderation action could not be applied.'); + moderationUserId = ''; + moderationMessageId = ''; + moderationReason = ''; + } catch (error) { + moderationError = error instanceof Error ? error.message : 'Moderation action failed.'; + } finally { + moderationBusy = false; + } + } + async function createOAuthLink(identity: 'streamer' | 'bot') { oauthBusy = true; oauthError = ''; @@ -363,7 +391,7 @@ STREAM PREVIEW⋮{#if playerSrc}{:else}STREAM OFFLINECONNECT TWITCH TO BEGIN{/if} ACTIVITY FEED⋮ALL ACTIVITYMODERATION{#if activityEvents.length}{#each activityEvents as event}{event.event_type}{new Date(event.occurred_at).toLocaleTimeString()}{/each}{:else}◌Nothing here yetFollows, subscriptions, raids, and server events will appear here.{/if} MY CHAT⋮⌁Chat is waitingConnect a streamer or bot account to begin. (chatIdentity = 'streamer')}>STREAMER (chatIdentity = 'bot')}>BOT event.key === 'Enter' && sendChatMessage()} />SEND{#if chatError}{chatError}{/if} - QUICK ACTIONS⋮ (showStreamEditor = !showStreamEditor)}>EDIT STREAM INFOMODERATIONBOT COMMANDSOVERLAYS{#if showStreamEditor}TITLECATEGORY searchCategories(event.currentTarget.value)} autocomplete="off" placeholder="Search Twitch categories" />{#if categoryOptions.length}{#each categoryOptions as category} { streamGameId = category.id; categorySearch = category.name; categoryOptions = []; }}>{category.name}{category.id}{/each}{/if}LANGUAGETAGSCLASSIFICATION LABELSSAVE STREAM INFO{#if streamError}{streamError}{/if}{/if} + QUICK ACTIONS⋮ (showStreamEditor = !showStreamEditor)}>EDIT STREAM INFO (showModeration = !showModeration)}>MODERATIONBOT COMMANDSOVERLAYS{#if showStreamEditor}TITLECATEGORY searchCategories(event.currentTarget.value)} autocomplete="off" placeholder="Search Twitch categories" />{#if categoryOptions.length}{#each categoryOptions as category} { streamGameId = category.id; categorySearch = category.name; categoryOptions = []; }}>{category.name}{category.id}{/each}{/if}LANGUAGETAGSCLASSIFICATION LABELSSAVE STREAM INFO{#if streamError}{streamError}{/if}{/if}{#if showModeration}ACTIONTIMEOUTBANUNBANDELETE MESSAGEUSER IDMESSAGE ID (DELETE)TIMEOUT SECONDSREASONAPPLY MODERATION{#if moderationError}{moderationError}{/if}{/if} {/if}