/*
* 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 (
);
};
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 : }
);
};