Skip to content

Commit

Permalink
feat: support video in announcement (#2332)
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyenhoaidanh authored Oct 30, 2023
1 parent f92279d commit 34e737d
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 45 deletions.
143 changes: 106 additions & 37 deletions src/components/Announcement/Popups/CenterPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { t } from '@lingui/macro'
import { X } from 'react-feather'
import { useMedia } from 'react-use'
import styled from 'styled-components'
import styled, { css } from 'styled-components'

import CtaButton from 'components/Announcement/Popups/CtaButton'
import {
Expand All @@ -10,13 +10,14 @@ import {
PopupItemType,
PopupType,
} from 'components/Announcement/type'
import Column from 'components/Column'
import Modal from 'components/Modal'
import Row, { RowBetween } from 'components/Row'
import { Z_INDEXS } from 'constants/styles'
import useMixpanel, { MIXPANEL_TYPE } from 'hooks/useMixpanel'
import useTheme from 'hooks/useTheme'
import { MEDIA_WIDTHS } from 'theme'
import { useNavigateToUrl } from 'utils/redirect'
import { useNavigateToUrl, validateRedirectURL } from 'utils/redirect'
import { escapeScriptHtml } from 'utils/string'

const Wrapper = styled.div`
Expand All @@ -31,13 +32,23 @@ const Wrapper = styled.div`
padding: 20px;
`}
`
const ContentWrapper = styled.div`
const ContentWrapper = styled.div<{ isVertical: boolean }>`
display: flex;
flex-direction: column;
overflow-y: auto;
overflow-x: hidden;
gap: 24px;
flex: 1;
max-width: 100%;
${({ isVertical }) =>
isVertical
? css`
flex-direction: column;
overflow-y: auto;
`
: css`
flex-direction: row;
gap: 24px;
overflow-y: hidden;
`}
${({ theme }) => theme.mediaWidth.upToMedium`
gap: 20px;
`}
Expand Down Expand Up @@ -73,9 +84,9 @@ const Image = styled.img`

const StyledCtaButton = styled(CtaButton)`
width: fit-content;
min-width: 220px;
height: 36px;
min-width: min(220px, 100%);
max-width: 100%;
height: 36px;
${({ theme }) => theme.mediaWidth.upToSmall`
width: fit-content;
min-width: 100px;
Expand All @@ -87,8 +98,48 @@ const Desc = styled.div`
word-break: break-word;
font-size: 14px;
line-height: 20px;
&::-webkit-scrollbar {
display: block;
width: 4px;
}
&::-webkit-scrollbar-thumb {
background: ${({ theme }) => theme.border};
}
`

const VIDEO_SIZE = `360px`
const VideoWrapper = styled.div`
width: 640px;
height: ${VIDEO_SIZE};
${({ theme }) => theme.mediaWidth.upToSmall`
max-width: 100%;
`}
`

const whitelistDomains = ['drive.google.com', 'www.youtube.com']
const Video = ({ url, title }: { url: string; title: string }) => {
try {
const { host } = new URL(url)
if (!whitelistDomains.includes(host) || !validateRedirectURL(url, { _dangerousSkipCheckWhitelist: true }))
return null
} catch (error) {
return null
}
return (
<VideoWrapper>
<iframe
width="100%"
height="100%"
src={url}
frameBorder="0"
title={title}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
/>
</VideoWrapper>
)
}

export default function CenterPopup({
onDismiss,
data,
Expand All @@ -106,6 +157,7 @@ export default function CenterPopup({
content,
ctas = [],
thumbnailImageURL,
thumbnailVideoURL,
} = templateBody as AnnouncementTemplatePopup

const navigate = useNavigateToUrl()
Expand All @@ -120,8 +172,41 @@ export default function CenterPopup({
})
}

const isVertical = !!thumbnailVideoURL && !isMobile

const renderContent = () => (
<>
<Desc
dangerouslySetInnerHTML={{ __html: escapeScriptHtml(content) }}
style={{ overflowY: isVertical ? 'auto' : undefined }}
/>
<ButtonWrapper justify="center">
{ctas.length > 0 ? (
ctas.map(item => (
<StyledCtaButton
key={item.url}
data={item}
color="primary"
onClick={() => {
onClickCta(item.url)
}}
/>
))
) : (
<StyledCtaButton data={{ name: t`Close`, url: '' }} color="primary" onClick={() => onClickCta()} />
)}
</ButtonWrapper>
</>
)

return (
<Modal isOpen={true} maxWidth={isMobile ? undefined : '800px'} onDismiss={onDismiss} zindex={Z_INDEXS.MODAL}>
<Modal
isOpen={true}
maxWidth={isMobile ? undefined : isVertical ? '100vw' : '800px'}
width={isVertical ? '1024px' : undefined}
onDismiss={onDismiss}
zindex={Z_INDEXS.MODAL}
>
<Wrapper>
<RowBetween align="center">
<Title>{name}</Title>
Expand All @@ -135,35 +220,19 @@ export default function CenterPopup({
style={{ minWidth: '24px' }}
/>
</RowBetween>
<ContentWrapper>
{thumbnailImageURL && <Image src={thumbnailImageURL} />}
<Desc
dangerouslySetInnerHTML={{
__html: escapeScriptHtml(content),
}}
/>
<ButtonWrapper justify="center">
{ctas.length > 0 ? (
ctas.map(item => (
<StyledCtaButton
key={item.url}
data={item}
color="primary"
onClick={() => {
onClickCta(item.url)
}}
/>
))
) : (
<StyledCtaButton
data={{ name: t`Close`, url: '' }}
color="primary"
onClick={() => {
onClickCta()
}}
/>
)}
</ButtonWrapper>
<ContentWrapper isVertical={!isVertical}>
{thumbnailVideoURL ? (
<Video url={thumbnailVideoURL} title={name} />
) : (
thumbnailImageURL && <Image src={thumbnailImageURL} />
)}
{isVertical ? (
<Column width={'320px'} height={VIDEO_SIZE} gap="14px" justifyContent={'space-between'}>
{renderContent()}
</Column>
) : (
renderContent()
)}
</ContentWrapper>
</Wrapper>
</Modal>
Expand Down
5 changes: 4 additions & 1 deletion src/components/Announcement/helper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChainId } from '@kyberswap/ks-sdk-core'

import { AnnouncementTemplatePopup, PopupContentAnnouncement, PopupItemType } from 'components/Announcement/type'
import { TIMES_IN_SECS } from 'constants/index'
import { APP_PATHS, TIMES_IN_SECS } from 'constants/index'

const LsKey = 'ack-announcements'
export const getAnnouncementsAckMap = () => JSON.parse(localStorage[LsKey] || '{}')
Expand All @@ -28,6 +28,9 @@ export const isPopupCanShow = (
chainId: ChainId,
account: string | undefined,
) => {
if ([APP_PATHS.IAM_CONSENT, APP_PATHS.IAM_LOGIN, APP_PATHS.IAM_LOGOUT].includes(window.location.pathname))
return false

const { templateBody = {}, metaMessageId } = popupInfo.content
const { endAt, startAt, chainIds = [] } = templateBody as AnnouncementTemplatePopup
const isRightChain = chainIds.includes(chainId + '')
Expand Down
1 change: 1 addition & 0 deletions src/components/Announcement/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export type AnnouncementTemplatePopup = {
name: string
content: string
thumbnailImageURL: string
thumbnailVideoURL?: string
type: 'NORMAL' | 'CRITICAL'
startAt: number
endAt: number
Expand Down
14 changes: 7 additions & 7 deletions src/constants/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ export const FIREBASE: { [key in EnvKeys]: { DEFAULT: FirebaseConfig; LIMIT_ORDE
appId: '1:522790089501:web:524403003ae65c09c727f4',
},
DEFAULT: {
apiKey: 'AIzaSyD1UhS2D-a5D6e20SuKgx87FGitbQUL_V8',
authDomain: 'notification-local-73771.firebaseapp.com',
projectId: 'notification-local-73771',
storageBucket: 'notification-local-73771.appspot.com',
messagingSenderId: '227120017035',
appId: '1:227120017035:web:36592ab3e81b5614b7ae8e',
measurementId: 'G-Q3EPQSWMM5',
apiKey: 'AIzaSyDszHtJ4CJq0mwjBJ1pTt5OOzG5tiooEsg',
authDomain: 'test-bace2.firebaseapp.com',
databaseURL: 'https://test-bace2-default-rtdb.asia-southeast1.firebasedatabase.app',
projectId: 'test-bace2',
storageBucket: 'test-bace2.appspot.com',
messagingSenderId: '337703820408',
appId: '1:337703820408:web:2fb16ef71941817dec618d',
},
},
staging: {
Expand Down

0 comments on commit 34e737d

Please sign in to comment.