import React, { useState, useEffect, useRef } from 'react' import Header from '../components/Header' import Sidebar from '../components/Sidebar' import AppList from '../components/AppList' import MovieSearch from '../components/MovieSearch' import '../styles/main.css' import { AppEntry, Bookmark } from '../components/Settings' interface OpenedApp { name: string imageUrl: string url: string } const HomePage: React.FC = () => { const [openedApps, setOpenedApps] = useState([]) const [activeApp, setActiveApp] = useState('home') const [appCardList, setAppCardList] = useState([]) const [movieQuery, setMovieQuery] = useState(null) const [movieSearchKey, setMovieSearchKey] = useState(0) const [openedFromSearch, setOpenedFromSearch] = useState(false) const [bookmarks, setBookmarks] = useState([]) const configRef = useRef({}) useEffect(() => { if (!window.electron) return window.electron.readConfig().then((cfg: any) => { configRef.current = cfg ?? {} if (cfg?.apps) setAppCardList(cfg.apps) if (cfg?.bookmarks) setBookmarks(cfg.bookmarks) if (cfg?.proxy?.host && cfg?.proxy?.port) { window.electron!.setProxy(cfg.proxy.host, cfg.proxy.port) } }) const offOpenedApps = window.electron.on('update-opened-apps', (apps: OpenedApp[], activeName: string) => { setOpenedApps(apps) setActiveApp(activeName ?? 'home') }) const offAlert = window.electron.on('alert', (text: string) => alert(text)) return () => { offOpenedApps(); offAlert() } }, []) const handleSidebarAppClick = (name: string) => { setActiveApp(name) window.electron?.showView(name) } const handleMovieSearch = (query: string) => { window.electron?.hideView() setMovieQuery(query) setMovieSearchKey(k => k + 1) setOpenedFromSearch(false) setActiveApp('movie-search') } const handleMovieSearchOpen = (name: string, url: string) => { window.electron?.createView(name, url, '', 1.0, resolveUseProxy(url)) setOpenedFromSearch(true) setActiveApp(name) } const handleBackToSearch = () => { window.electron?.hideView() setActiveApp('movie-search') } const handleBookmarkAdd = (title: string, url: string, poster: string, source: string, siteIcon?: string) => { // If caller didn't pass a site icon (e.g. movie search), look it up from the apps config by host. let icon = siteIcon || '' if (!icon) { try { const host = new URL(url).hostname const match = appCardList.find(a => { try { return new URL(a.url).hostname === host } catch { return false } }) if (match?.imageUrl) icon = match.imageUrl } catch {} } const sourceStr = source || (() => { try { return new URL(url).hostname.replace(/^www\./, '') } catch { return '' } })() const updated = [...bookmarks, { title, url, poster, source: sourceStr, siteIcon: icon }] setBookmarks(updated) configRef.current = { ...configRef.current, bookmarks: updated } window.electron?.writeConfig(configRef.current) } const handleBookmarkRemove = (index: number) => { const updated = bookmarks.filter((_, i) => i !== index) setBookmarks(updated) configRef.current = { ...configRef.current, bookmarks: updated } window.electron?.writeConfig(configRef.current) } const resolveUseProxy = (url: string) => { try { const host = new URL(url).hostname const match = appCardList.find(a => { try { return new URL(a.url).hostname === host } catch { return false } }) return match ? match.useProxy : true } catch { return true } } const handleBookmarkOpen = (b: Bookmark) => { window.electron?.createView(b.title, b.url, b.poster || '', 1.0, resolveUseProxy(b.url)) setActiveApp(b.title) } const sidebarApps = openedApps.map(app => ({ ...app, isActive: activeApp === app.name, onClick: () => handleSidebarAppClick(app.name), })) return ( <>
{activeApp !== 'movie-search' && ( )} ) } export default HomePage