/* * Kyoo - A portable and vast media library solution. * Copyright (c) Kyoo. * * See AUTHORS.md and LICENSE file in the project root for full license information. * * Kyoo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Kyoo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kyoo. If not, see . */ import { deleteAccount, logout, useAccount, useAccounts } from "@kyoo/models"; import { Alert, Input, IconButton, Header, Avatar, A, tooltip, ts, Menu, PressableFeedback, HR, } from "@kyoo/primitives"; import { Platform, TextInput, View, ViewProps } from "react-native"; import { useTranslation } from "react-i18next"; import { useRouter } from "solito/router"; import { Stylable, useYoshiki } from "yoshiki/native"; import Search from "@material-symbols/svg-400/rounded/search-fill.svg"; import Login from "@material-symbols/svg-400/rounded/login.svg"; import Register from "@material-symbols/svg-400/rounded/app_registration.svg"; import Logout from "@material-symbols/svg-400/rounded/logout.svg"; import Delete from "@material-symbols/svg-400/rounded/delete.svg"; import Settings from "@material-symbols/svg-400/rounded/settings.svg"; import { KyooLongLogo } from "./icon"; import { forwardRef, useEffect, useRef, useState } from "react"; export const NavbarTitle = (props: Stylable & { onLayout?: ViewProps["onLayout"] }) => { const { t } = useTranslation(); return ( ); }; const SearchBar = forwardRef(function SearchBar(props, ref) { const { theme } = useYoshiki(); const { t } = useTranslation(); const { push, replace, back } = useRouter(); const hasChanged = useRef(false); const [query, setQuery] = useState(""); useEffect(() => { if (Platform.OS !== "web" || !hasChanged.current) return; const action = window.location.pathname.startsWith("/search") ? replace : push; if (query) action(`/search?q=${encodeURI(query)}`, undefined, { shallow: true }); else back(); }, [query, push, replace, back]); return ( { hasChanged.current = true; setQuery(q); }} placeholder={t("navbar.search")} placeholderTextColor={theme.colors.white} containerStyle={{ height: ts(4), flexShrink: 1, borderColor: (theme) => theme.colors.white }} {...tooltip(t("navbar.search"))} {...props} /> ); }); const getDisplayUrl = (url: string) => { url = url.replace(/\/api$/, ""); url = url.replace(/https?:\/\//, ""); return url; }; export const NavbarProfile = () => { const { css, theme } = useYoshiki(); const { t } = useTranslation(); const account = useAccount(); const accounts = useAccounts(); return ( {accounts?.map((x) => ( } selected={x.selected} onSelect={() => x.select()} /> ))} {accounts.length > 0 &&
} {!account ? ( <> ) : ( <> { Alert.alert( t("login.delete"), t("login.delete-confirmation"), [ { text: t("misc.cancel"), style: "cancel" }, { text: t("misc.delete"), onPress: deleteAccount, style: "destructive", }, ], { cancelable: true, userInterfaceStyle: theme.mode === "auto" ? "light" : theme.mode, icon: "warning", }, ); }} /> )}
); }; export const NavbarRight = () => { const { css, theme } = useYoshiki(); const { t } = useTranslation(); const { push } = useRouter(); return ( {Platform.OS === "web" ? ( ) : ( push("/search")} {...tooltip(t("navbar.search"))} /> )} ); }; export const Navbar = (props: Stylable) => { const { css } = useYoshiki(); const { t } = useTranslation(); return (
theme.accent, paddingX: ts(2), height: { xs: 48, sm: 64 }, flexDirection: "row", justifyContent: { xs: "space-between", sm: "flex-start" }, alignItems: "center", shadowColor: "#000", shadowOffset: { width: 0, height: 4, }, shadowOpacity: 0.3, shadowRadius: 4.65, elevation: 8, zIndex: 1, }, props, )} > theme.contrast, })} > {t("navbar.browse")}
); };