Removed unnecessary imports.

This commit is contained in:
Phil 2022-09-13 18:18:57 +01:00
parent 6a900205c0
commit dc5742b28c
2 changed files with 174 additions and 176 deletions

View File

@ -1,134 +1,133 @@
import clsx from 'clsx' import clsx from 'clsx'
import React, { MouseEventHandler, ReactNode, useState } from 'react' import { MouseEventHandler, ReactNode, useState } from 'react'
import toast from 'react-hot-toast' import toast from 'react-hot-toast'
import { copyToClipboard } from 'web/lib/util/copy' import { LinkIcon } from '@heroicons/react/solid'
import { linkTwitchAccountRedirect } from 'web/lib/twitch/link-twitch-account' import { usePrivateUser, useUser } from 'web/hooks/use-user'
import { LinkIcon } from '@heroicons/react/solid' import { updatePrivateUser } from 'web/lib/firebase/users'
import { track } from 'web/lib/service/analytics' import { track } from 'web/lib/service/analytics'
import { Button, ColorType } from './../button' import { linkTwitchAccountRedirect } from 'web/lib/twitch/link-twitch-account'
import { LoadingIndicator } from './../loading-indicator' import { copyToClipboard } from 'web/lib/util/copy'
import { Row } from './../layout/row' import { Button, ColorType } from './../button'
import { usePrivateUser, useUser } from 'web/hooks/use-user' import { Row } from './../layout/row'
import { updatePrivateUser } from 'web/lib/firebase/users' import { LoadingIndicator } from './../loading-indicator'
import { deleteField } from 'firebase/firestore'
function BouncyButton(props: {
function BouncyButton(props: { children: ReactNode
children: ReactNode onClick?: MouseEventHandler<any>
onClick?: MouseEventHandler<any> color?: ColorType
color?: ColorType }) {
}) { const { children, onClick, color } = props
const { children, onClick, color } = props return (
return ( <Button
<Button color={color}
color={color} size="lg"
size="lg" onClick={onClick}
onClick={onClick} className="btn h-[inherit] flex-shrink-[inherit] border-none font-normal normal-case"
className="btn h-[inherit] flex-shrink-[inherit] border-none font-normal normal-case" >
> {children}
{children} </Button>
</Button> )
) }
}
export function TwitchPanel() {
export function TwitchPanel() { const user = useUser()
const user = useUser() const privateUser = usePrivateUser()
const privateUser = usePrivateUser()
const twitchInfo = privateUser?.twitchInfo
const twitchInfo = privateUser?.twitchInfo const twitchName = privateUser?.twitchInfo?.twitchName
const twitchName = privateUser?.twitchInfo?.twitchName const twitchToken = privateUser?.twitchInfo?.controlToken
const twitchToken = privateUser?.twitchInfo?.controlToken const twitchBotConnected = privateUser?.twitchInfo?.botEnabled
const twitchBotConnected = privateUser?.twitchInfo?.botEnabled
const linkIcon = <LinkIcon className="mr-2 h-6 w-6" aria-hidden="true" />
const linkIcon = <LinkIcon className="mr-2 h-6 w-6" aria-hidden="true" />
const copyOverlayLink = async () => {
const copyOverlayLink = async () => { copyToClipboard(`http://localhost:1000/overlay?t=${twitchToken}`)
copyToClipboard(`http://localhost:1000/overlay?t=${twitchToken}`) toast.success('Overlay link copied!', {
toast.success('Overlay link copied!', { icon: linkIcon,
icon: linkIcon, })
}) }
}
const copyDockLink = async () => {
const copyDockLink = async () => { copyToClipboard(`http://localhost:1000/dock?t=${twitchToken}`)
copyToClipboard(`http://localhost:1000/dock?t=${twitchToken}`) toast.success('Dock link copied!', {
toast.success('Dock link copied!', { icon: linkIcon,
icon: linkIcon, })
}) }
}
const updateBotConnected = (connected: boolean) => async () => {
const updateBotConnected = (connected: boolean) => async () => { if (user && twitchInfo) {
if (user && twitchInfo) { twitchInfo.botEnabled = connected
twitchInfo.botEnabled = connected await updatePrivateUser(user.id, { twitchInfo })
await updatePrivateUser(user.id, { twitchInfo }) }
} }
}
const [twitchLoading, setTwitchLoading] = useState(false)
const [twitchLoading, setTwitchLoading] = useState(false)
const createLink = async () => {
const createLink = async () => { if (!user || !privateUser) return
if (!user || !privateUser) return setTwitchLoading(true)
setTwitchLoading(true)
const promise = linkTwitchAccountRedirect(user, privateUser)
const promise = linkTwitchAccountRedirect(user, privateUser) track('link twitch from profile')
track('link twitch from profile') await promise
await promise
setTwitchLoading(false)
setTwitchLoading(false) }
}
return (
return ( <>
<> <div>
<div> <label className="label">Twitch</label>
<label className="label">Twitch</label>
{!twitchName ? (
{!twitchName ? ( <Row>
<Row> <Button
<Button color="indigo"
color="indigo" onClick={createLink}
onClick={createLink} disabled={twitchLoading}
disabled={twitchLoading} >
> Link your Twitch account
Link your Twitch account </Button>
</Button> {twitchLoading && <LoadingIndicator className="ml-4" />}
{twitchLoading && <LoadingIndicator className="ml-4" />} </Row>
</Row> ) : (
) : ( <Row>
<Row> <span className="mr-4 text-gray-500">Linked Twitch account</span>{' '}
<span className="mr-4 text-gray-500">Linked Twitch account</span>{' '} {twitchName}
{twitchName} </Row>
</Row> )}
)} </div>
</div>
{twitchToken && (
{twitchToken && ( <div>
<div> <div className="flex w-full">
<div className="flex w-full"> <div
<div className={clsx(
className={clsx( 'flex grow gap-4',
'flex grow gap-4', twitchToken ? '' : 'tooltip tooltip-top'
twitchToken ? '' : 'tooltip tooltip-top' )}
)} data-tip="You must link your Twitch account first"
data-tip="You must link your Twitch account first" >
> <BouncyButton color="blue" onClick={copyOverlayLink}>
<BouncyButton color="blue" onClick={copyOverlayLink}> Copy overlay link
Copy overlay link </BouncyButton>
</BouncyButton> <BouncyButton color="indigo" onClick={copyDockLink}>
<BouncyButton color="indigo" onClick={copyDockLink}> Copy dock link
Copy dock link </BouncyButton>
</BouncyButton> {twitchBotConnected ? (
{twitchBotConnected ? ( <BouncyButton color="red" onClick={updateBotConnected(false)}>
<BouncyButton color="red" onClick={updateBotConnected(false)}> Remove bot from your channel
Remove bot from your channel </BouncyButton>
</BouncyButton> ) : (
) : ( <BouncyButton color="green" onClick={updateBotConnected(true)}>
<BouncyButton color="green" onClick={updateBotConnected(true)}> Add bot to your channel
Add bot to your channel </BouncyButton>
</BouncyButton> )}
)} </div>
</div> </div>
</div> </div>
</div> )}
)} </>
</> )
) }
}

View File

@ -1,42 +1,41 @@
import { User, PrivateUser } from 'common/user' import { PrivateUser, User } from 'common/user'
import { generateNewApiKey } from '../api/api-key' import { generateNewApiKey } from '../api/api-key'
import { updatePrivateUser } from '../firebase/users'
const TWITCH_BOT_PUBLIC_URL = 'https://king-prawn-app-5btyw.ondigitalocean.app' // TODO: Add this to env config appropriately
const TWITCH_BOT_PUBLIC_URL = 'https://king-prawn-app-5btyw.ondigitalocean.app' // TODO: Add this to env config appropriately
export async function initLinkTwitchAccount(
export async function initLinkTwitchAccount( manifoldUserID: string,
manifoldUserID: string, manifoldUserAPIKey: string
manifoldUserAPIKey: string ): Promise<[string, Promise<{ twitchName: string; controlToken: string }>]> {
): Promise<[string, Promise<{ twitchName: string; controlToken: string }>]> { const response = await fetch(`${TWITCH_BOT_PUBLIC_URL}/api/linkInit`, {
const response = await fetch(`${TWITCH_BOT_PUBLIC_URL}/api/linkInit`, { method: 'POST',
method: 'POST', headers: {
headers: { 'Content-Type': 'application/json',
'Content-Type': 'application/json', },
}, body: JSON.stringify({
body: JSON.stringify({ manifoldID: manifoldUserID,
manifoldID: manifoldUserID, apiKey: manifoldUserAPIKey,
apiKey: manifoldUserAPIKey, redirectURL: window.location.href,
redirectURL: window.location.href, }),
}), })
}) const responseData = await response.json()
const responseData = await response.json() if (!response.ok) {
if (!response.ok) { throw new Error(responseData.message)
throw new Error(responseData.message) }
} const responseFetch = fetch(
const responseFetch = fetch( `${TWITCH_BOT_PUBLIC_URL}/api/linkResult?userID=${manifoldUserID}`
`${TWITCH_BOT_PUBLIC_URL}/api/linkResult?userID=${manifoldUserID}` )
) return [responseData.twitchAuthURL, responseFetch.then((r) => r.json())]
return [responseData.twitchAuthURL, responseFetch.then((r) => r.json())] }
}
export async function linkTwitchAccountRedirect(
export async function linkTwitchAccountRedirect( user: User,
user: User, privateUser: PrivateUser
privateUser: PrivateUser ) {
) { const apiKey = privateUser.apiKey ?? (await generateNewApiKey(user.id))
const apiKey = privateUser.apiKey ?? (await generateNewApiKey(user.id)) if (!apiKey) throw new Error("Couldn't retrieve or create Manifold api key")
if (!apiKey) throw new Error("Couldn't retrieve or create Manifold api key")
const [twitchAuthURL] = await initLinkTwitchAccount(user.id, apiKey)
const [twitchAuthURL] = await initLinkTwitchAccount(user.id, apiKey)
window.location.href = twitchAuthURL
window.location.href = twitchAuthURL }
}