Skip to content

Commit

Permalink
feat: Show warning and error depending on the blocked state
Browse files Browse the repository at this point in the history
  • Loading branch information
fzavalia committed Oct 4, 2023
1 parent 66bb944 commit e47733d
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState } from 'react'
import React, { ReactNode, useCallback, useEffect, useState } from 'react'
import { t } from 'decentraland-dapps/dist/modules/translation/utils'
import {
Button,
Expand All @@ -12,7 +12,9 @@ import {
Dropdown,
Empty,
Icon as DCLIcon,
Popup
Popup,
Message,
MessageContent
} from 'decentraland-ui'
import { config } from 'config'
import { isDevelopment } from 'lib/environment'
Expand All @@ -28,7 +30,7 @@ import { Props, SortBy } from './WorldListPage.types'
import NameTabs from './NameTabs'
import WorldsStorage from './WorldsStorage'
import { TabType, useCurrentlySelectedTab } from './hooks'
import { fromBytesToMegabytes } from './utils'
import { DCLWorldsStatus, fromBytesToMegabytes, getDCLWorldsStatus } from './utils'
import './WorldListPage.css'

const EXPLORER_URL = config.get('EXPLORER_URL', '')
Expand Down Expand Up @@ -127,19 +129,15 @@ const WorldListPage: React.FC<Props> = props => {
const renderWorldStatus = (ens: ENS) => {
let status = isWorldDeployed(ens) ? 'active' : 'inactive'

if (
status === 'active' &&
worldsWalletStats &&
!isExternalName(ens.subdomain) &&
worldsWalletStats.usedSpace > worldsWalletStats.maxAllowedSpace
) {
const blockedSince = new Date(worldsWalletStats.blockedSince).getTime()
const now = new Date().getTime()

if (now >= blockedSince) {
if (now - blockedSince > 48 * 60 * 60 * 1000 /* 48 hours */) {
if (status === 'active' && worldsWalletStats && !isExternalName(ens.subdomain)) {
const worldsStatus = getDCLWorldsStatus(worldsWalletStats)

switch (worldsStatus.status) {
case DCLWorldsStatus.BLOCKED: {
status = 'blocked'
} else {
break
}
case DCLWorldsStatus.TO_BE_BLOCKED: {
status = 'warning'
}
}
Expand Down Expand Up @@ -273,6 +271,42 @@ const WorldListPage: React.FC<Props> = props => {
)
}

const renderDCLNamesBlockedWorldsStatusMessage = () => {
if (!worldsWalletStats) {
return null
}

const dclWorldsStatus = getDCLWorldsStatus(worldsWalletStats)

if (dclWorldsStatus.status === DCLWorldsStatus.OK) {
return null
}

let warning = false
let error = false
let messageContent: ReactNode

if (dclWorldsStatus.status === DCLWorldsStatus.TO_BE_BLOCKED) {
warning = true
messageContent = t('worlds_list_page.worlds_warning_message.to_be_blocked', {
toBeBlockedAt: dclWorldsStatus.toBeBlockedAt.toLocaleDateString(),
b: (text: string) => <b>{text}</b>
})
} else {
error = true
messageContent = t('worlds_list_page.worlds_warning_message.blocked', {
blockedAt: dclWorldsStatus.blockedAt.toLocaleDateString(),
b: (text: string) => <b>{text}</b>
})
}

return (
<Message warning={warning} error={error}>
<MessageContent>{messageContent}</MessageContent>
</Message>
)
}

const renderDCLNamesView = () => {
return (
<div>
Expand All @@ -283,6 +317,7 @@ const WorldListPage: React.FC<Props> = props => {
className="worlds-storage"
/>
) : null}
{renderDCLNamesBlockedWorldsStatusMessage()}
{ensList.length > 0 ? renderList() : renderEmptyPage()}
</div>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fromBytesToMegabytes } from './utils'
import { WorldsWalletStats } from 'lib/api/worlds'
import { BLOCK_DELAY_IN_MILLISECONDS, DCLWorldsStatus, fromBytesToMegabytes, getDCLWorldsStatus } from './utils'

describe('when converting from bytes to megabytes', () => {
describe('when the number is 10000000', () => {
Expand All @@ -7,3 +8,89 @@ describe('when converting from bytes to megabytes', () => {
})
})
})

describe('when getting the dcl worlds status', () => {
let stats: WorldsWalletStats

beforeEach(() => {
stats = {
usedSpace: '0',
maxAllowedSpace: '0'
} as WorldsWalletStats
})

describe('when the used space is lower than the max allowed space', () => {
beforeEach(() => {
stats.usedSpace = '100'
stats.maxAllowedSpace = '101'
})

it('should return status ok', () => {
expect(getDCLWorldsStatus(stats)).toEqual({ status: DCLWorldsStatus.OK })
})
})

describe('when the used space is equal to the max allowed space', () => {
beforeEach(() => {
stats.usedSpace = '100'
stats.maxAllowedSpace = '100'
})

it('should return status ok', () => {
expect(getDCLWorldsStatus(stats)).toEqual({ status: DCLWorldsStatus.OK })
})
})

describe('when the used space is greater to the max allowed space', () => {
beforeEach(() => {
stats.usedSpace = '101'
stats.maxAllowedSpace = '100'
})

describe('and blocked since is not defined', () => {
beforeEach(() => {
stats.blockedSince = undefined
})

it('should return status ok', () => {
expect(getDCLWorldsStatus(stats)).toEqual({ status: DCLWorldsStatus.OK })
})
})

describe('and blocked since is defined as 1 day later than now', () => {
beforeEach(() => {
stats.blockedSince = new Date(Date.now() + 24 * 60 * 60 * 1000 /* 1 day */).toISOString()
})

it('should return status ok', () => {
expect(getDCLWorldsStatus(stats)).toEqual({ status: DCLWorldsStatus.OK })
})
})

describe('and blocked since is defined as 1 day earlier than now', () => {
beforeEach(() => {
stats.blockedSince = new Date(Date.now() - 24 * 60 * 60 * 1000 /* 1 day */).toISOString()
})

it('should return status to be blocked with the to be blocked date', () => {
expect(getDCLWorldsStatus(stats)).toEqual({
status: DCLWorldsStatus.TO_BE_BLOCKED,
toBeBlockedAt: new Date(new Date(stats.blockedSince!).getTime() + BLOCK_DELAY_IN_MILLISECONDS)
})
})
})

describe('and blocked since is defined as 3 days earlier than now', () => {
beforeEach(() => {
stats.blockedSince = new Date(Date.now() - 72 * 60 * 60 * 1000 /* 3 days */).toISOString()
})

it('should return status to be blocked with the to be blocked date', () => {
expect(getDCLWorldsStatus(stats)).toEqual({
status: DCLWorldsStatus.BLOCKED,
blockedAt: new Date(new Date(stats.blockedSince!).getTime() + BLOCK_DELAY_IN_MILLISECONDS)
})
})
})
})
})
48 changes: 48 additions & 0 deletions src/components/WorldListPage_WorldsForEnsOwnersFeature/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
import { WorldsWalletStats } from 'lib/api/worlds'

export const fromBytesToMegabytes = (bytes: number) => {
return bytes / 1024 / 1024
}

export const BLOCK_DELAY_IN_MILLISECONDS = 48 * 60 * 60 * 1000 // 48 hours

export enum DCLWorldsStatus {
OK = 'ok',
BLOCKED = 'blocked',
TO_BE_BLOCKED = 'to-be-blocked'
}

export type GetDCLWorldsStatusResult =
| {
status: DCLWorldsStatus.OK
}
| {
status: DCLWorldsStatus.TO_BE_BLOCKED
toBeBlockedAt: Date
}
| {
status: DCLWorldsStatus.BLOCKED
blockedAt: Date
}

export const getDCLWorldsStatus = (stats: WorldsWalletStats): GetDCLWorldsStatusResult => {
const now = new Date().getTime()
const blockedSince = stats.blockedSince ? new Date(stats.blockedSince).getTime() : null

if (stats.usedSpace <= stats.maxAllowedSpace || !blockedSince || now < blockedSince) {
return {
status: DCLWorldsStatus.OK
}
}

const blockedAt = new Date(blockedSince + BLOCK_DELAY_IN_MILLISECONDS)

if (now - blockedSince > BLOCK_DELAY_IN_MILLISECONDS) {
return {
status: DCLWorldsStatus.BLOCKED,
blockedAt: blockedAt
}
}

return {
status: DCLWorldsStatus.TO_BE_BLOCKED,
toBeBlockedAt: blockedAt
}
}
2 changes: 1 addition & 1 deletion src/lib/api/worlds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export type WorldsWalletStats = {
}[]
usedSpace: string
maxAllowedSpace: string
blockedSince: string
blockedSince?: string
}

export class WorldsAPI extends BaseAPI {
Expand Down
4 changes: 4 additions & 0 deletions src/modules/translation/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,10 @@
"worlds_storage": {
"space_used": "Space used",
"view_details": "view details"
},
"worlds_warning_message": {
"to_be_blocked": "You are using more storage than you are allowed. Unpublish some scenes to free some space or increase you maximum storage before <b>{toBeBlockedAt}</b> to avoid losing access to your scenes.",
"blocked": "Access to your scenes has been blocked since <b>{blockedAt}</b> because you don't have enough storage to maintain your currently published worlds. Unpublish some scenes to free some space or increase your maximum storage to regain access."
}
},
"error_page": {
Expand Down
4 changes: 4 additions & 0 deletions src/modules/translation/languages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,10 @@
"worlds_storage": {
"space_used": "Espacio utilizado",
"view_details": "ver detalles"
},
"worlds_warning_message": {
"to_be_blocked": "Está utilizando más almacenamiento del permitido. Cancele la publicación de algunas escenas para liberar espacio o aumentar su almacenamiento máximo antes de <b>{toBeBlockedAt}</b> para evitar perder el acceso a sus escenas.",
"blocked": "El acceso a tus escenas ha sido bloqueado desde <b>{blockedAt}</b> porque no tienes suficiente almacenamiento para mantener tus mundos publicados actualmente. Cancele la publicación de algunas escenas para liberar espacio o aumente su almacenamiento máximo para recuperar el acceso."
}
},
"error_page": {
Expand Down
4 changes: 4 additions & 0 deletions src/modules/translation/languages/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,10 @@
"worlds_storage": {
"space_used": "使用空间",
"view_details": "查看详情"
},
"worlds_warning_message": {
"to_be_blocked": "您使用的存储空间超出了允许的范围。 在<b>{toBeBlockedAt}</b>之前取消发布某些场景以释放空间或增加最大存储空间,以避免失去对场景的访问权限。",
"blocked": "自 <b>{blockedAt}</b> 起,对您的场景的访问已被阻止,因为您没有足够的存储空间来维护当前发布的世界。 取消发布某些场景以释放空间或增加最大存储空间以重新获得访问权限。"
}
},
"estate_editor": {
Expand Down

0 comments on commit e47733d

Please sign in to comment.