Skip to content

Commit

Permalink
Added full screen to browser mode and store URL in query parameter.
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahSaso committed Oct 12, 2023
1 parent be3cf4f commit a138ba2
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 24 deletions.
1 change: 1 addition & 0 deletions packages/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
"stopConnecting": "Stop connecting",
"stopFollowing": "Stop following",
"submit": "Submit",
"toggleFullScreen": "Toggle full screen",
"toggleTheme": "Toggle theme",
"topUp": "Top up",
"transfer": "Transfer",
Expand Down
10 changes: 8 additions & 2 deletions packages/stateful/components/dao/tabs/BrowserTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const BrowserTab = () => {
} = useDaoInfoContext()

const [msgs, setMsgs] = useState<CosmosMsgFor_Empty[]>()
const [fullScreen, setFullScreen] = useState(false)

const decodeDirect = (signDocBodyBytes: Uint8Array) => {
const encodedMessages = TxBody.decode(signDocBodyBytes).messages
Expand Down Expand Up @@ -165,7 +166,12 @@ export const BrowserTab = () => {

return (
<>
<StatelessBrowserTab iframeRef={iframeRef} />
<StatelessBrowserTab
fullScreen={fullScreen}
iframeRef={iframeRef}
setFullScreen={setFullScreen}
/>

{msgs && (
<ActionMatcherAndProposer
key={JSON.stringify(msgs)}
Expand Down Expand Up @@ -394,7 +400,7 @@ const ActionMatcherAndProposer = ({
<Modal
containerClassName="sm:!max-w-[90vw] !w-full"
header={{
title: 'Propose',
title: t('title.propose'),
}}
onClose={() => setMsgs(undefined)}
visible
Expand Down
126 changes: 105 additions & 21 deletions packages/stateless/components/dao/tabs/BrowserTab.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,108 @@
import { RefCallback, useState } from 'react'
import { CloseFullscreen, OpenInFull } from '@mui/icons-material'
import clsx from 'clsx'
import { useRouter } from 'next/router'
import {
Dispatch,
RefCallback,
SetStateAction,
useEffect,
useState,
} from 'react'
import { createPortal } from 'react-dom'
import { useTranslation } from 'react-i18next'

import { Button } from '../../buttons'
import { IconButton } from '../../icon_buttons'
import { TextInput } from '../../inputs'
import { Tooltip } from '../../tooltip'

export type BrowserTabProps = {
iframeRef: RefCallback<HTMLIFrameElement | null>
fullScreen: boolean
setFullScreen: Dispatch<SetStateAction<boolean>>
}

export const BrowserTab = ({ iframeRef }: BrowserTabProps) => {
type InnerBrowserTabProps = BrowserTabProps & {
url: string
setUrl: Dispatch<SetStateAction<string>>
className?: string
}

const InnerBrowserTab = ({
iframeRef,
fullScreen,
setFullScreen,
url,
setUrl,
className,
}: InnerBrowserTabProps) => {
const router = useRouter()
const { t } = useTranslation()
const [iframe, setIframe] = useState<HTMLIFrameElement | null>(null)

const [url, setUrl] = useState('')

const go = () => {
// Store URL in query parameter.
router.query.url = url
router.push(router, undefined, { shallow: true })

if (iframe) {
iframe.src = url
}
}

// On first iframe mount, go to url if valid already.
useEffect(() => {
try {
if (iframe && url && new URL(url).href) {
iframe.src = url
}
} catch {
// Ignore.
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [iframe])

return (
<div className="flex flex-col gap-2">
<div className="flex flex-row justify-between gap-2">
<TextInput
autoComplete="off"
onChange={(event) => setUrl(event.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
go()
}
}}
placeholder={t('form.url')}
value={url}
/>
<div className={clsx('flex flex-col gap-4', className)}>
<div
className={clsx(
'flex shrink-0 flex-row items-stretch gap-2',
fullScreen && 'px-safe-offset-4'
)}
>
<div className="flex grow flex-row items-stretch gap-1">
<TextInput
autoComplete="off"
className="grow"
onChange={(event) => setUrl(event.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
go()
}
}}
placeholder={t('form.url')}
value={url}
/>

<Button onClick={go} size="lg" variant="primary">
{t('button.go')}
</Button>
<Button className="shrink-0" onClick={go} size="lg" variant="primary">
{t('button.go')}
</Button>
</div>

<Tooltip title={t('button.toggleFullScreen')}>
<IconButton
Icon={fullScreen ? CloseFullscreen : OpenInFull}
className="!h-auto shrink-0"
onClick={() => setFullScreen((f) => !f)}
size="sm"
variant="ghost"
/>
</Tooltip>
</div>

<iframe
allow="clipboard-write"
className="h-[75vh] rounded-md"
className="min-h-[75vh] grow rounded-md"
ref={(ref) => {
setIframe(ref)
iframeRef(ref)
Expand All @@ -51,3 +111,27 @@ export const BrowserTab = ({ iframeRef }: BrowserTabProps) => {
</div>
)
}

export const BrowserTab = (props: BrowserTabProps) => {
const router = useRouter()
// Load URL from query parameter.
const [url, setUrl] = useState(
(typeof router.query.url === 'string' && router.query.url) || ''
)

return props.fullScreen ? (
createPortal(
<div className="fixed top-0 left-0 z-[39] h-screen w-screen bg-background-base p-safe pt-safe-or-4">
<InnerBrowserTab
className="h-full w-full"
setUrl={setUrl}
url={url}
{...props}
/>
</div>,
document.body
)
) : (
<InnerBrowserTab setUrl={setUrl} url={url} {...props} />
)
}
2 changes: 1 addition & 1 deletion packages/stateless/components/modals/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const Modal = ({
? createPortal(
<div
className={clsx(
'fixed top-0 left-0 z-40 flex h-full w-screen items-center justify-center p-4 backdrop-brightness-50 backdrop-filter transition-all duration-[120ms] p-safe',
'fixed top-0 left-0 z-40 flex h-screen w-screen items-center justify-center backdrop-brightness-50 backdrop-filter transition-all duration-[120ms] p-safe-or-4',
visible ? 'opacity-100' : 'pointer-events-none opacity-0',
onClose && 'cursor-pointer',
backdropClassName
Expand Down

0 comments on commit a138ba2

Please sign in to comment.