Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 5,112 Bytes
1c4a779 b8c4528 df83860 1c4a779 f27679f f42b4a1 3d4392e 139ef57 b8c4528 3d4392e f27679f df83860 f27679f df83860 b8c4528 f27679f f42b4a1 e40bd21 f42b4a1 f27679f df83860 f27679f e40bd21 f27679f 2ed75c8 f27679f 1c4a779 f27679f 8f2b05f f27679f 8f2b05f f27679f 1c4a779 f27679f 8f2b05f f27679f 8f2b05f f27679f 8f2b05f f27679f 1c4a779 f27679f 1c4a779 f27679f 1c4a779 f27679f d160b97 f27679f b8c4528 f27679f 29f166e f27679f 2ed75c8 f27679f df83860 f27679f df83860 f27679f df83860 f27679f df83860 f27679f df83860 f27679f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
"use client"
import { useEffect, useState, useTransition } from 'react'
import { AiTubeLogo } from "./logo"
import { useStore } from "@/app/state/useStore"
import { cn } from "@/lib/utils/cn"
import { getTags } from '@/app/api/actions/ai-tube-hf/getTags'
import Link from 'next/link'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { SearchInput } from '../search-input'
import { pathway } from '@/lib/fonts'
export function TopHeader() {
const [_pending, startTransition] = useTransition()
const view = useStore(s => s.view)
const setView = useStore(s => s.setView)
const displayMode = useStore(s => s.displayMode)
const setDisplayMode = useStore(s => s.setDisplayMode)
const headerMode = useStore(s => s.headerMode)
const setHeaderMode = useStore(s => s.setHeaderMode)
const setMenuMode = useStore(s => s.setMenuMode)
const currentTag = useStore(s => s.currentTag)
const setCurrentTag = useStore(s => s.setCurrentTag)
const currentTags = useStore(s => s.currentTags)
const setCurrentTags = useStore(s => s.setCurrentTags)
const setSearchAutocompleteQuery = useStore(s => s.setSearchAutocompleteQuery)
const searchAutocompleteResults = useStore(s => s.searchAutocompleteResults)
const setSearchQuery = useStore(s => s.setSearchQuery)
const [searchDraft, setSearchDraft] = useState("")
useEffect(() => {
const searchQuery = searchDraft.trim().toLowerCase()
setSearchQuery(searchQuery)
}, [searchDraft])
const isNormalSize = headerMode === "normal"
useEffect(() => {
if (view === "public_media_embed") {
setHeaderMode("hidden")
} else if (view === "public_media" || view === "public_channel" || view === "public_music_videos") {
setHeaderMode("compact")
setMenuMode("slider_hidden")
} else {
setHeaderMode("normal")
setMenuMode("normal_icon")
}
}, [view])
useEffect(() => {
startTransition(async () => {
const tags = await getTags()
setCurrentTags(tags)
})
}, [])
if (headerMode === "hidden") {
return null
}
return (
<div className={cn(
`flex flex-col`,
`overflow-hidden`,
`transition-all duration-200 ease-in-out`,
`w-full`,
)}>
<div className={cn(
`flex flex-row justify-between`,
`w-full`
)}>
<div className={cn(
`flex flex-col items-start justify-center`,
`w-full sm:w-64`,
)}>
<Link href="/">
<div className={cn(
`flex flex-row items-center justify-start`,
`transition-all duration-200 ease-in-out`,
// `cursor-pointer`,
"pt-2 text-3xl space-x-1",
view === "public_music_videos" ? "pl-1" : "",
pathway.className,
isNormalSize
? "sm:scale-125 mb-2 sm:ml-4 sm:mb-4" : "sm:scale-100 sm:mb-2"
)}
/*
onClick={() => {
setView(view === "public_music_videos" ? "public_music_videos" : "home")
}}
*/
>
<div className="flex items-center justify-center overflow-hidden h-10 w-6">
<div className="scale-[5%]">
<AiTubeLogo />
</div>
</div>
<div className="font-semibold">
{view === "public_music_videos" ? "AiTube Music" : "AiTube"}
</div>
</div>
</Link>
</div>
<div className={cn(
// TODO: show the disclaimer on mobile too, maybe with a modal or something
`hidden sm:flex`,
`flex-col`,
`items-center justify-center`,
`transition-all duration-200 ease-in-out`,
`px-4 py-2 w-max-64`,
`text-neutral-400 text-2xs sm:text-xs lg:text-sm italic`
)}>
<SearchInput />
</div>
<div className={cn("w-32 xl:w-42")}>
<span>
{/* reserved for future use */}
</span>
</div>
</div>
{
isNormalSize && view !== "public_music_videos" ?
<div className={cn(
`hidden sm:flex flex-row space-x-3`,
`text-[13px] font-semibold`,
`mb-4`
)}>
{currentTags.slice(0, 9).map(tag => (
<div
key={tag}
className={cn(
`flex flex-col items-center justify-center`,
`rounded-lg px-3 py-1 h-8`,
`cursor-pointer`,
`transition-all duration-200 ease-in-out`,
currentTag === tag
? `bg-neutral-100 text-neutral-800`
: `bg-neutral-800 text-neutral-50/90 hover:bg-neutral-700 hover:text-neutral-50/90`,
// `text-clip`
)}
onClick={() => {
setCurrentTag(currentTag === tag ? undefined : tag)
}}
>
<span className={cn(
`text-center`,
`capitalize`,
)}>{tag}</span>
</div>
))}
</div> : null}
</div>
)
}
|