fix: corriger toutes les erreurs de lint restantes (263 -> 0)
This commit is contained in:
@@ -20,7 +20,7 @@ async function jwennAwtis(slug) {
|
||||
}
|
||||
|
||||
export async function generateMetadata(props) {
|
||||
const params = await props.params;
|
||||
const params = await props.params
|
||||
const {slug} = params
|
||||
const anAwtis = await jwennAwtis(slug)
|
||||
|
||||
@@ -64,7 +64,7 @@ export async function generateMetadata(props) {
|
||||
}
|
||||
|
||||
export default async function AwtisPajSlug(props) {
|
||||
const params = await props.params;
|
||||
const params = await props.params
|
||||
const {slug} = params
|
||||
const anAwtis = await jwennAwtis(slug)
|
||||
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ async function jwennDone(paj) {
|
||||
}
|
||||
|
||||
export default async function AwitsPaj(props) {
|
||||
const searchParams = await props.searchParams;
|
||||
const searchParams = await props.searchParams
|
||||
const {paj} = searchParams
|
||||
const {pajTotal, awtisPouChakPaj, pajParsed} = await jwennDone(paj || 1)
|
||||
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ export default async function RootLayout({children}) {
|
||||
)
|
||||
|
||||
return (
|
||||
<html lang='fr' suppressHydrationWarning>
|
||||
<html suppressHydrationWarning lang='fr'>
|
||||
<body>
|
||||
{plausibleUrl
|
||||
? <PlausibleProvider src={plausibleUrl}>{inner}</PlausibleProvider>
|
||||
|
||||
+1
-2
@@ -7,7 +7,6 @@ import Statistik from '../components/akey/statistik'
|
||||
import Akey from '../components/akey'
|
||||
import AnVedette from '../components/akey/an-vedette'
|
||||
|
||||
import okiLogo from '../public/logo-512x512.png'
|
||||
import Footer from '../components/footer'
|
||||
import Aso from '../components/akey/aso'
|
||||
|
||||
@@ -26,7 +25,7 @@ export default async function Page() {
|
||||
|
||||
return (
|
||||
<Box sx={{display: 'flex', flexDirection: 'column', minHeight: '100vh'}}>
|
||||
<Akey logo={okiLogo} />
|
||||
<Akey />
|
||||
<Container sx={{flexGrow: 100}}>
|
||||
{dernierTeks && <AnVedette teks={dernierTeks} />}
|
||||
<Statistik statistik={statistik} />
|
||||
|
||||
@@ -21,10 +21,10 @@ async function jwennAnTeks(slug) {
|
||||
}
|
||||
|
||||
export async function generateMetadata(props) {
|
||||
const params = await props.params;
|
||||
const params = await props.params
|
||||
const {slug} = params
|
||||
|
||||
const anTeks = await jwennAnTeks(slug)
|
||||
const anTeks = await jwennAnTeks(slug)
|
||||
|
||||
const awtis = anTeks?.artistes?.length === 1 ? anTeks?.artistes[0].alias : getAlias(anTeks.artistes, anTeks.prioriteArtistes)
|
||||
const title = `PAWÒL-NU | ${awtis} - ${anTeks.titre}`
|
||||
@@ -67,12 +67,12 @@ export async function generateMetadata(props) {
|
||||
}
|
||||
|
||||
export default async function AnPawolPaj(props) {
|
||||
const params = await props.params;
|
||||
const params = await props.params
|
||||
const {slug} = params
|
||||
|
||||
const anTeks = await jwennAnTeks(slug)
|
||||
const {couverture} = anTeks
|
||||
const teksKuvetiFormat = formatKuveti(couverture)
|
||||
const teksKuvetiFormat = formatKuveti(couverture)
|
||||
|
||||
const jsonLd = {
|
||||
'@context': 'http://schema.org',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {Suspense} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import TeksDrawerLoader from '../../components/teks/teks-drawer-loader'
|
||||
import {CurrentTrackProvider} from '../../components/teks/current-track-context'
|
||||
import Loading from './loading'
|
||||
@@ -50,3 +51,7 @@ export default function PawolLayout({children}) {
|
||||
</CurrentTrackProvider>
|
||||
)
|
||||
}
|
||||
|
||||
PawolLayout.propTypes = {
|
||||
children: PropTypes.node.isRequired
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
export default function robots() {
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
|
||||
if (!isProduction) {
|
||||
return {
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ export default function Sipote() {
|
||||
<Box sx={{display: 'flex', marginTop: 10, flexDirection: 'column', minHeight: '100vh'}}>
|
||||
<Box sx={{flexGrow: 1, marginBottom: 10}}>
|
||||
<Container>
|
||||
<Typography gutterBottom sx={{fontWeight: 'bold', textAlign:'center' }} variant='h4' component='h1'>
|
||||
<Typography gutterBottom sx={{fontWeight: 'bold', textAlign: 'center'}} variant='h4' component='h1'>
|
||||
Soutenir ORGANISATION KA INTERNATIONALE !
|
||||
</Typography>
|
||||
<Paper sx={{padding: 2, marginTop: 3}}>
|
||||
|
||||
@@ -69,13 +69,13 @@ export default function ThemeRegistry(props) {
|
||||
return (
|
||||
<>
|
||||
<InitColorSchemeScript attribute='class' />
|
||||
<NextAppDirEmotionCacheProvider options={{key: 'mui'}}>
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline enableColorScheme />
|
||||
<ChanjeTem />
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</NextAppDirEmotionCacheProvider>
|
||||
<NextAppDirEmotionCacheProvider options={{key: 'mui'}}>
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline enableColorScheme />
|
||||
<ChanjeTem />
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</NextAppDirEmotionCacheProvider>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ export default function AnVedette({teks}) {
|
||||
<Box sx={{position: 'relative', width: '100%', aspectRatio: {xs: '1 / 1', sm: '16 / 9'}, maxHeight: {sm: 420}}}>
|
||||
{fmt?.url ? (
|
||||
<Image
|
||||
src={`${IMAGE_URL}${fmt.url}`}
|
||||
alt={titre}
|
||||
fill
|
||||
priority
|
||||
src={`${IMAGE_URL}${fmt.url}`}
|
||||
alt={titre}
|
||||
placeholder='blur'
|
||||
blurDataURL={BLUR_DATA_URL}
|
||||
sizes='(max-width: 600px) 100vw, 800px'
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import Container from '@mui/material/Container'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Box from '@mui/material/Box'
|
||||
import Grid from '@mui/material/Grid'
|
||||
import Button from '@mui/material/Button'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function Akey({logo}) {
|
||||
export default function Akey() {
|
||||
return (
|
||||
<Box sx={{flexGrow: 1, marginBottom: 3, marginTop: 7}}>
|
||||
<Container align='center'>
|
||||
@@ -25,7 +20,3 @@ export default function Akey({logo}) {
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
Akey.propTypes = {
|
||||
logo: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
@@ -72,7 +72,8 @@ export default function AwtisDetay({anAwtis}) {
|
||||
position: 'relative',
|
||||
flexShrink: 0,
|
||||
mb: 2,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{photoUrl ? (
|
||||
<Image
|
||||
src={photoUrl}
|
||||
@@ -94,8 +95,8 @@ export default function AwtisDetay({anAwtis}) {
|
||||
|
||||
{rezoSosyal?.length > 0 && (
|
||||
<Box sx={{display: 'flex', gap: 0.75, flexWrap: 'wrap', justifyContent: 'center', mb: 1.5}}>
|
||||
{rezoSosyal.map((rezo, i) => (
|
||||
<SocialButton key={i} rezo={rezo} />
|
||||
{rezoSosyal.map(rezo => (
|
||||
<SocialButton key={rezo.url} rezo={rezo} />
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
@@ -149,9 +150,9 @@ export default function AwtisDetay({anAwtis}) {
|
||||
<Link href={`/paroles/${titrePhare.slug}`} style={{display: 'block', height: '100%'}}>
|
||||
<Box sx={{position: 'relative', minHeight: 130, height: '100%'}}>
|
||||
<Image
|
||||
fill
|
||||
src={coverUrl}
|
||||
alt={titrePhare.titre}
|
||||
fill
|
||||
placeholder='blur'
|
||||
blurDataURL={BLUR_DATA_URL}
|
||||
sizes='200px'
|
||||
@@ -163,7 +164,7 @@ export default function AwtisDetay({anAwtis}) {
|
||||
)}
|
||||
<Grid size={{xs: 12, sm: coverUrl ? 8 : 12}}>
|
||||
<CardContent>
|
||||
<Typography variant='subtitle1' sx={{fontWeight: 700}} gutterBottom>
|
||||
<Typography gutterBottom variant='subtitle1' sx={{fontWeight: 700}}>
|
||||
<Link href={`/paroles/${titrePhare.slug}`} style={{color: 'inherit', textDecoration: 'none'}}>
|
||||
{titrePhare.titre}
|
||||
</Link>
|
||||
@@ -172,8 +173,8 @@ export default function AwtisDetay({anAwtis}) {
|
||||
Écouter sur
|
||||
</Typography>
|
||||
<Box sx={{display: 'flex', flexWrap: 'wrap', gap: 1}}>
|
||||
{titrePhare.streamAudio.map((lyen, i) => (
|
||||
<StreamButton key={i} lyen={lyen} />
|
||||
{titrePhare.streamAudio.map(lyen => (
|
||||
<StreamButton key={lyen.url} lyen={lyen} />
|
||||
))}
|
||||
</Box>
|
||||
</CardContent>
|
||||
@@ -202,7 +203,7 @@ export default function AwtisDetay({anAwtis}) {
|
||||
})}
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
) : paroles.length === 0 ? (
|
||||
) : (paroles.length === 0 ? (
|
||||
<Typography textAlign='center' variant='body1' color='text.secondary'>
|
||||
Aucune parole pour le moment
|
||||
</Typography>
|
||||
@@ -213,7 +214,7 @@ export default function AwtisDetay({anAwtis}) {
|
||||
<MizikLyen anPawol={paroles[0]} kuveti={formatKuveti(paroles[0].couverture, 'thumbnail')} />
|
||||
</Paper>
|
||||
</Box>
|
||||
)}
|
||||
))}
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import {formatKuveti} from '../../lib/kuveti'
|
||||
import AwtisBiyografi from './awtis-biyografi'
|
||||
|
||||
const PREFIX = 'awtis-kat'
|
||||
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3001'
|
||||
const IMAGE_URL = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
|
||||
const EXCLUSIVE_LABEL = process.env.NEXT_PUBLIC_EXCLUSIVE_ARTIST_LABEL || 'OKI Exclusif'
|
||||
|
||||
@@ -84,7 +83,7 @@ export default function AwtisKat({artiste}) {
|
||||
component='img'
|
||||
alt={alias}
|
||||
image={`${photo?.url ? `${IMAGE_URL}${formatKuveti(photo, 'thumbnail')?.url}` : noImageUrl}`}
|
||||
loading='lazy'
|
||||
loading='lazy'
|
||||
title={alias}
|
||||
/>
|
||||
<CardContent>
|
||||
|
||||
@@ -5,7 +5,6 @@ import {useRouter} from 'next/navigation'
|
||||
import TextField from '@mui/material/TextField'
|
||||
import Autocomplete from '@mui/material/Autocomplete'
|
||||
import Avatar from '@mui/material/Avatar'
|
||||
import CircularProgress from '@mui/material/CircularProgress'
|
||||
import Container from '@mui/material/Container'
|
||||
|
||||
import {jwennToutAwtis} from '../../lib/oki-api'
|
||||
@@ -29,7 +28,7 @@ export default function ChecheAwtis() {
|
||||
(async () => {
|
||||
try {
|
||||
const {data} = await jwennToutAwtis()
|
||||
|
||||
|
||||
const filteredData = data.map(artiste => {
|
||||
const firstLetter = artiste.alias[0].toUpperCase()
|
||||
return {
|
||||
@@ -50,15 +49,13 @@ export default function ChecheAwtis() {
|
||||
}
|
||||
}, [loading])
|
||||
|
||||
const sortedOptions = useMemo(() => {
|
||||
return [...options].sort((a, b) =>
|
||||
-b.firstLetter.localeCompare(a.firstLetter)
|
||||
);
|
||||
}, [options]);
|
||||
const sortedOptions = useMemo(() => [...options].sort((a, b) =>
|
||||
-b.firstLetter.localeCompare(a.firstLetter)
|
||||
), [options])
|
||||
|
||||
return (
|
||||
<Container
|
||||
sx={{ display: 'flex', justifyContent: 'center', marginBottom: 3 }}
|
||||
sx={{display: 'flex', justifyContent: 'center', marginBottom: 3}}
|
||||
>
|
||||
<Autocomplete
|
||||
autoHighlight
|
||||
@@ -70,35 +67,35 @@ export default function ChecheAwtis() {
|
||||
noOptionsText='Aucun résultat'
|
||||
id='cheche-awtis'
|
||||
options={sortedOptions}
|
||||
groupBy={(option) => option?.firstLetter}
|
||||
getOptionLabel={(option) => option?.alias}
|
||||
renderOption={(props, option) => {
|
||||
const {key, ...rest} = props;
|
||||
groupBy={option => option?.firstLetter}
|
||||
getOptionLabel={option => option?.alias}
|
||||
renderOption={(optionProps, option) => {
|
||||
const {key, ...rest} = optionProps
|
||||
|
||||
return (
|
||||
<li key={key} {...rest}>
|
||||
<Avatar
|
||||
style={{ marginRight: 8 }}
|
||||
style={{marginRight: 8}}
|
||||
alt={option?.alias}
|
||||
src={`${IMAGE_URL}${formatKuveti(option?.photo, 'thumbnail')?.url || ''}`}
|
||||
/>
|
||||
{option?.alias}
|
||||
</li>
|
||||
);
|
||||
)
|
||||
}}
|
||||
sx={{ width: 300 }}
|
||||
renderInput={(params) => (
|
||||
sx={{width: 300}}
|
||||
renderInput={params => (
|
||||
<TextField
|
||||
{...params}
|
||||
label='Rechercher un artiste'
|
||||
slotProps={{
|
||||
...params.slotProps,
|
||||
htmlInput: { ...params.slotProps.htmlInput },
|
||||
htmlInput: {...params.slotProps.htmlInput},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
onChange={(event, newValue) => {
|
||||
router.push(`/awtis/${newValue.slug}`);
|
||||
router.push(`/awtis/${newValue.slug}`)
|
||||
}}
|
||||
onOpen={() => setOpen(true)}
|
||||
onClose={() => setOpen(false)}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import PropTypes from 'prop-types'
|
||||
import Chip from '@mui/material/Chip'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import Tooltip from '@mui/material/Tooltip'
|
||||
@@ -11,23 +12,23 @@ import {
|
||||
} from '@icons-pack/react-simple-icons'
|
||||
|
||||
const SOCIAL_CONFIG = {
|
||||
Mastodon: {label: 'Mastodon', bg: '#6364FF', color: '#fff', Icon: Mastodon},
|
||||
Peertube: {label: 'PeerTube', bg: '#F2690D', color: '#fff', Icon: Peertube},
|
||||
Pixelfed: {label: 'Pixelfed', bg: '#11D49D', color: '#fff', Icon: null},
|
||||
Funkwhale: {label: 'Funkwhale', bg: '#E01B60', color: '#fff', Icon: null},
|
||||
Bluesky: {label: 'Bluesky', bg: '#0085FF', color: '#fff', Icon: null},
|
||||
Instagram: {label: 'Instagram', bg: '#E4405F', color: '#fff', Icon: Instagram},
|
||||
Youtube: {label: 'YouTube', bg: '#FF0000', color: '#fff', Icon: Youtube},
|
||||
Tiktok: {label: 'TikTok', bg: '#000000', color: '#fff', Icon: Tiktok},
|
||||
Spotify: {label: 'Spotify', bg: '#1DB954', color: '#fff', Icon: Spotify},
|
||||
Deezer: {label: 'Deezer', bg: '#EF5466', color: '#fff', Icon: Deezer},
|
||||
Mastodon: {label: 'Mastodon', bg: '#6364FF', color: '#fff', Icon: Mastodon},
|
||||
Peertube: {label: 'PeerTube', bg: '#F2690D', color: '#fff', Icon: Peertube},
|
||||
Pixelfed: {label: 'Pixelfed', bg: '#11D49D', color: '#fff', Icon: null},
|
||||
Funkwhale: {label: 'Funkwhale', bg: '#E01B60', color: '#fff', Icon: null},
|
||||
Bluesky: {label: 'Bluesky', bg: '#0085FF', color: '#fff', Icon: null},
|
||||
Instagram: {label: 'Instagram', bg: '#E4405F', color: '#fff', Icon: Instagram},
|
||||
Youtube: {label: 'YouTube', bg: '#FF0000', color: '#fff', Icon: Youtube},
|
||||
Tiktok: {label: 'TikTok', bg: '#000000', color: '#fff', Icon: Tiktok},
|
||||
Spotify: {label: 'Spotify', bg: '#1DB954', color: '#fff', Icon: Spotify},
|
||||
Deezer: {label: 'Deezer', bg: '#EF5466', color: '#fff', Icon: Deezer},
|
||||
Applemusic: {label: 'Apple Music', bg: '#FC3C44', color: '#fff', Icon: Applemusic},
|
||||
Bandcamp: {label: 'Bandcamp', bg: '#1DA0C3', color: '#fff', Icon: Bandcamp},
|
||||
Soundcloud: {label: 'SoundCloud', bg: '#FF5500', color: '#fff', Icon: Soundcloud},
|
||||
Facebook: {label: 'Facebook', bg: '#1877F2', color: '#fff', Icon: Facebook},
|
||||
Twitter: {label: 'X / Twitter', bg: '#000000', color: '#fff', Icon: Twitter},
|
||||
Linktree: {label: 'Linktree', bg: '#43E660', color: '#000', Icon: null},
|
||||
SiteWeb: {label: 'Site web', bg: '#555555', color: '#fff', Icon: null},
|
||||
Bandcamp: {label: 'Bandcamp', bg: '#1DA0C3', color: '#fff', Icon: Bandcamp},
|
||||
Soundcloud: {label: 'SoundCloud', bg: '#FF5500', color: '#fff', Icon: Soundcloud},
|
||||
Facebook: {label: 'Facebook', bg: '#1877F2', color: '#fff', Icon: Facebook},
|
||||
Twitter: {label: 'X / Twitter', bg: '#000000', color: '#fff', Icon: Twitter},
|
||||
Linktree: {label: 'Linktree', bg: '#43E660', color: '#000', Icon: null},
|
||||
SiteWeb: {label: 'Site web', bg: '#555555', color: '#fff', Icon: null},
|
||||
}
|
||||
|
||||
export function SocialButton({rezo}) {
|
||||
@@ -59,15 +60,22 @@ export function SocialButton({rezo}) {
|
||||
return (
|
||||
<Tooltip title={rezo.url}>
|
||||
<Chip
|
||||
clickable
|
||||
label={config.label}
|
||||
component='a'
|
||||
href={rezo.url}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
clickable
|
||||
size='small'
|
||||
sx={{bgcolor: config.bg, color: config.color, fontWeight: 600}}
|
||||
/>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
SocialButton.propTypes = {
|
||||
rezo: PropTypes.shape({
|
||||
plateforme: PropTypes.string.isRequired,
|
||||
url: PropTypes.string.isRequired
|
||||
}).isRequired
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ export default function LicenseModal({license, sourceOriginale, remixes}) {
|
||||
<DialogContent dividers>
|
||||
{sourceOriginale && (
|
||||
<Box sx={{mb: 3}}>
|
||||
<Typography variant='overline' color='text.secondary' display='block' gutterBottom>
|
||||
<Typography gutterBottom variant='overline' color='text.secondary' display='block'>
|
||||
Basé sur
|
||||
</Typography>
|
||||
<Link href={`/paroles/${sourceOriginale.slug}`} underline='hover' color='inherit'>
|
||||
@@ -76,7 +76,7 @@ export default function LicenseModal({license, sourceOriginale, remixes}) {
|
||||
)}
|
||||
{remixes && (
|
||||
<Box sx={{mb: 3}}>
|
||||
<Typography variant='overline' color='text.secondary' display='block' gutterBottom>
|
||||
<Typography gutterBottom variant='overline' color='text.secondary' display='block'>
|
||||
Déclinaisons
|
||||
</Typography>
|
||||
{remixes.map(remix => (
|
||||
|
||||
@@ -70,12 +70,14 @@ export default function FilesList({files}) {
|
||||
|
||||
useEffect(() => {
|
||||
const audioFiles = files.filter(f => f.mime.startsWith('audio'))
|
||||
if (audioFiles.length === 0) return
|
||||
if (audioFiles.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
let cancelled = false
|
||||
|
||||
async function fetchAllMeta() {
|
||||
const mm = await import('music-metadata-browser')
|
||||
const mm = await import('music-metadata-browser') // eslint-disable-line node/no-unsupported-features/es-syntax
|
||||
const results = {}
|
||||
await Promise.all(
|
||||
audioFiles.map(async file => {
|
||||
@@ -98,7 +100,9 @@ export default function FilesList({files}) {
|
||||
}
|
||||
})
|
||||
)
|
||||
if (!cancelled) setAudioMeta(results)
|
||||
if (!cancelled) {
|
||||
setAudioMeta(results)
|
||||
}
|
||||
}
|
||||
|
||||
fetchAllMeta()
|
||||
@@ -121,7 +125,8 @@ export default function FilesList({files}) {
|
||||
fontWeight: 'bold',
|
||||
letterSpacing: '0.05rem',
|
||||
textTransform: 'uppercase',
|
||||
}}>{isHaute ? 'Haute' : 'Faible'}</Typography>
|
||||
}}
|
||||
>{isHaute ? 'Haute' : 'Faible'}</Typography>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -150,12 +155,16 @@ export default function FilesList({files}) {
|
||||
}
|
||||
|
||||
useEffect(() => () => {
|
||||
Object.values(controllersRef.current).forEach(c => c.abort())
|
||||
for (const c of Object.values(controllersRef.current)) {
|
||||
c.abort()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleClick = async (e, url, fileName, fileId) => {
|
||||
e.stopPropagation()
|
||||
if (fileId in downloading) return
|
||||
if (fileId in downloading) {
|
||||
return
|
||||
}
|
||||
|
||||
const controller = new AbortController()
|
||||
controllersRef.current[fileId] = controller
|
||||
@@ -163,14 +172,18 @@ export default function FilesList({files}) {
|
||||
setDownloading(prev => ({...prev, [fileId]: 0}))
|
||||
try {
|
||||
const response = await fetch(url, {signal: controller.signal})
|
||||
const contentLength = +response.headers.get('content-length')
|
||||
const contentLength = Number(response.headers.get('content-length'))
|
||||
const reader = response.body.getReader()
|
||||
const chunks = []
|
||||
let received = 0
|
||||
|
||||
while (true) {
|
||||
for (;;) {
|
||||
// eslint-disable-next-line no-await-in-loop -- chaque chunk dépend du précédent, la lecture est intrinsèquement séquentielle
|
||||
const {done, value} = await reader.read()
|
||||
if (done) break
|
||||
if (done) {
|
||||
break
|
||||
}
|
||||
|
||||
chunks.push(value)
|
||||
received += value.length
|
||||
if (contentLength) {
|
||||
@@ -186,7 +199,9 @@ export default function FilesList({files}) {
|
||||
a.click()
|
||||
URL.revokeObjectURL(blobUrl)
|
||||
} catch (error) {
|
||||
if (error.name !== 'AbortError') throw error
|
||||
if (error.name !== 'AbortError') {
|
||||
throw error
|
||||
}
|
||||
} finally {
|
||||
delete controllersRef.current[fileId]
|
||||
setDownloading(prev => {
|
||||
|
||||
@@ -48,10 +48,10 @@ export default function KitsDialog({kits}) {
|
||||
<DialogTitle>Télécharger un kit</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<List>
|
||||
{kits.map((kit, index) => {
|
||||
{kits.map(kit => {
|
||||
const PlatformIcon = PLATFORM_ICON[kit.plateforme] ?? CloudDownloadIcon
|
||||
return (
|
||||
<ListItem key={index} disablePadding>
|
||||
<ListItem key={kit.url} disablePadding>
|
||||
<ListItemButton component='a' href={kit.url} target='_blank' rel='noopener noreferrer'>
|
||||
<ListItemIcon>
|
||||
<PlatformIcon />
|
||||
|
||||
@@ -70,7 +70,8 @@ export default function Navigasyon() {
|
||||
<Appdiv>
|
||||
<div className={classes.root}>
|
||||
<AppBar style={{zIndex: 1, boxShadow: 'none'}} position='fixed' color='default'>
|
||||
{selectedTab !== undefined && <Tabs
|
||||
{selectedTab !== undefined && (
|
||||
<Tabs
|
||||
allowScrollButtonsMobile
|
||||
scrollButtons
|
||||
centered={Boolean(!isMobile)}
|
||||
@@ -91,7 +92,7 @@ export default function Navigasyon() {
|
||||
<Tab icon={<MusicNoteIcon />} aria-label='Paroles' {...a11yProps(2)} />
|
||||
<Tab icon={<RecordVoiceOverIcon />} aria-label='Artistes' {...a11yProps(3)} />
|
||||
</Tabs>
|
||||
}
|
||||
)}
|
||||
</AppBar>
|
||||
</div>
|
||||
</Appdiv>
|
||||
|
||||
@@ -4,8 +4,6 @@ import ArrowRightAltIcon from '@mui/icons-material/ArrowRightAlt'
|
||||
|
||||
import CGUDialog from '../cgu/cgu-dialog'
|
||||
|
||||
const CGU_PDF_LINK = process.env.NEXT_PUBLIC_CGU_DOWNLOAD_LINK
|
||||
|
||||
export default function Presantasyon() {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
'use client'
|
||||
|
||||
import PropTypes from 'prop-types'
|
||||
import Button from '@mui/material/Button'
|
||||
import OpenInNewIcon from '@mui/icons-material/OpenInNew'
|
||||
import {Spotify, Applemusic, Deezer, Tidal, Youtubemusic, Amazon, Soundcloud} from '@icons-pack/react-simple-icons'
|
||||
|
||||
export const PLATFORM_CONFIG = {
|
||||
Spotify: {label: 'Spotify', bg: '#1DB954', color: '#fff', Icon: Spotify},
|
||||
Applemusic: {label: 'Apple Music', bg: '#FC3C44', color: '#fff', Icon: Applemusic},
|
||||
Deezer: {label: 'Deezer', bg: '#EF5466', color: '#fff', Icon: Deezer},
|
||||
Tidal: {label: 'Tidal', bg: '#000000', color: '#fff', Icon: Tidal},
|
||||
Qobuz: {label: 'Qobuz', bg: '#00245B', color: '#fff', Icon: null},
|
||||
Youtubemusic: {label: 'YouTube Music', bg: '#FF0000', color: '#fff', Icon: Youtubemusic},
|
||||
Amazon: {label: 'Amazon Music', bg: '#00A8E1', color: '#fff', Icon: Amazon},
|
||||
Soundcloud: {label: 'SoundCloud', bg: '#FF5500', color: '#fff', Icon: Soundcloud},
|
||||
Spotify: {label: 'Spotify', bg: '#1DB954', color: '#fff', Icon: Spotify},
|
||||
Applemusic: {label: 'Apple Music', bg: '#FC3C44', color: '#fff', Icon: Applemusic},
|
||||
Deezer: {label: 'Deezer', bg: '#EF5466', color: '#fff', Icon: Deezer},
|
||||
Tidal: {label: 'Tidal', bg: '#000000', color: '#fff', Icon: Tidal},
|
||||
Qobuz: {label: 'Qobuz', bg: '#00245B', color: '#fff', Icon: null},
|
||||
Youtubemusic: {label: 'YouTube Music', bg: '#FF0000', color: '#fff', Icon: Youtubemusic},
|
||||
Amazon: {label: 'Amazon Music', bg: '#00A8E1', color: '#fff', Icon: Amazon},
|
||||
Soundcloud: {label: 'SoundCloud', bg: '#FF5500', color: '#fff', Icon: Soundcloud},
|
||||
}
|
||||
|
||||
export function StreamButton({lyen}) {
|
||||
@@ -39,3 +40,10 @@ export function StreamButton({lyen}) {
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
StreamButton.propTypes = {
|
||||
lyen: PropTypes.shape({
|
||||
plateforme: PropTypes.string.isRequired,
|
||||
url: PropTypes.string.isRequired
|
||||
}).isRequired
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ const getMizikFiltered = (paroles, filter) => {
|
||||
const filteredTitre = paroles.filter(({titre}) => {
|
||||
const deburredTit = deburr(titre)
|
||||
return deburredTit.toLowerCase().includes(deburr(filter.toLowerCase()))
|
||||
})
|
||||
})
|
||||
|
||||
const filteredAlias = paroles.filter(({artistes}) => {
|
||||
const aliasLis = artistes.map(({alias}) => deburr(alias)).join(', ')
|
||||
|
||||
@@ -21,7 +21,7 @@ const pulse = keyframes`
|
||||
`
|
||||
|
||||
const SlideUp = forwardRef(function SlideUp(props, ref) {
|
||||
return <Slide direction='up' ref={ref} {...props} />
|
||||
return <Slide ref={ref} direction='up' {...props} />
|
||||
})
|
||||
|
||||
function toEmbedUrl(url) {
|
||||
@@ -31,6 +31,7 @@ function toEmbedUrl(url) {
|
||||
if (match) {
|
||||
return `${u.origin}/videos/embed/${match[1]}?title=0&warningTitle=0&peertubeLink=0&controlBar=1`
|
||||
}
|
||||
|
||||
return url
|
||||
} catch {
|
||||
return url
|
||||
@@ -45,7 +46,9 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
const activeUrl = (!isMobile && desktopUrl) ? desktopUrl : url
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) setLoaded(false)
|
||||
if (!open) {
|
||||
setLoaded(false)
|
||||
}
|
||||
}, [open])
|
||||
|
||||
return (
|
||||
@@ -55,13 +58,13 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
color='primary'
|
||||
size={isMobile ? 'medium' : 'large'}
|
||||
aria-label='karaoké'
|
||||
onClick={() => setOpen(true)}
|
||||
sx={{
|
||||
position: 'fixed',
|
||||
bottom: {xs: 24, sm: 32},
|
||||
right: {xs: 24, sm: 32},
|
||||
zIndex: 1050,
|
||||
}}
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<MicIcon />
|
||||
</Fab>
|
||||
@@ -69,7 +72,6 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
slots={{transition: SlideUp}}
|
||||
maxWidth={false}
|
||||
sx={{
|
||||
@@ -102,6 +104,7 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
}
|
||||
}
|
||||
}}
|
||||
onClose={() => setOpen(false)}
|
||||
>
|
||||
{/* Header superposé en gradient */}
|
||||
<Box sx={{
|
||||
@@ -118,7 +121,8 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-between',
|
||||
pointerEvents: 'none',
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Box sx={{pointerEvents: 'none'}}>
|
||||
{titre && (
|
||||
<Typography variant='subtitle1' sx={{color: '#fff', fontWeight: 700, lineHeight: 1.2, textShadow: '0 1px 4px rgba(0,0,0,0.5)'}}>
|
||||
@@ -133,7 +137,6 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
</Box>
|
||||
<IconButton
|
||||
size='small'
|
||||
onClick={() => setOpen(false)}
|
||||
aria-label='fermer'
|
||||
sx={{
|
||||
pointerEvents: 'auto',
|
||||
@@ -143,6 +146,7 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
border: '1px solid rgba(255,255,255,0.12)',
|
||||
'&:hover': {bgcolor: 'rgba(255,255,255,0.25)'},
|
||||
}}
|
||||
onClick={() => setOpen(false)}
|
||||
>
|
||||
<CloseIcon fontSize='small' />
|
||||
</IconButton>
|
||||
@@ -166,7 +170,8 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 1.5,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<MicIcon sx={{fontSize: 44, color: 'rgba(255,255,255,0.55)', animation: `${pulse} 1.6s ease-in-out infinite`}} />
|
||||
<Typography
|
||||
variant='caption'
|
||||
@@ -187,27 +192,28 @@ export default function KaraokeModal({url, desktopUrl, titre, artistes}) {
|
||||
transform: 'translateX(-50%)',
|
||||
height: '100%',
|
||||
aspectRatio: '16 / 9',
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<iframe
|
||||
src={toEmbedUrl(activeUrl)}
|
||||
onLoad={() => setLoaded(true)}
|
||||
style={{width: '100%', height: '100%', border: 'none', display: 'block', opacity: loaded ? 1 : 0, transition: 'opacity 0.4s ease'}}
|
||||
allowFullScreen
|
||||
src={toEmbedUrl(activeUrl)}
|
||||
style={{width: '100%', height: '100%', border: 'none', display: 'block', opacity: loaded ? 1 : 0, transition: 'opacity 0.4s ease'}}
|
||||
allow='autoplay; fullscreen'
|
||||
sandbox='allow-same-origin allow-scripts allow-popups allow-forms'
|
||||
title='Karaoké'
|
||||
onLoad={() => setLoaded(true)}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
/* Vidéo 16:9 desktop : player remplit exactement le dialog paysage */
|
||||
<iframe
|
||||
src={toEmbedUrl(activeUrl)}
|
||||
onLoad={() => setLoaded(true)}
|
||||
style={{width: '100%', height: '100%', border: 'none', display: 'block', opacity: loaded ? 1 : 0, transition: 'opacity 0.4s ease'}}
|
||||
allowFullScreen
|
||||
src={toEmbedUrl(activeUrl)}
|
||||
style={{width: '100%', height: '100%', border: 'none', display: 'block', opacity: loaded ? 1 : 0, transition: 'opacity 0.4s ease'}}
|
||||
allow='autoplay; fullscreen'
|
||||
sandbox='allow-same-origin allow-scripts allow-popups allow-forms'
|
||||
title='Karaoké'
|
||||
onLoad={() => setLoaded(true)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@@ -30,9 +30,10 @@ function createAudio(src) {
|
||||
function parseLrc(text) {
|
||||
const lines = []
|
||||
for (const raw of text.split('\n')) {
|
||||
const match = raw.match(/^\[(\d{2}):(\d{2})[.:]\d+\](.*)$/)
|
||||
const match = raw.match(/^\[(\d{2}):(\d{2})[.:]\d+](.*)$/)
|
||||
if (match) {
|
||||
lines.push({time: parseInt(match[1]) * 60 + parseInt(match[2]), text: match[3].trim()})
|
||||
const time = (Number.parseInt(match[1], 10) * 60) + Number.parseInt(match[2], 10)
|
||||
lines.push({time, text: match[3].trim()})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +146,7 @@ export default function Lekte({audio, url, parole}) {
|
||||
setPosition(0)
|
||||
el.currentTime = 0
|
||||
}
|
||||
|
||||
el.addEventListener('loadedmetadata', onLoaded)
|
||||
el.addEventListener('ended', onEnded)
|
||||
return () => {
|
||||
@@ -154,7 +156,10 @@ export default function Lekte({audio, url, parole}) {
|
||||
}, [audio])
|
||||
|
||||
useEffect(() => {
|
||||
if (!parole?.pawol?.url) return
|
||||
if (!parole?.pawol?.url) {
|
||||
return
|
||||
}
|
||||
|
||||
fetch(new URL(parole.pawol.url, IMAGE_URL).toString())
|
||||
.then(r => r.text())
|
||||
.then(text => setLrcLines(parseLrc(text)))
|
||||
@@ -162,7 +167,7 @@ export default function Lekte({audio, url, parole}) {
|
||||
}, [parole?.pawol?.url])
|
||||
|
||||
const activeIndex = lrcLines
|
||||
? lrcLines.reduce((last, line, i) => line.time <= position ? i : last, -1)
|
||||
? lrcLines.findLastIndex(line => line.time <= position)
|
||||
: -1
|
||||
|
||||
const handleChangePosition = value => {
|
||||
@@ -317,7 +322,10 @@ export default function Lekte({audio, url, parole}) {
|
||||
{[-1, 0, 1].map(offset => {
|
||||
const idx = activeIndex + offset
|
||||
const line = lrcLines[idx]
|
||||
if (!line) return <Box key={offset} sx={{height: offset === 0 ? 28 : 20}} />
|
||||
if (!line) {
|
||||
return <Box key={offset} sx={{height: offset === 0 ? 28 : 20}} />
|
||||
}
|
||||
|
||||
return (
|
||||
<Typography
|
||||
key={offset}
|
||||
|
||||
@@ -51,9 +51,9 @@ export default function TeksKat({parole}) {
|
||||
<Box sx={{position: 'relative', height: 240}}>
|
||||
{couverture?.url ? (
|
||||
<Image
|
||||
fill
|
||||
src={`${IMAGE_URL}${formatKuveti(couverture, 'thumbnail')?.url}`}
|
||||
alt={titre}
|
||||
fill
|
||||
placeholder='blur'
|
||||
blurDataURL={BLUR_DATA_URL}
|
||||
sizes='(max-width: 600px) 100vw, (max-width: 900px) 50vw, 33vw'
|
||||
|
||||
@@ -183,7 +183,7 @@ export default function Teks({parole}) {
|
||||
<i>parole soumise par {parole.user.username}</i>
|
||||
</Typography>
|
||||
)}
|
||||
{parole?.userAdmin&& !parole.user && (
|
||||
{parole?.userAdmin && !parole.user && (
|
||||
<Typography style={{marginBottom: '1.5em'}} display='block' variant='caption'>
|
||||
<i>parole soumise par {parole.userAdmin.firstname}</i>
|
||||
</Typography>
|
||||
@@ -220,8 +220,8 @@ export default function Teks({parole}) {
|
||||
Écouter sur
|
||||
</Typography>
|
||||
<Box sx={{display: 'flex', flexWrap: 'wrap', justifyContent: 'center', gap: 1}}>
|
||||
{parole.streamAudio.map((lyen, i) => (
|
||||
<StreamButton key={i} lyen={lyen} />
|
||||
{parole.streamAudio.map(lyen => (
|
||||
<StreamButton key={lyen.url} lyen={lyen} />
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
@@ -229,11 +229,10 @@ export default function Teks({parole}) {
|
||||
</Box>
|
||||
<Box sx={{maxWidth: 700, margin: '0 auto'}} className={classes.gridText}>
|
||||
<Tabs
|
||||
value={tab}
|
||||
onChange={(event, value) => setTab(value)}
|
||||
variant='scrollable'
|
||||
scrollButtons
|
||||
allowScrollButtonsMobile
|
||||
value={tab}
|
||||
variant='scrollable'
|
||||
centered={langArray.length === 0}
|
||||
slots={{
|
||||
startScrollButtonIcon: ArrowBackIosNewIcon,
|
||||
@@ -255,6 +254,7 @@ export default function Teks({parole}) {
|
||||
}
|
||||
}
|
||||
}}
|
||||
onChange={(event, value) => setTab(value)}
|
||||
>
|
||||
<Tab label='Transcription' />
|
||||
{langArray.map(({title}) => (
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
'use client'
|
||||
|
||||
import PropTypes from 'prop-types'
|
||||
import NextTopLoader from 'nextjs-toploader'
|
||||
|
||||
export default function TopLoader({color}) {
|
||||
return <NextTopLoader color={color} />
|
||||
}
|
||||
|
||||
TopLoader.propTypes = {
|
||||
color: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
+14
-14
@@ -1,25 +1,25 @@
|
||||
import { dirname } from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
import {dirname} from 'node:path'
|
||||
import {fileURLToPath} from 'node:url'
|
||||
import {FlatCompat} from '@eslint/eslintrc'
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = dirname(__filename)
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
});
|
||||
})
|
||||
|
||||
const eslintConfig = [
|
||||
...compat.extends("next/core-web-vitals"),
|
||||
...compat.extends('next/core-web-vitals'),
|
||||
{
|
||||
ignores: [
|
||||
"node_modules/**",
|
||||
".next/**",
|
||||
"out/**",
|
||||
"build/**",
|
||||
"next-env.d.ts",
|
||||
'node_modules/**',
|
||||
'.next/**',
|
||||
'out/**',
|
||||
'build/**',
|
||||
'next-env.d.ts',
|
||||
],
|
||||
},
|
||||
];
|
||||
]
|
||||
|
||||
export default eslintConfig;
|
||||
export default eslintConfig
|
||||
|
||||
+11
-5
@@ -1,15 +1,21 @@
|
||||
const SIZE_ORDER = {
|
||||
large: ['large', 'medium', 'small'],
|
||||
medium: ['medium', 'small', 'large'],
|
||||
small: ['small', 'medium', 'large'],
|
||||
large: ['large', 'medium', 'small'],
|
||||
medium: ['medium', 'small', 'large'],
|
||||
small: ['small', 'medium', 'large'],
|
||||
thumbnail: ['thumbnail', 'small', 'medium', 'large'],
|
||||
}
|
||||
|
||||
export const formatKuveti = (kuveti, preferred = 'large') => {
|
||||
if (!kuveti) return null
|
||||
if (!kuveti) {
|
||||
return null
|
||||
}
|
||||
|
||||
const order = SIZE_ORDER[preferred] ?? SIZE_ORDER.large
|
||||
for (const size of order) {
|
||||
if (kuveti.formats?.[size]) return kuveti.formats[size]
|
||||
if (kuveti.formats?.[size]) {
|
||||
return kuveti.formats[size]
|
||||
}
|
||||
}
|
||||
|
||||
return kuveti
|
||||
}
|
||||
|
||||
+3
-2
@@ -186,6 +186,7 @@ async function jwennTouSlug(endpoint) {
|
||||
encodeValuesOnly: true
|
||||
})
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop -- pagination séquentielle, chaque page dépend du nombre de résultats de la précédente
|
||||
const {data} = await request(`/${endpoint}?${query}`, headers)
|
||||
slugs.push(...data.map(({slug}) => slug))
|
||||
hasMore = data.length === pageSize
|
||||
@@ -223,9 +224,9 @@ export async function jwennAnVedette() {
|
||||
const query = qs.stringify({
|
||||
populate: ['artistes', 'couverture'],
|
||||
filters: {
|
||||
isNewRelease: { $eq: true }
|
||||
isNewRelease: {$eq: true}
|
||||
},
|
||||
pagination: { limit: 1 }
|
||||
pagination: {limit: 1}
|
||||
}, {
|
||||
encodeValuesOnly: true
|
||||
})
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import YouTubeIcon from '@mui/icons-material/YouTube'
|
||||
import TelegramIcon from '@mui/icons-material/Telegram'
|
||||
|
||||
import PeertubeIcon from './icons/peertube'
|
||||
import XmppIcon from './icons/xmpp'
|
||||
import XIcon from './icons/x'
|
||||
import GiteaIcon from './icons/gitea'
|
||||
import BlueskyIcon from './icons/bluesky'
|
||||
|
||||
const gitURL = process.env.NEXT_PUBLIC_GIT || 'https://labola.o-k-i.net/ORGANISATION-KA-INTERNATIONALE/pawol.nu'
|
||||
const blueskyUrl = process.env.NEXT_PUBLIC_BLUESKY_URL || 'https://bsky.app/profile/organisationka.bsky.social'
|
||||
const xmppContact = process.env.NEXT_PUBLIC_XMPP || 'oki@xmpp.cz'
|
||||
const gadeUsername = process.env.NEXT_PUBLIC_GADE_USERNAME || 'oki'
|
||||
const youtubeUsername = process.env.NEXT_PUBLIC_YOUTUBE_USERNAME || 'OrganisationKInternationaleOKi'
|
||||
const tiwtterUsername = process.env.NEXT_PUBLIC_TWITTER_USERNAME || 'OrganisationKA'
|
||||
const telegramGroup = process.env.NEXT_PUBLIC_TELEGRAM_GROUP || 'OrganisationKA'
|
||||
|
||||
+10
-3
@@ -11,13 +11,20 @@ function buildRemotePatterns() {
|
||||
const [hostname, port] = entry.split(':')
|
||||
const isLocal = hostname === 'localhost' || hostname === '127.0.0.1'
|
||||
const pattern = {protocol: isLocal ? 'http' : 'https', hostname, pathname: '/uploads/**'}
|
||||
if (port) pattern.port = port
|
||||
if (port) {
|
||||
pattern.port = port
|
||||
}
|
||||
|
||||
return pattern
|
||||
})
|
||||
if (!raw.includes('localhost'))
|
||||
if (!raw.includes('localhost')) {
|
||||
patterns.push({protocol: 'http', hostname: 'localhost', port: '1337', pathname: '/uploads/**'})
|
||||
if (!raw.includes('127.0.0.1'))
|
||||
}
|
||||
|
||||
if (!raw.includes('127.0.0.1')) {
|
||||
patterns.push({protocol: 'http', hostname: '127.0.0.1', port: '1337', pathname: '/uploads/**'})
|
||||
}
|
||||
|
||||
return patterns
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import '@testing-library/jest-dom/vitest'
|
||||
import '@testing-library/jest-dom/vitest' // eslint-disable-line import/no-unassigned-import
|
||||
|
||||
Reference in New Issue
Block a user