有 preview 图片,不再加载原始图片预览
This commit is contained in:
parent
a8f61f0c92
commit
08de256dcf
|
@ -73,7 +73,7 @@
|
||||||
padding: px2rem(5px);
|
padding: px2rem(5px);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: px2rem(15px);
|
margin-right: px2rem(15px);
|
||||||
margin-right: px2rem(15px);
|
margin-bottom: px2rem(15px);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,9 @@ import BackIcon from '../icons/back.svg';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import MoveIcon from '../icons/move.svg';
|
import MoveIcon from '../icons/move.svg';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
import InfoIcon from '../icons/info.svg';
|
||||||
|
|
||||||
// 兼容原来的用法,后续不直接试用。
|
// 兼容原来的用法,后续不直接试用。
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export const closeIcon = <CloseIcon />;
|
export const closeIcon = <CloseIcon />;
|
||||||
|
@ -115,6 +118,7 @@ registerIcon('fail', FailIcon);
|
||||||
registerIcon('search', SearchIcon);
|
registerIcon('search', SearchIcon);
|
||||||
registerIcon('back', BackIcon);
|
registerIcon('back', BackIcon);
|
||||||
registerIcon('move', MoveIcon);
|
registerIcon('move', MoveIcon);
|
||||||
|
registerIcon('info', InfoIcon);
|
||||||
|
|
||||||
export function Icon({
|
export function Icon({
|
||||||
icon,
|
icon,
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" version="1.1" p-id="1463">
|
||||||
|
<g id="Group-9">
|
||||||
|
<circle id="Oval-7" stroke="currentColor" fill="transparent" cx="8" cy="8" r="7.5"></circle>
|
||||||
|
<rect id="Rectangle-26" fill="currentColor" x="7" y="3" width="2" height="2"></rect>
|
||||||
|
<rect id="Rectangle-26-Copy" fill="currentColor" x="7" y="6" width="2" height="7"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 463 B |
|
@ -91,7 +91,7 @@ function gennerateId() {
|
||||||
|
|
||||||
let preventEvent = (e: any) => e.stopPropagation();
|
let preventEvent = (e: any) => e.stopPropagation();
|
||||||
|
|
||||||
function getNameFromUrl(url: string) {
|
export function getNameFromUrl(url: string) {
|
||||||
if (/(?:\/|^)([^\/]+?)$/.test(url)) {
|
if (/(?:\/|^)([^\/]+?)$/.test(url)) {
|
||||||
return decodeURIComponent(RegExp.$1);
|
return decodeURIComponent(RegExp.$1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,13 @@ import find = require('lodash/find');
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import {Payload} from '../../types';
|
import {Payload} from '../../types';
|
||||||
import {buildApi} from '../../utils/api';
|
import {buildApi} from '../../utils/api';
|
||||||
import {createObject, qsstringify} from '../../utils/helper';
|
import {createObject, qsstringify, guid} from '../../utils/helper';
|
||||||
import {Icon} from '../../components/icons';
|
import {Icon} from '../../components/icons';
|
||||||
import Button from '../../components/Button';
|
import Button from '../../components/Button';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import accepts from 'attr-accept';
|
import accepts from 'attr-accept';
|
||||||
|
import {getNameFromUrl} from './File';
|
||||||
|
|
||||||
let id = 1;
|
|
||||||
function gennerateId() {
|
|
||||||
return id++;
|
|
||||||
}
|
|
||||||
let preventEvent = (e: any) => e.stopPropagation();
|
let preventEvent = (e: any) => e.stopPropagation();
|
||||||
|
|
||||||
export interface ImageProps extends FormControlProps {
|
export interface ImageProps extends FormControlProps {
|
||||||
|
@ -122,7 +119,7 @@ export default class ImageControl extends React.Component<
|
||||||
? {
|
? {
|
||||||
value,
|
value,
|
||||||
url: value,
|
url: value,
|
||||||
id: gennerateId()
|
id: guid()
|
||||||
}
|
}
|
||||||
: value),
|
: value),
|
||||||
state: 'init'
|
state: 'init'
|
||||||
|
@ -146,6 +143,7 @@ export default class ImageControl extends React.Component<
|
||||||
files: []
|
files: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
files: Array<FileValue | FileX> = [];
|
||||||
cropper = React.createRef<Cropper>();
|
cropper = React.createRef<Cropper>();
|
||||||
dropzone = React.createRef<any>();
|
dropzone = React.createRef<any>();
|
||||||
current: FileValue | FileX | null = null;
|
current: FileValue | FileX | null = null;
|
||||||
|
@ -222,7 +220,7 @@ export default class ImageControl extends React.Component<
|
||||||
if (
|
if (
|
||||||
obj &&
|
obj &&
|
||||||
(org = find(
|
(org = find(
|
||||||
this.state.files,
|
this.files,
|
||||||
item => (item as FileValue).value === obj.value
|
item => (item as FileValue).value === obj.value
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
|
@ -239,7 +237,7 @@ export default class ImageControl extends React.Component<
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
files
|
files: this.files = files
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,15 +286,15 @@ export default class ImageControl extends React.Component<
|
||||||
const files = rejectedFiles.map((file: any) => ({
|
const files = rejectedFiles.map((file: any) => ({
|
||||||
...file,
|
...file,
|
||||||
state: 'invalid',
|
state: 'invalid',
|
||||||
id: gennerateId(),
|
id: guid(),
|
||||||
name: file.name
|
name: file.name
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
files: multiple
|
files: this.files = multiple
|
||||||
? this.state.files.concat(files)
|
? this.files.concat(files)
|
||||||
: this.state.files.length
|
: this.files.length
|
||||||
? this.state.files
|
? this.files
|
||||||
: files.slice(0, 1)
|
: files.slice(0, 1)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -316,7 +314,7 @@ export default class ImageControl extends React.Component<
|
||||||
{
|
{
|
||||||
uploading: true,
|
uploading: true,
|
||||||
locked: true,
|
locked: true,
|
||||||
files: this.state.files.map(file => {
|
files: this.files = this.files.map(file => {
|
||||||
if (file.state === 'error') {
|
if (file.state === 'error') {
|
||||||
file.state = 'pending';
|
file.state = 'pending';
|
||||||
}
|
}
|
||||||
|
@ -347,23 +345,20 @@ export default class ImageControl extends React.Component<
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const file = find(
|
const file = find(this.files, item => item.state === 'pending') as FileX;
|
||||||
this.state.files,
|
|
||||||
item => item.state === 'pending'
|
|
||||||
) as FileX;
|
|
||||||
if (file) {
|
if (file) {
|
||||||
this.current = file;
|
this.current = file;
|
||||||
|
|
||||||
file.state = 'uploading';
|
file.state = 'uploading';
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
files: this.state.files.concat()
|
files: this.files = this.files.concat()
|
||||||
},
|
},
|
||||||
() =>
|
() =>
|
||||||
this.sendFile(
|
this.sendFile(
|
||||||
file as FileX,
|
file as FileX,
|
||||||
(error, file, obj) => {
|
(error, file, obj) => {
|
||||||
const files = this.state.files.concat();
|
const files = this.files.concat();
|
||||||
const idx = files.indexOf(file);
|
const idx = files.indexOf(file);
|
||||||
|
|
||||||
if (!~idx) {
|
if (!~idx) {
|
||||||
|
@ -383,26 +378,29 @@ export default class ImageControl extends React.Component<
|
||||||
|
|
||||||
return this.setState(
|
return this.setState(
|
||||||
{
|
{
|
||||||
files: files,
|
files: this.files = files,
|
||||||
error: error
|
error: error
|
||||||
},
|
},
|
||||||
this.tick
|
this.tick
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newFile = obj as FileValue;
|
newFile = {
|
||||||
|
...obj,
|
||||||
|
preview: file.preview
|
||||||
|
} as FileValue;
|
||||||
}
|
}
|
||||||
files.splice(idx, 1, newFile);
|
files.splice(idx, 1, newFile);
|
||||||
this.current = null;
|
this.current = null;
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
files: files
|
files: this.files = files
|
||||||
},
|
},
|
||||||
this.tick
|
this.tick
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
progress => {
|
progress => {
|
||||||
const files = this.state.files.concat();
|
const files = this.files.concat();
|
||||||
const idx = files.indexOf(file);
|
const idx = files.indexOf(file);
|
||||||
|
|
||||||
if (!~idx) {
|
if (!~idx) {
|
||||||
|
@ -412,7 +410,7 @@ export default class ImageControl extends React.Component<
|
||||||
// file 是个非 File 对象,先不copy了直接改。
|
// file 是个非 File 对象,先不copy了直接改。
|
||||||
file.progress = progress;
|
file.progress = progress;
|
||||||
this.setState({
|
this.setState({
|
||||||
files
|
files: this.files = files
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -428,7 +426,7 @@ export default class ImageControl extends React.Component<
|
||||||
|
|
||||||
if (this.resolve) {
|
if (this.resolve) {
|
||||||
this.resolve(
|
this.resolve(
|
||||||
this.state.files.some(file => file.state === 'error')
|
this.files.some(file => file.state === 'error')
|
||||||
? '文件上传失败请重试'
|
? '文件上传失败请重试'
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
@ -440,13 +438,13 @@ export default class ImageControl extends React.Component<
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFile(file: FileValue, index: number) {
|
removeFile(file: FileValue, index: number) {
|
||||||
const files = this.state.files.concat();
|
const files = this.files.concat();
|
||||||
|
|
||||||
files.splice(index, 1);
|
files.splice(index, 1);
|
||||||
|
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
files: files
|
files: this.files = files
|
||||||
},
|
},
|
||||||
this.onChange
|
this.onChange
|
||||||
);
|
);
|
||||||
|
@ -455,7 +453,7 @@ export default class ImageControl extends React.Component<
|
||||||
editImage(index: number) {
|
editImage(index: number) {
|
||||||
const {multiple} = this.props;
|
const {multiple} = this.props;
|
||||||
|
|
||||||
const files = this.state.files;
|
const files = this.files;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
cropFile: {
|
cropFile: {
|
||||||
|
@ -475,7 +473,7 @@ export default class ImageControl extends React.Component<
|
||||||
valueField
|
valueField
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const files = this.state.files.filter(
|
const files = this.files.filter(
|
||||||
file => file.state == 'uploaded' || file.state == 'init'
|
file => file.state == 'uploaded' || file.state == 'init'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -542,7 +540,7 @@ export default class ImageControl extends React.Component<
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
blob.id = gennerateId();
|
blob.id = guid();
|
||||||
files.push(blob);
|
files.push(blob);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -577,7 +575,7 @@ export default class ImageControl extends React.Component<
|
||||||
}
|
}
|
||||||
|
|
||||||
const {multiple, maxLength, maxSize, accept} = this.props;
|
const {multiple, maxLength, maxSize, accept} = this.props;
|
||||||
let currentFiles = this.state.files;
|
let currentFiles = this.files;
|
||||||
|
|
||||||
if (!multiple && currentFiles.length) {
|
if (!multiple && currentFiles.length) {
|
||||||
currentFiles = [];
|
currentFiles = [];
|
||||||
|
@ -604,9 +602,9 @@ export default class ImageControl extends React.Component<
|
||||||
}
|
}
|
||||||
|
|
||||||
file.state = 'pending';
|
file.state = 'pending';
|
||||||
file.id = gennerateId();
|
file.id = guid();
|
||||||
if (!file.preview || !file.url) {
|
if (!file.preview || !file.url) {
|
||||||
file.preview = window.URL.createObjectURL(file);
|
file.preview = URL.createObjectURL(file);
|
||||||
}
|
}
|
||||||
inputFiles.push(file);
|
inputFiles.push(file);
|
||||||
});
|
});
|
||||||
|
@ -618,7 +616,7 @@ export default class ImageControl extends React.Component<
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
error: undefined,
|
error: undefined,
|
||||||
files: currentFiles.concat(inputFiles),
|
files: this.files = currentFiles.concat(inputFiles),
|
||||||
locked: true
|
locked: true
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
|
@ -769,7 +767,7 @@ export default class ImageControl extends React.Component<
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
delete img.onload;
|
delete img.onload;
|
||||||
const files = this.state.files.concat();
|
const files = this.files.concat();
|
||||||
const file = files[index];
|
const file = files[index];
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
@ -789,7 +787,7 @@ export default class ImageControl extends React.Component<
|
||||||
|
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
files: files
|
files: this.files = files
|
||||||
},
|
},
|
||||||
!needUploading ? this.onChange : undefined
|
!needUploading ? this.onChange : undefined
|
||||||
);
|
);
|
||||||
|
@ -802,13 +800,13 @@ export default class ImageControl extends React.Component<
|
||||||
return this.state.lockedReason;
|
return this.state.lockedReason;
|
||||||
} else if (
|
} else if (
|
||||||
this.state.uploading ||
|
this.state.uploading ||
|
||||||
this.state.files.some(item => item.state === 'pending')
|
this.files.some(item => item.state === 'pending')
|
||||||
) {
|
) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
this.resolve = resolve;
|
this.resolve = resolve;
|
||||||
this.startUpload();
|
this.startUpload();
|
||||||
});
|
});
|
||||||
} else if (this.state.files.some(item => item.state === 'error')) {
|
} else if (this.files.some(item => item.state === 'error')) {
|
||||||
return '文件上传失败请重试';
|
return '文件上传失败请重试';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -890,7 +888,7 @@ export default class ImageControl extends React.Component<
|
||||||
'is-reject': isDragReject
|
'is-reject': isDragReject
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
把图片拖到这,然后松完成添加!
|
把图片拖到这,然后松开完成添加!
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
@ -962,7 +960,7 @@ export default class ImageControl extends React.Component<
|
||||||
this,
|
this,
|
||||||
key
|
key
|
||||||
)}
|
)}
|
||||||
src={file.url || file.preview}
|
src={file.preview || file.url}
|
||||||
alt={file.name}
|
alt={file.name}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -973,11 +971,11 @@ export default class ImageControl extends React.Component<
|
||||||
>
|
>
|
||||||
{file.info ? (
|
{file.info ? (
|
||||||
[
|
[
|
||||||
<div key="1">
|
<div key="info">
|
||||||
{file.info.width} x {file.info.height}
|
{file.info.width} x {file.info.height}
|
||||||
</div>,
|
</div>,
|
||||||
file.info.len ? (
|
file.info.len ? (
|
||||||
<div key="2">
|
<div key="size">
|
||||||
{ImageControl.formatFileSize(
|
{ImageControl.formatFileSize(
|
||||||
file.info.len
|
file.info.len
|
||||||
)}
|
)}
|
||||||
|
@ -1020,6 +1018,13 @@ export default class ImageControl extends React.Component<
|
||||||
<Icon icon="remove" className="icon" />
|
<Icon icon="remove" className="icon" />
|
||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
|
<a
|
||||||
|
data-tooltip={getNameFromUrl(file.value)}
|
||||||
|
data-position="bottom"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<Icon icon="info" className="icon" />
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
Loading…
Reference in New Issue