Skip to content

Commit

Permalink
Fix bugs discovered during code review
Browse files Browse the repository at this point in the history
Signed-off-by: Olga Bulat <obulat@gmail.com>
  • Loading branch information
obulat committed Mar 17, 2024
1 parent 4ab6f09 commit 07088d5
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 119 deletions.
66 changes: 0 additions & 66 deletions frontend/src/composables/use-collection.ts

This file was deleted.

9 changes: 7 additions & 2 deletions frontend/src/composables/use-search-type.ts
Expand Up @@ -11,7 +11,6 @@ import {
SearchType,
} from "~/constants/media"

import { useMediaStore } from "~/stores/media"
import { useSearchStore } from "~/stores/search"
import { useFeatureFlagStore } from "~/stores/feature-flag"

Expand Down Expand Up @@ -65,8 +64,14 @@ export default function useSearchType() {
next: searchType,
component: componentName,
})

// `setActiveType` is called after the search middleware
// ran and updated the search store state
// TODO: Figure out why
if (activeType.value === searchType) {
return
}
useSearchStore().setSearchType(searchType)
useMediaStore().clearMedia()
previousSearchType.value = searchType
}

Expand Down
74 changes: 54 additions & 20 deletions frontend/src/pages/audio/collection.vue
Expand Up @@ -4,22 +4,29 @@
v-if="collectionParams"
search-term=""
:is-fetching="isFetching"
:results="results"
:results="{ type: 'audio', items: media }"
:collection-label="collectionLabel"
:collection-params="collectionParams"
@load-more="handleLoadMore"
@load-more="loadMore"
/>
</div>
</template>

<script lang="ts">
import { defineComponent, useFetch, useMeta } from "@nuxtjs/composition-api"
import { computed } from "vue"
import {
defineComponent,
useFetch,
useMeta,
useRoute,
} from "@nuxtjs/composition-api"
import { computed, ref, watch } from "vue"
import { collectionMiddleware } from "~/middleware/collection"
import { useSearchStore } from "~/stores/search"
import { useCollection } from "~/composables/use-collection"
import { AUDIO } from "~/constants/media"
import { useMediaStore } from "~/stores/media"
import type { AudioDetail } from "~/types/media"
import { useI18n } from "~/composables/use-i18n"
import VCollectionResults from "~/components/VSearchResultsGrid/VCollectionResults.vue"
Expand All @@ -29,36 +36,63 @@ export default defineComponent({
layout: "content-layout",
middleware: collectionMiddleware,
setup() {
const mediaStore = useMediaStore()
const searchStore = useSearchStore()
const collectionParams = computed(() => searchStore.collectionParams)
const isFetching = computed(() => mediaStore.fetchState.isFetching)
const {
results,
creatorUrl,
fetchMedia,
handleLoadMore,
collectionLabel,
isFetching,
} = useCollection({
mediaType: AUDIO,
const media = ref<AudioDetail[]>([])
const creatorUrl = ref<string>()
const i18n = useI18n()
const collectionLabel = computed(() => {
if (!collectionParams.value) {
return ""
}
const { collection, ...params } = collectionParams.value
return i18n
.t(`collection.label.${collection}.audio`, { ...params })
.toString()
})
const fetchMedia = async (
{ shouldPersistMedia }: { shouldPersistMedia: boolean } = {
shouldPersistMedia: false,
}
) => {
media.value = (await mediaStore.fetchMedia({
shouldPersistMedia,
})) as (typeof media)["value"]
creatorUrl.value =
media.value.length > 0 ? media.value[0].creator_url : undefined
}
const loadMore = () => {
fetchMedia({ shouldPersistMedia: true })
}
useMeta({
meta: [{ hid: "robots", name: "robots", content: "all" }],
})
useFetch(async () => {
await fetchMedia()
})
useMeta({
meta: [{ hid: "robots", name: "robots", content: "all" }],
// Fetch media when the route changes, e.g. when the user navigates from
// a creator collection page to a source collection page.
const route = useRoute()
watch(route, () => {
fetchMedia()
})
return {
results,
collectionParams,
isFetching,
creatorUrl,
media,
collectionLabel,
handleLoadMore,
loadMore,
}
},
head: {},
Expand Down
68 changes: 51 additions & 17 deletions frontend/src/pages/image/collection.vue
Expand Up @@ -4,22 +4,28 @@
v-if="collectionParams"
search-term=""
:is-fetching="isFetching"
:results="results"
:results="{ type: 'image', items: media }"
:collection-label="collectionLabel"
:collection-params="collectionParams"
@load-more="handleLoadMore"
@load-more="loadMore"
/>
</div>
</template>

<script lang="ts">
import { defineComponent, useFetch, useMeta } from "@nuxtjs/composition-api"
import { computed } from "vue"
import {
defineComponent,
useFetch,
useMeta,
useRoute,
} from "@nuxtjs/composition-api"
import { computed, ref, watch } from "vue"
import { collectionMiddleware } from "~/middleware/collection"
import { useCollection } from "~/composables/use-collection"
import { useMediaStore } from "~/stores/media"
import { useSearchStore } from "~/stores/search"
import { IMAGE } from "~/constants/media"
import type { ImageDetail } from "~/types/media"
import { useI18n } from "~/composables/use-i18n"
import VCollectionResults from "~/components/VSearchResultsGrid/VCollectionResults.vue"
Expand All @@ -29,21 +35,42 @@ export default defineComponent({
layout: "content-layout",
middleware: collectionMiddleware,
setup() {
const mediaStore = useMediaStore()
const searchStore = useSearchStore()
const collectionParams = computed(() => searchStore.collectionParams)
const isFetching = computed(() => mediaStore.fetchState.isFetching)
const {
results,
creatorUrl,
fetchMedia,
handleLoadMore,
collectionLabel,
isFetching,
} = useCollection({
mediaType: IMAGE,
const media = ref<ImageDetail[]>([])
const creatorUrl = ref<string>()
const i18n = useI18n()
const collectionLabel = computed(() => {
if (!collectionParams.value) {
return ""
}
const { collection, ...params } = collectionParams.value
return i18n
.t(`collection.label.${collection}.image`, { ...params })
.toString()
})
const fetchMedia = async (
{ shouldPersistMedia }: { shouldPersistMedia: boolean } = {
shouldPersistMedia: false,
}
) => {
media.value = (await mediaStore.fetchMedia({
shouldPersistMedia,
})) as (typeof media)["value"]
creatorUrl.value =
media.value.length > 0 ? media.value[0].creator_url : undefined
}
const loadMore = () => {
fetchMedia({ shouldPersistMedia: true })
}
useMeta({
meta: [{ hid: "robots", name: "robots", content: "all" }],
})
Expand All @@ -52,13 +79,20 @@ export default defineComponent({
await fetchMedia()
})
// Fetch media when the route changes, e.g. when the user navigates from
// a creator collection page to a source collection page.
const route = useRoute()
watch(route, () => {
fetchMedia()
})
return {
collectionParams,
results,
isFetching,
creatorUrl,
collectionLabel,
handleLoadMore,
loadMore,
media,
}
},
head: {},
Expand Down
14 changes: 3 additions & 11 deletions frontend/src/pages/search.vue
Expand Up @@ -147,23 +147,15 @@ export default defineComponent({
const isFetching = computed(() => fetchState.value.isFetching)
/**
* Search middleware runs when the path changes. This watcher
* is necessary to handle the query changes.
*
* It updates the search store state from the URL query,
* fetches media, and scrolls to top if necessary.
* The search middleware updates the search store on every path or query
* change.
* This watcher fetches media, and scrolls to top if necessary.
*/
watch(route, async (newRoute, oldRoute) => {
if (
newRoute.path !== oldRoute.path ||
!isShallowEqualObjects(newRoute.query, oldRoute.query)
) {
const { query: urlQuery, path } = newRoute
searchStore.setSearchStateFromUrl({ urlQuery, path })
const mediaStore = useMediaStore()
mediaStore.clearMedia()
/**
* By default, Nuxt only scrolls to top when the path changes.
* This is a workaround to scroll to top when the query changes.
Expand Down
3 changes: 0 additions & 3 deletions frontend/src/stores/media/index.ts
Expand Up @@ -416,9 +416,6 @@ export const useMediaStore = defineStore("media", {
async fetchMedia(payload: { shouldPersistMedia?: boolean } = {}) {
const mediaType = this._searchType
const shouldPersistMedia = Boolean(payload.shouldPersistMedia)
if (!shouldPersistMedia) {
this.clearMedia()
}

const mediaToFetch = this._fetchableMediaTypes

Expand Down

0 comments on commit 07088d5

Please sign in to comment.