Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Merge branch 'dev' into cms-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
HexaField authored Jun 17, 2024
2 parents 7817ff5 + bfec725 commit f6110ab
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 5 deletions.
10 changes: 10 additions & 0 deletions packages/client-core/i18n/en/editor.json
Original file line number Diff line number Diff line change
Expand Up @@ -1384,5 +1384,15 @@
"tabs": {
"scene-assets": "Assets",
"project-assets": "Project Assets"
},
"generatingThumbnails": {
"title": "Generating Thumbnails",
"amountRemaining": "{{count}} remaining"
},
"assetMetadata": {
"name": "Name",
"path": "Path",
"type": "Type",
"tags": "Tags"
}
}
23 changes: 21 additions & 2 deletions packages/ui/src/components/editor/layout/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,24 @@ export const ContextMenu = ({
return positionY
}

const positionX = open ? anchorPosition.left - panel?.getBoundingClientRect().left! : 0
// Calculate the X position of the context menu based on the menu width and space to the right of the panel in order to avoid overflow
const calculatePositionX = () => {
let positionX = open ? anchorPosition.left - panel?.getBoundingClientRect().left! : 0

if (open && menuRef.current) {
const menuWidth = menuRef.current.offsetWidth

// if the panel width is less than the menu width plus the menu pos x offset, we need to move the menu left
const offset = panel?.getBoundingClientRect().width! - (menuWidth + positionX)
if (offset < 0) {
positionX = positionX + offset
}
}

return positionX
}

const [positionX, setPositionX] = useState(calculatePositionX())
const [positionY, setPositionY] = useState(calculatePositionY())

const [isScrollable, setIsScrollable] = useState(false)
Expand All @@ -80,6 +97,7 @@ export const ContextMenu = ({
setIsScrollable(parentHeight <= menuHeight + 1)

setPositionY(calculatePositionY())
setPositionX(calculatePositionX())
}
}, [open])

Expand All @@ -89,10 +107,11 @@ export const ContextMenu = ({
{open && anchorEl && (
<div
ref={menuRef}
className="absolute z-[200] w-44 rounded-lg bg-neutral-900 shadow-lg"
className="absolute z-[200] w-fit min-w-44 rounded-lg bg-neutral-900 shadow-lg"
style={{
top: `${positionY}px`,
left: `${positionX}px`,
maxWidth: `${panel?.getBoundingClientRect().width}px`,
maxHeight: `${panel?.getBoundingClientRect().height}px`,
overflowY: isScrollable ? 'auto' : 'visible'
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import Input from '../../../../../primitives/tailwind/Input'
import LoadingView from '../../../../../primitives/tailwind/LoadingView'
import Text from '../../../../../primitives/tailwind/Text'
import Tooltip from '../../../../../primitives/tailwind/Tooltip'
import { ContextMenu } from '../../../layout/ContextMenu'
import { FileIcon } from '../../Files/icon'

type Category = {
Expand Down Expand Up @@ -94,10 +95,33 @@ const generateAssetsBreadcrumb = (categories: Category[], target: string) => {
}

const ResourceFile = ({ resource }: { resource: StaticResourceType }) => {
const { t } = useTranslation()

const [anchorPosition, setAnchorPosition] = React.useState<any>(undefined)
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null)
const open = Boolean(anchorEl)

const handleContextMenu = (event: React.MouseEvent<HTMLDivElement>) => {
event.preventDefault()
event.stopPropagation()
setAnchorEl(event.currentTarget)
setAnchorPosition({
top: event.clientY,
left: event.clientX
})
}

const handleClose = () => {
setAnchorEl(null)
setAnchorPosition({ left: 0, top: 0 })
}

const { onAssetSelectionChanged } = useContext(AssetsPreviewContext)

const assetType = AssetLoader.getAssetType(resource.key)
const name = resource.key.split('/').at(-1)!
const splitResourceKey = resource.key.split('/')
const name = splitResourceKey.at(-1)!
const path = splitResourceKey.slice(0, -1).join('/') + '/'

const [_, drag, preview] = useDrag(() => ({
type: assetType,
Expand All @@ -123,16 +147,85 @@ const ResourceFile = ({ resource }: { resource: StaticResourceType }) => {
size: 'unknown size'
})
}
className="mt-[10px] flex cursor-pointer flex-col items-center justify-center align-middle"
onContextMenu={handleContextMenu}
className={'mt-[10px] flex cursor-pointer flex-col items-center justify-center align-middle'}
>
<span className="mb-[5px] h-[70px] w-[70px] text-[70px]">
<FileIcon thumbnailURL={resource.thumbnailURL} type={assetType} />
</span>
<span className="w-[100px] overflow-hidden overflow-ellipsis whitespace-nowrap text-sm text-white">{name}</span>

<ContextMenu
open={open}
anchorEl={anchorEl}
panelId={'asset-browser-panel'}
anchorPosition={anchorPosition}
onClose={handleClose}
className="gap-1"
>
<div className="w-full rounded-lg bg-theme-surface-main px-4 py-2 text-sm text-white">
<MetadataTable
rows={[
{ label: t('editor:assetMetadata.name'), value: `${name}` },
{ label: t('editor:assetMetadata.path'), value: `${path}` },
{ label: t('editor:assetMetadata.type'), value: `${resource.mimeType}` },
{ label: t('editor:assetMetadata.tags'), value: `${resource.tags || 'none'}` }
]}
/>
{/* TODO: add more actions (compressing images/models, editing tags, etc) here as desired */}
<MenuDivider />
<Button
fullWidth
size="small"
variant="transparent"
className="text-s text-left hover:bg-theme-surfaceInput"
onClick={() => handleClose()}
>
{t('editor:visualScript.modal.buttons.close')}
</Button>
</div>
</ContextMenu>
</div>
)
}

export const MenuDivider = () => {
return <div className="my-2 flex w-full border-b border-theme-primary" />
}

interface MetadataTableProps {
rows: MetadataTableRowProps[]
}

const MetadataTable: React.FC<MetadataTableProps> = ({ rows }) => (
<table className="cursor-default select-text">
<tbody>
{rows.map((row, index) => (
<MetadataTableRow key={index} label={row.label} value={row.value} />
))}
</tbody>
</table>
)

interface MetadataTableRowProps {
label: string
value: string
}

const MetadataTableRow: React.FC<MetadataTableRowProps> = ({ label, value }) => (
<tr>
<td className="font-semibold">{label}</td>
<td
className="cursor-default select-text pl-4"
onContextMenu={(e) => {
e.stopPropagation() // allow user to copy selected text
}}
>
{value}
</td>
</tr>
)

function iterativelyListTags(obj: object): string[] {
const tags: string[] = []
for (const key in obj) {
Expand Down Expand Up @@ -433,7 +526,7 @@ const AssetPanel = () => {
{t('editor:layout.filebrowser.uploadAssets')}
</Button>
</div>
<div className="flex h-full">
<div id="asset-browser-panel" className="flex h-full overflow-y-auto">
<CategoriesList />
<div className="grid flex-1 grid-cols-3 gap-2 overflow-auto p-2">
<ResourceItems />
Expand Down

0 comments on commit f6110ab

Please sign in to comment.