Skip to content

Commit

Permalink
feat: Add drag in drop (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
rhea-so committed May 8, 2024
2 parents ab6802f + 26a1dac commit 3d1d9f6
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 0 deletions.
2 changes: 2 additions & 0 deletions web/src/locales/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"iso": "ISO",
"taken-at": "Taken At",

"drag-and-drop-photos-here": "Drag and drop photos here",

"root.tab.convert": "Convert",
"root.tab.theme-settings": "Theme Settings",
"root.tab.export-settings": "Export Settings",
Expand Down
2 changes: 2 additions & 0 deletions web/src/locales/translations/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"iso": "ISO感度",
"taken-at": "撮影日時",

"drag-and-drop-photos-here": "写真をここにドラッグ&ドロップ",

"root.tab.convert": "変換",
"root.tab.theme-settings": "テーマ設定",
"root.tab.export-settings": "エクスポート設定",
Expand Down
2 changes: 2 additions & 0 deletions web/src/locales/translations/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"iso": "ISO",
"taken-at": "촬영 일시",

"drag-and-drop-photos-here": "사진을 여기에 끌어다 놓거나 여기를 클릭하여 사진을 불러옵니다.",

"root.tab.convert": "프레임 씌우기",
"root.tab.theme-settings": "테마 설정",
"root.tab.export-settings": "내보내기 설정",
Expand Down
99 changes: 99 additions & 0 deletions web/src/pages/convert/components/add-photo.drag-in-drop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { ChangeEvent } from 'react';
import Photo from '../../../core/photo';
import { useStore } from '../../../store';
import DragInDropIcon from '../../../icons/drag-in-drop.icon';
import { t } from 'i18next';

const AddPhotoDragInDrop = () => {
const { photos, setPhotos, setLoading, setOpenedAddPhotoErrorDialog, darkMode } = useStore();

const onDragEnter = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
};

const onDragLeave = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
};

const onDragOver = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
};

const onDrop = async (e: React.DragEvent<HTMLDivElement>) => {
setLoading(true);
e.preventDefault();
e.stopPropagation();
const { files } = e.dataTransfer;
if (!files) return;
try {
await Promise.all(Array.from(files).map(Photo.create)).then((newPhotos) => {
setPhotos([...photos, ...newPhotos]);
});
} catch (e) {
console.error(e);
setOpenedAddPhotoErrorDialog(true);
}
setLoading(false);
};

const onChange = async (event: ChangeEvent<HTMLInputElement>) => {
setLoading(true);
await new Promise((resolve) => setTimeout(resolve, 100));
const { files } = event.target;
if (!files) return;
try {
await Promise.all(Array.from(files).map(Photo.create)).then((newPhotos) => {
setPhotos([...photos, ...newPhotos]);
});
} catch (e) {
console.error(e);
setOpenedAddPhotoErrorDialog(true);
}
setLoading(false);
};

return (
<>
<input type="file" accept="image/*" onChange={onChange} onClick={(e) => (e.currentTarget.value = '')} multiple hidden />

<div
style={{
cursor: 'pointer',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: '20rem',
border: `2px dashed ${darkMode ? '#fff' : '#000'}`,
borderRadius: '0.5rem',
margin: '32px',
}}
onDragEnter={onDragEnter}
onDragLeave={onDragLeave}
onDragOver={onDragOver}
onDrop={onDrop}
onClick={() => {
const input: HTMLInputElement | null = document.querySelector('input[type="file"]');
if (input) input.click();
}}
>
<DragInDropIcon size={48} />
<div
style={{
fontSize: '1rem',
color: darkMode ? '#fff' : '#000',
marginTop: '1rem',
}}
className="text-center"
>
{t('drag-and-drop-photos-here')}
</div>
</div>
</>
);
};

export default AddPhotoDragInDrop;
3 changes: 3 additions & 0 deletions web/src/pages/convert/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SettingsIcon from '../../icons/settings.icon';
import ImageIcon from '../../icons/image.icon';
import GenerateIcon from '../../icons/generate.icon';
import AddPhotoErrorDialog from './components/add-photo-error.dialog';
import AddPhotoDragInDrop from './components/add-photo.drag-in-drop';

const FramePage = () => {
const { t } = useTranslation();
Expand All @@ -27,6 +28,8 @@ const FramePage = () => {
<DownloadAllPhotoButton />
</Toolbar>

{photos.length === 0 && <AddPhotoDragInDrop />}

{photos.length !== 0 && (
<BlockTitle>
{t('root.loaded-photos')}
Expand Down

0 comments on commit 3d1d9f6

Please sign in to comment.