fix(front): content form modals opening and closing

This commit is contained in:
upsiflu 2025-02-07 12:57:19 +01:00
parent 54654c4e13
commit 594a406916
6 changed files with 19 additions and 85 deletions

View File

@ -7,7 +7,6 @@ import { useI18n } from 'vue-i18n'
import useLogger from '~/composables/useLogger' import useLogger from '~/composables/useLogger'
import Textarea from '~/components/ui/Textarea.vue' import Textarea from '~/components/ui/Textarea.vue'
import Button from '~/components/ui/Button.vue'
interface Events { interface Events {
(e: 'update:modelValue', value: string): void (e: 'update:modelValue', value: string): void
@ -48,86 +47,16 @@ const labels = computed(() => ({
const remainingChars = computed(() => props.charLimit - props.modelValue.length) const remainingChars = computed(() => props.charLimit - props.modelValue.length)
const loadPreview = async () => {
isLoadingPreview.value = true
try {
const response = await axios.post('text-preview/', { text: value.value, permissive: props.permissive })
preview.value = response.data.rendered
} catch (error) {
logger.error(error)
}
isLoadingPreview.value = false
}
watchDebounced(value, async () => {
await loadPreview()
}, { immediate: true, debounce: 500 })
watchEffect(async () => {
if (isPreviewing.value) {
if (value.value && !preview.value && !isLoadingPreview.value) {
await loadPreview()
}
}
})
watch(isPreviewing, (to, from) => {
if (from === true) {
textarea.value.focus()
}
}, { flush: 'post' })
onMounted(async () => {
if (props.autofocus) {
await nextTick()
textarea.value.focus()
}
})
</script> </script>
<template> <template>
<Button <Textarea
@click.prevent="isPreviewing = false" ref="textarea"
:aria-pressed="!isPreviewing" v-model="value"
title="write" :required="required || undefined"
> :placeholder="labels.placeholder"
{{ t('components.common.ContentForm.button.write') }} :autofocus = "autofocus || undefined"
</Button> />
<Button
@click.prevent="isPreviewing = true"
:aria-pressed="!isPreviewing"
title="preview"
>
{{ t('components.common.ContentForm.button.preview') }}
</Button>
<template v-if="isPreviewing">
<div
v-if="isLoadingPreview"
class="ui placeholder"
>
<div class="paragraph">
<div class="line" />
<div class="line" />
<div class="line" />
<div class="line" />
</div>
</div>
<p v-else-if="!preview">
{{ t('components.common.ContentForm.empty.noContent') }}
</p>
<sanitized-html
v-else
:html="preview"
/>
</template>
<template v-else>
<Textarea
ref="textarea"
v-model="value"
:required="required"
:placeholder="labels.placeholder"
/>
</template>
<span <span
v-if="charLimit" v-if="charLimit"
:class="['right', 'floated', {'ui danger text': remainingChars < 0}]" :class="['right', 'floated', {'ui danger text': remainingChars < 0}]"

View File

@ -14,8 +14,9 @@ import axios from 'axios'
import useEditConfigs from '~/composables/moderation/useEditConfigs' import useEditConfigs from '~/composables/moderation/useEditConfigs'
import useErrorHandler from '~/composables/useErrorHandler' import useErrorHandler from '~/composables/useErrorHandler'
import Button from '~/components/ui/Button.vue'
import DangerousButton from '~/components/common/DangerousButton.vue' import DangerousButton from '~/components/common/DangerousButton.vue'
import Button from '~/components/ui/Button.vue'
import Card from '~/components/ui/Card.vue' import Card from '~/components/ui/Card.vue'
import Spacer from '~/components/ui/Spacer.vue' import Spacer from '~/components/ui/Spacer.vue'

View File

@ -7,8 +7,11 @@ import { computed, ref, watchEffect } from 'vue'
import { useStore } from '~/store' import { useStore } from '~/store'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import ContentForm from '../common/ContentForm.vue'
import Modal from '~/components/ui/Modal.vue' import Modal from '~/components/ui/Modal.vue'
import Button from '~/components/ui/Button.vue' import Button from '~/components/ui/Button.vue'
import Alert from '~/components/ui/Alert.vue'
interface ReportType { interface ReportType {
anonymous: boolean anonymous: boolean
@ -238,9 +241,9 @@ watchEffect(async () => {
</div> </div>
</div> </div>
<template #actions> <template #actions>
<Button <Button destructive
v-if="canSubmit" v-if="canSubmit"
:class="['ui', 'success', {loading: isLoading}, 'button']" :is-loading="isLoading"
type="submit" type="submit"
form="report-form" form="report-form"
> >

View File

@ -78,13 +78,12 @@ const addToPlaylist = async (playlistId: number, allowDuplicates: boolean) => {
} }
store.dispatch('playlists/fetchOwn') store.dispatch('playlists/fetchOwn')
const playlistIsOpen = store.state.playlists.showModal
</script> </script>
<template> <template>
<Modal <Modal
v-model=playlistIsOpen v-model="store.state.playlists.showModal"
title="t('components.playlists.PlaylistModal.header.addToPlaylist')" :title="t('components.playlists.PlaylistModal.header.addToPlaylist')"
> >
<h4 class="header"> <h4 class="header">
<template v-if="track"> <template v-if="track">

View File

@ -19,6 +19,7 @@
order: 0; order: 0;
outline: none; outline: none;
border: none; border: none;
color: currentcolor;
} }
overflow: hidden; overflow: hidden;

View File

@ -115,11 +115,12 @@ const paginateOptions = computed(() => sortedUniq([12, 30, 50, paginateBy.value]
<Header <Header
:h1="t('views.playlists.List.header.browse')" :h1="t('views.playlists.List.header.browse')"
:action="{ :action="{
onClick: () => store.commit('playlists/showModal', true), onClick: () => { store.commit('playlists/showModal', true) },
text: t('views.playlists.List.button.manage'), text: t('views.playlists.List.button.manage'),
}" }"
icon="bi-music-note-list" icon="bi-music-note-list"
primary primary
:aria-pressed="store.state.playlists.showModal"
/> />
<Layout form flex <Layout form flex
:class="['ui', {'loading': isLoading}, 'form']" :class="['ui', {'loading': isLoading}, 'form']"