import { createContext, useCallback, useContext, useEffect, useState } from 'react' import AnonIcon from '../svgs/spy-fill.svg' import { useRouter } from 'next/router' import cookie from 'cookie' import { useMe, useMeRefresh } from './me' import Image from 'react-bootstrap/Image' import Link from 'next/link' import { SSR } from '../lib/constants' import { USER } from '../fragments/users' import { useQuery } from '@apollo/client' const AccountContext = createContext() const b64Decode = str => Buffer.from(str, 'base64').toString('utf-8') export const AccountProvider = ({ children }) => { const me = useMe() const [accounts, setAccounts] = useState([]) const [isAnon, setIsAnon] = useState(true) useEffect(() => { try { const { multi_auth: multiAuthCookie } = cookie.parse(document.cookie) const accounts = multiAuthCookie ? JSON.parse(b64Decode(multiAuthCookie)) : me ? [{ id: me.id, name: me.name, photoId: me.photoId }] : [] setAccounts(accounts) } catch (err) { console.error('error parsing cookies:', err) } }, []) const addAccount = useCallback(user => { setAccounts(accounts => [...accounts, user]) }, [setAccounts]) const removeAccount = useCallback(userId => { setAccounts(accounts => accounts.filter(({ id }) => id !== userId)) }, [setAccounts]) useEffect(() => { // document not defined on server if (SSR) return const { 'multi_auth.user-id': multiAuthUserIdCookie } = cookie.parse(document.cookie) if (!multiAuthUserIdCookie) return false setIsAnon(multiAuthUserIdCookie === 'anonymous') }, []) return {children} } export const useAccounts = () => useContext(AccountContext) const AnonAccount = ({ selected, onClick }) => { const { isAnon, setIsAnon } = useAccounts() const refreshMe = useMeRefresh() return (
{ document.cookie = 'multi_auth.user-id=anonymous' // order is important to prevent flashes of no session setIsAnon(true) await refreshMe() }} />
anonymous
{isAnon &&
selected
}
) } const Account = ({ account, className }) => { const me = useMe() const [name, setName] = useState(account.name) const [src, setSrc] = useState(account.photoId || '/dorian400.jpg') const refreshMe = useMeRefresh() const { setIsAnon } = useAccounts() useQuery(USER, { variables: { id: account.id }, onCompleted ({ user: { name, photoId } }) { if (photoId) { const src = `https://${process.env.NEXT_PUBLIC_MEDIA_DOMAIN}/${photoId}` setSrc(src) } setName(name) } } ) return (
{ document.cookie = `multi_auth.user-id=${account.id}` await refreshMe() // order is important to prevent flashes of inconsistent data in switch account dialog setIsAnon(false) }} /> @{name} {Number(me?.id) === Number(account.id) &&
selected
}
) } const AddAccount = () => { const router = useRouter() return (
{ router.push({ pathname: '/login', query: { callbackUrl: window.location.origin + router.asPath, multiAuth: true } }) }} />
+ add account
) } export default function SwitchAccountDialog () { const { accounts } = useAccounts() return ( <>

Switch Account

{ accounts.map((account) => ) }
) }