Skip to content

Commit

Permalink
Add source links to creator pages (#3780)
Browse files Browse the repository at this point in the history
* Add source links to creator pages

Signed-off-by: Olga Bulat <obulat@gmail.com>

* Update frontend/src/components/VCollectionHeader/VCollectionHeader.vue

* Update collection header

Signed-off-by: Olga Bulat <obulat@gmail.com>

* Add changes from code review

Signed-off-by: Olga Bulat <obulat@gmail.com>

* Update snapshots

Signed-off-by: Olga Bulat <obulat@gmail.com>

* Change to desktop layout after `sm` breakpoint

Signed-off-by: Olga Bulat <obulat@gmail.com>

* Update snapshots

Signed-off-by: Olga Bulat <obulat@gmail.com>

---------

Signed-off-by: Olga Bulat <obulat@gmail.com>
  • Loading branch information
obulat authored Mar 14, 2024
1 parent e9e91b0 commit 07be593
Show file tree
Hide file tree
Showing 20 changed files with 426 additions and 310 deletions.
166 changes: 106 additions & 60 deletions frontend/src/components/VCollectionHeader/VCollectionHeader.vue
Original file line number Diff line number Diff line change
@@ -1,53 +1,83 @@
<template>
<div
class="collection-header grid grid-cols-[1.5rem,1fr] gap-x-2 gap-y-4 md:grid-rows-[auto,auto] md:gap-y-8"
:class="
collection === 'tag'
? 'tags grid-rows-[auto,auto] md:grid-cols-[2.5rem,1fr]'
: 'grid-rows-[auto,auto,auto] md:grid-cols-[2.5rem,1fr,auto]'
"
class="collection-header grid gap-2 sm:grid-cols-[1fr,auto]"
:class="{ 'no-link': !showCollectionExternalLink }"
>
<VIcon :name="iconName" :size="isMd ? 10 : 6" class="icon" />
<h1 class="title text-3xl font-semibold leading-snug md:text-6xl">
{{ title }}
<h1 class="title flex flex-col gap-2 sm:flex-row">
<VIcon
:name="iconName"
:title="collection"
:size="10"
class="icon hidden sm:flex"
/>
<span class="label-regular flex text-dark-charcoal-70 sm:hidden">{{
$t(`collection.heading.${collection}`)
}}</span>
<span class="text-3xl font-semibold leading-snug sm:text-6xl">{{
title
}}</span>
</h1>
<VButton
v-if="collection !== 'tag' && url"
v-if="showCollectionExternalLink"
as="VLink"
variant="filled-dark"
size="medium"
class="button label-bold !flex-none md:ms-4 md:mt-1"
class="link label-bold mt-1 !w-full"
has-icon-end
show-external-icon
:external-icon-size="6"
:href="url"
@click="sendAnalyticsEvent"
>{{ $t(`collection.link.${collection}`) }}</VButton
>
<p
class="results caption-regular md:label-regular mt-2 text-dark-charcoal-70 md:mt-0"
<div
class="results mt-6 flex w-full min-w-0 flex-col items-start gap-1 sm:mt-0 sm:flex-row sm:items-center"
>
{{ resultsLabel }}
</p>
<p
class="label-regular w-max text-dark-charcoal-70 sm:whitespace-nowrap"
:class="{ 'pb-2 sm:pb-0': collection !== 'creator' }"
>
{{ resultsLabel }}
</p>
<VScrollableLine
v-if="collection === 'creator'"
class="-ms-2 -mt-1.5px h-8 w-[calc(100%+theme(space.4))] sm:ms-0"
>
<VButton
as="VLink"
size="disabled"
variant="transparent-gray"
class="label-bold m-1.5px h-8 w-max gap-x-1 whitespace-nowrap p-1"
:href="sourceCollectionLink"
has-icon-start
><VIcon
name="institution"
:title="$t('collection.link.source')"
/><span class="w-max whitespace-nowrap">{{
source.name
}}</span></VButton
>
</VScrollableLine>
</div>
</div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType } from "vue"
import { computed, defineComponent, type PropType } from "vue"
import { useUiStore } from "~/stores/ui"
import type { CollectionParams } from "~/types/search"
import { useAnalytics } from "~/composables/use-analytics"
import { useMediaStore } from "~/stores/media"
import { useProviderStore } from "~/stores/provider"
import { SupportedMediaType } from "~/constants/media"
import { useSearchStore } from "~/stores/search"
import type { CollectionParams } from "~/types/search"
import type { SupportedMediaType } from "~/constants/media"
import { useI18nResultsCount } from "~/composables/use-i18n-utilities"
import { useMediaStore } from "~/stores/media"
import VIcon from "~/components/VIcon/VIcon.vue"
import VButton from "~/components/VButton.vue"
import VScrollableLine from "~/components/VScrollableLine.vue"
const icons = {
tag: "tag",
Expand All @@ -60,7 +90,7 @@ const icons = {
*/
export default defineComponent({
name: "VCollectionHeader",
components: { VIcon, VButton },
components: { VScrollableLine, VIcon, VButton },
props: {
collectionParams: {
type: Object as PropType<CollectionParams>,
Expand All @@ -77,19 +107,28 @@ export default defineComponent({
setup(props) {
const mediaStore = useMediaStore()
const providerStore = useProviderStore()
const uiStore = useUiStore()
const searchStore = useSearchStore()
const iconName = computed(() => icons[props.collectionParams.collection])
const collection = computed(() => props.collectionParams.collection)
const sourceName = computed(() => {
const source = computed(() => {
if (props.collectionParams.collection === "tag") {
return ""
return {
name: "",
link: "",
}
}
return {
name: providerStore.getProviderName(
props.collectionParams.source,
props.mediaType
),
link: providerStore.getSourceUrl(
props.collectionParams.source,
props.mediaType
),
}
return providerStore.getProviderName(
props.collectionParams.source,
props.mediaType
)
})
const title = computed(() => {
Expand All @@ -98,7 +137,7 @@ export default defineComponent({
} else if (props.collectionParams.collection === "creator") {
return props.collectionParams.creator
}
return sourceName.value
return source.value.name
})
const url = computed(() => {
Expand All @@ -107,35 +146,41 @@ export default defineComponent({
} else if (props.collectionParams.collection === "creator") {
return props.creatorUrl
}
return providerStore.getSourceUrl(
props.collectionParams.source,
props.mediaType
)
return source.value.link
})
const sourceCollectionLink = computed(() => {
if (props.collectionParams.collection !== "creator") {
return ""
}
return searchStore.getCollectionPath({
type: props.mediaType,
collectionParams: {
collection: "source",
source: props.collectionParams.source,
},
})
})
const showCollectionExternalLink = computed(() => {
return Boolean(props.collectionParams.collection !== "tag" && url.value)
})
const { getI18nCollectionResultCountLabel } = useI18nResultsCount()
const resultsLabel = computed(() => {
if (mediaStore.resultCount === 0 && mediaStore.fetchState.isFetching) {
return ""
}
const resultsCount = mediaStore.results[props.mediaType].count
if (props.collectionParams.collection === "creator") {
return getI18nCollectionResultCountLabel(
resultsCount,
props.mediaType,
"creator",
{ source: sourceName.value }
)
}
return getI18nCollectionResultCountLabel(
resultsCount,
props.mediaType,
props.collectionParams.collection
)
})
const isMd = computed(() => uiStore.isBreakpoint("md"))
const { sendCustomEvent } = useAnalytics()
const sendAnalyticsEvent = () => {
Expand All @@ -157,9 +202,11 @@ export default defineComponent({
collection,
title,
resultsLabel,
source,
url,
sourceCollectionLink,
showCollectionExternalLink,
iconName,
isMd,
sendAnalyticsEvent,
}
},
Expand All @@ -168,29 +215,28 @@ export default defineComponent({

<style scoped>
.collection-header {
grid-template-areas: "icon title" "button button" "results results";
grid-template-areas: "title" "link" "results";
}
.no-link {
grid-template-areas: "title" "results";
}
@screen md {
@screen sm {
.collection-header {
grid-template-areas: "icon title button" "results results results";
grid-template-rows: minmax(3.75rem, auto) minmax(2rem, auto);
grid-template-areas: "title link" "results results";
}
}
.collection-header.tags {
grid-template-areas: "icon title" "results results";
}
@screen md {
.collection-header.tags {
grid-template-areas: "icon title" "results results";
.no-link {
grid-template-rows: minmax(3.625rem, auto) minmax(2rem, auto);
grid-template-columns: auto;
grid-template-areas: "title" "results";
}
}
.icon {
grid-area: icon;
}
.title {
grid-area: title;
}
.button {
grid-area: button;
.link {
grid-area: link;
}
.results {
grid-area: results;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const imageProviderNames = [

export const AllCollectionsTemplate = (args) => ({
template: `
<div class="wrapper w-full p-2 flex flex-col gap-2 bg-dark-charcoal-06">
<div class="wrapper w-full p-3 flex flex-col gap-4 bg-dark-charcoal-06">
<VCollectionHeader v-for="collection in args.collections" :key="collection.collectionName" v-bind="collection" class="bg-white"/>
</div>`,
components: { VCollectionHeader },
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VCollectionPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:collection-params="collectionParams"
:creator-url="creatorUrl"
:media-type="mediaType"
:class="mediaType === 'image' ? 'mb-4' : 'mb-2'"
class="mb-2 md:mb-3"
/>
<VAudioList
v-if="results.type === 'audio'"
Expand Down
Loading

0 comments on commit 07be593

Please sign in to comment.