/* eslint-disable no-nested-ternary */ import { motion } from 'framer-motion'; import { BsmImage } from 'renderer/components/shared/bsm-image.component'; import { ClockIcon } from 'renderer/components/svgs/icons/clock-icon.component'; import { MapIcon } from 'renderer/components/svgs/icons/map-icon.component'; import { PersonIcon } from 'renderer/components/svgs/icons/person-icon.component'; import { useThemeColor } from 'renderer/hooks/use-theme-color.hook'; import { NpsIcon } from 'renderer/components/svgs/icons/nps-icon.component'; import { GlowEffect } from 'renderer/components/shared/glow-effect.component'; import { memo, useState } from 'react'; import { SearchIcon } from 'renderer/components/svgs/icons/search-icon.component'; import { BsmButton } from 'renderer/components/shared/bsm-button.component'; import Tippy from '@tippyjs/react'; import { Observable, of } from 'rxjs'; import { useObservable } from 'renderer/hooks/use-observable.hook'; import { BsmBasicSpinner } from 'renderer/components/shared/bsm-basic-spinner/bsm-basic-spinner.component'; import defaultImage from "../../../../../assets/images/default-version-img.jpg"; import equal from 'fast-deep-equal'; import { useTranslation } from 'renderer/hooks/use-translation.hook'; import { sToMs } from 'shared/helpers/time.helpers'; import formatDuration from 'format-duration'; export type PlaylistItemComponentProps = { title?: string; author?: string; coverBase64?: string; coverUrl?: string; nbMaps?: number; nbMappers?: number; duration?: number; minNps?: number; maxNps?: number; selected$?: Observable; isDownloading$?: Observable; isInQueue$?: Observable; onClick?: () => void; onClickOpen?: () => void; onClickOpenFile?: () => void; onClickDelete?: () => void; onClickSync?: () => void; onClickDownload?: () => void; onClickCancelDownload?: () => void; onClickEdit?: () => void; } export const PlaylistItem = memo(({ title, author, coverUrl, coverBase64, duration, nbMaps, nbMappers, minNps, maxNps, selected$, isDownloading$, isInQueue$, onClick, onClickOpen, onClickOpenFile, onClickSync, onClickDownload, onClickDelete, onClickCancelDownload, onClickEdit }: PlaylistItemComponentProps) => { const t = useTranslation(); const color = useThemeColor("first-color"); const [hovered, setHovered] = useState(false); const selected = useObservable(() => selected$ ?? of(false), false, [selected$]); const isDownloading = useObservable(() => isDownloading$ ?? of(), false, [isDownloading$]); const isInQueue = useObservable(() => isInQueue$ ?? of(), false, [isInQueue$]); const nbMapsText = nbMaps ? Intl.NumberFormat(undefined, { notation: "compact" }).format(nbMaps).trim() : null; const nbMappersText = nbMappers ? Intl.NumberFormat(undefined, { notation: "compact" }).format(nbMappers).trim() : null; const minNpsText = minNps ? Math.round(minNps * 10) / 10 : 0; const maxNpsText = maxNps ? Math.round(maxNps * 10) / 10 : 0; const showNps = minNps !== undefined && maxNps !== undefined; const durationText = (() => { if (!duration) { return null; } const durationMs = sToMs(duration); return formatDuration(durationMs, { leading: true }); })(); return ( setHovered(() => true)} onHoverEnd={() => setHovered(() => false)}>
{e.stopPropagation(); onClick?.()}}>
{e.stopPropagation(); onClickOpen?.()}} />

{title}

{t("playlist.created-by")} {author}

{ nbMapsText &&
{nbMapsText}
} { nbMappersText &&
{nbMappersText}
} { durationText &&
{durationText}
} { showNps &&
{`${minNpsText} - ${maxNpsText}`}
}
e.stopPropagation()}> {(isDownloading || isInQueue) && onClickCancelDownload ? ( ) : (undefined)} {onClickSync ? ( isDownloading ? ( ) : !isInQueue ? ( ) : undefined ) : undefined} {onClickDownload ? ( isDownloading ? ( ) : !isInQueue ? ( ) : undefined ) : undefined} {onClickEdit ? ( ) : undefined} {onClickOpenFile ? : undefined} {(onClickDelete && !isDownloading && !isInQueue) ? : undefined}
) }, equal);