Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BACK_TO_TOP event and fire when button is clicked #4953

Merged
merged 15 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions frontend/src/components/VLoadMore.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { useElementVisibility } from "@vueuse/core"
import { useMediaStore } from "~/stores/media"
import { useSearchStore } from "~/stores/search"

import type { ResultKind } from "~/types/result"
import type { Collection } from "~/types/search"
import type { SingleResultProps } from "~/types/collection-component-props"
import type { SupportedSearchType } from "~/constants/media"

Expand All @@ -36,16 +34,9 @@ const { $sendCustomEvent } = useNuxtApp()
const { currentPage } = storeToRefs(mediaStore)

const eventPayload = computed(() => {
let kind: ResultKind =
searchStore.strategy === "default" ? "search" : "collection"
const collectionType = (searchStore.collectionValue as Collection) ?? "null"
return {
searchType: props.searchType,
query: props.searchTerm,
...searchStore.searchParamsForEvent,
resultPage: currentPage.value || 1,
kind,
collectionType,
collectionValue: searchStore.collectionValue ?? "null",
}
})

Expand Down
45 changes: 42 additions & 3 deletions frontend/src/components/VScrollButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<script setup lang="ts">
import { useNuxtApp, useRoute } from "#imports"

import { computed } from "vue"

import { useSearchStore } from "~/stores/search"
import { useMediaStore } from "~/stores/media"

const positionWithoutSidebar = "ltr:right-4 rtl:left-4"
const positionWithSidebar = "ltr:right-[22rem] rtl:left-[22rem]"

Expand All @@ -9,15 +14,49 @@ const props = withDefaults(
{ isFilterSidebarVisible: true }
)

const route = useRoute()
const { $sendCustomEvent } = useNuxtApp()
const searchStore = useSearchStore()
const mediaStore = useMediaStore()

defineEmits<{ tab: [KeyboardEvent] }>()

const SEARCH_ROUTES = ["search-image", "search-audio", "search"]
const ANALYTICS_ROUTES = [
...SEARCH_ROUTES,
"image-collection",
"audio-collection",
]

const hClass = computed(() =>
props.isFilterSidebarVisible ? positionWithSidebar : positionWithoutSidebar
)
const scrollToTop = (e: MouseEvent) => {
const element =
(e.currentTarget as HTMLElement)?.closest("#main-page") || window
const scrollToTop = () => {
const routeName = route.name?.toString().split("__")[0]

if (!routeName || !ANALYTICS_ROUTES.includes(routeName)) {
window.scrollTo({ top: 0, left: 0, behavior: "smooth" })
return
}

const isSearchRoute = routeName && SEARCH_ROUTES.includes(routeName)

const mainPage = document.getElementById("main-page")

const scrollPixels = isSearchRoute ? mainPage?.scrollTop : window.scrollY
const maxScroll = isSearchRoute
? mainPage?.scrollHeight
: document.body.scrollHeight

const element = isSearchRoute ? mainPage || window : window
element.scrollTo({ top: 0, left: 0, behavior: "smooth" })

$sendCustomEvent("BACK_TO_TOP", {
...searchStore.searchParamsForEvent,
resultPage: mediaStore.currentPage,
scrollPixels: scrollPixels ?? -1,
maxScroll: maxScroll ?? -1,
})
}
</script>

Expand Down
12 changes: 12 additions & 0 deletions frontend/src/stores/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import type {
CollectionParams,
PaginatedCollectionQuery,
} from "~/types/search"
import { SearchParamsForEvent } from "~/types/analytics"

import type { LocationQuery, RouteLocationNormalized } from "vue-router"

Expand Down Expand Up @@ -240,6 +241,17 @@ export const useSearchStore = defineStore("search", {
}
}
},
searchParamsForEvent(): SearchParamsForEvent {
return {
kind: this.strategy === "default" ? "search" : "collection",
query: this.searchTerm,
searchType: isSearchTypeSupported(this.searchType)
? this.searchType
: ALL_MEDIA,
collectionType: this.collectionParams?.collection ?? "null",
collectionValue: this.collectionValue ?? "null",
}
},
},
actions: {
getApiRequestQuery(mediaType: SupportedMediaType) {
Expand Down
48 changes: 26 additions & 22 deletions frontend/src/types/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ export type AudioComponent =
| "VAllResultsGrid"

/**
* Common properties related to searches
* on collection pages, added in the
* "Additional Search Views" project.
* Common properties for search and collection events.
*/
type CollectionProperties = {
export type SearchParamsForEvent = {
kind: "search" | "collection"
searchType: SupportedSearchType
query: string

/**
* Common properties related to searches on collection pages, added in the
* "Additional Search Views" project.
*/
/** If a collection page, the type of collection */
collectionType: Collection | "null"
/** A string representing a unique identifier for the collection */
Expand Down Expand Up @@ -101,6 +107,18 @@ export type Events = {
/** The content type being searched (can include All content) */
searchType: SearchType
}
/**
* Description: The user clicks on the "back to top" caret button in the bottom-right of
* the search results page.
*/
BACK_TO_TOP: {
/** The current page of results the user is on. */
resultPage: number
/** The number of pixels the user has scrolled. */
scrollPixels: number
/** The maximum number of pixels the user has scrolled on this page load. */
maxScroll: number
} & SearchParamsForEvent
/**
* Description: Whenever the user scrolls to the end of the results page.
* Useful to evaluate how often users load more results or click
Expand All @@ -114,15 +132,9 @@ export type Events = {
* - Do users find a result before reaching the end of the results?
*/
REACH_RESULT_END: {
/** The media type being searched */
searchType: SupportedSearchType
/** The kind of search reached (a collection, a standard search view, etc.) */
kind: ResultKind
/** The search term */
query: string
/** The current page of results the user is on. */
resultPage: number
} & CollectionProperties
} & SearchParamsForEvent
/**
* Description: The user clicks the CTA button to the external source to use the image
* Questions:
Expand Down Expand Up @@ -269,7 +281,7 @@ export type Events = {
* - How often do searches lead to clicking a result?
* - Are there popular searches that do not result in result selection?
*/
SELECT_SEARCH_RESULT: {
SELECT_SEARCH_RESULT: Omit<SearchParamsForEvent, "searchType" | "kind"> & {
/** The unique ID of the media */
id: string
/** If the result is a related result, provide the ID of the 'original' result */
Expand All @@ -280,13 +292,11 @@ export type Events = {
mediaType: SearchType
/** The slug (not the prettified name) of the provider */
provider: string
/** The search term */
query: string
/** the reasons for why this result is considered sensitive */
sensitivities: string
/** whether the result was blurred or visible when selected by the user */
isBlurred: boolean | "null"
} & CollectionProperties
}
/**
* Description: When a user opens the external sources popover.
* Questions:
Expand All @@ -312,16 +322,10 @@ export type Events = {
* from anyway?
*/
LOAD_MORE_RESULTS: {
/** The media type being searched */
searchType: SearchType
/** The kind of search (a collection, a standard search view, etc.) */
kind: ResultKind
/** The search term */
query: string
/** The current page of results the user is on,
* *before* loading more results.. */
resultPage: number
} & CollectionProperties
} & SearchParamsForEvent
/**
* Description: Whenever the user sets a filter. Filter category and key are the values used in code, not the user-facing filter labels.
* Questions:
Expand Down