import { Component, createRef } from 'react'; import ContentPasteIcon from '@mui/icons-material/ContentPaste'; import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; import { StorageManagerContext } from '../../api/storageManagerContext'; import { PanelTile } from '../panels'; import { requireObject } from '../../utils/apiShape'; import { notifyError } from '../../utils/notify'; import { prepareArticlePhoto } from '../../utils/prepareArticlePhoto'; import { pasteImageOrFallback } from '../../utils/pasteImage'; import { articleWithUploadedPhoto, primaryPhoto } from '../../utils/articleDetail'; import ArticlePhoto from './ArticlePhoto'; import ArticlePhotosDialog from './ArticlePhotosDialog'; class ArticlePhotoTile extends Component { static contextType = StorageManagerContext; constructor(props) { super(props); this.fileInputRef = createRef(); this.state = { busy: false, editOpen: false }; this.handlePasteClick = this.handlePasteClick.bind(this); this.handleFileChange = this.handleFileChange.bind(this); this.handleEditOpen = this.handleEditOpen.bind(this); this.handleEditClose = this.handleEditClose.bind(this); this.uploadRawImage = this.uploadRawImage.bind(this); } async uploadRawImage(rawBlob) { const { article: articleData, onArticleUpdated } = this.props; this.setState({ busy: true }); try { const file = await prepareArticlePhoto(rawBlob); const uploadStarted = performance.now(); const res = await this.context.article.addImage(articleData.sku, file); console.log('[article-photo] upload', { uploadMs: Math.round(performance.now() - uploadStarted), bytes: file.size, sku: articleData.sku, }); requireObject(res, 'POST /api/article/:sku/image'); requireObject(res.image, 'image'); onArticleUpdated?.(articleWithUploadedPhoto(articleData, res.image)); } catch (err) { notifyError(err); } finally { this.setState({ busy: false }); } } handlePasteClick() { if (this.state.busy) return; void pasteImageOrFallback(() => { this.fileInputRef.current?.click(); }).then((image) => { if (image) void this.uploadRawImage(image); }); } handleFileChange(event) { const file = event.target.files?.[0]; event.target.value = ''; if (!file) return; void this.uploadRawImage(file); } handleEditOpen() { this.setState({ editOpen: true }); } handleEditClose() { this.setState({ editOpen: false }); } render() { const { article: articleData, onArticleUpdated, wide = 1, minHeight = 200, sx, tileKey, } = this.props; const { busy, editOpen } = this.state; const photo = primaryPhoto(articleData); const hasPhoto = photo?.thumbHash != null || photo?.fullHash != null; return ( <> ); } } export default ArticlePhotoTile;