/* * 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 { logout, useAccount, useAccounts, useHasPermission } from "@kyoo/models"; import { A, Avatar, HR, Header, IconButton, Input, Link, Menu, PressableFeedback, tooltip, ts, } from "@kyoo/primitives"; import Admin from "@material-symbols/svg-400/rounded/admin_panel_settings.svg"; import Register from "@material-symbols/svg-400/rounded/app_registration.svg"; import Login from "@material-symbols/svg-400/rounded/login.svg"; import Logout from "@material-symbols/svg-400/rounded/logout.svg"; import Search from "@material-symbols/svg-400/rounded/search-fill.svg"; import Settings from "@material-symbols/svg-400/rounded/settings.svg"; import { type ReactElement, forwardRef, useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Platform, type TextInput, View, type ViewProps } from "react-native"; import { useRouter } from "solito/router"; import { type Stylable, percent, useYoshiki } from "yoshiki/native"; import { AdminPage } from "../admin"; import { KyooLongLogo } from "./icon"; export const NavbarTitle = (props: Stylable & { onLayout?: ViewProps["onLayout"] }) => { const { t } = useTranslation(); const { css } = useYoshiki(); 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 ? ( <> ) : ( <> )}
); }; export const NavbarRight = () => { const { css, theme } = useYoshiki(); const { t } = useTranslation(); const { push } = useRouter(); const isAdmin = useHasPermission(AdminPage.requiredPermissions); return ( {Platform.OS === "web" ? ( ) : ( push("/search")} {...tooltip(t("navbar.search"))} /> )} {isAdmin && ( )} ); }; export const Navbar = ({ left, right, ...props }: { left?: ReactElement | null; right?: ReactElement | null } & 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, )} > {left !== undefined ? ( left ) : ( <> theme.contrast, })} > {t("navbar.browse")} )} {right !== undefined ? right : }
); };