[new feature] Uploader: support preview non-image file (#3604)

This commit is contained in:
neverland 2019-06-22 15:39:49 +08:00 committed by GitHub
parent a27df2c25f
commit dea0d28361
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 17 deletions

View File

@ -18,6 +18,7 @@
top: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: @image-placeholder-text-color;

View File

@ -6,6 +6,10 @@ import ImagePreview from '../image-preview';
const [sfc, bem] = use('uploader');
function isImageDataUrl(dataUrl) {
return dataUrl.indexOf('data:image') === 0;
}
export default sfc({
inheritAttrs: false,
@ -136,10 +140,14 @@ export default sfc({
}
},
onPreviewImage(startPosition) {
onPreviewImage(item) {
const imageFiles = this.fileList
.map(item => item.content)
.filter(content => isImageDataUrl(content));
ImagePreview({
images: this.fileList.map(file => file.content),
startPosition
images: imageFiles,
startPosition: imageFiles.indexOf(item.content)
});
},
@ -148,23 +156,33 @@ export default sfc({
return;
}
return this.fileList.map((file, index) => (
return this.fileList.map((item, index) => (
<div class={bem('preview')}>
<Image
fit="cover"
src={file.content}
src={item.content}
class={bem('preview-image')}
width={this.previewSize}
height={this.previewSize}
scopedSlots={{
error() {
return [
<Icon class={bem('file-icon')} name="description" />,
<div class={[bem('file-name'), 'van-ellipsis']}>{item.file.name}</div>
];
}
}}
onClick={() => {
this.onPreviewImage(index);
if (isImageDataUrl(item.content)) {
this.onPreviewImage(item);
}
}}
/>
<Icon
name="delete"
class={bem('preview-delete')}
onClick={() => {
this.onDelete(file, index);
this.onDelete(item, index);
}}
/>
</div>

View File

@ -68,4 +68,19 @@
background-color: @uploader-delete-background-color;
}
}
&__file-icon {
color: @gray-darker;
font-size: 20px;
}
&__file-name {
box-sizing: border-box;
width: 100%;
margin-top: 5px;
padding: 0 5px;
color: @gray-darker;
font-size: 12px;
text-align: center;
}
}

View File

@ -22,7 +22,7 @@ exports[`max-count prop 1`] = `
<div class="van-uploader">
<div class="van-uploader__wrapper">
<div class="van-uploader__preview">
<div class="van-image van-uploader__preview-image"><img src="test" class="van-image__img" style="object-fit: cover;">
<div class="van-image van-uploader__preview-image"><img src="data:image/test" class="van-image__img" style="object-fit: cover;">
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
<!----></i></div>
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
@ -32,11 +32,29 @@ exports[`max-count prop 1`] = `
</div>
`;
exports[`preview not image file 1`] = `
<div class="van-uploader">
<div class="van-uploader__wrapper">
<div class="van-uploader__preview">
<div class="van-image van-uploader__preview-image">
<div class="van-image__error"><i class="van-icon van-icon-description van-uploader__file-icon" style="">
<!----></i>
<div class="van-uploader__file-name van-ellipsis">test.md</div>
</div>
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
<!----></i>
</div>
<div class="van-uploader__upload"><i class="van-icon van-icon-plus van-uploader__upload-icon">
<!----></i><input type="file" accept="image/*" class="van-uploader__input"></div>
</div>
</div>
`;
exports[`preview-size prop 1`] = `
<div class="van-uploader">
<div class="van-uploader__wrapper">
<div class="van-uploader__preview" style="">
<div class="van-image van-uploader__preview-image" style="width: 30px; height: 30px;"><img src="test" class="van-image__img" style="object-fit: cover;">
<div class="van-image van-uploader__preview-image" style="width: 30px; height: 30px;"><img src="data:image/test" class="van-image__img" style="object-fit: cover;">
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
<!----></i></div>
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
@ -52,7 +70,7 @@ exports[`render preview image 1`] = `
<div class="van-uploader">
<div class="van-uploader__wrapper">
<div class="van-uploader__preview">
<div class="van-image van-uploader__preview-image"><img src="test" class="van-image__img" style="object-fit: cover;">
<div class="van-image van-uploader__preview-image"><img src="data:image/test" class="van-image__img" style="object-fit: cover;">
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
<!----></i></div>
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">

View File

@ -5,22 +5,23 @@ window.File = function () {
this.size = 10000;
};
const mockFileDataUrl = 'data:image/test';
const mockFile = new File([], '/Users');
const file = { target: { files: [mockFile] } };
const multiFile = { target: { files: [mockFile, mockFile] } };
window.FileReader = function () {
this.readAsText = function () {
this.onload &&
this.onload({
target: {
result: 'test'
result: mockFileDataUrl
}
});
};
this.readAsDataURL = this.readAsText;
};
const mockFile = new File([], '/Users');
const file = { target: { files: [mockFile] } };
const multiFile = { target: { files: [mockFile, mockFile] } };
test('disabled', () => {
const afterRead = jest.fn();
const wrapper = mount(Uploader, {
@ -39,7 +40,7 @@ it('read text', done => {
propsData: {
resultType: 'text',
afterRead: readFile => {
expect(readFile.content).toEqual('test');
expect(readFile.content).toEqual(mockFileDataUrl);
done();
}
}
@ -276,5 +277,26 @@ it('click to preview image', async () => {
wrapper.find('.van-image').trigger('click');
expect(document.querySelector('.van-image-preview')).toBeTruthy();
const imagePreviewNode = document.querySelector('.van-image-preview');
expect(imagePreviewNode).toBeTruthy();
imagePreviewNode.remove();
});
it('preview not image file', async () => {
const wrapper = mount(Uploader, {
propsData: {
fileList: [{
content: 'data:application',
file: {
name: 'test.md'
}
}]
}
});
wrapper.find('img').trigger('error');
wrapper.find('.van-image').trigger('click');
expect(document.querySelector('.van-image-preview')).toBeFalsy();
expect(wrapper).toMatchSnapshot();
});