Skip to content

Commit

Permalink
Add mosaic component
Browse files Browse the repository at this point in the history
  • Loading branch information
jlpereira committed Sep 20, 2023
1 parent 3938e11 commit b00bc15
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 37 deletions.
56 changes: 19 additions & 37 deletions src/components/Gallery/GalleryCarousel/GalleryCarousel.global.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
>
<Transition name="fade">
<img
v-if="currentDepiction.image"
v-if="currentDepiction.imageOriginal"
class="object-cover overflow-hidden h-full w-full absolute top-0 my-0"
:key="currentDepiction.image"
:src="currentDepiction.image"
:key="currentDepiction.imageOriginal"
:src="currentDepiction.imageOriginal"
:alt="currentDepiction.label"
/>
</Transition>
Expand Down Expand Up @@ -37,8 +37,8 @@
</template>

<script setup>
import { onMounted, ref, computed, onBeforeUnmount } from 'vue'
import { makeAPIRequest } from '@/utils'
import { ref, computed, watch, onBeforeUnmount } from 'vue'
import { useGallery } from '../useGallery.js'
const props = defineProps({
depictionId: {
Expand All @@ -57,51 +57,33 @@ const props = defineProps({
}
})
const depictions = ref([])
const { depictions } = useGallery({ props })
const currentIndex = ref(0)
const containerStyle = computed(() => ({ height: props.height }))
const currentDepiction = computed(() => depictions.value[currentIndex.value] || {})
const currentDepiction = computed(
() => depictions.value[currentIndex.value] || {}
)
const isOtu = computed(() => currentDepiction.value.objectType === 'Otu')
const label = computed(() =>
[
currentDepiction.value.objectLabel,
currentDepiction.value.attribution
].join(' ')
[currentDepiction.value.objectLabel, currentDepiction.value.attribution].join(
' '
)
)
let timeout = null
function updateIndex() {
currentIndex.value = (currentIndex.value + 1) % depictions.value.length
}
function makeGalleryImage(depiction) {
return {
objectId: depiction.depiction_object_id,
objectType: depiction.depiction_object_type,
objectLabel: depiction.depiction_object.label,
label: depiction.label,
image: depiction.image.original,
attribution: depiction.attribution?.label || ''
}
}
onMounted(() => {
if (props.depictionId.length) {
makeAPIRequest
.get('/depictions/gallery', {
params: { depiction_id: props.depictionId }
})
.then(({ data }) => {
depictions.value = data.map(makeGalleryImage)
if (props.interval) {
timeout = setInterval(updateIndex, props.interval)
} else {
currentIndex.value = Math.floor(Math.random() * data.length)
}
})
watch(depictions, () => {
if (props.interval) {
clearInterval(timeout)
timeout = setInterval(updateIndex, props.interval)
} else {
currentIndex.value = Math.floor(Math.random() * data.length)
}
})
Expand Down
73 changes: 73 additions & 0 deletions src/components/Gallery/GalleryMosaic/GalleryMosaic.global.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<template>
<div
class="grid gap-2"
:class="!props.wrap && 'grid-flow-col'"
:style="
props.wrap &&
`grid-template-columns: repeat(auto-fit, minmax(${props.imageWidth}, 1fr))`
"
>
<component
v-for="item in depictions"
:key="item.id"
:is="getTagElement(item)"
:to="{
name: 'otus-id',
params: { id: item.objectId }
}"
>
<img
:src="item.imageMedium"
:style="imageStyle"
class="max-w-full my-0 object-cover w-full"
/>
<span
v-if="label"
class="text-sm"
v-html="item.labelAttribution"
/>
</component>
</div>
</template>

<script setup>
import { computed } from 'vue'
import { useGallery } from '../useGallery.js'
const props = defineProps({
depictionId: {
type: Array,
default: () => []
},
imageHeight: {
type: String,
default: '112px'
},
imageWidth: {
type: String,
default: '200px'
},
wrap: {
type: Boolean,
default: false
},
label: {
type: Boolean,
default: false
}
})
const imageStyle = computed(() => ({
height: props.imageHeight
}))
function getTagElement(depiction) {
return depiction.objectType === 'Otu' ? 'RouterLink' : 'div'
}
const { depictions } = useGallery({ props })
</script>
49 changes: 49 additions & 0 deletions src/components/Gallery/useGallery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ref, watch } from 'vue'
import { makeAPIRequest } from '@/utils'

export function useGallery({ props }) {
const depictions = ref([])

function makeGalleryImage(depiction) {
return {
id: depiction.id,
objectId: depiction.depiction_object_id,
objectType: depiction.depiction_object_type,
objectLabel: depiction.depiction_object.label,
label: depiction.label,
imageOriginal: depiction.image.original,
imageMedium: depiction.image.medium,
attribution: depiction.attribution?.label || '',
labelAttribution: [
depiction.depiction_object.label,
depiction.attribution?.label || ''
].join(' ')
}
}

watch(
() => props.depictionId,
(ids) => {
if (ids.length) {
makeAPIRequest
.get('/depictions/gallery', {
params: { depiction_id: ids }
})
.then(({ data }) => {
depictions.value = data
.map(makeGalleryImage)
.sort(
(a, b) =>
props.depictionId.indexOf(a.id) -
props.depictionId.indexOf(b.id)
)
})
}
},
{ immediate: true }
)

return {
depictions
}
}

0 comments on commit b00bc15

Please sign in to comment.