SYMBOL INDEX (176 symbols across 54 files) FILE: main/helpers/db/connectDB.ts constant APP_DATA (line 15) | const APP_DATA = app.getPath("userData"); constant ART_DIR (line 16) | const ART_DIR = path.join(APP_DATA, "utilities/uploads/covers"); function isAudioFile (line 40) | function isAudioFile(filePath: string): boolean { function findFirstImageInDirectory (line 44) | function findFirstImageInDirectory(dir: string): string | null { function readFilesRecursively (line 70) | function readFilesRecursively(dir: string, batch = 100): string[] { function scanEntireLibrary (line 104) | function scanEntireLibrary(dir: string): string[] { function processLibrary (line 540) | async function processLibrary(musicFolder: string, incremental = false) { function getAllFilePathsFromDb (line 604) | async function getAllFilePathsFromDb(): Promise> { function scanImmediateDirectory (line 610) | function scanImmediateDirectory(dir: string): string[] { function processBatch (line 659) | async function processBatch(files: string[], dbFilePaths: Set) { function processAudioFile (line 674) | async function processAudioFile(file: string, albumCache: Map { function processEmbeddedArt (line 818) | async function processEmbeddedArt(cover: any): Promise { function cleanupOrphanedRecords (line 851) | async function cleanupOrphanedRecords(currentFiles: string[]) { function sendToRenderer (line 955) | function sendToRenderer(channel: string, data: any) { FILE: main/helpers/lastfm-service.ts constant API_URL (line 33) | const API_URL = "https://ws.audioscrobbler.com/2.0/"; constant CACHE_TTL (line 36) | const CACHE_TTL = 15 * 60 * 1000; constant DEV_API_KEY (line 72) | const DEV_API_KEY = process.env.LASTFM_API_KEY || ""; constant DEV_API_SECRET (line 73) | const DEV_API_SECRET = process.env.LASTFM_API_SECRET || ""; FILE: main/preload.ts method send (line 4) | send(channel: string, value: unknown) { method on (line 7) | on(channel: string, callback: (...args: unknown[]) => void) { method invoke (line 16) | async invoke(channel: string, ...args: unknown[]) { type IpcHandler (line 29) | type IpcHandler = typeof handler; FILE: renderer/components/ErrorBoundary.tsx type Props (line 5) | interface Props { type State (line 10) | interface State { class ErrorBoundary (line 15) | class ErrorBoundary extends Component { method getDerivedStateFromError (line 21) | public static getDerivedStateFromError(error: Error): State { method componentDidCatch (line 25) | public componentDidCatch(error: Error, errorInfo: ErrorInfo) { method render (line 34) | public render() { FILE: renderer/components/LoadingSkeletons.tsx function ArtistGridSkeleton (line 4) | function ArtistGridSkeleton({ count = 12, viewMode = 'grid-large' }: { c... function AlbumGridSkeleton (line 41) | function AlbumGridSkeleton({ count = 12 }: { count?: number }) { function SongListSkeleton (line 55) | function SongListSkeleton({ count = 10 }: { count?: number }) { function ArtistDetailSkeleton (line 72) | function ArtistDetailSkeleton() { FILE: renderer/components/PageTransition.tsx type PageTransitionProps (line 5) | interface PageTransitionProps { function PageTransition (line 28) | function PageTransition({ children }: PageTransitionProps) { FILE: renderer/components/PageTransitionMinimal.tsx type PageTransitionProps (line 3) | interface PageTransitionProps { function PageTransitionMinimal (line 10) | function PageTransitionMinimal({ children }: PageTransitionProps) { FILE: renderer/components/main/lyrics.tsx type LyricsProps (line 7) | interface LyricsProps { FILE: renderer/components/main/navbar.tsx type Settings (line 37) | type Settings = { type NavLink (line 42) | type NavLink = { FILE: renderer/components/main/player.tsx function getAlbumCoverUrl (line 84) | function getAlbumCoverUrl(song: Song | undefined): string { FILE: renderer/components/themeProvider.tsx function ThemeProvider (line 7) | function ThemeProvider({ children, ...props }: ThemeProviderProps) { FILE: renderer/components/ui/actions.tsx type Data (line 12) | type Data = { function Actions (line 17) | function Actions() { FILE: renderer/components/ui/album.tsx type Album (line 5) | type Album = { type AlbumCardProps (line 12) | type AlbumCardProps = { FILE: renderer/components/ui/badge.tsx type BadgeProps (line 25) | interface BadgeProps function Badge (line 29) | function Badge({ className, variant, ...props }: BadgeProps) { FILE: renderer/components/ui/button.tsx type ButtonProps (line 25) | interface ButtonProps FILE: renderer/components/ui/carousel.tsx type CarouselApi (line 18) | type CarouselApi = UseEmblaCarouselType[1]; type UseCarouselParameters (line 19) | type UseCarouselParameters = Parameters; type CarouselOptions (line 20) | type CarouselOptions = UseCarouselParameters[0]; type CarouselPlugin (line 21) | type CarouselPlugin = UseCarouselParameters[1]; type CarouselProps (line 23) | type CarouselProps = { type CarouselContextProps (line 30) | type CarouselContextProps = { function useCarousel (line 41) | function useCarousel() { FILE: renderer/components/ui/command.tsx type CommandDialogProps (line 26) | interface CommandDialogProps extends DialogProps {} FILE: renderer/components/ui/form.tsx type FormFieldContextValue (line 18) | type FormFieldContextValue< type FormItemContextValue (line 65) | type FormItemContextValue = { FILE: renderer/components/ui/input.tsx type InputProps (line 5) | interface InputProps FILE: renderer/components/ui/skeleton.tsx function Skeleton (line 3) | function Skeleton({ FILE: renderer/components/ui/songs.tsx type Playlist (line 38) | type Playlist = { type SongsProps (line 43) | type SongsProps = { FILE: renderer/components/ui/sonner.tsx type ToasterProps (line 6) | type ToasterProps = React.ComponentProps; FILE: renderer/components/ui/spinner.tsx type SpinnerProps (line 4) | interface SpinnerProps extends React.HTMLAttributes {} FILE: renderer/context/playerContext.tsx type Song (line 12) | interface Song { type PlayerState (line 26) | interface PlayerState { type PlayerContextType (line 37) | interface PlayerContextType extends PlayerState { function findSongIndexById (line 85) | function findSongIndexById(songs: Song[], id: number): number { FILE: renderer/hooks/useDebounce.ts function useDebounce (line 3) | function useDebounce(value: T, delay: number = 300): T { FILE: renderer/hooks/useScrollAreaRestoration.ts constant DEBUG (line 4) | const DEBUG = false; constant MAX_RESTORE_ATTEMPTS (line 5) | const MAX_RESTORE_ATTEMPTS = 10; constant RESTORE_ATTEMPT_DELAY (line 6) | const RESTORE_ATTEMPT_DELAY = 100; constant MAX_RESTORE_TIME (line 7) | const MAX_RESTORE_TIME = 2000; function useScrollAreaRestoration (line 9) | function useScrollAreaRestoration(key: string) { FILE: renderer/lib/albumCache.ts type Album (line 2) | interface Album { type AlbumCacheStore (line 12) | interface AlbumCacheStore { constant CACHE_TTL (line 44) | const CACHE_TTL = 5 * 60 * 1000; class AlbumCache (line 46) | class AlbumCache { method constructor (line 50) | private constructor() { method getInstance (line 69) | public static getInstance(): AlbumCache { method sortAlbums (line 77) | public sortAlbums( method getAllAlbums (line 137) | public getAllAlbums(): Album[] { method getFilteredAlbums (line 142) | public getFilteredAlbums(): Album[] { method getSearchResults (line 147) | public getSearchResults(): Album[] { method getPage (line 152) | public getPage(): number { method isInitialized (line 157) | public isInitialized(): boolean { method hasMore (line 162) | public hasMore(): boolean { method getSortSettings (line 167) | public getSortSettings(): { sortBy: string; sortOrder: string } { method getViewMode (line 175) | public getViewMode(): "grid" | "compact-grid" | "list" { method getLastSearchQuery (line 180) | public getLastSearchQuery(): string { method isStale (line 185) | public isStale(): boolean { method setAllAlbums (line 190) | public setAllAlbums(albums: Album[]): void { method addAlbums (line 197) | public addAlbums(newAlbums: Album[]): void { method setFilteredAlbums (line 210) | public setFilteredAlbums(albums: Album[]): void { method setSearchResults (line 216) | public setSearchResults(albums: Album[], query: string): void { method updatePagination (line 223) | public updatePagination(page: number, hasMore: boolean): void { method updateSortSettings (line 230) | public updateSortSettings(sortBy: string, sortOrder: string): void { method updateViewMode (line 237) | public updateViewMode(viewMode: "grid" | "compact-grid" | "list"): void { method getAlbumWithSongs (line 243) | public async getAlbumWithSongs(albumId: number): Promise { method setInitialized (line 270) | public setInitialized(): void { method resetCache (line 276) | public resetCache(): void { method resetState (line 284) | public resetState(resetData: Partial): void { method saveToLocalStorage (line 327) | private saveToLocalStorage(): void { FILE: renderer/lib/apiConfig.ts constant PROD_API_URL (line 5) | const PROD_API_URL = "https://wora-ten.vercel.app"; constant DEV_API_URL (line 6) | const DEV_API_URL = "http://localhost:3000"; constant API_BASE_URL (line 9) | const API_BASE_URL = isDev ? DEV_API_URL : PROD_API_URL; FILE: renderer/lib/helpers.ts type MetadataResponse (line 6) | interface MetadataResponse { type LyricLine (line 11) | interface LyricLine { function fetchCover (line 31) | async function fetchCover(artist: string, album: string) { type DiscordState (line 157) | interface DiscordState { FILE: renderer/lib/lastfm-client.ts constant LASTFM_API_BASE (line 10) | const LASTFM_API_BASE = `${API_BASE_URL}/api/lastfm`; FILE: renderer/lib/lastfm.ts type Song (line 4) | interface Song { type LastFmUserCache (line 18) | interface LastFmUserCache { constant CACHE_EXPIRY_MS (line 29) | const CACHE_EXPIRY_MS = 24 * 60 * 60 * 1000; FILE: renderer/lib/songCache.ts type SongCacheStore (line 5) | interface SongCacheStore { constant CACHE_TTL (line 33) | const CACHE_TTL = 5 * 60 * 1000; class SongCache (line 35) | class SongCache { method constructor (line 39) | private constructor() { method getInstance (line 58) | public static getInstance(): SongCache { method sortSongs (line 66) | public sortSongs(songs: Song[], sortBy: string, sortOrder: string): So... method getAllSongs (line 92) | public getAllSongs(): Song[] { method getFilteredSongs (line 97) | public getFilteredSongs(): Song[] { method getSearchResults (line 102) | public getSearchResults(): Song[] { method getPage (line 107) | public getPage(): number { method isInitialized (line 112) | public isInitialized(): boolean { method hasMore (line 117) | public hasMore(): boolean { method getSortSettings (line 122) | public getSortSettings(): { sortBy: string; sortOrder: string } { method getLastSearchQuery (line 130) | public getLastSearchQuery(): string { method isStale (line 135) | public isStale(): boolean { method setAllSongs (line 140) | public setAllSongs(songs: Song[]): void { method addSongs (line 147) | public addSongs(newSongs: Song[]): void { method setFilteredSongs (line 158) | public setFilteredSongs(songs: Song[]): void { method setSearchResults (line 164) | public setSearchResults(songs: Song[], query: string): void { method updatePagination (line 171) | public updatePagination(page: number, hasMore: boolean): void { method updateSortSettings (line 178) | public updateSortSettings(sortBy: string, sortOrder: string): void { method setInitialized (line 185) | public setInitialized(): void { method resetCache (line 191) | public resetCache(): void { method resetState (line 199) | public resetState(resetData: Partial): void { method saveToLocalStorage (line 239) | private saveToLocalStorage(): void { FILE: renderer/lib/utils.ts function cn (line 4) | function cn(...inputs: ClassValue[]) { FILE: renderer/pages/_app.tsx constant SPECIAL_LAYOUTS (line 14) | const SPECIAL_LAYOUTS = ["/setup"]; function App (line 16) | function App({ Component, pageProps }) { FILE: renderer/pages/albums.tsx type ViewMode (line 34) | type ViewMode = "grid-large" | "grid-small" | "list"; function Albums (line 37) | function Albums() { FILE: renderer/pages/albums/[slug].tsx type Album (line 16) | type Album = { function Album (line 25) | function Album() { FILE: renderer/pages/artists/[name].tsx type Album (line 20) | type Album = { type Artist (line 29) | type Artist = { type ArtistInfo (line 50) | type ArtistInfo = { type TopTrack (line 72) | type TopTrack = { function ArtistView (line 81) | function ArtistView() { FILE: renderer/pages/artists/index.tsx type ArtistItem (line 26) | type ArtistItem = { type ViewMode (line 33) | type ViewMode = "grid-large" | "grid-small" | "list"; type SortBy (line 34) | type SortBy = "name" | "albums" | "songs"; type SortOrder (line 35) | type SortOrder = "asc" | "desc"; function ArtistsPage (line 38) | function ArtistsPage() { FILE: renderer/pages/home.tsx function Home (line 16) | function Home() { FILE: renderer/pages/playlists.tsx function Playlists (line 38) | function Playlists() { FILE: renderer/pages/playlists/[slug].tsx type Playlist (line 47) | type Playlist = { function Playlist (line 55) | function Playlist() { FILE: renderer/pages/settings.tsx type Settings (line 59) | type Settings = { type LastFmSettings (line 69) | type LastFmSettings = { function Settings (line 76) | function Settings() { FILE: renderer/pages/setup.tsx function Setup (line 10) | function Setup() { FILE: renderer/pages/songs.tsx function AllSongs (line 25) | function AllSongs() { FILE: renderer/preload.d.ts type Window (line 4) | interface Window { FILE: vercel/pages/_app.tsx function App (line 3) | function App({ Component, pageProps }: AppProps) { FILE: vercel/pages/api/config.ts constant LASTFM_CONFIG (line 3) | const LASTFM_CONFIG = { FILE: vercel/pages/api/index.ts function handler (line 3) | function handler(req: NextApiRequest, res: NextApiResponse) { FILE: vercel/pages/api/lastfm/auth.ts function handler (line 6) | async function handler( FILE: vercel/pages/api/lastfm/now-playing.ts function handler (line 5) | async function handler( FILE: vercel/pages/api/lastfm/scrobble.ts function handler (line 5) | async function handler( FILE: vercel/pages/api/lastfm/track-info.ts function handler (line 4) | async function handler( FILE: vercel/pages/api/lastfm/user-info.ts function handler (line 5) | async function handler( FILE: vercel/pages/index.tsx function Home (line 3) | function Home() {