Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
All results grid (#618)
Browse files Browse the repository at this point in the history
* Update figma links in README

* Search results title (#577)

* Fix ci tests by restoring scopedSlots param in search results title spec

* Fix search result title casing

* Updated load more button (#578)

* Update `content-types` test with load more button changes

* VHeader (#488)

* Add VHeader stub
Rename VSearchBar and VSearchButton and move to VHeader
Add VLogoLoader to VHeader and adjust header styles

* Extract search route handling into composable, set Logo loading when fetching

* Update pnpm lockfile

* Add VFilterButton (#489)

Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Co-authored-by: Zack Krida <zackkrida@pm.me>

* Add searchbar to header (#491)

Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Co-authored-by: Zack Krida <zackkrida@pm.me>

* Update references to `InputField` to point to `VInputField` (#586)

* New 404 page (#583)

Co-authored-by: Krystle Salazar <krystle.salazar@automattic.com>

Co-authored-by: Zack Krida <zackkrida@pm.me>
Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Co-authored-by: Dhruv Bhanushali <dhruv_b@live.com>
Co-authored-by: Krystle Salazar <krystle.salazar@automattic.com>

* Fix video tab

The media store query.mediaType is null for video, so it's not possible to use it as a key to look up results in the store

* Fix filters e2e tests by opening the sidebar

* Fix openverse.pot after-merge problems

* Fix e2e tests

* Show a generated artwork when the audio thumbnail is absent (#600)

* Fix single result back links

* Fix photo detail test

* Fix photo-details test

* Combine layouts into a single default (#599)

* Add header icons (#604)

* Fix error when `<rect>` dimensions are negative (#605)

* Default to all from the homepage; init

* Add `VContentLink` component (#560)

Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Co-authored-by: Olga Bulat <obulat@gmail.com>

* Prevent unsupported media types causing header errors

* Better video tab fix

* Fix homepage test

* Remove sample audio data (#571)

* Modify "fetchState" mutations to support ALL_MEDIA

* All_MEDIA state working except for SET_MEDIA

* all media state init

* UI suppoort for media count

* wip

* ugh

* Mobile box layout adjustments

* Fix image clicks

* Content links

* Add debugging comment

* Remove dead code

* Result rounded corners

* Update src/utils/srand.js

* Focus states

* Small styling improvements to image grid title and horizontal spacing

* Refactor fetching for all media (#621)

* Refactor all fetching to use getters more

* Disable failing tests

* Revert index/key rename in image cell v-for

Co-authored-by: Zack Krida <zackkrida@pm.me>

* Add a wrapper to FETCH_MEDIA to simplify fetching all content (#640)

Add a wrapper to FETCH_MEDIA to simplify fetching all content

* Double number of skeleton boxes

* Progress

* Remove unused filter display component

* Set query when using filters

* Fix tests

* truncate audio box text

Co-authored-by: Krystle Salazar <krystle.salazar@ciens.ucv.ve>
Co-authored-by: Olga Bulat <obulat@gmail.com>
Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Co-authored-by: Dhruv Bhanushali <dhruv_b@live.com>
Co-authored-by: Krystle Salazar <krystle.salazar@automattic.com>
  • Loading branch information
6 people authored Jan 21, 2022
1 parent c13125e commit f9f549b
Show file tree
Hide file tree
Showing 49 changed files with 782 additions and 570 deletions.
6 changes: 6 additions & 0 deletions nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ export default {
autoprefixer: {},
},
},
// Enables use of IDE debuggers
extend(config, ctx) {
if (ctx.isDev) {
config.devtool = ctx.isClient ? 'source-map' : 'inline-source-map'
}
},
},
storybook: {
port: 6006, // standard port for Storybook
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"author": "sebworks",
"private": true,
"scripts": {
"dev": "pnpm i18n:create-locales-list && pnpm i18n:update-locales && cross-env ENABLE_AUDIO=true nuxt",
"dev": "pnpm i18n:create-locales-list && pnpm i18n:update-locales && cross-env nuxt",
"build": "pnpm i18n:get-translations && nuxt build",
"generate": "nuxt generate",
"start": "nuxt start",
Expand All @@ -22,7 +22,7 @@
"test:watch": "jest --collectCoverage=false --watch",
"test:unit": "jest --collectCoverage=false",
"test:e2e": "playwright test",
"run-server": "cross-env ENABLE_AUDIO=true nuxt build && pnpm start",
"run-server": "cross-env nuxt build && pnpm start",
"e2e:ci": "start-server-and-test run-server http://localhost:8443 test:e2e",
"generate-e2e-tests": "playwright codegen localhost:8443/",
"types": "tsc --noEmit",
Expand All @@ -48,6 +48,7 @@
"@nuxtjs/sitemap": "^2.4.0",
"@nuxtjs/svg": "^0.3.0",
"@popperjs/core": "^2.11.2",
"@tailwindcss/line-clamp": "^0.3.1",
"axios": "^0.21.2",
"axios-mock-adapter": "^1.20.0",
"babel-core": "^7.0.0-bridge.0",
Expand All @@ -72,6 +73,7 @@
"node-html-parser": "^5.1.0",
"nuxt": "^2.15.4",
"reakit-utils": "^0.15.2",
"seeded-rand": "^2.0.1",
"uuid": "^8.3.2",
"vue-i18n": "^8.26.5"
},
Expand Down
16 changes: 16 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/ImageGrid/ImageCell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export default {
if (!event.metaKey && !event.ctrlKey) {
event.preventDefault()
const detailRoute = this.localeRoute({
name: 'photo-detail-page',
name: 'PhotoDetailPage',
params: { id: image.id, location: window.scrollY },
})
this.$router.push(detailRoute)
Expand Down
7 changes: 5 additions & 2 deletions src/components/ImageGrid/ImageGrid.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<template>
<section class="image-grid my-6">
<section class="image-grid -mx-2">
<div class="image-grid__cells">
<ImageCell v-for="(image, index) in images" :key="index" :image="image" />
</div>
<h5 v-if="isError" class="image-grid__notification py-4">
<h5
v-if="isError && !fetchState.isFinished"
class="image-grid__notification py-4"
>
{{ fetchState.fetchingError }}
</h5>
<footer class="px-2">
Expand Down
2 changes: 1 addition & 1 deletion src/components/SearchGridCell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export default {
if (!event.metaKey && !event.ctrlKey) {
event.preventDefault()
const detailRoute = this.localeRoute({
name: 'photo-detail-page',
name: 'PhotoDetailPage',
params: { id: image.id, location: window.scrollY },
})
this.$router.push(detailRoute)
Expand Down
5 changes: 1 addition & 4 deletions src/components/SearchTypeTabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ import { queryStringToSearchType } from '~/utils/search-query-transform'
export default {
name: 'SearchTypeTabs',
data() {
let contentTypes = [IMAGE, AUDIO, VIDEO]
if (process.env.enableAudio) {
contentTypes.unshift(ALL_MEDIA)
}
let contentTypes = [ALL_MEDIA, IMAGE, AUDIO, VIDEO]
return {
contentTypes,
}
Expand Down
17 changes: 15 additions & 2 deletions src/components/SearchTypeToggle.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
<template>
<div class="flex" role="radiogroup" :aria-label="$t('hero.aria.search-type')">
<div
class="flex gap-2"
role="radiogroup"
:aria-label="$t('hero.aria.search-type')"
>
<button
class="toggle-button"
role="radio"
type="button"
:aria-checked="value === 'all'"
@click="$emit('selected', 'image')"
>
{{ $t('hero.search-type.all') }}
</button>
<button
class="toggle-button"
role="radio"
Expand All @@ -10,7 +23,7 @@
{{ $t('hero.search-type.image') }}
</button>
<button
class="toggle-button ms-2"
class="toggle-button"
role="radio"
type="button"
:aria-checked="value === 'audio'"
Expand Down
9 changes: 3 additions & 6 deletions src/components/Skeleton/GridSkeleton.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<template>
<section class="px-10 pb-16">
<div
v-if="isForTab == 'all'"
class="grid gap-4 tab:grid-cols-2 lg:grid-cols-5"
>
<section>
<div v-if="isForTab == 'all'" class="grid gap-4 grid-cols-2 lg:grid-cols-5">
<VBone v-for="idx in numElems" :key="idx" class="square" />
</div>

Expand Down Expand Up @@ -38,7 +35,7 @@ export default {
numElems: {
type: Number,
default: function () {
if (this.isForTab === 'all') return 10
if (this.isForTab === 'all') return 20
if (this.isForTab === 'image') return 30
return 8
},
Expand Down
158 changes: 158 additions & 0 deletions src/components/VAllResultsGrid/VAllResultsGrid.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<template>
<div>
<div
v-if="!noResults"
class="results-grid grid grid-cols-2 lg:grid-cols-5 2xl:grid-cols-6 gap-4 mb-4"
>
<NuxtLink
v-for="[key, item] in results"
:key="key"
:to="{ path: `/search/${key}`, query: $route.query }"
class="lg:col-span-2 focus:bg-white focus:border-tx focus:ring focus:ring-pink focus:outline-none focus:shadow-ring focus:text-black rounded-sm"
>
<VContentLink :results-count="item.count" :media-type="key" />
</NuxtLink>
</div>
<GridSkeleton
v-if="resultsLoading && allMedia.length === 0"
is-for-tab="all"
/>
<div
v-else
class="results-grid grid grid-cols-2 lg:grid-cols-5 2xl:grid-cols-6 gap-4"
>
<div v-for="item in allMedia" :key="item.id">
<VImageCell
v-if="item.frontendMediaType === 'image'"
:key="item.id"
:image="item"
/>
<VAudioCell
v-if="item.frontendMediaType === 'audio'"
:key="item.id"
:audio="item"
/>
</div>
</div>

<template v-if="isError" class="m-auto w-1/2 text-center pt-6">
<h5>{{ errorHeader }}</h5>
<p>{{ fetchState.fetchingError }}</p>
</template>

<VLoadMore
v-if="canLoadMore && !fetchState.isFinished"
class="mt-4"
:is-fetching="resultsLoading"
data-testid="load-more"
@onLoadMore="onLoadMore"
/>
</div>
</template>

<script>
import { computed, defineComponent, useContext } from '@nuxtjs/composition-api'
import VImageCell from '~/components/VAllResultsGrid/VImageCell.vue'
import VAudioCell from '~/components/VAllResultsGrid/VAudioCell.vue'
import VLoadMore from '~/components/VLoadMore.vue'
import srand from '~/utils/srand'
export default defineComponent({
name: 'VAllResultsGrid',
components: { VImageCell, VAudioCell, VLoadMore },
props: ['canLoadMore'],
setup(_, { emit }) {
const { i18n, store } = useContext()
const onLoadMore = () => {
emit('load-more')
}
/** @type {import('@nuxtjs/composition-api').ComputedRef<boolean>} */
const resultsLoading = computed(() => {
return (
Boolean(store.getters['media/fetchState'].fetchingError) ||
store.getters['media/fetchState'].isFetching
)
})
/**
*
* @type { ComputedRef<import('../../store/types').AudioDetail[] | import('../../store/types').ImageDetail[]> }
*/
const allMedia = computed(() => {
// if (resultsLoading.value) return []
const media = store.getters['media/mediaResults']
const mediaKeys = Object.keys(media)
// Seed the random number generator with the ID of
// the first and last search result, so the non-image
// distribution is the same on repeated searches
const rand = srand(Object.keys(media[mediaKeys[0]])[0])
const randomIntegerInRange = (min, max) =>
Math.floor(rand() * (max - min + 1)) + min
/** @type {import('../../store/types').AudioDetail[] | import('../../store/types').ImageDetail[]} */
const newResults = []
// first push all images to the results list
for (const id of Object.keys(media['image'])) {
const item = media['image'][id]
item.frontendMediaType = 'image'
newResults.push(item)
}
// push other items into the list, using a random index.
let nonImageIndex = 1
for (const type of Object.keys(media).slice(1)) {
for (const id of Object.keys(media[type])) {
const item = media[type][id]
item.frontendMediaType = type
newResults.splice(nonImageIndex, 0, item)
if (nonImageIndex > newResults.length + 1) break
nonImageIndex = randomIntegerInRange(
nonImageIndex + 1,
nonImageIndex + 6
)
}
}
return newResults
})
const isError = computed(
() => !!store.getters['media/fetchState'].fetchingError
)
/** @type {import('@nuxtjs/composition-api').ComputedRef<import('../../store/types').FetchState>} */
const fetchState = computed(() => {
return store.getters['media/fetchState']
})
const errorHeader = computed(() => {
const type = i18n.t('browse-page.search-form.audio')
return i18n.t('browse-page.fetching-error', { type })
})
const results = computed(() => {
return Object.entries(store.getters['media/results'])
})
const noResults = computed(
() => fetchState.value.isFinished && allMedia.value.length === 0
)
return {
isError,
errorHeader,
allMedia,
onLoadMore,
fetchState,
resultsLoading,
results,
noResults,
}
},
})
</script>
38 changes: 38 additions & 0 deletions src/components/VAllResultsGrid/VAudioCell.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<NuxtLink
:to="localePath(`/audio/${audio.id}`)"
class="block focus:bg-white focus:border-tx focus:ring focus:ring-pink focus:outline-none focus:shadow-ring rounded-sm"
@click.native="navigateToSinglePage(audio)"
>
<VAudioTrack :audio="audio" layout="box" size="full" />
</NuxtLink>
</template>

<script>
import { useContext, useRouter } from '@nuxtjs/composition-api'
import { defineComponent } from '@vue/composition-api'
import VAudioTrack from '~/components/VAudioTrack/VAudioTrack.vue'
export default defineComponent({
components: { VAudioTrack },
props: ['audio'],
setup() {
const { i18n } = useContext()
const router = useRouter()
const navigateToSinglePage = (audio) => (/** @type MouseEvent */ event) => {
if (!event.metaKey && !event.ctrlKey) {
event.preventDefault()
const detailRoute = i18n.localeRoute({
name: 'AudioDetailPage',
params: { id: audio.id, location: window.scrollY },
})
router.push(detailRoute)
}
}
return {
navigateToSinglePage,
}
},
})
</script>
Loading

0 comments on commit f9f549b

Please sign in to comment.