mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-06-05 13:55:18 -04:00
Start server url selector page for native
This commit is contained in:
@@ -25,7 +25,7 @@ export { MovieDetails, ShowDetails } from "./details";
|
||||
export { CollectionPage } from "./collection";
|
||||
export { Player } from "./player";
|
||||
export { SearchPage } from "./search";
|
||||
export { LoginPage, RegisterPage, OidcCallbackPage } from "./login";
|
||||
export { ServerUrlPage, LoginPage, RegisterPage, OidcCallbackPage } from "./login";
|
||||
export { DownloadPage, DownloadProvider } from "./downloads";
|
||||
export { SettingsPage } from "./settings";
|
||||
export { AdminPage } from "./admin";
|
||||
|
||||
@@ -20,4 +20,5 @@
|
||||
|
||||
export { LoginPage } from "./login";
|
||||
export { RegisterPage } from "./register";
|
||||
export { ServerUrlPage } from "./server-url";
|
||||
export { OidcCallbackPage } from "./oidc";
|
||||
|
||||
@@ -31,15 +31,7 @@ import { FormPage } from "./form";
|
||||
import { PasswordInput } from "./password-input";
|
||||
import { OidcLogin } from "./oidc";
|
||||
|
||||
export const cleanApiUrl = (apiUrl: string) => {
|
||||
if (Platform.OS === "web") return undefined;
|
||||
if (!/https?:\/\//.test(apiUrl)) apiUrl = "http://" + apiUrl;
|
||||
apiUrl = apiUrl.replace(/\/$/, "");
|
||||
return apiUrl + "/api";
|
||||
};
|
||||
|
||||
export const LoginPage: QueryPage<{ error?: string }> = ({ error: initialError }) => {
|
||||
const [apiUrl, setApiUrl] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState<string | undefined>(initialError);
|
||||
@@ -49,19 +41,9 @@ export const LoginPage: QueryPage<{ error?: string }> = ({ error: initialError }
|
||||
const { css } = useYoshiki();
|
||||
|
||||
return (
|
||||
<FormPage
|
||||
{...css({
|
||||
marginTop: Platform.OS === "web" ? ts(6) : 0,
|
||||
})}
|
||||
>
|
||||
<FormPage>
|
||||
<H1>{t("login.login")}</H1>
|
||||
<OidcLogin />
|
||||
{Platform.OS !== "web" && (
|
||||
<>
|
||||
<P {...css({ paddingLeft: ts(1) })}>{t("login.server")}</P>
|
||||
<Input variant="big" onChangeText={setApiUrl} />
|
||||
</>
|
||||
)}
|
||||
<P {...css({ paddingLeft: ts(1) })}>{t("login.username")}</P>
|
||||
<Input autoComplete="username" variant="big" onChangeText={(value) => setUsername(value)} />
|
||||
<P {...css({ paddingLeft: ts(1) })}>{t("login.password")}</P>
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
KyooErrors,
|
||||
QueryIdentifier,
|
||||
QueryPage,
|
||||
ServerInfo,
|
||||
@@ -31,7 +30,7 @@ import { Button, HR, P, Skeleton, ts } from "@kyoo/primitives";
|
||||
import { View, ImageBackground } from "react-native";
|
||||
import { percent, rem, useYoshiki } from "yoshiki/native";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useRouter } from "solito/router";
|
||||
import { ErrorView } from "../errors";
|
||||
|
||||
|
||||
@@ -29,11 +29,9 @@ import { percent, px, useYoshiki } from "yoshiki/native";
|
||||
import { DefaultLayout } from "../layout";
|
||||
import { FormPage } from "./form";
|
||||
import { PasswordInput } from "./password-input";
|
||||
import { cleanApiUrl } from "./login";
|
||||
import { OidcLogin } from "./oidc";
|
||||
|
||||
export const RegisterPage: QueryPage = () => {
|
||||
const [apiUrl, setApiUrl] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
@@ -86,7 +84,6 @@ export const RegisterPage: QueryPage = () => {
|
||||
const { error } = await login(
|
||||
"register",
|
||||
{ email, username, password, apiUrl: cleanApiUrl(apiUrl) },
|
||||
5_000,
|
||||
);
|
||||
setError(error);
|
||||
if (error) return;
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { QueryIdentifier, QueryPage, ServerInfo, ServerInfoP, useFetch } from "@kyoo/models";
|
||||
import { Button, P, Input, ts, H1, HR } from "@kyoo/primitives";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Platform, View } from "react-native";
|
||||
import { useRouter } from "solito/router";
|
||||
import { Theme, useYoshiki } from "yoshiki/native";
|
||||
import { DefaultLayout } from "../layout";
|
||||
|
||||
export const cleanApiUrl = (apiUrl: string) => {
|
||||
if (Platform.OS === "web") return undefined;
|
||||
if (!/https?:\/\//.test(apiUrl)) apiUrl = "http://" + apiUrl;
|
||||
apiUrl = apiUrl.replace(/\/$/, "");
|
||||
return apiUrl + "/api";
|
||||
};
|
||||
|
||||
const query: QueryIdentifier<ServerInfo> = {
|
||||
path: ["info"],
|
||||
parser: ServerInfoP,
|
||||
};
|
||||
|
||||
export const ServerUrlPage: QueryPage = () => {
|
||||
const [apiUrl, setApiUrl] = useState("");
|
||||
const { data, error } = useFetch(query);
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const { css } = useYoshiki();
|
||||
|
||||
return (
|
||||
<View
|
||||
{...css({
|
||||
marginX: ts(3),
|
||||
justifyContent: "space-between",
|
||||
flexGrow: 1,
|
||||
})}
|
||||
>
|
||||
<H1>{t("login.server")}</H1>
|
||||
<View {...css({ justifyContent: "center" })}>
|
||||
<Input variant="big" onChangeText={setApiUrl} />
|
||||
{error && (
|
||||
<P {...css({ color: (theme: Theme) => theme.colors.red, alignSelf: "center" })}>
|
||||
{error.errors[0]}
|
||||
</P>
|
||||
)}
|
||||
</View>
|
||||
<View {...css({ marginTop: ts(5) })}>
|
||||
<Button
|
||||
text={t("login.guest")}
|
||||
onPress={() => {}}
|
||||
disabled={error != null || data?.allowGuests != true}
|
||||
/>
|
||||
<HR />
|
||||
<View {...css({ flexDirection: "row", gap: ts(2) })}>
|
||||
<Button
|
||||
text={t("login.login")}
|
||||
onPress={async () => {
|
||||
router.replace(`/login?apiUrl=${apiUrl}`, undefined, {
|
||||
experimental: { nativeBehavior: "stack-replace", isNestedNavigator: false },
|
||||
});
|
||||
}}
|
||||
disabled={error != null}
|
||||
{...css({ flexGrow: 1, flexShrink: 1 })}
|
||||
/>
|
||||
<Button
|
||||
text={t("login.register")}
|
||||
onPress={async () => {
|
||||
router.replace(`/register?apiUrl=${apiUrl}`, undefined, {
|
||||
experimental: { nativeBehavior: "stack-replace", isNestedNavigator: false },
|
||||
});
|
||||
}}
|
||||
disabled={error != null}
|
||||
{...css({ flexGrow: 1, flexShrink: 1 })}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
ServerUrlPage.getLayout = DefaultLayout;
|
||||
Reference in New Issue
Block a user