working linking logic

This commit is contained in:
mantikoros 2022-08-29 00:51:25 -05:00
parent 6b05561517
commit bfef873b53
5 changed files with 88 additions and 16 deletions

View File

@ -62,6 +62,10 @@ export type PrivateUser = {
initialIpAddress?: string
apiKey?: string
notificationPreferences?: notification_subscribe_types
twitchInfo?: {
twitchName: string
controlToken: string
}
}
export type notification_subscribe_types = 'all' | 'less' | 'none'

View File

@ -70,7 +70,7 @@ service cloud.firestore {
allow read: if userId == request.auth.uid || isAdmin();
allow update: if (userId == request.auth.uid || isAdmin())
&& request.resource.data.diff(resource.data).affectedKeys()
.hasOnly(['apiKey', 'unsubscribedFromResolutionEmails', 'unsubscribedFromCommentEmails', 'unsubscribedFromAnswerEmails', 'notificationPreferences', 'unsubscribedFromWeeklyTrendingEmails' ]);
.hasOnly(['apiKey', 'twitchInfo', 'unsubscribedFromResolutionEmails', 'unsubscribedFromCommentEmails', 'unsubscribedFromAnswerEmails', 'notificationPreferences', 'unsubscribedFromWeeklyTrendingEmails' ]);
}
match /private-users/{userId}/views/{viewId} {

View File

@ -13,7 +13,6 @@ import { createUser } from 'web/lib/firebase/api'
import { randomString } from 'common/util/random'
import { identifyUser, setUserProperty } from 'web/lib/service/analytics'
import { useStateCheckEquality } from 'web/hooks/use-state-check-equality'
import { handleRedirectAfterSignup } from 'web/hooks/use-redirect-after-signup'
// Either we haven't looked up the logged in user yet (undefined), or we know
// the user is not logged in (null), or we know the user is logged in.
@ -64,13 +63,11 @@ export function AuthProvider(props: {
// Note: Cap on localStorage size is ~5mb
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(current))
setCachedReferralInfoForUser(current.user)
handleRedirectAfterSignup(current.user)
} else {
// User logged out; reset to null
deleteTokenCookies()
setAuthUser(null)
localStorage.removeItem(CACHED_USER_KEY)
handleRedirectAfterSignup(null)
}
})
}, [setAuthUser])

View File

@ -1,3 +1,7 @@
import { User, PrivateUser } from 'common/lib/user'
import { generateNewApiKey } from '../api/api-key'
import { updatePrivateUser } from '../firebase/users'
const TWITCH_BOT_PUBLIC_URL = 'https://king-prawn-app-5btyw.ondigitalocean.app'
export async function initLinkTwitchAccount(
@ -23,3 +27,21 @@ export async function initLinkTwitchAccount(
)
return [responseData.twitchAuthURL, responseFetch.then((r) => r.json())]
}
export async function linkTwitchAccount(user: User, privateUser: PrivateUser) {
const apiKey = privateUser.apiKey ?? (await generateNewApiKey(user.id))
if (!apiKey) throw new Error("Couldn't retrieve or create Manifold api key")
const [twitchAuthURL, linkSuccessPromise] = await initLinkTwitchAccount(
user.id,
apiKey
)
console.log('opening twitch link', twitchAuthURL)
window.open(twitchAuthURL)
const twitchInfo = await linkSuccessPromise
await updatePrivateUser(user.id, { twitchInfo })
console.log(`Successfully linked Twitch account '${twitchInfo.twitchName}'`)
}

View File

@ -1,21 +1,53 @@
import { useState } from 'react'
import { Page } from 'web/components/page'
import { Col } from 'web/components/layout/col'
import { ManifoldLogo } from 'web/components/nav/manifold-logo'
import { useSaveReferral } from 'web/hooks/use-save-referral'
import { SEO } from 'web/components/SEO'
import { Spacer } from 'web/components/layout/spacer'
import { firebaseLogin } from 'web/lib/firebase/users'
import { withTracking } from 'web/lib/service/analytics'
import { firebaseLogin, getUserAndPrivateUser } from 'web/lib/firebase/users'
import { track } from 'web/lib/service/analytics'
import { Row } from 'web/components/layout/row'
import { Button } from 'web/components/button'
import { useTracking } from 'web/hooks/use-tracking'
import { useRedirectAfterSignup } from 'web/hooks/use-redirect-after-signup'
import { linkTwitchAccount } from 'web/lib/twitch/link-twitch-account'
import { usePrivateUser, useUser } from 'web/hooks/use-user'
import { LoadingIndicator } from 'web/components/loading-indicator'
export default function TwitchLandingPage() {
useRedirectAfterSignup('twitch')
useSaveReferral()
useTracking('view twitch landing page')
const user = useUser()
const privateUser = usePrivateUser()
const twitchUser = privateUser?.twitchInfo?.twitchName
const callback =
user && privateUser
? () => linkTwitchAccount(user, privateUser)
: async () => {
const result = await firebaseLogin()
const userId = result.user.uid
const { user, privateUser } = await getUserAndPrivateUser(userId)
if (!user || !privateUser) return
await linkTwitchAccount(user, privateUser)
}
const [isLoading, setLoading] = useState(false)
const getStarted = async () => {
setLoading(true)
const promise = callback()
track('twitch page button click')
await promise
setLoading(false)
}
return (
<Page>
<SEO
@ -48,15 +80,32 @@ export default function TwitchLandingPage() {
<br />
</div>
</div>
<Spacer h={6} />
<Button
size="2xl"
color="gradient"
className="self-center"
onClick={withTracking(firebaseLogin, 'twitch page button click')}
>
Get started
</Button>
{twitchUser ? (
<div className="mt-3 self-center rounded-lg bg-gradient-to-r from-pink-300 via-purple-300 to-indigo-400 p-4 ">
<div className="overflow-hidden rounded-lg bg-white px-4 py-5 shadow sm:p-6">
<div className="truncate text-sm font-medium text-gray-500">
Twitch account linked
</div>
<div className="mt-1 text-2xl font-semibold text-gray-900">
{twitchUser}
</div>
</div>
</div>
) : isLoading ? (
<LoadingIndicator spinnerClassName="w-16 h-16" />
) : (
<Button
size="2xl"
color="gradient"
className="self-center"
onClick={getStarted}
>
Get started
</Button>
)}
</Col>
</Col>
</Col>