Files
mini-programs/src/components/UploadCover/upload-source-popup.tsx

174 lines
5.4 KiB
TypeScript

import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'
import { Image, View, Text, ScrollView, Button } from '@tarojs/components'
import Taro from '@tarojs/taro'
import img from '../../config/images'
import publishService from '../../services/publishService'
import { CommonPopup } from '../'
import emptyStatus from '../../static/emptyStatus/publish-empty.png'
import './upload-source-popup.scss'
type SourceType = 'history' | 'preset'
type ImageItem = {
id: string
url: string
tempFilePath?: string
}
interface UploadImageProps {
onAdd: (images: ImageItem[]) => void
}
export const sourceMap = new Map<SourceType, string>([
['history', '历史图库'],
['preset', '预设图库']
])
const checkImageSelected = (images: ImageItem[], image: ImageItem) => {
return images.some(item => item.id === image.id)
}
export default forwardRef(function UploadImage(props: UploadImageProps, ref) {
const {
onAdd = () => void 0,
} = props
const [visible, setVisible] = useState(false)
const [sourceType, setSourceType] = useState<SourceType>('history')
const [maxCount, setMaxCount] = useState(9)
const [images, setImages] = useState<ImageItem[]>([])
const [selectedImages, setSelectedImages] = useState<ImageItem[]>([])
const handleImageClick = (image: ImageItem) => {
if (checkImageSelected(selectedImages, image)) {
setSelectedImages(selectedImages.filter(item => item.id !== image.id))
} else if (!outOfMax) {
setSelectedImages([...selectedImages, image])
} else {
Taro.showToast({
title: `最多选择${maxCount}张图片`,
icon: 'none'
})
}
}
useImperativeHandle(ref, () => ({
show: (sourceType: SourceType, maxCount: number) => {
setVisible(true)
setSourceType(sourceType)
setMaxCount(maxCount)
fetchImages()
}
}))
function fetchImages() {
publishService.getPictures({
pageOption: {
page: 1,
pageSize: 100,
},
seachOption: {
tag: '',
resource_type: 'image',
dateRange: [],
},
}).then(res => {
if (res.success) {
let start = 0
setImages(res.data.data.rows.map(item => ({
id: (Date.now() + start++).toString(),
url: item.thumbnail_url,
})))
} else {
// TODO: 显示错误信息
Taro.showToast({
title: res.message,
icon: 'none'
})
}
})
}
function onClose() {
setVisible(false)
setSelectedImages([])
setImages([])
setSourceType('history')
setMaxCount(9)
}
const handleConfirm = () => {
if (selectedImages.length > 0) {
onAdd(selectedImages)
setVisible(false)
} else {
Taro.showToast({
title: '请选择图片',
icon: 'none'
})
}
}
const outOfMax = selectedImages.length >= maxCount
return (
<>
<CommonPopup
visible={visible}
onClose={onClose}
round
hideFooter
position='bottom'
zIndex={1001}
>
<View className="upload-popup">
<View className="upload-popup-title">{sourceMap.get(sourceType)}</View>
{/* TODO: 分页 加载更多 */}
{/* TODO: 图片加载失败 */}
{/* TODO: 图片加载中 */}
<ScrollView
scrollY
className="upload-popup-scroll-view"
>
{images.length > 0 ? (
<View className="upload-popup-image-list">
{images.map(item => {
const isSelected = checkImageSelected(selectedImages, item)
return (
<View className={`upload-popup-image-item ${outOfMax ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`} onClick={() => handleImageClick(item)}>
<Image className="upload-popup-image-item-image" src={item.url} />
<View className={`upload-popup-image-item-select ${isSelected ? 'selected' : ''}`}>
{isSelected ? (
<Image className="select-image-icon" src={img.ICON_CIRCLE_SELECT_ARROW} />
) : (
<Image className="select-image-icon" src={img.ICON_CIRCLE_UNSELECT} />
)}
</View>
</View>
)
})}
</View>
) : (
<View className="upload-popup-image-list-empty">
<Image className="upload-popup-image-list-empty-image" src={emptyStatus} />
<Text className="upload-popup-image-list-empty-text"></Text>
</View>
)}
</ScrollView>
{images.length > 0 ? (
<View className="upload-popup-footer">
<Button className="upload-popup-footer-cancel" onClick={() => setVisible(false)}></Button>
<Button className={`upload-popup-footer-confirm ${selectedImages.length > 0 ? 'active' : ''}`} type='primary' onClick={handleConfirm}></Button>
</View>
) : (
<View className="upload-popup-footer">
<Button className="upload-popup-footer-cancel" onClick={() => setVisible(false)}></Button>
</View>
)}
</View>
</CommonPopup>
{/* <View className="upload-source-popup-text" onClick={() => setVisible(true)}>{sourceMap.get(sourceType)}选取</View> */}
</>
);
});