import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { Drawer, DrawerContent, DrawerHeader, DrawerTrigger } from '@/components/ui/drawer' import { Label } from '@/components/ui/label' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { Separator } from '@/components/ui/separator' import SocialGraphFilter from '@/components/SocialGraphFilter' import { ExtendedKind } from '@/constants' import { cn } from '@/lib/utils' import { useKindFilter } from '@/providers/KindFilterProvider' import { useScreenSize } from '@/providers/ScreenSizeProvider' import { useSocialGraphFilter } from '@/providers/SocialGraphFilterProvider' import { ListFilter } from 'lucide-react' import { kinds } from 'nostr-tools' import { useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' const KIND_FILTER_OPTIONS = [ { kindGroup: [kinds.ShortTextNote, ExtendedKind.COMMENT], label: 'Posts' }, { kindGroup: [kinds.Repost, kinds.GenericRepost], label: 'Reposts' }, { kindGroup: [kinds.LongFormArticle], label: 'Articles' }, { kindGroup: [kinds.Highlights], label: 'Highlights' }, { kindGroup: [ExtendedKind.POLL], label: 'Polls' }, { kindGroup: [ExtendedKind.VOICE, ExtendedKind.VOICE_COMMENT], label: 'Voice Posts' }, { kindGroup: [ExtendedKind.PICTURE], label: 'Photo Posts' }, { kindGroup: [ ExtendedKind.VIDEO, ExtendedKind.SHORT_VIDEO, ExtendedKind.ADDRESSABLE_NORMAL_VIDEO, ExtendedKind.ADDRESSABLE_SHORT_VIDEO ], label: 'Video Posts' } ] const ALL_KINDS = KIND_FILTER_OPTIONS.flatMap(({ kindGroup }) => kindGroup) export default function KindFilter({ showKinds, onShowKindsChange, showSocialGraphFilter = false }: { showKinds: number[] onShowKindsChange: (kinds: number[]) => void showSocialGraphFilter?: boolean }) { const { t } = useTranslation() const { isSmallScreen } = useScreenSize() const { showKinds: savedShowKinds } = useKindFilter() const { proximityLevel: savedProximity, includeMode: savedIncludeMode, updateProximityLevel, updateIncludeMode } = useSocialGraphFilter() const [open, setOpen] = useState(false) const { updateShowKinds } = useKindFilter() const [temporaryShowKinds, setTemporaryShowKinds] = useState(showKinds) const [temporaryProximity, setTemporaryProximity] = useState(savedProximity) const [temporaryIncludeMode, setTemporaryIncludeMode] = useState(savedIncludeMode) const [isPersistent, setIsPersistent] = useState(false) const isDifferentFromSaved = useMemo(() => { const kindsDifferent = !isSameKindFilter(showKinds, savedShowKinds) const proximityDifferent = showSocialGraphFilter && savedProximity !== null return kindsDifferent || proximityDifferent }, [showKinds, savedShowKinds, savedProximity, showSocialGraphFilter]) const isTemporaryDifferentFromSaved = useMemo( () => !isSameKindFilter(temporaryShowKinds, savedShowKinds), [temporaryShowKinds, savedShowKinds] ) useEffect(() => { setTemporaryShowKinds(showKinds) setTemporaryProximity(savedProximity) setTemporaryIncludeMode(savedIncludeMode) setIsPersistent(false) }, [open, savedProximity, savedIncludeMode]) const handleApply = () => { if (temporaryShowKinds.length === 0) { // must select at least one kind return } const newShowKinds = [...temporaryShowKinds].sort() if (!isSameKindFilter(newShowKinds, showKinds)) { onShowKindsChange(newShowKinds) } // Apply social graph filter changes if (showSocialGraphFilter) { if (temporaryProximity !== savedProximity) { updateProximityLevel(temporaryProximity) } if (temporaryIncludeMode !== savedIncludeMode) { updateIncludeMode(temporaryIncludeMode) } } if (isPersistent) { updateShowKinds(newShowKinds) } setIsPersistent(false) setOpen(false) } const trigger = ( ) const content = (
{KIND_FILTER_OPTIONS.map(({ kindGroup, label }) => { const checked = kindGroup.every((k) => temporaryShowKinds.includes(k)) return (
{ if (!checked) { // add all kinds in this group setTemporaryShowKinds((prev) => Array.from(new Set([...prev, ...kindGroup]))) } else { // remove all kinds in this group setTemporaryShowKinds((prev) => prev.filter((k) => !kindGroup.includes(k))) } }} >

{t(label)}

kind {kindGroup.join(', ')}

) })}
{showSocialGraphFilter && ( <> )}
) if (isSmallScreen) { return ( <> {trigger} {content} ) } return ( {trigger} {content} ) } function isSameKindFilter(a: number[], b: number[]) { if (a.length !== b.length) { return false } const sortedA = [...a].sort() const sortedB = [...b].sort() return sortedA.every((value, index) => value === sortedB[index]) }