Skip to content

Commit

Permalink
Use script setup and t from useNuxtApp.$i18n
Browse files Browse the repository at this point in the history
Signed-off-by: Olga Bulat <[email protected]>

layout

Signed-off-by: Olga Bulat <[email protected]>
  • Loading branch information
obulat committed Feb 4, 2024
1 parent f9e4d49 commit d3bcfd4
Show file tree
Hide file tree
Showing 85 changed files with 3,702 additions and 4,261 deletions.
6 changes: 6 additions & 0 deletions frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ export default defineNuxtConfig({
* Disable debug mode to prevent excessive timing logs.
*/
debug: false,
experimental: {
/**
* Improve router performance, see https://nuxt.com/blog/v3-10#%EF%B8%8F-build-time-route-metadata
*/
scanPageMeta: true,
},
modules: [
"@pinia/nuxt",
"@nuxtjs/i18n",
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
},
"devDependencies": {
"@nuxt/test-utils": "^3.9.0",
"@nuxtjs/i18n": "8.0.1",
"@nuxtjs/i18n": "npm:@nuxtjs/i18n-edge@8.0.1-28448146.2145ce5",
"@playwright/test": "1.40.1",
"@testing-library/user-event": "^14.5.2",
"@testing-library/vue": "^8.0.1",
Expand Down
32 changes: 8 additions & 24 deletions frontend/src/app.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
<template>
<div>
<Html :lang="head.htmlAttrs.lang" :dir="head.htmlAttrs.dir" />
<Body>
<div :class="[isDesktopLayout ? 'desktop' : 'mobile', breakpoint]">
<VSkipToContentButton />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<VGlobalAudioSection />
</div>
<div id="modal"></div>
</Body>
<div :class="[isDesktopLayout ? 'desktop' : 'mobile', breakpoint]">
<VSkipToContentButton />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<VGlobalAudioSection />
</div>
<div id="modal"></div>
</template>

<script setup lang="ts">
import {
computed,
onMounted,
useRoute,
useCookie,
useLocaleHead,
} from "#imports"
import { computed, onMounted, useRoute, useCookie } from "#imports"
import { useUiStore } from "~/stores/ui"
import { useFeatureFlagStore } from "~/stores/feature-flag"
Expand All @@ -31,11 +20,6 @@ import type { OpenverseCookieState } from "~/types/cookies"
import VSkipToContentButton from "~/components/VSkipToContentButton.vue"
const head = useLocaleHead({
addDirAttribute: true,
identifierAttribute: "id",
})
/**
* Lifecycle hooks in async setup should be called before the first await.
*/
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/components/VAudioDetails/VRelatedAudio.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
<template>
<section v-if="showRelated">
<h2 class="heading-6 lg:heading-6 mb-6">
{{ $t("audioDetails.relatedAudios") }}
{{ t("audioDetails.relatedAudios") }}
</h2>
<VAudioCollection
:results="media"
kind="related"
:collection-label="$t('audioDetails.relatedAudios')"
:collection-label="t('audioDetails.relatedAudios')"
class="mb-12"
/>
</section>
</template>

<script setup lang="ts">
import { useNuxtApp } from "#imports"
import { computed, toRef, watch } from "vue"
import { useRelatedMediaStore } from "~/stores/media/related-media"
Expand All @@ -24,6 +26,9 @@ import VAudioCollection from "~/components/VSearchResultsGrid/VAudioCollection.v
const props = defineProps<{
mediaId: string
}>()
const {
$i18n: { t },
} = useNuxtApp()
const relatedMediaStore = useRelatedMediaStore()
Expand Down
177 changes: 90 additions & 87 deletions frontend/src/components/VAudioTrack/VAudioControl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:size="buttonSize"
:variant="layout === 'box' ? 'transparent-dark' : 'filled-dark'"
:icon-props="icon === undefined ? undefined : { name: icon, size: iSize }"
:label="$t(label)"
:label="t(label)"
:connections="connections"
:disabled="!doneHydrating"
@click.stop.prevent="handleClick"
Expand All @@ -31,8 +31,10 @@
</VIconButton>
</template>

<script lang="ts">
import { computed, defineComponent, PropType } from "vue"
<script setup lang="ts">
import { useNuxtApp } from "#imports"
import { computed } from "vue"
import {
AudioLayout,
Expand All @@ -41,11 +43,12 @@ import {
audioStatuses,
statusVerbMap,
} from "~/constants/audio"
import { defineEvent } from "~/types/emits"
import type { ButtonConnections } from "~/types/button"
import { useHydrating } from "~/composables/use-hydrating"
import { warn } from "~/utils/console"
import VIconButton from "~/components/VIconButton/VIconButton.vue"
const statusIconMap = {
Expand Down Expand Up @@ -77,105 +80,105 @@ const sizes = {
* Displays the control for switching between the playing and paused states of
* a media file.
*/
export default defineComponent({
name: "VAudioControl",
components: { VIconButton },
model: {
prop: "status",
event: "toggle",
},
props: {
const props = withDefaults(
defineProps<{
/**
* the current play status of the audio
*/
status: {
type: String as PropType<AudioStatus>,
required: true,
validator: (val: string) =>
(audioStatuses as readonly string[]).includes(val),
},
status: AudioStatus
/**
* The size of the button. The size affects both the size of the button
* itself and the icon inside it.
*/
size: {
type: String as PropType<"small" | "medium" | "large">,
required: true,
validator: (val: string) => ["small", "medium", "large"].includes(val),
},
size: "small" | "medium" | "large"
/**
* The parent audio layout currently in use. The connections are determined
* by the layout and the size of the button.
*/
layout: {
type: String as PropType<AudioLayout>,
default: "full",
validator: (val: string) =>
(audioLayouts as readonly string[]).includes(val),
},
layout?: AudioLayout
/**
* Whether the audio control button can be focused by using the `Tab` key
*/
isTabbable: {
type: Boolean,
default: true,
},
},
emits: {
toggle: defineEvent<["paused" | "playing"]>(),
},
setup(props, { emit }) {
const isPlaying = computed(() => props.status === "playing")
const isLoading = computed(() => props.status === "loading")
/**
* Get the button label based on the current status of the player.
*/
const label = computed(() => `playPause.${statusVerbMap[props.status]}`)
/**
* Get the button icon based on the current status of the player.
*/
const icon = computed(() => statusIconMap[props.status])
isTabbable?: boolean
}>(),
{
layout: "full",
isTabbable: true,
}
)
/**
* Set the connections (none-rounded corners) for the button based on the layout.
*/
const connections = computed(() => {
return props.layout === "row" && props.size === "small"
? []
: [...layoutConnectionsMap[props.layout]]
})
/** Convert the `audio-control` sizes to `VIconButton` sizes */
const buttonSize = computed(() => sizes[props.size].button)
const iSize = computed(() => sizes[props.size].icon)
const handleMouseDown = (event: MouseEvent) => {
if (!props.isTabbable) {
// to prevent focus
event.preventDefault()
}
}
const handleClick = () => {
emit("toggle", isPlaying.value || isLoading.value ? "paused" : "playing")
}
const { doneHydrating } = useHydrating()
return {
label,
icon,
connections,
buttonSize,
iSize,
isLoading,
handleClick,
handleMouseDown,
doneHydrating,
}
},
const validateStatus = (val: string) => {
return (audioStatuses as readonly string[]).includes(val)
}
if (!validateStatus(props.status)) {
warn(
`VAudioControl: The prop 'status' must be one of ${audioStatuses.join(
", "
)}.`
)
}
const validateSize = (val: string) => {
return ["small", "medium", "large"].includes(val)
}
if (!validateSize(props.size)) {
warn(
`VAudioControl: The prop 'size' must be one of 'small', 'medium' or 'large'.`
)
}
const validateLayout = (val: string) => {
return (audioLayouts as readonly string[]).includes(val)
}
if (!validateLayout(props.layout)) {
warn(
`VAudioControl: The prop 'layout' must be one of ${audioLayouts.join(
", "
)}.`
)
}
const emit = defineEmits<{
toggle: ["paused" | "playing"]
}>()
const {
$i18n: { t },
} = useNuxtApp()
const isPlaying = computed(() => props.status === "playing")
const isLoading = computed(() => props.status === "loading")
/**
* Get the button label based on the current status of the player.
*/
const label = computed(() => `playPause.${statusVerbMap[props.status]}`)
/**
* Get the button icon based on the current status of the player.
*/
const icon = computed(() => statusIconMap[props.status])
/**
* Set the connections (none-rounded corners) for the button based on the layout.
*/
const connections = computed(() => {
return props.layout === "row" && props.size === "small"
? []
: [...layoutConnectionsMap[props.layout]]
})
/** Convert the `audio-control` sizes to `VIconButton` sizes */
const buttonSize = computed(() => sizes[props.size].button)
const iSize = computed(() => sizes[props.size].icon)
const handleMouseDown = (event: MouseEvent) => {
if (!props.isTabbable) {
// to prevent focus
event.preventDefault()
}
}
const handleClick = () => {
emit("toggle", isPlaying.value || isLoading.value ? "paused" : "playing")
}
const { doneHydrating } = useHydrating()
</script>

<style scoped>
Expand Down
Loading

0 comments on commit d3bcfd4

Please sign in to comment.