Skip to content

Commit

Permalink
Merge 36d8e04 into fd8c7fe
Browse files Browse the repository at this point in the history
  • Loading branch information
fzavalia committed Oct 9, 2023
2 parents fd8c7fe + 36d8e04 commit bd8a73e
Show file tree
Hide file tree
Showing 17 changed files with 268 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.title {
font-size: 20px;
font-weight: 700;
text-align: center;
max-width: 400px;
}

.img {
text-align: center;
margin-bottom: 32px;
}

.description {
text-align: center;
display: flex;
flex-direction: column;
gap: 32px;
margin: auto;
font-size: 14px;
}

.description .bold {
font-weight: 700;
}

.actions {
display: flex;
flex-direction: column;
gap: 14px;
margin-top: 32px !important;
}

.actions :global(.ui.button) {
margin-left: 0px !important;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useCallback } from 'react'
import { Button, ModalActions, ModalContent, ModalNavigation } from 'decentraland-ui'
import Modal from 'decentraland-dapps/dist/containers/Modal'
import { t } from 'decentraland-dapps/dist/modules/translation/utils'
import { Props } from './WorldsForENSOwnersAnnouncementModal.types'
import { persistCanOpenWorldsForENSOwnersAnnouncementModal } from './utils'
import ensImg from './images/ens.svg'
import styles from './WorldsForENSOwnersAnnouncementModal.module.css'

export const DOCUMENTATION_URL = 'https://docs.decentraland.org/creator/worlds/about/'

const WorldsForENSOwnersAnnouncementModal: React.FC<Props> = ({ name, onClose }) => {
const handleOnClose = useCallback(() => {
persistCanOpenWorldsForENSOwnersAnnouncementModal(false)
onClose()
}, [onClose])

return (
<Modal name={name} onClose={onClose}>
<ModalNavigation
title={<div className={styles.title}>{t('worlds_for_ens_owners_announcement_modal.title')}</div>}
onClose={handleOnClose}
/>
<ModalContent>
<div className={styles.img}>
<img src={ensImg} alt="ens" />
</div>
<div className={styles.description}>
<div className={styles.bold}>{t('worlds_for_ens_owners_announcement_modal.description_ens')}</div>
<div>
{t('worlds_for_ens_owners_announcement_modal.description_dcl', {
b: (text: string) => <span className={styles.bold}>{text}</span>
})}
</div>
</div>
</ModalContent>
<ModalActions className={styles.actions}>
<Button primary onClick={handleOnClose}>
{t('worlds_for_ens_owners_announcement_modal.start_building')}
</Button>
<Button as="a" href={DOCUMENTATION_URL} target="_blank" rel="noopener noreferrer">
{t('worlds_for_ens_owners_announcement_modal.learn_more')}
</Button>
</ModalActions>
</Modal>
)
}

export default React.memo(WorldsForENSOwnersAnnouncementModal)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ModalProps } from 'decentraland-dapps/dist/providers/ModalProvider/ModalProvider.types'

export type Props = ModalProps
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import WorldsForENSOwnersAnnouncementModal from './WorldsForENSOwnersAnnouncementModal'

export default WorldsForENSOwnersAnnouncementModal
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { getLocalStorage } from 'decentraland-dapps/dist/lib/localStorage'
import { LocalStorage } from 'decentraland-dapps/dist/lib/types'
import {
LOCALSTORAGE_WORLDS_FOR_ENS_OWNERS_ANNOUNCEMENT,
canOpenWorldsForENSOwnersAnnouncementModal,
persistCanOpenWorldsForENSOwnersAnnouncementModal
} from './utils'

jest.mock('decentraland-dapps/dist/lib/localStorage')

const mockGetLocalStorage = getLocalStorage as jest.MockedFunction<typeof getLocalStorage>

let setItem: jest.MockedFunction<LocalStorage['setItem']>
let ls: LocalStorage

beforeEach(() => {
setItem = jest.fn()

ls = {
getItem: () => null,
setItem
} as unknown as LocalStorage

mockGetLocalStorage.mockReturnValueOnce(ls)
})

describe('when getting if the worlds for ens owners announcement modal can be opened', () => {
describe('when the local storage returns something else than "1"', () => {
it('should return true', () => {
expect(canOpenWorldsForENSOwnersAnnouncementModal()).toBeTruthy()
})
})

describe('when the local storage returns "1"', () => {
beforeEach(() => {
ls.getItem = () => '1'
})

it('should return false', () => {
expect(canOpenWorldsForENSOwnersAnnouncementModal()).toBeFalsy()
})
})
})

describe('when persisting if the worlds for ens owners announcement modal can be opened', () => {
describe('when the value is true', () => {
it('should call the set item local storage method with undefined', () => {
persistCanOpenWorldsForENSOwnersAnnouncementModal(true)

expect(setItem).toHaveBeenCalledWith(LOCALSTORAGE_WORLDS_FOR_ENS_OWNERS_ANNOUNCEMENT, undefined)
})
})

describe('when the value is false', () => {
it('should call the set item local storage method with "1"', () => {
persistCanOpenWorldsForENSOwnersAnnouncementModal(false)

expect(setItem).toHaveBeenCalledWith(LOCALSTORAGE_WORLDS_FOR_ENS_OWNERS_ANNOUNCEMENT, '1')
})
})
})
13 changes: 13 additions & 0 deletions src/components/Modals/WorldsForENSOwnersAnnouncementModal/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { getLocalStorage } from 'decentraland-dapps/dist/lib/localStorage'

export const LOCALSTORAGE_WORLDS_FOR_ENS_OWNERS_ANNOUNCEMENT = 'builder-worlds-for-ens-owners-announcement'

export const persistCanOpenWorldsForENSOwnersAnnouncementModal = (canOpen: boolean) => {
const ls = getLocalStorage()
ls.setItem(LOCALSTORAGE_WORLDS_FOR_ENS_OWNERS_ANNOUNCEMENT, canOpen ? undefined : '1')
}

export const canOpenWorldsForENSOwnersAnnouncementModal = () => {
const ls = getLocalStorage()
return ls.getItem(LOCALSTORAGE_WORLDS_FOR_ENS_OWNERS_ANNOUNCEMENT) !== '1'
}
1 change: 1 addition & 0 deletions src/components/Modals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ export { default as SceneCreationModal } from './SceneCreationModal'
export { default as EditVideoModal } from './EditVideoModal'
export { default as EmotesV2AnnouncementModal } from './EmotesV2AnnouncementModal'
export { default as WorldsYourStorageModal } from './WorldsYourStorageModal'
export { default as WorldsForENSOwnersAnnouncementModal } from './WorldsForENSOwnersAnnouncementModal'
4 changes: 3 additions & 1 deletion src/components/ScenesPage/ScenesPage.container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { isLoggingIn } from 'modules/identity/selectors'
import { getProjects, getPage, getSortBy, getTotalPages, didCreate } from 'modules/ui/dashboard/selectors'
import { loadPoolsRequest } from 'modules/pool/actions'
import { getPoolList } from 'modules/pool/selectors'
import { getIsWorldsForEnsOwnersEnabled } from 'modules/features/selectors'
import { MapStateProps, MapDispatchProps, MapDispatch } from './ScenesPage.types'
import ScenesPage from './ScenesPage'

Expand All @@ -20,7 +21,8 @@ const mapState = (state: RootState): MapStateProps => ({
sortBy: getSortBy(state),
totalPages: getTotalPages(state),
didCreate: didCreate(state),
poolList: getPoolList(state)
poolList: getPoolList(state),
isWorldsForENSOwnersEnabled: getIsWorldsForEnsOwnersEnabled(state)
})

const mapDispatch = (dispatch: MapDispatch): MapDispatchProps => ({
Expand Down
21 changes: 20 additions & 1 deletion src/components/ScenesPage/ScenesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,37 @@ import SyncToast from 'components/SyncToast'
import { SortBy } from 'modules/ui/dashboard/types'
import { NavigationTab } from 'components/Navigation/Navigation.types'
import SceneCreationSelector from 'components/SceneCreationSelector'
import { canOpenWorldsForENSOwnersAnnouncementModal } from 'components/Modals/WorldsForENSOwnersAnnouncementModal/utils'
import { locations } from 'routing/locations'
import { PaginationOptions } from 'routing/utils'
import { Props, DefaultProps } from './ScenesPage.types'
import './ScenesPage.css'

const ScenesPage: React.FC<Props> = props => {
const { page, poolList, projects, sortBy, totalPages, isFetching, isLoggingIn, onLoadFromScenePool, onOpenModal, onPageChange } = props
const {
page,
poolList,
projects,
sortBy,
totalPages,
isFetching,
isLoggingIn,
isWorldsForENSOwnersEnabled,
onLoadFromScenePool,
onOpenModal,
onPageChange
} = props

useEffect(() => {
onLoadFromScenePool({ sortBy: 'updated_at', sortOrder: 'desc' })
}, [onLoadFromScenePool, onOpenModal])

useEffect(() => {
if (isWorldsForENSOwnersEnabled && canOpenWorldsForENSOwnersAnnouncementModal()) {
onOpenModal('WorldsForENSOwnersAnnouncementModal')
}
}, [isWorldsForENSOwnersEnabled, onOpenModal])

const handleOpenImportModal = useCallback(() => {
onOpenModal('ImportModal')
}, [onOpenModal])
Expand Down
5 changes: 3 additions & 2 deletions src/components/ScenesPage/ScenesPage.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ export type Props = DefaultProps & {
page: number
sortBy: SortBy
totalPages: number
poolList: Pool[] | null
isWorldsForENSOwnersEnabled: boolean
onOpenModal: typeof openModal
onPageChange: (options: PaginationOptions) => void
onLoadFromScenePool: typeof loadPoolsRequest
poolList: Pool[] | null
}

export type MapStateProps = Pick<
Props,
'projects' | 'isFetching' | 'isLoggingIn' | 'page' | 'sortBy' | 'totalPages' | 'didCreate' | 'poolList'
'projects' | 'isFetching' | 'isLoggingIn' | 'page' | 'sortBy' | 'totalPages' | 'didCreate' | 'poolList' | 'isWorldsForENSOwnersEnabled'
>
export type MapDispatchProps = Pick<Props, 'onOpenModal' | 'onPageChange' | 'onLoadFromScenePool'>
export type MapDispatch = Dispatch<CallHistoryMethodAction | OpenModalAction | LoadPoolsRequestAction>
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ const mapState = (state: RootState): MapStateProps => ({

const mapDispatch = (dispatch: MapDispatch): MapDispatchProps => ({
onNavigate: path => dispatch(push(path)),
onOpenModal: metadata => dispatch(openModal('WorldsYourStorageModal', metadata))
onOpenYourStorageModal: metadata => dispatch(openModal('WorldsYourStorageModal', metadata)),
onOpenWorldsForENSOwnersAnnouncementModal: () => dispatch(openModal('WorldsForENSOwnersAnnouncementModal'))
})

export default connect(mapState, mapDispatch)(WorldListPage)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import CopyToClipboard from 'components/CopyToClipboard/CopyToClipboard'
import Icon from 'components/Icon'
import LoggedInDetailPage from 'components/LoggedInDetailPage'
import { NavigationTab } from 'components/Navigation/Navigation.types'
import { canOpenWorldsForENSOwnersAnnouncementModal } from 'components/Modals/WorldsForENSOwnersAnnouncementModal/utils'
import { Props, SortBy } from './WorldListPage.types'
import NameTabs from './NameTabs'
import WorldsStorage from './WorldsStorage'
Expand All @@ -39,7 +40,18 @@ const ENS_DOMAINS_URL = config.get('ENS_DOMAINS_URL', '')
const PAGE_SIZE = 12

const WorldListPage: React.FC<Props> = props => {
const { ensList, externalNames, error, deploymentsByWorlds, isLoading, projects, worldsWalletStats, onNavigate, onOpenModal } = props
const {
ensList,
externalNames,
error,
deploymentsByWorlds,
isLoading,
projects,
worldsWalletStats,
onNavigate,
onOpenYourStorageModal,
onOpenWorldsForENSOwnersAnnouncementModal
} = props
const [sortBy, setSortBy] = useState(SortBy.ASC)
const [page, setPage] = useState(1)
const { tab } = useCurrentlySelectedTab()
Expand Down Expand Up @@ -332,7 +344,7 @@ const WorldListPage: React.FC<Props> = props => {
currentBytes={Number(worldsWalletStats.usedSpace)}
className="worlds-storage"
onViewDetails={() => {
onOpenModal({ stats: worldsWalletStats })
onOpenYourStorageModal({ stats: worldsWalletStats })
}}
/>
) : null}
Expand All @@ -355,6 +367,12 @@ const WorldListPage: React.FC<Props> = props => {
setPage(1)
}, [tab])

useEffect(() => {
if (canOpenWorldsForENSOwnersAnnouncementModal()) {
onOpenWorldsForENSOwnersAnnouncementModal()
}
}, [onOpenWorldsForENSOwnersAnnouncementModal])

return (
<LoggedInDetailPage
className="WorldListPage view"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export type Props = {
isLoading: boolean
worldsWalletStats?: WorldsWalletStats
onNavigate: (path: string) => void
onOpenModal: (metadata: WorldsYourStorageModalMetadata) => void
onOpenYourStorageModal: (metadata: WorldsYourStorageModalMetadata) => void
onOpenWorldsForENSOwnersAnnouncementModal: () => void
}

export type State = {
Expand All @@ -32,5 +33,5 @@ export type MapStateProps = Pick<
Props,
'ensList' | 'externalNames' | 'deploymentsByWorlds' | 'isLoading' | 'error' | 'projects' | 'isLoggedIn' | 'worldsWalletStats'
>
export type MapDispatchProps = Pick<Props, 'onNavigate' | 'onOpenModal'>
export type MapDispatchProps = Pick<Props, 'onNavigate' | 'onOpenYourStorageModal' | 'onOpenWorldsForENSOwnersAnnouncementModal'>
export type MapDispatch = Dispatch
7 changes: 7 additions & 0 deletions src/modules/translation/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2116,5 +2116,12 @@
"names_buy": "BUY NAME",
"proposal": "These storage rules were voted on and passed in a governance DAO proposal.",
"learn_more": "LEARN MORE"
},
"worlds_for_ens_owners_announcement_modal": {
"title": "Introducing ENS Worlds and Enhanced Storage for Decentraland Worlds",
"description_ens": "ENS domain holders can now create Worlds with 25 MB of dedicated storage.",
"description_dcl": "Decentraland NAME holders get <b>100 MB of storage</b> per <b>NAME, LAND, or 2,000 MANA</b>, now with the flexibility of shared storage for more creative freedom.",
"start_building": "start building",
"learn_more": "learn more about worlds"
}
}
7 changes: 7 additions & 0 deletions src/modules/translation/languages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -2134,5 +2134,12 @@
"names_buy": "COMPRAR NAME",
"proposal": "Estas reglas de almacenamiento fueron votadas y aprobadas en una propuesta de la DAO.",
"learn_more": "APRENDER MÁS"
},
"worlds_for_ens_owners_announcement_modal": {
"title": "Introduciendo Mundos ENS y Almacenamiento Mejorado para Mundos Decentraland",
"description_ens": "Los titulares de Dominios ENS ahora pueden crear Mundos con 25 MB de almacenamiento dedicado.",
"description_dcl": "Los titulares de NAMEs de Decentraland obtienen <b>100 MB de almacenamiento</b> por <b>NAME, LAND, o 2,000 MANA</b>, ahora con la flexibilidad del almacenamiento compartido para mayor libertad creativa.",
"start_building": "comenzar a construir",
"learn_more": "aprende más sobre los mundos"
}
}
7 changes: 7 additions & 0 deletions src/modules/translation/languages/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -2117,5 +2117,12 @@
"names_buy": "购买 NAME",
"proposal": "这些存储规则经过治理 DAO 提案的投票并获得通过。",
"learn_more": "了解更多"
},
"worlds_for_ens_owners_announcement_modal": {
"title": "介绍 ENS 世界和 Decentraland 世界的增强存储",
"description_ens": "ENS 域名持有者现在可以创建具有 25 MB 专用存储空间的世界。",
"description_dcl": "Decentraland NAME 持有者每个 <b>NAME、LAND 或 2000 MANA</b> 获得 <b>100 MB 的存储空间</b>,现在具有共享存储的灵活性,以实现更多的创造自由。",
"start_building": "开始构建",
"learn_more": "了解更多关于世界的信息"
}
}

0 comments on commit bd8a73e

Please sign in to comment.