PronounsPage/components/ExampleCategoryListItem.vue

90 lines
3.1 KiB
Vue

<script setup lang="ts">
import type { ExampleCategory, PronounExample, Pronoun } from '~/src/classes.ts';
import { randomItem } from '~/src/helpers.ts';
const props = withDefaults(defineProps<{
exampleCategory: ExampleCategory;
pronounsChoice: Pronoun[];
counter?: number;
link?: boolean;
showPronunciation?: boolean;
}>(), {
counter: 0,
});
const { $translator: translator } = useNuxtApp();
const pronounExample = ref(props.exampleCategory.examples[0]);
const example = computed(() => {
if (pronoun.value === undefined) {
return pronounExample.value.singular;
}
return pronounExample.value.example(pronoun.value, props.counter);
});
const pronoun = ref<Pronoun | undefined>();
const exampleValues = computed(() => pronoun.value?.toExampleValues(props.counter));
const suitablePronounExamples = computed((): PronounExample[] => {
return props.exampleCategory.examples.filter((pronounExample) => {
return props.pronounsChoice.some((pronoun) => {
const example = pronounExample.example(pronoun, props.counter);
return example.areRequiredExampleValuesPresent(pronoun.toExampleValues(props.counter));
});
});
});
const hasDifferentExample = computed((): boolean => {
return props.pronounsChoice.length > 1 || suitablePronounExamples.value.length > 1;
});
const tooltipText = computed((): string => {
if (props.exampleCategory.name) {
return translator.translate('pronouns.examples.shuffleNamed', { category: props.exampleCategory.name });
}
return translator.translate('pronouns.examples.shuffle');
});
const selectDifferentExample = (): void => {
const changeExample = suitablePronounExamples.value.length > 1;
if (changeExample) {
const differentPronounExamples = suitablePronounExamples.value.filter((otherExample) => {
return otherExample !== toRaw(pronounExample.value);
});
pronounExample.value = randomItem(differentPronounExamples);
}
selectPronounForExample(!changeExample);
};
const selectPronounForExample = (forceDifferent: boolean): void => {
const suitablePronouns = props.pronounsChoice.filter((otherPronoun) => {
return example.value.areRequiredExampleValuesPresent(otherPronoun.toExampleValues()) &&
(!forceDifferent || otherPronoun !== toRaw(pronoun.value));
});
pronoun.value = randomItem(suitablePronouns);
};
selectPronounForExample(false);
</script>
<template>
<li v-if="pronoun !== undefined && exampleValues !== undefined" class="my-1">
<ExampleItem :example :example-values :show-pronunciation>
<small v-if="link">
(<nuxt-link :to="`/${pronoun.canonicalName}`"><Spelling escape :text="pronoun.canonicalName" /></nuxt-link>)
</small>
</ExampleItem>
<Tooltip :text="tooltipText">
<button
v-if="hasDifferentExample"
type="button"
class="btn btn-sm btn-link px-1 py-0"
@click="selectDifferentExample()"
>
<Icon v="random" />
</button>
</Tooltip>
</li>
</template>