import React from 'react'; import { Transition } from '@headlessui/react' export default class SiteSwitcher extends React.Component { constructor() { super() this.handleClick = this.handleClick.bind(this) this.handleKeydown = this.handleKeydown.bind(this); this.populateSites = this.populateSites.bind(this); this.state = { open: false, sites: null, error: null, loading: true } } componentDidMount() { this.populateSites(); document.addEventListener("keydown", this.handleKeydown); document.addEventListener('mousedown', this.handleClick, false); } componentWillUnmount() { document.removeEventListener("keydown", this.handleKeydown); document.removeEventListener('mousedown', this.handleClick, false); } populateSites() { if (!this.props.loggedIn) return; fetch('/api/sites') .then( response => { if (!response.ok) { throw response } return response.json() }) .then((sites) => this.setState({loading: false, sites: sites})) .catch((e) => this.setState({loading: false, error: e})) } handleClick(e) { if (this.dropDownNode && this.dropDownNode.contains(e.target)) return; if (!this.state.open) return; this.setState({open: false}) } handleKeydown(e) { const { query, history, site } = this.props; const { sites } = this.state; if (e.target.tagName === 'INPUT') return true; if (e.ctrlKey || e.metaKey || e.altKey || e.isComposing || e.keyCode === 229 || !sites) return; const siteNum = parseInt(e.key) if (1 <= siteNum && siteNum <= 9 && siteNum <= sites.length && sites[siteNum-1] !== site.domain) { window.location = `/${encodeURIComponent(sites[siteNum-1])}` } } toggle() { if (!this.props.loggedIn) return; this.setState({open: !this.state.open}) if (!this.state.sites) { this.populateSites(); } } renderSiteLink(domain, index) { const extraClass = domain === this.props.site.domain ? 'font-medium text-gray-900 dark:text-gray-100 cursor-default font-bold' : 'hover:bg-gray-100 dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-gray-100 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-900 dark:focus:text-gray-100' return ( {e.target.onerror = null; e.target.src="https://icons.duckduckgo.com/ip3/placeholder.ico"}} className="inline w-4 mr-2 align-middle" /> {domain} {index < 9 && {index+1}} ) } renderSettingsLink() { if (['owner', 'admin'].includes(this.props.currentUserRole)) { return (
Site settings
) } } renderDropdown() { if (this.state.loading) { return
} else if (this.state.error) { return
Something went wrong, try again
} else { return ( { this.renderSettingsLink() }
{ this.state.sites.map(this.renderSiteLink.bind(this)) }
Add Site
) } } renderArrow() { if (this.props.loggedIn) { return ( ) } } render() { const hoverClass = this.props.loggedIn ? 'hover:text-gray-500 dark:hover:text-gray-200 focus:border-blue-300 focus:ring ' : 'cursor-default' return (
this.dropDownNode = node} >
{ this.renderDropdown() }
) } }