diff --git a/contentcuration/contentcuration/frontend/shared/utils/icons.js b/contentcuration/contentcuration/frontend/shared/utils/icons.js new file mode 100644 index 0000000000..5fbe2f3ff4 --- /dev/null +++ b/contentcuration/contentcuration/frontend/shared/utils/icons.js @@ -0,0 +1,30 @@ +import camelCase from 'lodash/camelCase'; +import { ContentKindsNames } from 'shared/leUtils/ContentKinds'; + +const EMPTY = '_empty'; +const CONTENT_KIND_ICONS = { + [ContentKindsNames.TOPIC]: 'topic', + [ContentKindsNames.TOPIC + EMPTY]: 'emptyTopic', + [ContentKindsNames.VIDEO]: 'video', + [ContentKindsNames.AUDIO]: 'audio', + [ContentKindsNames.SLIDESHOW]: 'slideshow', + [ContentKindsNames.EXERCISE]: 'exercise', + [ContentKindsNames.DOCUMENT]: 'document', + [ContentKindsNames.HTML5]: 'html5', + [ContentKindsNames.ZIM]: 'html5', +}; + +export function getContentKindIcon(kind, isEmpty = false) { + const icon = (isEmpty ? [kind + EMPTY] : []).concat([kind]).find(k => k in CONTENT_KIND_ICONS); + return icon ? CONTENT_KIND_ICONS[icon] : 'error'; +} + +export function getLearningActivityIcon(activity) { + if (activity.toLowerCase() === 'explore') { + return 'interactShaded'; + } else if (activity === 'multiple') { + return 'allActivities'; + } else { + return `${camelCase(activity) + 'Solid'}`; + } +} diff --git a/contentcuration/contentcuration/frontend/shared/views/channel/ChannelThumbnail.vue b/contentcuration/contentcuration/frontend/shared/views/channel/ChannelThumbnail.vue index d8a5a07d84..25d4a7fbb3 100644 --- a/contentcuration/contentcuration/frontend/shared/views/channel/ChannelThumbnail.vue +++ b/contentcuration/contentcuration/frontend/shared/views/channel/ChannelThumbnail.vue @@ -16,7 +16,7 @@ > <VCard ref="thumbnail" - class="thumbnail" + class="thumbnail-wrapper" data-test="loading" > <VLayout @@ -355,7 +355,7 @@ border: 2px solid var(--v-grey-darken2); } - .thumbnail { + .thumbnail-wrapper { padding: 28% 0; /* stylelint-disable-next-line custom-property-pattern */ border-color: var(--v-greyBorder-base) !important; diff --git a/contentcuration/contentcuration/frontend/shared/views/files/Thumbnail.vue b/contentcuration/contentcuration/frontend/shared/views/files/Thumbnail.vue index 98caf3423e..fc57eb8579 100644 --- a/contentcuration/contentcuration/frontend/shared/views/files/Thumbnail.vue +++ b/contentcuration/contentcuration/frontend/shared/views/files/Thumbnail.vue @@ -6,11 +6,12 @@ [kind]: compact, 'icon-only': compact, nothumbnail: !showThumbnail && !compact, + 'with-caption': showCaption, }" :style="{ 'max-width': maxWidth }" > <VLayout - v-if="kind && !printing && showKind && !compact" + v-if="showCaption" tag="figcaption" row align-center @@ -21,12 +22,10 @@ shrink class="px-1" > - <VIconWrapper - v-if="!compact" - dark - small - :aria-label="kindTitle" - v-text="icon" + <KIcon + :icon="icon" + class="icon-thumbnail" + :style="{ fill: '#ffffff' }" /> </VFlex> <VFlex shrink> @@ -46,42 +45,39 @@ v-else-if="printing" class="printable-icon" > - <VIconWrapper + <!-- <VIconWrapper :color="$vuetify.theme[kind]" capture-as-image > {{ icon }} - </VIconWrapper> + </VIconWrapper> --> + <KIcon + class="icon-thumbnail" + :icon="icon" + /> </div> <!-- Bury icon within SVG so it's more responsive, since font-size scaling is more difficult --> - <svg + <div v-else-if="compact" - viewBox="0 0 24 24" - :aria-label="kindTitle" - class="thumbnail-image" + class="kicon-wrapper" > <KIcon - icon="infoOutline" - :x="+10" - :y="y + 20" + :icon="icon" + class="icon-thumbnail" :style="{ fill: '#ffffff' }" /> - </svg> - <svg + </div> + <div v-else - viewBox="0 0 40 40" - :aria-label="kindTitle" - class="nothumbnail-image" - :class="$isRTL ? 'rtl-image' : 'ltr-image'" + class="kicon-wrapper" > <KIcon icon="image" - :x="-3" - :y="y - 14" - :style="{ fill: '#999999' }" + class="icon-thumbnail" + :style="{ fill: '#999999', fontSize: '3em' }" /> - </svg> + </div> </figure> </template> @@ -89,8 +85,8 @@ <script> + import { getContentKindIcon } from 'shared/utils/icons'; import { constantsTranslationMixin, printingMixin } from 'shared/mixins'; - import { getContentKindIcon } from 'shared/vuetify/icons'; export default { name: 'Thumbnail', @@ -136,22 +132,15 @@ }, }, computed: { - y() { - switch (this.kind) { - case 'exercise': - return 28; - case 'topic': - case 'audio': - default: - return 26; - } - }, objectFit() { return this.kind ? 'cover' : 'contain'; }, icon() { return getContentKindIcon(this.kind, this.isEmpty); }, + showCaption() { + return this.kind && !this.printing && this.showKind && !this.compact; + }, thumbnailSrc() { return this.encoding && this.encoding.base64 ? this.encoding.base64 : this.src; }, @@ -296,4 +285,23 @@ } } + .kicon-wrapper { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + + .icon-thumbnail { + top: 0; + } + } + + .thumbnail.with-caption { + .kicon-wrapper { + height: calc(100% - #{$caption-height}); + } + } + </style>