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

Commit

Permalink
image convert modal (#10466)
Browse files Browse the repository at this point in the history
  • Loading branch information
aditya-mitra authored Jun 28, 2024
1 parent 0d0abf0 commit 40c7fa4
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 14 deletions.
8 changes: 8 additions & 0 deletions packages/client-core/i18n/en/editor.json
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,8 @@
"uploadAssets": "Upload Assets",
"search-placeholder": "Search folders",
"generatingThumbnails": "Generating Thumbnails ({{count}} remaining)",
"file": "File",
"directory": "Directory",
"fileProperties": {
"name": "Name:",
"type": "Type:",
Expand Down Expand Up @@ -1213,6 +1215,12 @@
"dateModified": "Date Modified",
"size": "Size"
}
},
"image-convert": {
"format": "Format",
"resize": "Resize",
"width": "Width",
"height": "Height"
}
},
"scene-assets": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
CPAL-1.0 License
The contents of this file are subject to the Common Public Attribution License
Version 1.0. (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
https://github.com/EtherealEngine/etherealengine/blob/dev/LICENSE.
The License is based on the Mozilla Public License Version 1.1, but Sections 14
and 15 have been added to cover use of software over a computer network and
provide for limited attribution for the Original Developer. In addition,
Exhibit A has been modified to be consistent with Exhibit B.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
specific language governing rights and limitations under the License.
The Original Code is Ethereal Engine.
The Original Developer is the Initial Developer. The Initial Developer of the
Original Code is the Ethereal Engine team.
All portions of the code written by the Ethereal Engine team are Copyright © 2021-2023
Ethereal Engine. All Rights Reserved.
*/

import React from 'react'
import { useTranslation } from 'react-i18next'

import { PopoverState } from '@etherealengine/client-core/src/common/services/PopoverState'
import { imageConvertPath } from '@etherealengine/common/src/schema.type.module'
import { FileDataType } from '@etherealengine/editor/src/components/assets/FileBrowser/FileDataType'
import {
ImageConvertDefaultParms,
ImageConvertParms
} from '@etherealengine/engine/src/assets/constants/ImageConvertParms'
import { useHookstate } from '@etherealengine/hyperflux'
import { useMutation } from '@etherealengine/spatial/src/common/functions/FeathersHooks'
import Checkbox from '../../../../../primitives/tailwind/Checkbox'
import Label from '../../../../../primitives/tailwind/Label'
import Modal from '../../../../../primitives/tailwind/Modal'
import Select from '../../../../../primitives/tailwind/Select'
import Text from '../../../../../primitives/tailwind/Text'
import NumericInput from '../../../input/Numeric'

export default function ImageConvertModal({
file,
refreshDirectory
}: {
file: FileDataType
refreshDirectory: () => Promise<void>
}) {
const { t } = useTranslation()
const modalProcessing = useHookstate(false)

const convertProperties = useHookstate<ImageConvertParms>(ImageConvertDefaultParms)
const imageConvertMutation = useMutation(imageConvertPath)

const handleSubmit = async () => {
convertProperties.src.set(file.isFolder ? `${file.url}/${file.key}` : file.url)
imageConvertMutation
.create({
...convertProperties.value
})
.then(() => {
refreshDirectory()
PopoverState.hidePopupover()
})
}

return (
<Modal
title={t('editor:layout.filebrowser.convert')}
className="w-[50vw] max-w-2xl"
onSubmit={handleSubmit}
onClose={PopoverState.hidePopupover}
submitLoading={modalProcessing.value}
>
<div className="ml-32 flex flex-col gap-4">
<Text fontWeight="semibold">
{file.name} {file.isFolder ? t('editor:layout.filebrowser.directory') : t('editor:layout.filebrowser.file')}
</Text>
<div className="flex items-center gap-2">
<Label className="w-16">{t('editor:layout.filebrowser.image-convert.format')}</Label>
<Select
inputClassName="px-2 py-0.5 text-[#9CA0AA] text-sm"
options={[
{ label: 'PNG', value: 'png' },
{ label: 'JPG', value: 'jpg' },
{ label: 'WEBP', value: 'webp' }
]}
currentValue={convertProperties.format.value}
onChange={(value) => convertProperties.format.set(value)}
/>
</div>
<div className="flex items-center gap-2">
<Label className="w-16">{t('editor:layout.filebrowser.image-convert.resize')}</Label>
<Checkbox
className="bg-theme-highlight"
value={convertProperties.resize.value}
onChange={(value) => convertProperties.resize.set(value)}
/>
</div>
{convertProperties.resize.value && (
<>
<div className="flex items-center gap-2">
<Label className="w-16">{t('editor:layout.filebrowser.image-convert.width')}</Label>
<NumericInput
className="w-52 bg-[#141619] px-2 py-0.5"
value={convertProperties.width.value}
onChange={(value) => convertProperties.width.set(value)}
/>
</div>
<div className="flex items-center gap-2">
<Label className="w-16">{t('editor:layout.filebrowser.image-convert.height')}</Label>
<NumericInput
className="w-52 bg-[#141619] px-2 py-0.5"
value={convertProperties.height.value}
onChange={(value) => convertProperties.height.set(value)}
/>
</div>
</>
)}
</div>
</Modal>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import Button from '../../../../../primitives/tailwind/Button'
import Tooltip from '../../../../../primitives/tailwind/Tooltip'
import { FileIcon } from '../icon'
import DeleteFileModal from './DeleteFileModal'
import ImageConvertModal from './ImageConvertModal'
import RenameFileModal from './RenameFileModal'

export const canDropItemOverFolder = (folderName: string) =>
Expand All @@ -67,7 +68,6 @@ export const FileTableWrapper = ({ wrap, children }: { wrap: boolean; children:
}
const { t } = useTranslation()
const selectedTableColumns = useHookstate(getMutableState(FilesViewModeSettings).list.selectedTableColumns).value
const fontSize = useHookstate(getMutableState(FilesViewModeSettings).list.fontSize).value
return (
<div className="table-container">
<table className="w-full">
Expand Down Expand Up @@ -201,7 +201,6 @@ type FileBrowserItemType = {
setFileProperties: any
setOpenPropertiesModal: any
setOpenCompress: any
setOpenConvert: any
isFilesLoading: boolean
projectName: string
onClick: (event: React.MouseEvent, currentFile: FileDataType) => void
Expand All @@ -210,6 +209,7 @@ type FileBrowserItemType = {
isListView: boolean
staticResourceModifiedDates: Record<string, string>
isSelected: boolean
refreshDirectory: () => Promise<void>
}

export function FileBrowserItem({
Expand All @@ -219,15 +219,15 @@ export function FileBrowserItem({
setOpenPropertiesModal,
setFileProperties,
setOpenCompress,
setOpenConvert,
projectName,
onClick,
dropItemsOnPanel,
isFilesLoading,
addFolder,
isListView,
staticResourceModifiedDates,
isSelected
isSelected,
refreshDirectory
}: FileBrowserItemType) {
const { t } = useTranslation()
const [anchorEvent, setAnchorEvent] = React.useState<undefined | React.MouseEvent<HTMLDivElement>>(undefined)
Expand Down Expand Up @@ -307,12 +307,6 @@ export function FileBrowserItem({
handleClose()
}

const viewConvert = () => {
setFileProperties(item)
setOpenConvert(true)
handleClose()
}

const [_dragProps, drag, preview] = disableDnD
? [undefined, undefined, undefined]
: useDrag(() => ({
Expand Down Expand Up @@ -413,7 +407,15 @@ export function FileBrowserItem({
<Button variant="outline" size="small" fullWidth onClick={viewCompress}>
{t('editor:layout.filebrowser.compress')}
</Button>
<Button variant="outline" size="small" fullWidth onClick={viewConvert}>
<Button
variant="outline"
size="small"
fullWidth
onClick={() =>
PopoverState.showPopupover(<ImageConvertModal file={item} refreshDirectory={refreshDirectory} />)
}
disabled={!(['jpg', 'png', 'webp'].includes(item.type) || item.isFolder)}
>
{t('editor:layout.filebrowser.convert')}
</Button>
</ContextMenu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ const FileBrowserContentPanel: React.FC<FileBrowserContentPanelProps> = (props)

const openProperties = useHookstate(false)
const openCompress = useHookstate(false)
const openConvert = useHookstate(false)

const openConfirm = useHookstate(false)
const contentToDeletePath = useHookstate('')
Expand Down Expand Up @@ -515,13 +514,13 @@ const FileBrowserContentPanel: React.FC<FileBrowserContentPanelProps> = (props)
setOpenPropertiesModal={openProperties.set}
setFileProperties={fileProperties.set}
setOpenCompress={openCompress.set}
setOpenConvert={openConvert.set}
dropItemsOnPanel={dropItemsOnPanel}
isFilesLoading={isLoading}
addFolder={createNewFolder}
isListView={isListView}
staticResourceModifiedDates={staticResourceModifiedDates.value}
isSelected={selectedFileKeys.value.includes(file.key)}
refreshDirectory={refreshDirectory}
/>
))}
</>
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/primitives/tailwind/Checkbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ const Checkbox = ({ className, containerClassName, label, value, onChange, disab
className={twMerge(
'grid h-4 w-4 place-items-center rounded border border-theme-primary',
value ? 'bg-blue-primary' : 'bg-theme-surfaceInput',
disabled ? 'cursor-not-allowed opacity-50' : ''
disabled ? 'cursor-not-allowed opacity-50' : '',
className
)}
>
{value && <HiCheck className="h-3 w-3 text-white" />}
Expand Down

0 comments on commit 40c7fa4

Please sign in to comment.