Merge pull request #15360 from netchampfaris/marketplaces-fixes

fix(image): New Image component to consistently handle broken images
This commit is contained in:
Faris Ansari 2018-09-10 12:29:50 +05:30 committed by GitHub
commit 80e6cad7ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 14 deletions

View File

@ -28,7 +28,7 @@
<div class="row margin-bottom"> <div class="row margin-bottom">
<div class="col-md-3"> <div class="col-md-3">
<div class="hub-item-image"> <div class="hub-item-image">
<img v-img-src="image"> <base-image :src="image" :alt="title" />
</div> </div>
</div> </div>
<div class="col-md-8"> <div class="col-md-8">

View File

@ -0,0 +1,40 @@
<template>
<div class="hub-image">
<img :src="src" :alt="alt" v-show="!is_loading && !is_broken"/>
<div class="hub-image-loading" v-if="is_loading">
<span class="octicon octicon-cloud-download"></span>
</div>
<div class="hub-image-broken" v-if="is_broken">
<span class="octicon octicon-file-media"></span>
</div>
</div>
</template>
<script>
export default {
name: 'Image',
props: ['src', 'alt'],
data() {
return {
is_loading: true,
is_broken: false
}
},
created() {
this.handle_image();
},
methods: {
handle_image() {
let img = new Image();
img.src = this.src;
img.onload = () => {
this.is_loading = false;
};
img.onerror = () => {
this.is_loading = false;
this.is_broken = true;
};
}
}
};
</script>

View File

@ -15,7 +15,7 @@
</i> </i>
</div> </div>
<div class="hub-card-body"> <div class="hub-card-body">
<img class="hub-card-image" v-img-src="item.image"/> <base-image class="hub-card-image" :src="item.image" :alt="title" />
<div class="hub-card-overlay"> <div class="hub-card-overlay">
<div v-if="is_local" class="hub-card-overlay-body"> <div v-if="is_local" class="hub-card-overlay-body">
<div class="hub-card-overlay-button"> <div class="hub-card-overlay-button">

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="hub-list-item" :data-route="item.route"> <div class="hub-list-item" :data-route="item.route">
<div class="hub-list-left"> <div class="hub-list-left">
<img class="hub-list-image" v-img-src="item.image"> <base-image class="hub-list-image" :src="item.image" />
<div class="hub-list-body ellipsis"> <div class="hub-list-body ellipsis">
<div class="hub-list-title">{{item.item_name}}</div> <div class="hub-list-title">{{item.item_name}}</div>
<div class="hub-list-subtitle ellipsis"> <div class="hub-list-subtitle ellipsis">

View File

@ -7,6 +7,7 @@ import SearchInput from './components/SearchInput.vue';
import DetailView from './components/DetailView.vue'; import DetailView from './components/DetailView.vue';
import DetailHeaderItem from './components/DetailHeaderItem.vue'; import DetailHeaderItem from './components/DetailHeaderItem.vue';
import EmptyState from './components/EmptyState.vue'; import EmptyState from './components/EmptyState.vue';
import Image from './components/Image.vue';
Vue.prototype.__ = window.__; Vue.prototype.__ = window.__;
Vue.prototype.frappe = window.frappe; Vue.prototype.frappe = window.frappe;
@ -17,6 +18,7 @@ Vue.component('search-input', SearchInput);
Vue.component('detail-view', DetailView); Vue.component('detail-view', DetailView);
Vue.component('detail-header-item', DetailHeaderItem); Vue.component('detail-header-item', DetailHeaderItem);
Vue.component('empty-state', EmptyState); Vue.component('empty-state', EmptyState);
Vue.component('base-image', Image);
Vue.directive('route', { Vue.directive('route', {
bind(el, binding) { bind(el, binding) {
@ -51,16 +53,6 @@ const handleImage = (el, src) => {
img.src = src; img.src = src;
} }
Vue.directive('img-src', {
bind(el, binding) {
handleImage(el, binding.value);
},
update(el, binding) {
if (binding.value === binding.oldValue) return;
handleImage(el, binding.value);
}
});
Vue.filter('striphtml', function (text) { Vue.filter('striphtml', function (text) {
return strip_html(text || ''); return strip_html(text || '');
}); });

View File

@ -1,4 +1,5 @@
@import "../../../../frappe/frappe/public/less/variables.less"; @import "variables.less";
@import (reference) "desk.less";
body[data-route^="marketplace/"] { body[data-route^="marketplace/"] {
.layout-side-section { .layout-side-section {
@ -26,6 +27,22 @@ body[data-route^="marketplace/"] {
font-size: @text-medium; font-size: @text-medium;
} }
.hub-image {
height: 200px;
}
.hub-image-loading, .hub-image-broken {
.img-background();
display: flex;
align-items: center;
justify-content: center;
span {
font-size: 32px;
color: @text-extra-muted;
}
}
.progress-bar { .progress-bar {
background-color: #89da28; background-color: #89da28;
} }
@ -136,6 +153,7 @@ body[data-route^="marketplace/"] {
} }
.hub-item-image { .hub-item-image {
position: relative;
border: 1px solid @border-color; border: 1px solid @border-color;
border-radius: 4px; border-radius: 4px;
overflow: hidden; overflow: hidden;